js:add lib and .d.ts
This commit is contained in:
parent
624e90e4a8
commit
7cde16a75d
2
doric-js/.gitignore
vendored
2
doric-js/.gitignore
vendored
@ -1,5 +1,3 @@
|
||||
node_modules/
|
||||
build/
|
||||
demo/
|
||||
.DS_Store
|
||||
package-lock.json
|
6
doric-js/lib/index.d.ts
vendored
Normal file
6
doric-js/lib/index.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
export * from './src/runtime/global';
|
||||
export * from './src/ui/index.ui';
|
||||
export * from "./src/widget/index.widget";
|
||||
export * from './src/native/index.native';
|
||||
export * from "./src/util/index.util";
|
||||
export * from "./src/pattern/index.pattern";
|
1
doric-js/lib/index.debug.d.ts
vendored
Normal file
1
doric-js/lib/index.debug.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './index';
|
108
doric-js/lib/index.debug.js
Normal file
108
doric-js/lib/index.debug.js
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import * as doric from './src/runtime/sandbox';
|
||||
import * as WebSocket from 'ws';
|
||||
const WebSocketClient = require('ws');
|
||||
const fs = require('fs');
|
||||
let context = process.cwd() + '/build/context';
|
||||
const contextId = fs.readFileSync(context, { encoding: 'utf8' });
|
||||
console.log("debugging context id: " + contextId);
|
||||
let global = new Function('return this')();
|
||||
global.doric = doric;
|
||||
global.context = doric.jsObtainContext(contextId);
|
||||
global.Entry = doric.jsObtainEntry(contextId);
|
||||
// dev kit client
|
||||
const devClient = new WebSocketClient('ws://localhost:7777');
|
||||
devClient.on('open', function open() {
|
||||
console.log('dev kit connected on 7777');
|
||||
});
|
||||
devClient.on('message', function incoming(data) {
|
||||
console.log(data);
|
||||
});
|
||||
devClient.on('error', function incoming(error) {
|
||||
console.log(error);
|
||||
});
|
||||
// debug server
|
||||
const debugServer = new WebSocket.Server({ port: 2080 });
|
||||
debugServer.on('connection', function connection(ws) {
|
||||
console.log('connected');
|
||||
ws.on('message', function incoming(message) {
|
||||
let messageObject = JSON.parse(message);
|
||||
switch (messageObject.cmd) {
|
||||
case "injectGlobalJSFunction":
|
||||
console.log(messageObject.name);
|
||||
Reflect.set(global, messageObject.name, function () {
|
||||
let args = [].slice.call(arguments);
|
||||
console.log("===============================");
|
||||
console.log(args);
|
||||
console.log("===============================");
|
||||
ws.send(JSON.stringify({
|
||||
cmd: 'injectGlobalJSFunction',
|
||||
name: messageObject.name,
|
||||
arguments: args
|
||||
}));
|
||||
});
|
||||
break;
|
||||
case "invokeMethod":
|
||||
console.log(messageObject.objectName);
|
||||
console.log(messageObject.functionName);
|
||||
let args = [];
|
||||
for (let i = 0; i < messageObject.javaValues.length; i++) {
|
||||
let javaValue = messageObject.javaValues[i];
|
||||
if (javaValue.type === 0) {
|
||||
args.push(null);
|
||||
}
|
||||
else if (javaValue.type === 1) {
|
||||
args.push(parseFloat(javaValue.value));
|
||||
}
|
||||
else if (javaValue.type === 2) {
|
||||
args.push((javaValue.value == 'true'));
|
||||
}
|
||||
else if (javaValue.type === 3) {
|
||||
args.push(javaValue.value.toString());
|
||||
}
|
||||
else if (javaValue.type === 4) {
|
||||
args.push(JSON.parse(javaValue.value));
|
||||
}
|
||||
else if (javaValue.type === 5) {
|
||||
args.push(JSON.parse(javaValue.value));
|
||||
}
|
||||
}
|
||||
console.log(args);
|
||||
console.log(messageObject.hashKey);
|
||||
let object = Reflect.get(global, messageObject.objectName);
|
||||
let method = Reflect.get(object, messageObject.functionName);
|
||||
let result = Reflect.apply(method, undefined, args);
|
||||
console.log(result);
|
||||
ws.send(JSON.stringify({
|
||||
cmd: 'invokeMethod',
|
||||
result: result
|
||||
}));
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
debugServer.on('listening', function connection(ws) {
|
||||
console.log('debugger server started on 2080');
|
||||
});
|
||||
global.injectGlobal = (objName, obj) => {
|
||||
Reflect.set(global, objName, JSON.parse(obj));
|
||||
};
|
||||
global.sendToNative = () => {
|
||||
};
|
||||
global.receiveFromNative = () => {
|
||||
};
|
||||
export * from './index';
|
5
doric-js/lib/index.js
Normal file
5
doric-js/lib/index.js
Normal file
@ -0,0 +1,5 @@
|
||||
export * from './src/ui/index.ui';
|
||||
export * from "./src/widget/index.widget";
|
||||
export * from './src/native/index.native';
|
||||
export * from "./src/util/index.util";
|
||||
export * from "./src/pattern/index.pattern";
|
1
doric-js/lib/index.runtime.d.ts
vendored
Normal file
1
doric-js/lib/index.runtime.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './src/runtime/sandbox';
|
16
doric-js/lib/index.runtime.js
Normal file
16
doric-js/lib/index.runtime.js
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export * from './src/runtime/sandbox';
|
24
doric-js/lib/src/mock/driver.d.ts
vendored
Normal file
24
doric-js/lib/src/mock/driver.d.ts
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
import { Panel } from '../ui/panel';
|
||||
import { View } from '../ui/view';
|
||||
export interface Driver {
|
||||
/**
|
||||
* Create and destory page
|
||||
*/
|
||||
createPage(): Panel;
|
||||
destoryPage(): Panel;
|
||||
/**
|
||||
* Page lifecycle
|
||||
*/
|
||||
dispatchOnCreate(): void;
|
||||
dispatchOnDestory(): void;
|
||||
dispatchOnShow(): void;
|
||||
dispatchOnHidden(): void;
|
||||
/**
|
||||
* Page render
|
||||
*/
|
||||
dispatchBuild(): View;
|
||||
}
|
||||
export interface Responser {
|
||||
constructor(): void;
|
||||
respond(action: string, extra: any): void;
|
||||
}
|
0
doric-js/lib/src/mock/driver.js
Normal file
0
doric-js/lib/src/mock/driver.js
Normal file
9
doric-js/lib/src/native/animate.d.ts
vendored
Normal file
9
doric-js/lib/src/native/animate.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
/**
|
||||
* Only supports x,y,width,height,corner(just for four corners),rotation,bgColor,
|
||||
* @param panel @see Panel
|
||||
*/
|
||||
export declare function animate(context: BridgeContext): (args: {
|
||||
animations: () => void;
|
||||
duration: number;
|
||||
}) => Promise<any>;
|
57
doric-js/lib/src/native/animate.js
Normal file
57
doric-js/lib/src/native/animate.js
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Panel } from "../ui/panel";
|
||||
import { takeLet } from "../pattern/candies";
|
||||
/**
|
||||
* Only supports x,y,width,height,corner(just for four corners),rotation,bgColor,
|
||||
* @param panel @see Panel
|
||||
*/
|
||||
export function animate(context) {
|
||||
const entity = context.entity;
|
||||
if (entity instanceof Panel) {
|
||||
let panel = entity;
|
||||
return (args) => {
|
||||
return takeLet(panel.context.animate)(it => {
|
||||
return it.submit().then(() => {
|
||||
args.animations();
|
||||
return takeLet(panel.getRootView())(root => {
|
||||
if (root.isDirty()) {
|
||||
const model = root.toModel();
|
||||
model.duration = args.duration;
|
||||
const ret = it.animateRender(model);
|
||||
root.clean();
|
||||
return ret;
|
||||
}
|
||||
for (let v of panel.allHeadViews()) {
|
||||
if (v.isDirty()) {
|
||||
const model = v.toModel();
|
||||
const ret = it.animateRender(model);
|
||||
it.clean();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
throw new Error('Cannot find any animated elements');
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
else {
|
||||
return (args) => {
|
||||
return Promise.reject(`Cannot find panel in Context:${context.id}`);
|
||||
};
|
||||
}
|
||||
}
|
7
doric-js/lib/src/native/index.native.d.ts
vendored
Normal file
7
doric-js/lib/src/native/index.native.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
export * from './modal';
|
||||
export * from './navbar';
|
||||
export * from './navigator';
|
||||
export * from './network';
|
||||
export * from './storage';
|
||||
export * from './popover';
|
||||
export * from './animate';
|
22
doric-js/lib/src/native/index.native.js
Normal file
22
doric-js/lib/src/native/index.native.js
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export * from './modal';
|
||||
export * from './navbar';
|
||||
export * from './navigator';
|
||||
export * from './network';
|
||||
export * from './storage';
|
||||
export * from './popover';
|
||||
export * from './animate';
|
24
doric-js/lib/src/native/modal.d.ts
vendored
Normal file
24
doric-js/lib/src/native/modal.d.ts
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
import { Gravity } from "../util/gravity";
|
||||
export declare function modal(context: BridgeContext): {
|
||||
toast: (msg: string, gravity?: Gravity) => void;
|
||||
alert: (arg: string | {
|
||||
title: string;
|
||||
msg: string;
|
||||
okLabel?: string | undefined;
|
||||
}) => Promise<any>;
|
||||
confirm: (arg: string | {
|
||||
title: string;
|
||||
msg: string;
|
||||
okLabel?: string | undefined;
|
||||
cancelLabel?: string | undefined;
|
||||
}) => Promise<any>;
|
||||
prompt: (arg: {
|
||||
title?: string | undefined;
|
||||
msg?: string | undefined;
|
||||
okLabel?: string | undefined;
|
||||
cancelLabel?: string | undefined;
|
||||
text?: string | undefined;
|
||||
defaultText?: string | undefined;
|
||||
}) => Promise<string>;
|
||||
};
|
30
doric-js/lib/src/native/modal.js
Normal file
30
doric-js/lib/src/native/modal.js
Normal file
@ -0,0 +1,30 @@
|
||||
import { Gravity } from "../util/gravity";
|
||||
export function modal(context) {
|
||||
return {
|
||||
toast: (msg, gravity = Gravity.Bottom) => {
|
||||
context.modal.toast({
|
||||
msg,
|
||||
gravity: gravity.toModel(),
|
||||
});
|
||||
},
|
||||
alert: (arg) => {
|
||||
if (typeof arg === 'string') {
|
||||
return context.modal.alert({ msg: arg });
|
||||
}
|
||||
else {
|
||||
return context.modal.alert(arg);
|
||||
}
|
||||
},
|
||||
confirm: (arg) => {
|
||||
if (typeof arg === 'string') {
|
||||
return context.modal.confirm({ msg: arg });
|
||||
}
|
||||
else {
|
||||
return context.modal.confirm(arg);
|
||||
}
|
||||
},
|
||||
prompt: (arg) => {
|
||||
return context.modal.prompt(arg);
|
||||
},
|
||||
};
|
||||
}
|
8
doric-js/lib/src/native/navbar.d.ts
vendored
Normal file
8
doric-js/lib/src/native/navbar.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
import { Color } from "../util/color";
|
||||
export declare function navbar(context: BridgeContext): {
|
||||
isHidden: () => Promise<boolean>;
|
||||
setHidden: (hidden: boolean) => Promise<any>;
|
||||
setTitle: (title: string) => Promise<any>;
|
||||
setBgColor: (color: Color) => Promise<any>;
|
||||
};
|
28
doric-js/lib/src/native/navbar.js
Normal file
28
doric-js/lib/src/native/navbar.js
Normal file
@ -0,0 +1,28 @@
|
||||
import { Panel } from "../ui/panel";
|
||||
export function navbar(context) {
|
||||
const entity = context.entity;
|
||||
let panel = undefined;
|
||||
if (entity instanceof Panel) {
|
||||
panel = entity;
|
||||
}
|
||||
return {
|
||||
isHidden: () => {
|
||||
return context.navbar.isHidden();
|
||||
},
|
||||
setHidden: (hidden) => {
|
||||
return context.navbar.setHidden({
|
||||
hidden,
|
||||
});
|
||||
},
|
||||
setTitle: (title) => {
|
||||
return context.navbar.setTitle({
|
||||
title,
|
||||
});
|
||||
},
|
||||
setBgColor: (color) => {
|
||||
return context.navbar.setBgColor({
|
||||
color: color.toModel(),
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
9
doric-js/lib/src/native/navigator.d.ts
vendored
Normal file
9
doric-js/lib/src/native/navigator.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
export declare function navigator(context: BridgeContext): {
|
||||
push: (scheme: string, config?: {
|
||||
alias?: string | undefined;
|
||||
animated?: boolean | undefined;
|
||||
extra?: object | undefined;
|
||||
} | undefined) => Promise<any>;
|
||||
pop: (animated?: boolean) => Promise<any>;
|
||||
};
|
15
doric-js/lib/src/native/navigator.js
Normal file
15
doric-js/lib/src/native/navigator.js
Normal file
@ -0,0 +1,15 @@
|
||||
export function navigator(context) {
|
||||
return {
|
||||
push: (scheme, config) => {
|
||||
if (config && config.extra) {
|
||||
config.extra = JSON.stringify(config.extra);
|
||||
}
|
||||
return context.navigator.push({
|
||||
scheme, config
|
||||
});
|
||||
},
|
||||
pop: (animated = true) => {
|
||||
return context.navigator.pop({ animated });
|
||||
},
|
||||
};
|
||||
}
|
27
doric-js/lib/src/native/network.d.ts
vendored
Normal file
27
doric-js/lib/src/native/network.d.ts
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
export interface IRequest {
|
||||
url?: string;
|
||||
method?: "get" | "post" | "put" | "delete";
|
||||
headers?: {
|
||||
[index: string]: string;
|
||||
};
|
||||
params?: {
|
||||
[index: string]: string;
|
||||
};
|
||||
data?: object | string;
|
||||
timeout?: number;
|
||||
}
|
||||
export interface IResponse {
|
||||
data: any;
|
||||
status: number;
|
||||
headers?: {
|
||||
[index: string]: string;
|
||||
};
|
||||
}
|
||||
export declare function network(context: BridgeContext): {
|
||||
request: (config: IRequest) => Promise<IResponse>;
|
||||
get: (url: string, config?: IRequest | undefined) => Promise<IResponse>;
|
||||
post: (url: string, data?: string | object | undefined, config?: IRequest | undefined) => Promise<IResponse>;
|
||||
put: (url: string, data?: string | object | undefined, config?: IRequest | undefined) => Promise<IResponse>;
|
||||
delete: (url: string, data?: string | object | undefined, config?: IRequest | undefined) => Promise<IResponse>;
|
||||
};
|
63
doric-js/lib/src/native/network.js
Normal file
63
doric-js/lib/src/native/network.js
Normal file
@ -0,0 +1,63 @@
|
||||
function transformRequest(request) {
|
||||
let url = request.url || "";
|
||||
if (request.params !== undefined) {
|
||||
const queryStrings = [];
|
||||
for (let key in request.params) {
|
||||
queryStrings.push(`${key}=${encodeURIComponent(request.params[key])}`);
|
||||
}
|
||||
request.url = `${request.url}${url.indexOf('?') >= 0 ? '&' : '?'}${queryStrings.join('&')}`;
|
||||
}
|
||||
if (typeof request.data === 'object') {
|
||||
request.data = JSON.stringify(request.data);
|
||||
}
|
||||
return request;
|
||||
}
|
||||
export function network(context) {
|
||||
return {
|
||||
request: (config) => {
|
||||
return context.network.request(transformRequest(config));
|
||||
},
|
||||
get: (url, config) => {
|
||||
let finalConfig = config;
|
||||
if (finalConfig === undefined) {
|
||||
finalConfig = {};
|
||||
}
|
||||
finalConfig.url = url;
|
||||
finalConfig.method = "get";
|
||||
return context.network.request(transformRequest(finalConfig));
|
||||
},
|
||||
post: (url, data, config) => {
|
||||
let finalConfig = config;
|
||||
if (finalConfig === undefined) {
|
||||
finalConfig = {};
|
||||
}
|
||||
finalConfig.url = url;
|
||||
finalConfig.method = "post";
|
||||
if (data !== undefined) {
|
||||
finalConfig.data = data;
|
||||
}
|
||||
return context.network.request(transformRequest(finalConfig));
|
||||
},
|
||||
put: (url, data, config) => {
|
||||
let finalConfig = config;
|
||||
if (finalConfig === undefined) {
|
||||
finalConfig = {};
|
||||
}
|
||||
finalConfig.url = url;
|
||||
finalConfig.method = "put";
|
||||
if (data !== undefined) {
|
||||
finalConfig.data = data;
|
||||
}
|
||||
return context.network.request(transformRequest(finalConfig));
|
||||
},
|
||||
delete: (url, data, config) => {
|
||||
let finalConfig = config;
|
||||
if (finalConfig === undefined) {
|
||||
finalConfig = {};
|
||||
}
|
||||
finalConfig.url = url;
|
||||
finalConfig.method = "delete";
|
||||
return context.network.request(transformRequest(finalConfig));
|
||||
},
|
||||
};
|
||||
}
|
6
doric-js/lib/src/native/popover.d.ts
vendored
Normal file
6
doric-js/lib/src/native/popover.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
import { View } from "../ui/view";
|
||||
export declare function popover(context: BridgeContext): {
|
||||
show: (view: View) => Promise<any>;
|
||||
dismiss: (view?: View | undefined) => Promise<any>;
|
||||
};
|
27
doric-js/lib/src/native/popover.js
Normal file
27
doric-js/lib/src/native/popover.js
Normal file
@ -0,0 +1,27 @@
|
||||
import { Panel } from "../ui/panel";
|
||||
export function popover(context) {
|
||||
const entity = context.entity;
|
||||
let panel = undefined;
|
||||
if (entity instanceof Panel) {
|
||||
panel = entity;
|
||||
}
|
||||
return {
|
||||
show: (view) => {
|
||||
if (panel) {
|
||||
panel.addHeadView(view);
|
||||
}
|
||||
return context.popover.show(view.toModel());
|
||||
},
|
||||
dismiss: (view = undefined) => {
|
||||
if (panel) {
|
||||
if (view) {
|
||||
panel.removeHeadView(view);
|
||||
}
|
||||
else {
|
||||
panel.clearHeadViews();
|
||||
}
|
||||
}
|
||||
return context.popover.dismiss(view ? { id: view.viewId } : undefined);
|
||||
},
|
||||
};
|
||||
}
|
7
doric-js/lib/src/native/storage.d.ts
vendored
Normal file
7
doric-js/lib/src/native/storage.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
export declare function storage(context: BridgeContext): {
|
||||
setItem: (key: string, value: string, zone?: string | undefined) => Promise<any>;
|
||||
getItem: (key: string, zone?: string | undefined) => Promise<string>;
|
||||
remove: (key: string, zone?: string | undefined) => Promise<any>;
|
||||
clear: (zone: string) => Promise<any>;
|
||||
};
|
16
doric-js/lib/src/native/storage.js
Normal file
16
doric-js/lib/src/native/storage.js
Normal file
@ -0,0 +1,16 @@
|
||||
export function storage(context) {
|
||||
return {
|
||||
setItem: (key, value, zone) => {
|
||||
return context.storage.setItem({ key, value, zone });
|
||||
},
|
||||
getItem: (key, zone) => {
|
||||
return context.storage.getItem({ key, zone });
|
||||
},
|
||||
remove: (key, zone) => {
|
||||
return context.storage.remove({ key, zone });
|
||||
},
|
||||
clear: (zone) => {
|
||||
return context.storage.clear({ zone });
|
||||
},
|
||||
};
|
||||
}
|
8
doric-js/lib/src/pattern/candies.d.ts
vendored
Normal file
8
doric-js/lib/src/pattern/candies.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
export declare function take<T>(target: T): (block: (p: T) => void) => void;
|
||||
export declare function takeNonNull<T, R>(target?: T): (block: (p: T) => R) => R | undefined;
|
||||
export declare function takeNull<T, R>(target?: T): (block: () => R) => R | undefined;
|
||||
export declare function takeLet<T, R>(target: T): (block: (p: T) => R | undefined) => R | undefined;
|
||||
export declare function takeAlso<T>(target: T): (block: (p: T) => void) => T;
|
||||
export declare function takeIf<T>(target: T): (predicate: (t: T) => boolean) => T | undefined;
|
||||
export declare function takeUnless<T>(target: T): (predicate: (t: T) => boolean) => T | undefined;
|
||||
export declare function repeat(action: (count: number) => void): (times: number) => void;
|
62
doric-js/lib/src/pattern/candies.js
Normal file
62
doric-js/lib/src/pattern/candies.js
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export function take(target) {
|
||||
return (block) => {
|
||||
block(target);
|
||||
};
|
||||
}
|
||||
export function takeNonNull(target) {
|
||||
return (block) => {
|
||||
if (target !== undefined) {
|
||||
return block(target);
|
||||
}
|
||||
};
|
||||
}
|
||||
export function takeNull(target) {
|
||||
return (block) => {
|
||||
if (target === undefined) {
|
||||
return block();
|
||||
}
|
||||
};
|
||||
}
|
||||
export function takeLet(target) {
|
||||
return (block) => {
|
||||
return block(target);
|
||||
};
|
||||
}
|
||||
export function takeAlso(target) {
|
||||
return (block) => {
|
||||
block(target);
|
||||
return target;
|
||||
};
|
||||
}
|
||||
export function takeIf(target) {
|
||||
return (predicate) => {
|
||||
return predicate(target) ? target : undefined;
|
||||
};
|
||||
}
|
||||
export function takeUnless(target) {
|
||||
return (predicate) => {
|
||||
return predicate(target) ? undefined : target;
|
||||
};
|
||||
}
|
||||
export function repeat(action) {
|
||||
return (times) => {
|
||||
for (let i = 0; i < times; i++) {
|
||||
action(i);
|
||||
}
|
||||
};
|
||||
}
|
3
doric-js/lib/src/pattern/index.pattern.d.ts
vendored
Normal file
3
doric-js/lib/src/pattern/index.pattern.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './candies';
|
||||
export * from './provider';
|
||||
export * from './mvvm';
|
18
doric-js/lib/src/pattern/index.pattern.js
Normal file
18
doric-js/lib/src/pattern/index.pattern.js
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export * from './candies';
|
||||
export * from './provider';
|
||||
export * from './mvvm';
|
27
doric-js/lib/src/pattern/mvvm.d.ts
vendored
Normal file
27
doric-js/lib/src/pattern/mvvm.d.ts
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
import { Group } from "../ui/view";
|
||||
import { Panel } from "../ui/panel";
|
||||
export declare abstract class ViewHolder {
|
||||
abstract build(root: Group): void;
|
||||
}
|
||||
export declare type Setter<M> = (state: M) => void;
|
||||
export declare abstract class ViewModel<M extends Object, V extends ViewHolder> {
|
||||
private state;
|
||||
private viewHolder;
|
||||
constructor(obj: M, v: V);
|
||||
getState(): M;
|
||||
updateState(setter: Setter<M>): void;
|
||||
attach(view: Group): void;
|
||||
abstract onAttached(state: M, vh: V): void;
|
||||
abstract onBind(state: M, vh: V): void;
|
||||
}
|
||||
export declare type ViewModelClass<M, V extends ViewHolder> = new (m: M, v: V) => ViewModel<M, V>;
|
||||
export declare type ViewHolderClass<V> = new () => V;
|
||||
export declare abstract class VMPanel<M extends Object, V extends ViewHolder> extends Panel {
|
||||
private vm?;
|
||||
private vh?;
|
||||
abstract getViewModelClass(): ViewModelClass<M, V>;
|
||||
abstract getState(): M;
|
||||
abstract getViewHolderClass(): ViewHolderClass<V>;
|
||||
getViewModel(): ViewModel<M, V> | undefined;
|
||||
build(root: Group): void;
|
||||
}
|
31
doric-js/lib/src/pattern/mvvm.js
Normal file
31
doric-js/lib/src/pattern/mvvm.js
Normal file
@ -0,0 +1,31 @@
|
||||
import { Panel } from "../ui/panel";
|
||||
export class ViewHolder {
|
||||
}
|
||||
export class ViewModel {
|
||||
constructor(obj, v) {
|
||||
this.state = obj;
|
||||
this.viewHolder = v;
|
||||
}
|
||||
getState() {
|
||||
return this.state;
|
||||
}
|
||||
updateState(setter) {
|
||||
setter(this.state);
|
||||
this.onBind(this.state, this.viewHolder);
|
||||
}
|
||||
attach(view) {
|
||||
this.viewHolder.build(view);
|
||||
this.onAttached(this.state, this.viewHolder);
|
||||
this.onBind(this.state, this.viewHolder);
|
||||
}
|
||||
}
|
||||
export class VMPanel extends Panel {
|
||||
getViewModel() {
|
||||
return this.vm;
|
||||
}
|
||||
build(root) {
|
||||
this.vh = new (this.getViewHolderClass());
|
||||
this.vm = new (this.getViewModelClass())(this.getState(), this.vh);
|
||||
this.vm.attach(root);
|
||||
}
|
||||
}
|
42
doric-js/lib/src/pattern/provider.d.ts
vendored
Normal file
42
doric-js/lib/src/pattern/provider.d.ts
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
export declare type Observer<T> = (v: T) => void;
|
||||
export declare type Updater<T> = (v: T) => T;
|
||||
export interface IObservable<T> {
|
||||
addObserver(observer: Observer<T | undefined>): void;
|
||||
removeObserver(observer: Observer<T | undefined>): void;
|
||||
update(updater: Updater<T | undefined>): void;
|
||||
}
|
||||
export declare class Observable<M> implements IObservable<M> {
|
||||
private provider;
|
||||
private clz;
|
||||
private observers;
|
||||
constructor(provider: IProvider, clz: {
|
||||
new (...args: any[]): M;
|
||||
});
|
||||
addObserver(observer: Observer<M | undefined>): void;
|
||||
removeObserver(observer: Observer<M | undefined>): void;
|
||||
update(updater: Updater<M | undefined>): void;
|
||||
}
|
||||
export interface IProvider {
|
||||
provide(obj: Object): void;
|
||||
acquire<T>(clz: {
|
||||
new (...args: any[]): T;
|
||||
}): T | undefined;
|
||||
remove<T>(clz: {
|
||||
new (...args: any[]): T;
|
||||
}): void;
|
||||
clear(): void;
|
||||
observe<T>(clz: {
|
||||
new (...args: any[]): T;
|
||||
}): Observable<T>;
|
||||
}
|
||||
export declare class Provider implements IProvider {
|
||||
private provision;
|
||||
private observableMap;
|
||||
provide(obj: Object): void;
|
||||
acquire<T>(clz: {
|
||||
new (...args: any[]): T;
|
||||
}): T | undefined;
|
||||
remove<T>(clz: new (...args: any[]) => T): void;
|
||||
clear(): void;
|
||||
observe<T>(clz: new (...args: any[]) => T): Observable<T>;
|
||||
}
|
50
doric-js/lib/src/pattern/provider.js
Normal file
50
doric-js/lib/src/pattern/provider.js
Normal file
@ -0,0 +1,50 @@
|
||||
export class Observable {
|
||||
constructor(provider, clz) {
|
||||
this.observers = new Set;
|
||||
this.provider = provider;
|
||||
this.clz = clz;
|
||||
}
|
||||
addObserver(observer) {
|
||||
this.observers.add(observer);
|
||||
}
|
||||
removeObserver(observer) {
|
||||
this.observers.delete(observer);
|
||||
}
|
||||
update(updater) {
|
||||
const oldV = this.provider.acquire(this.clz);
|
||||
const newV = updater(oldV);
|
||||
if (newV !== undefined) {
|
||||
this.provider.provide(newV);
|
||||
}
|
||||
for (let observer of this.observers) {
|
||||
observer(newV);
|
||||
}
|
||||
}
|
||||
}
|
||||
export class Provider {
|
||||
constructor() {
|
||||
this.provision = new Map;
|
||||
this.observableMap = new Map;
|
||||
}
|
||||
provide(obj) {
|
||||
this.provision.set(obj.constructor, obj);
|
||||
}
|
||||
acquire(clz) {
|
||||
const ret = this.provision.get(clz);
|
||||
return ret;
|
||||
}
|
||||
remove(clz) {
|
||||
this.provision.delete(clz);
|
||||
}
|
||||
clear() {
|
||||
this.provision.clear();
|
||||
}
|
||||
observe(clz) {
|
||||
let observable = this.observableMap.get(clz);
|
||||
if (observable === undefined) {
|
||||
observable = new Observable(this, clz);
|
||||
this.observableMap.set(clz, observable);
|
||||
}
|
||||
return observable;
|
||||
}
|
||||
}
|
22
doric-js/lib/src/runtime/global.d.ts
vendored
Normal file
22
doric-js/lib/src/runtime/global.d.ts
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
export * from 'reflect-metadata';
|
||||
export declare type BridgeContext = {
|
||||
[index: string]: {
|
||||
[index: string]: (args?: any) => Promise<any>;
|
||||
};
|
||||
};
|
||||
declare global {
|
||||
const context: BridgeContext;
|
||||
const Environment: {
|
||||
platform: "Android" | "iOS" | "Qt" | "h5";
|
||||
platformVersion: string;
|
||||
appName: string;
|
||||
appVersion: string;
|
||||
libVersion: string;
|
||||
screenWidth: number;
|
||||
screenHeight: number;
|
||||
};
|
||||
function Entry(constructor: {
|
||||
new (...args: any[]): {};
|
||||
}): any;
|
||||
}
|
||||
export {};
|
0
doric-js/lib/src/runtime/global.js
Normal file
0
doric-js/lib/src/runtime/global.js
Normal file
27
doric-js/lib/src/runtime/sandbox.d.ts
vendored
Normal file
27
doric-js/lib/src/runtime/sandbox.d.ts
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
import "reflect-metadata";
|
||||
export declare function jsCallResolve(contextId: string, callbackId: string, args?: any): void;
|
||||
export declare function jsCallReject(contextId: string, callbackId: string, args?: any): void;
|
||||
export declare class Context {
|
||||
entity: any;
|
||||
id: string;
|
||||
callbacks: Map<string, {
|
||||
resolve: Function;
|
||||
reject: Function;
|
||||
}>;
|
||||
hookBeforeNativeCall(): void;
|
||||
hookAfterNativeCall(): void;
|
||||
constructor(id: string);
|
||||
callNative(namespace: string, method: string, args?: any): Promise<any>;
|
||||
register(instance: Object): void;
|
||||
}
|
||||
export declare function jsObtainContext(id: string): Context | undefined;
|
||||
export declare function jsReleaseContext(id: string): void;
|
||||
export declare function __require__(name: string): any;
|
||||
export declare function jsRegisterModule(name: string, moduleObject: any): void;
|
||||
export declare function jsCallEntityMethod(contextId: string, methodName: string, args?: any): any;
|
||||
export declare function jsObtainEntry(contextId: string): <T extends new (...args: any[]) => {}>(constructor: T) => {
|
||||
new (...args: any[]): {
|
||||
context: Context | undefined;
|
||||
};
|
||||
} & T;
|
||||
export declare function jsCallbackTimer(timerId: number): void;
|
302
doric-js/lib/src/runtime/sandbox.js
Normal file
302
doric-js/lib/src/runtime/sandbox.js
Normal file
@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { uniqueId } from "../util/uniqueId";
|
||||
import { loge } from "../util/log";
|
||||
import "reflect-metadata";
|
||||
function hookBeforeNativeCall(context) {
|
||||
if (context) {
|
||||
Reflect.defineMetadata('__doric_context__', context, global);
|
||||
context.hookBeforeNativeCall();
|
||||
}
|
||||
}
|
||||
function hookAfterNativeCall(context) {
|
||||
if (context) {
|
||||
context.hookAfterNativeCall();
|
||||
}
|
||||
}
|
||||
function getContext() {
|
||||
return Reflect.getMetadata('__doric_context__', global);
|
||||
}
|
||||
function setContext(context) {
|
||||
Reflect.defineMetadata('__doric_context__', context, global);
|
||||
}
|
||||
export function jsCallResolve(contextId, callbackId, args) {
|
||||
const context = gContexts.get(contextId);
|
||||
if (context === undefined) {
|
||||
loge(`Cannot find context for context id:${contextId}`);
|
||||
return;
|
||||
}
|
||||
const callback = context.callbacks.get(callbackId);
|
||||
if (callback === undefined) {
|
||||
loge(`Cannot find call for context id:${contextId},callback id:${callbackId}`);
|
||||
return;
|
||||
}
|
||||
const argumentsList = [];
|
||||
for (let i = 2; i < arguments.length; i++) {
|
||||
argumentsList.push(arguments[i]);
|
||||
}
|
||||
hookBeforeNativeCall(context);
|
||||
Reflect.apply(callback.resolve, context, argumentsList);
|
||||
hookAfterNativeCall(context);
|
||||
}
|
||||
export function jsCallReject(contextId, callbackId, args) {
|
||||
const context = gContexts.get(contextId);
|
||||
if (context === undefined) {
|
||||
loge(`Cannot find context for context id:${contextId}`);
|
||||
return;
|
||||
}
|
||||
const callback = context.callbacks.get(callbackId);
|
||||
if (callback === undefined) {
|
||||
loge(`Cannot find call for context id:${contextId},callback id:${callbackId}`);
|
||||
return;
|
||||
}
|
||||
const argumentsList = [];
|
||||
for (let i = 2; i < arguments.length; i++) {
|
||||
argumentsList.push(arguments[i]);
|
||||
}
|
||||
hookBeforeNativeCall(context);
|
||||
Reflect.apply(callback.reject, context.entity, argumentsList);
|
||||
hookAfterNativeCall(context);
|
||||
}
|
||||
export class Context {
|
||||
constructor(id) {
|
||||
this.callbacks = new Map;
|
||||
this.id = id;
|
||||
return new Proxy(this, {
|
||||
get: (target, p) => {
|
||||
if (Reflect.has(target, p)) {
|
||||
return Reflect.get(target, p);
|
||||
}
|
||||
else {
|
||||
const namespace = p;
|
||||
return new Proxy({}, {
|
||||
get: (target, p) => {
|
||||
if (Reflect.has(target, p)) {
|
||||
return Reflect.get(target, p);
|
||||
}
|
||||
else {
|
||||
const context = this;
|
||||
return function () {
|
||||
const args = [];
|
||||
args.push(namespace);
|
||||
args.push(p);
|
||||
for (let arg of arguments) {
|
||||
args.push(arg);
|
||||
}
|
||||
return Reflect.apply(context.callNative, context, args);
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
hookBeforeNativeCall() {
|
||||
if (this.entity && Reflect.has(this.entity, 'hookBeforeNativeCall')) {
|
||||
Reflect.apply(Reflect.get(this.entity, 'hookBeforeNativeCall'), this.entity, []);
|
||||
}
|
||||
}
|
||||
hookAfterNativeCall() {
|
||||
if (this.entity && Reflect.has(this.entity, 'hookAfterNativeCall')) {
|
||||
Reflect.apply(Reflect.get(this.entity, 'hookAfterNativeCall'), this.entity, []);
|
||||
}
|
||||
}
|
||||
callNative(namespace, method, args) {
|
||||
const callbackId = uniqueId('callback');
|
||||
nativeBridge(this.id, namespace, method, callbackId, args);
|
||||
return new Promise((resolve, reject) => {
|
||||
this.callbacks.set(callbackId, {
|
||||
resolve,
|
||||
reject,
|
||||
});
|
||||
});
|
||||
}
|
||||
register(instance) {
|
||||
this.entity = instance;
|
||||
}
|
||||
}
|
||||
const gContexts = new Map;
|
||||
const gModules = new Map;
|
||||
export function jsObtainContext(id) {
|
||||
if (gContexts.has(id)) {
|
||||
const context = gContexts.get(id);
|
||||
setContext(context);
|
||||
return context;
|
||||
}
|
||||
else {
|
||||
const context = new Context(id);
|
||||
gContexts.set(id, context);
|
||||
setContext(context);
|
||||
return context;
|
||||
}
|
||||
}
|
||||
export function jsReleaseContext(id) {
|
||||
const context = gContexts.get(id);
|
||||
const args = arguments;
|
||||
if (context) {
|
||||
timerInfos.forEach((v, k) => {
|
||||
if (v.context === context) {
|
||||
if (global.nativeClearTimer === undefined) {
|
||||
return Reflect.apply(_clearTimeout, undefined, args);
|
||||
}
|
||||
timerInfos.delete(k);
|
||||
nativeClearTimer(k);
|
||||
}
|
||||
});
|
||||
}
|
||||
gContexts.delete(id);
|
||||
}
|
||||
export function __require__(name) {
|
||||
if (gModules.has(name)) {
|
||||
return gModules.get(name);
|
||||
}
|
||||
else {
|
||||
if (nativeRequire(name)) {
|
||||
return gModules.get(name);
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
export function jsRegisterModule(name, moduleObject) {
|
||||
gModules.set(name, moduleObject);
|
||||
}
|
||||
export function jsCallEntityMethod(contextId, methodName, args) {
|
||||
const context = gContexts.get(contextId);
|
||||
if (context === undefined) {
|
||||
loge(`Cannot find context for context id:${contextId}`);
|
||||
return;
|
||||
}
|
||||
if (context.entity === undefined) {
|
||||
loge(`Cannot find holder for context id:${contextId}`);
|
||||
return;
|
||||
}
|
||||
if (Reflect.has(context.entity, methodName)) {
|
||||
const argumentsList = [];
|
||||
for (let i = 2; i < arguments.length; i++) {
|
||||
argumentsList.push(arguments[i]);
|
||||
}
|
||||
hookBeforeNativeCall(context);
|
||||
const ret = Reflect.apply(Reflect.get(context.entity, methodName), context.entity, argumentsList);
|
||||
hookAfterNativeCall(context);
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
loge(`Cannot find method for context id:${contextId},method name is:${methodName}`);
|
||||
}
|
||||
}
|
||||
export function jsObtainEntry(contextId) {
|
||||
const context = jsObtainContext(contextId);
|
||||
return (constructor) => {
|
||||
const ret = class extends constructor {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.context = context;
|
||||
}
|
||||
};
|
||||
if (context) {
|
||||
context.register(new ret);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
const global = Function('return this')();
|
||||
let __timerId__ = 0;
|
||||
const timerInfos = new Map;
|
||||
const _setTimeout = global.setTimeout;
|
||||
const _setInterval = global.setInterval;
|
||||
const _clearTimeout = global.clearTimeout;
|
||||
const _clearInterval = global.clearInterval;
|
||||
const doricSetTimeout = function (handler, timeout, ...args) {
|
||||
if (global.nativeSetTimer === undefined) {
|
||||
return Reflect.apply(_setTimeout, undefined, arguments);
|
||||
}
|
||||
const id = __timerId__++;
|
||||
timerInfos.set(id, {
|
||||
callback: () => {
|
||||
Reflect.apply(handler, undefined, args);
|
||||
timerInfos.delete(id);
|
||||
},
|
||||
context: getContext(),
|
||||
});
|
||||
nativeSetTimer(id, timeout || 0, false);
|
||||
return id;
|
||||
};
|
||||
const doricSetInterval = function (handler, timeout, ...args) {
|
||||
if (global.nativeSetTimer === undefined) {
|
||||
return Reflect.apply(_setInterval, undefined, arguments);
|
||||
}
|
||||
const id = __timerId__++;
|
||||
timerInfos.set(id, {
|
||||
callback: () => {
|
||||
Reflect.apply(handler, undefined, args);
|
||||
},
|
||||
context: getContext(),
|
||||
});
|
||||
nativeSetTimer(id, timeout || 0, true);
|
||||
return id;
|
||||
};
|
||||
const doricClearTimeout = function (timerId) {
|
||||
if (global.nativeClearTimer === undefined) {
|
||||
return Reflect.apply(_clearTimeout, undefined, arguments);
|
||||
}
|
||||
timerInfos.delete(timerId);
|
||||
nativeClearTimer(timerId);
|
||||
};
|
||||
const doricClearInterval = function (timerId) {
|
||||
if (global.nativeClearTimer === undefined) {
|
||||
return Reflect.apply(_clearInterval, undefined, arguments);
|
||||
}
|
||||
timerInfos.delete(timerId);
|
||||
nativeClearTimer(timerId);
|
||||
};
|
||||
if (!global.setTimeout) {
|
||||
global.setTimeout = doricSetTimeout;
|
||||
}
|
||||
else {
|
||||
global.doricSetTimeout = doricSetTimeout;
|
||||
}
|
||||
if (!global.setInterval) {
|
||||
global.setInterval = doricSetInterval;
|
||||
}
|
||||
else {
|
||||
global.doricSetInterval = doricSetInterval;
|
||||
}
|
||||
if (!global.clearTimeout) {
|
||||
global.clearTimeout = doricClearTimeout;
|
||||
}
|
||||
else {
|
||||
global.doricClearTimeout = doricClearTimeout;
|
||||
}
|
||||
if (!global.clearInterval) {
|
||||
global.clearInterval = doricClearInterval;
|
||||
}
|
||||
else {
|
||||
global.doricClearInterval = doricClearInterval;
|
||||
}
|
||||
export function jsCallbackTimer(timerId) {
|
||||
const timerInfo = timerInfos.get(timerId);
|
||||
if (timerInfo === undefined) {
|
||||
return;
|
||||
}
|
||||
if (timerInfo.callback instanceof Function) {
|
||||
hookBeforeNativeCall(timerInfo.context);
|
||||
Reflect.apply(timerInfo.callback, timerInfo.context, []);
|
||||
hookAfterNativeCall(timerInfo.context);
|
||||
}
|
||||
}
|
127
doric-js/lib/src/ui/animation.d.ts
vendored
Normal file
127
doric-js/lib/src/ui/animation.d.ts
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
import { Modeling, Model } from "../util/types";
|
||||
export declare type AnimatedKey = "translationX" | "translationY" | "scaleX" | "scaleY" | "rotation" | "pivotX" | "pivotY";
|
||||
export declare enum RepeatMode {
|
||||
RESTART = 1,
|
||||
REVERSE = 2
|
||||
}
|
||||
export interface IAnimation extends Modeling {
|
||||
duration: number;
|
||||
delay?: number;
|
||||
}
|
||||
export interface Changeable {
|
||||
fromValue: number;
|
||||
toValue: number;
|
||||
key: AnimatedKey;
|
||||
repeatCount?: number;
|
||||
repeatMode?: RepeatMode;
|
||||
}
|
||||
export declare enum FillMode {
|
||||
/**
|
||||
* The receiver is removed from the presentation when the animation is completed.
|
||||
*/
|
||||
Removed = 0,
|
||||
/**
|
||||
* The receiver remains visible in its final state when the animation is completed.
|
||||
*/
|
||||
Forward = 1,
|
||||
/**
|
||||
* The receiver clamps values before zero to zero when the animation is completed.
|
||||
*/
|
||||
Backward = 2,
|
||||
/**
|
||||
* The receiver clamps values at both ends of the object’s time space
|
||||
*/
|
||||
Both = 3
|
||||
}
|
||||
export declare enum TimingFunction {
|
||||
/**
|
||||
* The system default timing function. Use this function to ensure that the timing of your animations matches that of most system animations.
|
||||
*/
|
||||
Default = 0,
|
||||
/**
|
||||
* Linear pacing, which causes an animation to occur evenly over its duration.
|
||||
*/
|
||||
Linear = 1,
|
||||
/**
|
||||
* Ease-in pacing, which causes an animation to begin slowly and then speed up as it progresses.
|
||||
*/
|
||||
EaseIn = 2,
|
||||
/**
|
||||
* Ease-out pacing, which causes an animation to begin quickly and then slow as it progresses.
|
||||
*/
|
||||
EaseOut = 3,
|
||||
/**
|
||||
* Ease-in-ease-out pacing, which causes an animation to begin slowly, accelerate through the middle of its duration, and then slow again before completing.
|
||||
*/
|
||||
EaseInEaseOut = 4
|
||||
}
|
||||
declare abstract class Animation implements IAnimation {
|
||||
changeables: Map<AnimatedKey, Changeable>;
|
||||
duration: number;
|
||||
repeatCount?: number;
|
||||
repeatMode?: RepeatMode;
|
||||
delay?: number;
|
||||
fillMode: FillMode;
|
||||
timingFunction?: TimingFunction;
|
||||
toModel(): {
|
||||
type: string;
|
||||
delay: number | undefined;
|
||||
duration: number;
|
||||
changeables: {
|
||||
key: AnimatedKey;
|
||||
fromValue: number;
|
||||
toValue: number;
|
||||
}[];
|
||||
repeatCount: number | undefined;
|
||||
repeatMode: RepeatMode | undefined;
|
||||
fillMode: FillMode;
|
||||
timingFunction: TimingFunction | undefined;
|
||||
};
|
||||
}
|
||||
export declare class ScaleAnimation extends Animation {
|
||||
private scaleXChangeable;
|
||||
private scaleYChangeable;
|
||||
constructor();
|
||||
set fromScaleX(v: number);
|
||||
get fromScaleX(): number;
|
||||
set toScaleX(v: number);
|
||||
get toScaleX(): number;
|
||||
set fromScaleY(v: number);
|
||||
get fromScaleY(): number;
|
||||
set toScaleY(v: number);
|
||||
get toScaleY(): number;
|
||||
}
|
||||
export declare class TranslationAnimation extends Animation {
|
||||
private translationXChangeable;
|
||||
private translationYChangeable;
|
||||
constructor();
|
||||
set fromTranslationX(v: number);
|
||||
get fromTranslationX(): number;
|
||||
set toTranslationX(v: number);
|
||||
get toTranslationX(): number;
|
||||
set fromTranslationY(v: number);
|
||||
get fromTranslationY(): number;
|
||||
set toTranslationY(v: number);
|
||||
get toTranslationY(): number;
|
||||
}
|
||||
export declare class RotationAnimation extends Animation {
|
||||
private rotationChaneable;
|
||||
constructor();
|
||||
set fromRotation(v: number);
|
||||
get fromRotation(): number;
|
||||
set toRotation(v: number);
|
||||
get toRotation(): number;
|
||||
}
|
||||
export declare class AnimationSet implements IAnimation {
|
||||
private animations;
|
||||
_duration: number;
|
||||
delay?: number;
|
||||
addAnimation(anim: IAnimation): void;
|
||||
get duration(): number;
|
||||
set duration(v: number);
|
||||
toModel(): {
|
||||
animations: Model;
|
||||
delay: number | undefined;
|
||||
};
|
||||
}
|
||||
export {};
|
218
doric-js/lib/src/ui/animation.js
Normal file
218
doric-js/lib/src/ui/animation.js
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export var RepeatMode;
|
||||
(function (RepeatMode) {
|
||||
RepeatMode[RepeatMode["RESTART"] = 1] = "RESTART";
|
||||
RepeatMode[RepeatMode["REVERSE"] = 2] = "REVERSE";
|
||||
})(RepeatMode || (RepeatMode = {}));
|
||||
export var FillMode;
|
||||
(function (FillMode) {
|
||||
/**
|
||||
* The receiver is removed from the presentation when the animation is completed.
|
||||
*/
|
||||
FillMode[FillMode["Removed"] = 0] = "Removed";
|
||||
/**
|
||||
* The receiver remains visible in its final state when the animation is completed.
|
||||
*/
|
||||
FillMode[FillMode["Forward"] = 1] = "Forward";
|
||||
/**
|
||||
* The receiver clamps values before zero to zero when the animation is completed.
|
||||
*/
|
||||
FillMode[FillMode["Backward"] = 2] = "Backward";
|
||||
/**
|
||||
* The receiver clamps values at both ends of the object’s time space
|
||||
*/
|
||||
FillMode[FillMode["Both"] = 3] = "Both";
|
||||
})(FillMode || (FillMode = {}));
|
||||
export var TimingFunction;
|
||||
(function (TimingFunction) {
|
||||
/**
|
||||
* The system default timing function. Use this function to ensure that the timing of your animations matches that of most system animations.
|
||||
*/
|
||||
TimingFunction[TimingFunction["Default"] = 0] = "Default";
|
||||
/**
|
||||
* Linear pacing, which causes an animation to occur evenly over its duration.
|
||||
*/
|
||||
TimingFunction[TimingFunction["Linear"] = 1] = "Linear";
|
||||
/**
|
||||
* Ease-in pacing, which causes an animation to begin slowly and then speed up as it progresses.
|
||||
*/
|
||||
TimingFunction[TimingFunction["EaseIn"] = 2] = "EaseIn";
|
||||
/**
|
||||
* Ease-out pacing, which causes an animation to begin quickly and then slow as it progresses.
|
||||
*/
|
||||
TimingFunction[TimingFunction["EaseOut"] = 3] = "EaseOut";
|
||||
/**
|
||||
* Ease-in-ease-out pacing, which causes an animation to begin slowly, accelerate through the middle of its duration, and then slow again before completing.
|
||||
*/
|
||||
TimingFunction[TimingFunction["EaseInEaseOut"] = 4] = "EaseInEaseOut";
|
||||
})(TimingFunction || (TimingFunction = {}));
|
||||
class Animation {
|
||||
constructor() {
|
||||
this.changeables = new Map;
|
||||
this.duration = 0;
|
||||
this.fillMode = FillMode.Forward;
|
||||
}
|
||||
toModel() {
|
||||
const changeables = [];
|
||||
for (let e of this.changeables.values()) {
|
||||
changeables.push({
|
||||
key: e.key,
|
||||
fromValue: e.fromValue,
|
||||
toValue: e.toValue,
|
||||
});
|
||||
}
|
||||
return {
|
||||
type: this.constructor.name,
|
||||
delay: this.delay,
|
||||
duration: this.duration,
|
||||
changeables,
|
||||
repeatCount: this.repeatCount,
|
||||
repeatMode: this.repeatMode,
|
||||
fillMode: this.fillMode,
|
||||
timingFunction: this.timingFunction
|
||||
};
|
||||
}
|
||||
}
|
||||
export class ScaleAnimation extends Animation {
|
||||
constructor() {
|
||||
super();
|
||||
this.scaleXChangeable = {
|
||||
key: "scaleX",
|
||||
fromValue: 1,
|
||||
toValue: 1,
|
||||
};
|
||||
this.scaleYChangeable = {
|
||||
key: "scaleY",
|
||||
fromValue: 1,
|
||||
toValue: 1,
|
||||
};
|
||||
this.changeables.set("scaleX", this.scaleXChangeable);
|
||||
this.changeables.set("scaleY", this.scaleYChangeable);
|
||||
}
|
||||
set fromScaleX(v) {
|
||||
this.scaleXChangeable.fromValue = v;
|
||||
}
|
||||
get fromScaleX() {
|
||||
return this.scaleXChangeable.fromValue;
|
||||
}
|
||||
set toScaleX(v) {
|
||||
this.scaleXChangeable.toValue = v;
|
||||
}
|
||||
get toScaleX() {
|
||||
return this.scaleXChangeable.toValue;
|
||||
}
|
||||
set fromScaleY(v) {
|
||||
this.scaleYChangeable.fromValue = v;
|
||||
}
|
||||
get fromScaleY() {
|
||||
return this.scaleYChangeable.fromValue;
|
||||
}
|
||||
set toScaleY(v) {
|
||||
this.scaleYChangeable.toValue = v;
|
||||
}
|
||||
get toScaleY() {
|
||||
return this.scaleYChangeable.toValue;
|
||||
}
|
||||
}
|
||||
export class TranslationAnimation extends Animation {
|
||||
constructor() {
|
||||
super();
|
||||
this.translationXChangeable = {
|
||||
key: "translationX",
|
||||
fromValue: 1,
|
||||
toValue: 1,
|
||||
};
|
||||
this.translationYChangeable = {
|
||||
key: "translationY",
|
||||
fromValue: 1,
|
||||
toValue: 1,
|
||||
};
|
||||
this.changeables.set("translationX", this.translationXChangeable);
|
||||
this.changeables.set("translationY", this.translationYChangeable);
|
||||
}
|
||||
set fromTranslationX(v) {
|
||||
this.translationXChangeable.fromValue = v;
|
||||
}
|
||||
get fromTranslationX() {
|
||||
return this.translationXChangeable.fromValue;
|
||||
}
|
||||
set toTranslationX(v) {
|
||||
this.translationXChangeable.toValue = v;
|
||||
}
|
||||
get toTranslationX() {
|
||||
return this.translationXChangeable.toValue;
|
||||
}
|
||||
set fromTranslationY(v) {
|
||||
this.translationYChangeable.fromValue = v;
|
||||
}
|
||||
get fromTranslationY() {
|
||||
return this.translationYChangeable.fromValue;
|
||||
}
|
||||
set toTranslationY(v) {
|
||||
this.translationYChangeable.toValue = v;
|
||||
}
|
||||
get toTranslationY() {
|
||||
return this.translationYChangeable.toValue;
|
||||
}
|
||||
}
|
||||
export class RotationAnimation extends Animation {
|
||||
constructor() {
|
||||
super();
|
||||
this.rotationChaneable = {
|
||||
key: "rotation",
|
||||
fromValue: 1,
|
||||
toValue: 1,
|
||||
};
|
||||
this.changeables.set("rotation", this.rotationChaneable);
|
||||
}
|
||||
set fromRotation(v) {
|
||||
this.rotationChaneable.fromValue = v;
|
||||
}
|
||||
get fromRotation() {
|
||||
return this.rotationChaneable.fromValue;
|
||||
}
|
||||
set toRotation(v) {
|
||||
this.rotationChaneable.toValue = v;
|
||||
}
|
||||
get toRotation() {
|
||||
return this.rotationChaneable.toValue;
|
||||
}
|
||||
}
|
||||
export class AnimationSet {
|
||||
constructor() {
|
||||
this.animations = [];
|
||||
this._duration = 0;
|
||||
}
|
||||
addAnimation(anim) {
|
||||
this.animations.push(anim);
|
||||
}
|
||||
get duration() {
|
||||
return this._duration;
|
||||
}
|
||||
set duration(v) {
|
||||
this._duration = v;
|
||||
this.animations.forEach(e => e.duration = v);
|
||||
}
|
||||
toModel() {
|
||||
return {
|
||||
animations: this.animations.map(e => {
|
||||
return e.toModel();
|
||||
}),
|
||||
delay: this.delay,
|
||||
};
|
||||
}
|
||||
}
|
3
doric-js/lib/src/ui/index.ui.d.ts
vendored
Normal file
3
doric-js/lib/src/ui/index.ui.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './view';
|
||||
export * from './panel';
|
||||
export * from './animation';
|
18
doric-js/lib/src/ui/index.ui.js
Normal file
18
doric-js/lib/src/ui/index.ui.js
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export * from './view';
|
||||
export * from './panel';
|
||||
export * from './animation';
|
32
doric-js/lib/src/ui/panel.d.ts
vendored
Normal file
32
doric-js/lib/src/ui/panel.d.ts
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
import { View, Group } from "./view";
|
||||
import { Root } from '../widget/layouts';
|
||||
import { BridgeContext } from '../runtime/global';
|
||||
export declare function NativeCall(target: Panel, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor;
|
||||
export declare abstract class Panel {
|
||||
context: BridgeContext;
|
||||
onCreate(): void;
|
||||
onDestroy(): void;
|
||||
onShow(): void;
|
||||
onHidden(): void;
|
||||
abstract build(rootView: Group): void;
|
||||
private __data__?;
|
||||
private __root__;
|
||||
private headviews;
|
||||
addHeadView(v: View): void;
|
||||
allHeadViews(): IterableIterator<View>;
|
||||
removeHeadView(v: View | string): void;
|
||||
clearHeadViews(): void;
|
||||
getRootView(): Root;
|
||||
getInitData(): object | undefined;
|
||||
private __init__;
|
||||
private __onCreate__;
|
||||
private __onDestroy__;
|
||||
private __onShow__;
|
||||
private __onHidden__;
|
||||
private __build__;
|
||||
private __response__;
|
||||
private retrospectView;
|
||||
private nativeRender;
|
||||
private hookBeforeNativeCall;
|
||||
private hookAfterNativeCall;
|
||||
}
|
206
doric-js/lib/src/ui/panel.js
Normal file
206
doric-js/lib/src/ui/panel.js
Normal file
@ -0,0 +1,206 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { View } from "./view";
|
||||
import { loge } from '../util/log';
|
||||
import { Root } from '../widget/layouts';
|
||||
export function NativeCall(target, propertyKey, descriptor) {
|
||||
const originVal = descriptor.value;
|
||||
descriptor.value = function () {
|
||||
const ret = Reflect.apply(originVal, this, arguments);
|
||||
return ret;
|
||||
};
|
||||
return descriptor;
|
||||
}
|
||||
export class Panel {
|
||||
constructor() {
|
||||
this.__root__ = new Root;
|
||||
this.headviews = new Map;
|
||||
}
|
||||
onCreate() { }
|
||||
onDestroy() { }
|
||||
onShow() { }
|
||||
onHidden() { }
|
||||
addHeadView(v) {
|
||||
this.headviews.set(v.viewId, v);
|
||||
}
|
||||
allHeadViews() {
|
||||
return this.headviews.values();
|
||||
}
|
||||
removeHeadView(v) {
|
||||
if (v instanceof View) {
|
||||
this.headviews.delete(v.viewId);
|
||||
}
|
||||
else {
|
||||
this.headviews.delete(v);
|
||||
}
|
||||
}
|
||||
clearHeadViews() {
|
||||
this.headviews.clear();
|
||||
}
|
||||
getRootView() {
|
||||
return this.__root__;
|
||||
}
|
||||
getInitData() {
|
||||
return this.__data__;
|
||||
}
|
||||
__init__(frame, data) {
|
||||
if (data) {
|
||||
this.__data__ = JSON.parse(data);
|
||||
}
|
||||
this.__root__.width = frame.width;
|
||||
this.__root__.height = frame.height;
|
||||
this.__root__.children.length = 0;
|
||||
this.build(this.__root__);
|
||||
}
|
||||
__onCreate__() {
|
||||
this.onCreate();
|
||||
}
|
||||
__onDestroy__() {
|
||||
this.onDestroy();
|
||||
}
|
||||
__onShow__() {
|
||||
this.onShow();
|
||||
}
|
||||
__onHidden__() {
|
||||
this.onHidden();
|
||||
}
|
||||
__build__() {
|
||||
this.build(this.__root__);
|
||||
}
|
||||
__response__(viewIds, callbackId) {
|
||||
const v = this.retrospectView(viewIds);
|
||||
if (v === undefined) {
|
||||
loge(`Cannot find view for ${viewIds}`);
|
||||
}
|
||||
else {
|
||||
const argumentsList = [callbackId];
|
||||
for (let i = 2; i < arguments.length; i++) {
|
||||
argumentsList.push(arguments[i]);
|
||||
}
|
||||
return Reflect.apply(v.responseCallback, v, argumentsList);
|
||||
}
|
||||
}
|
||||
retrospectView(ids) {
|
||||
return ids.reduce((acc, cur) => {
|
||||
if (acc === undefined) {
|
||||
if (cur === this.__root__.viewId) {
|
||||
return this.__root__;
|
||||
}
|
||||
return this.headviews.get(cur);
|
||||
}
|
||||
else {
|
||||
if (Reflect.has(acc, "subviewById")) {
|
||||
return Reflect.apply(Reflect.get(acc, "subviewById"), acc, [cur]);
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
}, undefined);
|
||||
}
|
||||
nativeRender(model) {
|
||||
this.context.shader.render(model);
|
||||
}
|
||||
hookBeforeNativeCall() {
|
||||
if (Environment.platform !== 'h5') {
|
||||
this.__root__.clean();
|
||||
for (let v of this.headviews.values()) {
|
||||
v.clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
hookAfterNativeCall() {
|
||||
if (Environment.platform !== 'h5') {
|
||||
//Here insert a native call to ensure the promise is resolved done.
|
||||
nativeEmpty();
|
||||
if (this.__root__.isDirty()) {
|
||||
const model = this.__root__.toModel();
|
||||
this.nativeRender(model);
|
||||
}
|
||||
for (let v of this.headviews.values()) {
|
||||
if (v.isDirty()) {
|
||||
const model = v.toModel();
|
||||
this.nativeRender(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Promise.resolve().then(() => {
|
||||
if (this.__root__.isDirty()) {
|
||||
const model = this.__root__.toModel();
|
||||
this.nativeRender(model);
|
||||
this.__root__.clean();
|
||||
}
|
||||
for (let v of this.headviews.values()) {
|
||||
if (v.isDirty()) {
|
||||
const model = v.toModel();
|
||||
this.nativeRender(model);
|
||||
v.clean();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
__decorate([
|
||||
NativeCall,
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, String]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], Panel.prototype, "__init__", null);
|
||||
__decorate([
|
||||
NativeCall,
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], Panel.prototype, "__onCreate__", null);
|
||||
__decorate([
|
||||
NativeCall,
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], Panel.prototype, "__onDestroy__", null);
|
||||
__decorate([
|
||||
NativeCall,
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], Panel.prototype, "__onShow__", null);
|
||||
__decorate([
|
||||
NativeCall,
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], Panel.prototype, "__onHidden__", null);
|
||||
__decorate([
|
||||
NativeCall,
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], Panel.prototype, "__build__", null);
|
||||
__decorate([
|
||||
NativeCall,
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Array, String]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], Panel.prototype, "__response__", null);
|
174
doric-js/lib/src/ui/view.d.ts
vendored
Normal file
174
doric-js/lib/src/ui/view.d.ts
vendored
Normal file
@ -0,0 +1,174 @@
|
||||
import { Color, GradientColor } from "../util/color";
|
||||
import { Modeling, Model } from "../util/types";
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
import { LayoutConfig } from '../util/layoutconfig';
|
||||
import { IAnimation } from "./animation";
|
||||
export declare function Property(target: Object, propKey: string): void;
|
||||
export interface IView {
|
||||
width?: number;
|
||||
height?: number;
|
||||
backgroundColor?: Color | GradientColor;
|
||||
corners?: number | {
|
||||
leftTop?: number;
|
||||
rightTop?: number;
|
||||
leftBottom?: number;
|
||||
rightBottom?: number;
|
||||
};
|
||||
border?: {
|
||||
width: number;
|
||||
color: Color;
|
||||
};
|
||||
shadow?: {
|
||||
color: Color;
|
||||
opacity: number;
|
||||
radius: number;
|
||||
offsetX: number;
|
||||
offsetY: number;
|
||||
};
|
||||
/**
|
||||
* float [0,..1]
|
||||
*/
|
||||
alpha?: number;
|
||||
hidden?: boolean;
|
||||
padding?: {
|
||||
left?: number;
|
||||
right?: number;
|
||||
top?: number;
|
||||
bottom?: number;
|
||||
};
|
||||
layoutConfig?: LayoutConfig;
|
||||
onClick?: Function;
|
||||
identifier?: string;
|
||||
/**++++++++++transform++++++++++*/
|
||||
translationX?: number;
|
||||
translationY?: number;
|
||||
scaleX?: number;
|
||||
scaleY?: number;
|
||||
/**
|
||||
* float [0,..1]
|
||||
*/
|
||||
pivotX?: number;
|
||||
/**
|
||||
* float [0,..1]
|
||||
*/
|
||||
pivotY?: number;
|
||||
/**
|
||||
* rotation*PI
|
||||
*/
|
||||
rotation?: number;
|
||||
}
|
||||
export declare abstract class View implements Modeling, IView {
|
||||
width: number;
|
||||
height: number;
|
||||
x: number;
|
||||
y: number;
|
||||
backgroundColor?: Color | GradientColor;
|
||||
corners?: number | {
|
||||
leftTop?: number;
|
||||
rightTop?: number;
|
||||
leftBottom?: number;
|
||||
rightBottom?: number;
|
||||
};
|
||||
border?: {
|
||||
width: number;
|
||||
color: Color;
|
||||
};
|
||||
shadow?: {
|
||||
color: Color;
|
||||
opacity: number;
|
||||
radius: number;
|
||||
offsetX: number;
|
||||
offsetY: number;
|
||||
};
|
||||
alpha?: number;
|
||||
hidden?: boolean;
|
||||
viewId: string;
|
||||
padding?: {
|
||||
left?: number;
|
||||
right?: number;
|
||||
top?: number;
|
||||
bottom?: number;
|
||||
};
|
||||
layoutConfig?: LayoutConfig;
|
||||
onClick?: Function;
|
||||
superview?: Superview;
|
||||
callbacks: Map<String, Function>;
|
||||
private callback2Id;
|
||||
private id2Callback;
|
||||
constructor();
|
||||
/** Anchor start*/
|
||||
get left(): number;
|
||||
set left(v: number);
|
||||
get right(): number;
|
||||
set right(v: number);
|
||||
get top(): number;
|
||||
set top(v: number);
|
||||
get bottom(): number;
|
||||
set bottom(v: number);
|
||||
get centerX(): number;
|
||||
get centerY(): number;
|
||||
set centerX(v: number);
|
||||
set centerY(v: number);
|
||||
/** Anchor end*/
|
||||
private __dirty_props__;
|
||||
get dirtyProps(): {
|
||||
[index: string]: Model;
|
||||
};
|
||||
nativeViewModel: {
|
||||
id: string;
|
||||
type: string;
|
||||
props: {
|
||||
[index: string]: Model;
|
||||
};
|
||||
};
|
||||
onPropertyChanged(propKey: string, oldV: Model, newV: Model): void;
|
||||
clean(): void;
|
||||
isDirty(): boolean;
|
||||
responseCallback(id: string, ...args: any): any;
|
||||
toModel(): {
|
||||
id: string;
|
||||
type: string;
|
||||
props: {
|
||||
[index: string]: Model;
|
||||
};
|
||||
};
|
||||
let(block: (it: this) => void): void;
|
||||
also(block: (it: this) => void): this;
|
||||
apply(config: IView): this;
|
||||
in(group: Group): this;
|
||||
nativeChannel(context: any, name: string): (args?: any) => Promise<any>;
|
||||
getWidth(context: BridgeContext): Promise<number>;
|
||||
getHeight(context: BridgeContext): Promise<number>;
|
||||
getLocationOnScreen(context: BridgeContext): Promise<{
|
||||
x: number;
|
||||
y: number;
|
||||
}>;
|
||||
/**++++++++++transform++++++++++*/
|
||||
translationX?: number;
|
||||
translationY?: number;
|
||||
scaleX?: number;
|
||||
scaleY?: number;
|
||||
pivotX?: number;
|
||||
pivotY?: number;
|
||||
rotation?: number;
|
||||
/**----------transform----------*/
|
||||
doAnimation(context: BridgeContext, animation: IAnimation): Promise<void>;
|
||||
}
|
||||
export declare abstract class Superview extends View {
|
||||
subviewById(id: string): View | undefined;
|
||||
abstract allSubviews(): Iterable<View>;
|
||||
isDirty(): boolean;
|
||||
clean(): void;
|
||||
toModel(): {
|
||||
id: string;
|
||||
type: string;
|
||||
props: {
|
||||
[index: string]: Model;
|
||||
};
|
||||
};
|
||||
}
|
||||
export declare abstract class Group extends Superview {
|
||||
readonly children: View[];
|
||||
allSubviews(): View[];
|
||||
addChild(view: View): void;
|
||||
}
|
328
doric-js/lib/src/ui/view.js
Normal file
328
doric-js/lib/src/ui/view.js
Normal file
@ -0,0 +1,328 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
import { obj2Model } from "../util/types";
|
||||
import { uniqueId } from "../util/uniqueId";
|
||||
import { loge } from "../util/log";
|
||||
export function Property(target, propKey) {
|
||||
Reflect.defineMetadata(propKey, true, target);
|
||||
}
|
||||
export class View {
|
||||
constructor() {
|
||||
this.width = 0;
|
||||
this.height = 0;
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.viewId = uniqueId('ViewId');
|
||||
this.callbacks = new Map;
|
||||
/** Anchor end*/
|
||||
this.__dirty_props__ = {};
|
||||
this.nativeViewModel = {
|
||||
id: this.viewId,
|
||||
type: this.constructor.name,
|
||||
props: this.__dirty_props__,
|
||||
};
|
||||
return new Proxy(this, {
|
||||
get: (target, p, receiver) => {
|
||||
return Reflect.get(target, p, receiver);
|
||||
},
|
||||
set: (target, p, v, receiver) => {
|
||||
const oldV = Reflect.get(target, p, receiver);
|
||||
const ret = Reflect.set(target, p, v, receiver);
|
||||
if (Reflect.getMetadata(p, target) && oldV !== v) {
|
||||
receiver.onPropertyChanged(p.toString(), oldV, v);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
});
|
||||
}
|
||||
callback2Id(f) {
|
||||
const id = uniqueId('Function');
|
||||
this.callbacks.set(id, f);
|
||||
return id;
|
||||
}
|
||||
id2Callback(id) {
|
||||
let f = this.callbacks.get(id);
|
||||
if (f === undefined) {
|
||||
f = Reflect.get(this, id);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
/** Anchor start*/
|
||||
get left() {
|
||||
return this.x;
|
||||
}
|
||||
set left(v) {
|
||||
this.x = v;
|
||||
}
|
||||
get right() {
|
||||
return this.x + this.width;
|
||||
}
|
||||
set right(v) {
|
||||
this.x = v - this.width;
|
||||
}
|
||||
get top() {
|
||||
return this.y;
|
||||
}
|
||||
set top(v) {
|
||||
this.y = v;
|
||||
}
|
||||
get bottom() {
|
||||
return this.y + this.height;
|
||||
}
|
||||
set bottom(v) {
|
||||
this.y = v - this.height;
|
||||
}
|
||||
get centerX() {
|
||||
return this.x + this.width / 2;
|
||||
}
|
||||
get centerY() {
|
||||
return this.y + this.height / 2;
|
||||
}
|
||||
set centerX(v) {
|
||||
this.x = v - this.width / 2;
|
||||
}
|
||||
set centerY(v) {
|
||||
this.y = v - this.height / 2;
|
||||
}
|
||||
get dirtyProps() {
|
||||
return this.__dirty_props__;
|
||||
}
|
||||
onPropertyChanged(propKey, oldV, newV) {
|
||||
if (newV instanceof Function) {
|
||||
newV = this.callback2Id(newV);
|
||||
}
|
||||
else {
|
||||
newV = obj2Model(newV);
|
||||
}
|
||||
this.__dirty_props__[propKey] = newV;
|
||||
}
|
||||
clean() {
|
||||
for (const key in this.__dirty_props__) {
|
||||
if (Reflect.has(this.__dirty_props__, key)) {
|
||||
Reflect.deleteProperty(this.__dirty_props__, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
isDirty() {
|
||||
return Reflect.ownKeys(this.__dirty_props__).length !== 0;
|
||||
}
|
||||
responseCallback(id, ...args) {
|
||||
const f = this.id2Callback(id);
|
||||
if (f instanceof Function) {
|
||||
const argumentsList = [];
|
||||
for (let i = 1; i < arguments.length; i++) {
|
||||
argumentsList.push(arguments[i]);
|
||||
}
|
||||
return Reflect.apply(f, this, argumentsList);
|
||||
}
|
||||
else {
|
||||
loge(`Cannot find callback:${id} for ${JSON.stringify(this.toModel())}`);
|
||||
}
|
||||
}
|
||||
toModel() {
|
||||
return this.nativeViewModel;
|
||||
}
|
||||
let(block) {
|
||||
block(this);
|
||||
}
|
||||
also(block) {
|
||||
block(this);
|
||||
return this;
|
||||
}
|
||||
apply(config) {
|
||||
for (let key in config) {
|
||||
Reflect.set(this, key, Reflect.get(config, key, config), this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
in(group) {
|
||||
group.addChild(this);
|
||||
return this;
|
||||
}
|
||||
nativeChannel(context, name) {
|
||||
let thisView = this;
|
||||
return function (args = undefined) {
|
||||
const func = context.shader.command;
|
||||
const viewIds = [];
|
||||
while (thisView != undefined) {
|
||||
viewIds.push(thisView.viewId);
|
||||
thisView = thisView.superview;
|
||||
}
|
||||
const params = {
|
||||
viewIds: viewIds.reverse(),
|
||||
name,
|
||||
args,
|
||||
};
|
||||
return Reflect.apply(func, undefined, [params]);
|
||||
};
|
||||
}
|
||||
getWidth(context) {
|
||||
return this.nativeChannel(context, 'getWidth')();
|
||||
}
|
||||
getHeight(context) {
|
||||
return this.nativeChannel(context, 'getHeight')();
|
||||
}
|
||||
getLocationOnScreen(context) {
|
||||
return this.nativeChannel(context, "getLocationOnScreen")();
|
||||
}
|
||||
/**----------transform----------*/
|
||||
doAnimation(context, animation) {
|
||||
return this.nativeChannel(context, "doAnimation")(animation.toModel()).then((args) => {
|
||||
for (let key in args) {
|
||||
Reflect.set(this, key, Reflect.get(args, key, args), this);
|
||||
Reflect.deleteProperty(this.__dirty_props__, key);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "width", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "height", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "x", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "y", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], View.prototype, "backgroundColor", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], View.prototype, "corners", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], View.prototype, "border", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], View.prototype, "shadow", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "alpha", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Boolean)
|
||||
], View.prototype, "hidden", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], View.prototype, "viewId", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], View.prototype, "padding", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], View.prototype, "layoutConfig", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], View.prototype, "onClick", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "translationX", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "translationY", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "scaleX", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "scaleY", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "pivotX", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "pivotY", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "rotation", void 0);
|
||||
export class Superview extends View {
|
||||
subviewById(id) {
|
||||
for (let v of this.allSubviews()) {
|
||||
if (v.viewId === id) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
isDirty() {
|
||||
if (super.isDirty()) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
for (const v of this.allSubviews()) {
|
||||
if (v.isDirty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
clean() {
|
||||
for (let v of this.allSubviews()) {
|
||||
v.clean();
|
||||
}
|
||||
super.clean();
|
||||
}
|
||||
toModel() {
|
||||
const subviews = [];
|
||||
for (let v of this.allSubviews()) {
|
||||
if (v != undefined) {
|
||||
v.superview = this;
|
||||
if (v.isDirty()) {
|
||||
subviews.push(v.toModel());
|
||||
}
|
||||
}
|
||||
}
|
||||
this.dirtyProps.subviews = subviews;
|
||||
return super.toModel();
|
||||
}
|
||||
}
|
||||
export class Group extends Superview {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.children = new Proxy([], {
|
||||
set: (target, index, value) => {
|
||||
const ret = Reflect.set(target, index, value);
|
||||
// Let getDirty return true
|
||||
this.dirtyProps.children = this.children.map(e => e.viewId);
|
||||
return ret;
|
||||
}
|
||||
});
|
||||
}
|
||||
allSubviews() {
|
||||
return this.children;
|
||||
}
|
||||
addChild(view) {
|
||||
this.children.push(view);
|
||||
}
|
||||
}
|
47
doric-js/lib/src/util/color.d.ts
vendored
Normal file
47
doric-js/lib/src/util/color.d.ts
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
import { Modeling } from "./types";
|
||||
/**
|
||||
* Store color as format AARRGGBB or RRGGBB
|
||||
*/
|
||||
export declare class Color implements Modeling {
|
||||
static BLACK: Color;
|
||||
static DKGRAY: Color;
|
||||
static GRAY: Color;
|
||||
static LTGRAY: Color;
|
||||
static WHITE: Color;
|
||||
static RED: Color;
|
||||
static GREEN: Color;
|
||||
static BLUE: Color;
|
||||
static YELLOW: Color;
|
||||
static CYAN: Color;
|
||||
static MAGENTA: Color;
|
||||
static TRANSPARENT: Color;
|
||||
_value: number;
|
||||
constructor(v: number);
|
||||
static parse(str: string): Color;
|
||||
static safeParse(str: string, defVal?: Color): Color;
|
||||
alpha(v: number): Color;
|
||||
toModel(): number;
|
||||
}
|
||||
export declare enum GradientOrientation {
|
||||
/** draw the gradient from the top to the bottom */
|
||||
TOP_BOTTOM = 0,
|
||||
/** draw the gradient from the top-right to the bottom-left */
|
||||
TR_BL = 1,
|
||||
/** draw the gradient from the right to the left */
|
||||
RIGHT_LEFT = 2,
|
||||
/** draw the gradient from the bottom-right to the top-left */
|
||||
BR_TL = 3,
|
||||
/** draw the gradient from the bottom to the top */
|
||||
BOTTOM_TOP = 4,
|
||||
/** draw the gradient from the bottom-left to the top-right */
|
||||
BL_TR = 5,
|
||||
/** draw the gradient from the left to the right */
|
||||
LEFT_RIGHT = 6,
|
||||
/** draw the gradient from the top-left to the bottom-right */
|
||||
TL_BR = 7
|
||||
}
|
||||
export interface GradientColor {
|
||||
start: Color;
|
||||
end: Color;
|
||||
orientation: GradientOrientation;
|
||||
}
|
73
doric-js/lib/src/util/color.js
Normal file
73
doric-js/lib/src/util/color.js
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* Store color as format AARRGGBB or RRGGBB
|
||||
*/
|
||||
export class Color {
|
||||
constructor(v) {
|
||||
this._value = 0;
|
||||
this._value = v | 0x0;
|
||||
}
|
||||
static parse(str) {
|
||||
if (!str.startsWith("#")) {
|
||||
throw new Error(`Parse color error with ${str}`);
|
||||
}
|
||||
const val = parseInt(str.substr(1), 16);
|
||||
if (str.length === 7) {
|
||||
return new Color(val | 0xff000000);
|
||||
}
|
||||
else if (str.length === 9) {
|
||||
return new Color(val);
|
||||
}
|
||||
else {
|
||||
throw new Error(`Parse color error with ${str}`);
|
||||
}
|
||||
}
|
||||
static safeParse(str, defVal = Color.TRANSPARENT) {
|
||||
let color = defVal;
|
||||
try {
|
||||
color = Color.parse(str);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
finally {
|
||||
return color;
|
||||
}
|
||||
}
|
||||
alpha(v) {
|
||||
v = v * 255;
|
||||
return new Color((this._value & 0xffffff) | ((v & 0xff) << 24));
|
||||
}
|
||||
toModel() {
|
||||
return this._value;
|
||||
}
|
||||
}
|
||||
Color.BLACK = new Color(0xFF000000);
|
||||
Color.DKGRAY = new Color(0xFF444444);
|
||||
Color.GRAY = new Color(0xFF888888);
|
||||
Color.LTGRAY = new Color(0xFFCCCCCC);
|
||||
Color.WHITE = new Color(0xFFFFFFFF);
|
||||
Color.RED = new Color(0xFFFF0000);
|
||||
Color.GREEN = new Color(0xFF00FF00);
|
||||
Color.BLUE = new Color(0xFF0000FF);
|
||||
Color.YELLOW = new Color(0xFFFFFF00);
|
||||
Color.CYAN = new Color(0xFF00FFFF);
|
||||
Color.MAGENTA = new Color(0xFFFF00FF);
|
||||
Color.TRANSPARENT = new Color(0);
|
||||
export var GradientOrientation;
|
||||
(function (GradientOrientation) {
|
||||
/** draw the gradient from the top to the bottom */
|
||||
GradientOrientation[GradientOrientation["TOP_BOTTOM"] = 0] = "TOP_BOTTOM";
|
||||
/** draw the gradient from the top-right to the bottom-left */
|
||||
GradientOrientation[GradientOrientation["TR_BL"] = 1] = "TR_BL";
|
||||
/** draw the gradient from the right to the left */
|
||||
GradientOrientation[GradientOrientation["RIGHT_LEFT"] = 2] = "RIGHT_LEFT";
|
||||
/** draw the gradient from the bottom-right to the top-left */
|
||||
GradientOrientation[GradientOrientation["BR_TL"] = 3] = "BR_TL";
|
||||
/** draw the gradient from the bottom to the top */
|
||||
GradientOrientation[GradientOrientation["BOTTOM_TOP"] = 4] = "BOTTOM_TOP";
|
||||
/** draw the gradient from the bottom-left to the top-right */
|
||||
GradientOrientation[GradientOrientation["BL_TR"] = 5] = "BL_TR";
|
||||
/** draw the gradient from the left to the right */
|
||||
GradientOrientation[GradientOrientation["LEFT_RIGHT"] = 6] = "LEFT_RIGHT";
|
||||
/** draw the gradient from the top-left to the bottom-right */
|
||||
GradientOrientation[GradientOrientation["TL_BR"] = 7] = "TL_BR";
|
||||
})(GradientOrientation || (GradientOrientation = {}));
|
26
doric-js/lib/src/util/gravity.d.ts
vendored
Normal file
26
doric-js/lib/src/util/gravity.d.ts
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
import { Modeling } from "./types";
|
||||
export declare const LEFT: number;
|
||||
export declare const RIGHT: number;
|
||||
export declare const TOP: number;
|
||||
export declare const BOTTOM: number;
|
||||
export declare const CENTER_X: number;
|
||||
export declare const CENTER_Y: number;
|
||||
export declare const CENTER: number;
|
||||
export declare class Gravity implements Modeling {
|
||||
val: number;
|
||||
left(): Gravity;
|
||||
right(): Gravity;
|
||||
top(): Gravity;
|
||||
bottom(): Gravity;
|
||||
center(): Gravity;
|
||||
centerX(): Gravity;
|
||||
centerY(): Gravity;
|
||||
toModel(): number;
|
||||
private static origin;
|
||||
static Center: Gravity;
|
||||
static Left: Gravity;
|
||||
static Right: Gravity;
|
||||
static Top: Gravity;
|
||||
static Bottom: Gravity;
|
||||
}
|
||||
export declare function gravity(): Gravity;
|
71
doric-js/lib/src/util/gravity.js
Normal file
71
doric-js/lib/src/util/gravity.js
Normal file
@ -0,0 +1,71 @@
|
||||
const SPECIFIED = 1;
|
||||
const START = 1 << 1;
|
||||
const END = 1 << 2;
|
||||
const SHIFT_X = 0;
|
||||
const SHIFT_Y = 4;
|
||||
export const LEFT = (START | SPECIFIED) << SHIFT_X;
|
||||
export const RIGHT = (END | SPECIFIED) << SHIFT_X;
|
||||
export const TOP = (START | SPECIFIED) << SHIFT_Y;
|
||||
export const BOTTOM = (END | SPECIFIED) << SHIFT_Y;
|
||||
export const CENTER_X = SPECIFIED << SHIFT_X;
|
||||
export const CENTER_Y = SPECIFIED << SHIFT_Y;
|
||||
export const CENTER = CENTER_X | CENTER_Y;
|
||||
export class Gravity {
|
||||
constructor() {
|
||||
this.val = 0;
|
||||
}
|
||||
left() {
|
||||
const val = this.val | LEFT;
|
||||
const ret = new Gravity;
|
||||
ret.val = val;
|
||||
return ret;
|
||||
}
|
||||
right() {
|
||||
const val = this.val | RIGHT;
|
||||
const ret = new Gravity;
|
||||
ret.val = val;
|
||||
return ret;
|
||||
}
|
||||
top() {
|
||||
const val = this.val | TOP;
|
||||
const ret = new Gravity;
|
||||
ret.val = val;
|
||||
return ret;
|
||||
}
|
||||
bottom() {
|
||||
const val = this.val | BOTTOM;
|
||||
const ret = new Gravity;
|
||||
ret.val = val;
|
||||
return ret;
|
||||
}
|
||||
center() {
|
||||
const val = this.val | CENTER;
|
||||
const ret = new Gravity;
|
||||
ret.val = val;
|
||||
return ret;
|
||||
}
|
||||
centerX() {
|
||||
const val = this.val | CENTER_X;
|
||||
const ret = new Gravity;
|
||||
ret.val = val;
|
||||
return ret;
|
||||
}
|
||||
centerY() {
|
||||
const val = this.val | CENTER_Y;
|
||||
const ret = new Gravity;
|
||||
ret.val = val;
|
||||
return ret;
|
||||
}
|
||||
toModel() {
|
||||
return this.val;
|
||||
}
|
||||
}
|
||||
Gravity.origin = new Gravity;
|
||||
Gravity.Center = Gravity.origin.center();
|
||||
Gravity.Left = Gravity.origin.left();
|
||||
Gravity.Right = Gravity.origin.right();
|
||||
Gravity.Top = Gravity.origin.top();
|
||||
Gravity.Bottom = Gravity.origin.bottom();
|
||||
export function gravity() {
|
||||
return new Gravity;
|
||||
}
|
6
doric-js/lib/src/util/index.util.d.ts
vendored
Normal file
6
doric-js/lib/src/util/index.util.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
export * from './color';
|
||||
export * from './gravity';
|
||||
export * from './layoutconfig';
|
||||
export * from './log';
|
||||
export * from './types';
|
||||
export * from './uniqueId';
|
21
doric-js/lib/src/util/index.util.js
Normal file
21
doric-js/lib/src/util/index.util.js
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export * from './color';
|
||||
export * from './gravity';
|
||||
export * from './layoutconfig';
|
||||
export * from './log';
|
||||
export * from './types';
|
||||
export * from './uniqueId';
|
66
doric-js/lib/src/util/layoutconfig.d.ts
vendored
Normal file
66
doric-js/lib/src/util/layoutconfig.d.ts
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
import { Gravity } from "./gravity";
|
||||
import { Modeling } from "./types";
|
||||
export declare enum LayoutSpec {
|
||||
/**
|
||||
* Depends on what's been set on width or height.
|
||||
*/
|
||||
JUST = 0,
|
||||
/**
|
||||
* Depends on it's content.
|
||||
*/
|
||||
FIT = 1,
|
||||
/**
|
||||
* Extend as much as parent let it take.
|
||||
*/
|
||||
MOST = 2
|
||||
}
|
||||
export interface LayoutConfig {
|
||||
widthSpec?: LayoutSpec;
|
||||
heightSpec?: LayoutSpec;
|
||||
margin?: {
|
||||
left?: number;
|
||||
right?: number;
|
||||
top?: number;
|
||||
bottom?: number;
|
||||
};
|
||||
alignment?: Gravity;
|
||||
weight?: number;
|
||||
}
|
||||
export declare class LayoutConfigImpl implements LayoutConfig, Modeling {
|
||||
widthSpec?: LayoutSpec;
|
||||
heightSpec?: LayoutSpec;
|
||||
margin?: {
|
||||
left?: number;
|
||||
right?: number;
|
||||
top?: number;
|
||||
bottom?: number;
|
||||
};
|
||||
alignment?: Gravity;
|
||||
weight?: number;
|
||||
fit(): this;
|
||||
most(): this;
|
||||
just(): this;
|
||||
configWidth(w: LayoutSpec): this;
|
||||
configHeight(h: LayoutSpec): this;
|
||||
configMargin(m: {
|
||||
left?: number;
|
||||
right?: number;
|
||||
top?: number;
|
||||
bottom?: number;
|
||||
}): this;
|
||||
configAlignment(a: Gravity): this;
|
||||
configWeight(w: number): this;
|
||||
toModel(): {
|
||||
widthSpec: LayoutSpec | undefined;
|
||||
heightSpec: LayoutSpec | undefined;
|
||||
margin: {
|
||||
left?: number | undefined;
|
||||
right?: number | undefined;
|
||||
top?: number | undefined;
|
||||
bottom?: number | undefined;
|
||||
} | undefined;
|
||||
alignment: number | undefined;
|
||||
weight: number | undefined;
|
||||
};
|
||||
}
|
||||
export declare function layoutConfig(): LayoutConfigImpl;
|
64
doric-js/lib/src/util/layoutconfig.js
Normal file
64
doric-js/lib/src/util/layoutconfig.js
Normal file
@ -0,0 +1,64 @@
|
||||
export var LayoutSpec;
|
||||
(function (LayoutSpec) {
|
||||
/**
|
||||
* Depends on what's been set on width or height.
|
||||
*/
|
||||
LayoutSpec[LayoutSpec["JUST"] = 0] = "JUST";
|
||||
/**
|
||||
* Depends on it's content.
|
||||
*/
|
||||
LayoutSpec[LayoutSpec["FIT"] = 1] = "FIT";
|
||||
/**
|
||||
* Extend as much as parent let it take.
|
||||
*/
|
||||
LayoutSpec[LayoutSpec["MOST"] = 2] = "MOST";
|
||||
})(LayoutSpec || (LayoutSpec = {}));
|
||||
export class LayoutConfigImpl {
|
||||
fit() {
|
||||
this.widthSpec = LayoutSpec.FIT;
|
||||
this.heightSpec = LayoutSpec.FIT;
|
||||
return this;
|
||||
}
|
||||
most() {
|
||||
this.widthSpec = LayoutSpec.MOST;
|
||||
this.heightSpec = LayoutSpec.MOST;
|
||||
return this;
|
||||
}
|
||||
just() {
|
||||
this.widthSpec = LayoutSpec.JUST;
|
||||
this.heightSpec = LayoutSpec.JUST;
|
||||
return this;
|
||||
}
|
||||
configWidth(w) {
|
||||
this.widthSpec = w;
|
||||
return this;
|
||||
}
|
||||
configHeight(h) {
|
||||
this.heightSpec = h;
|
||||
return this;
|
||||
}
|
||||
configMargin(m) {
|
||||
this.margin = m;
|
||||
return this;
|
||||
}
|
||||
configAlignment(a) {
|
||||
this.alignment = a;
|
||||
return this;
|
||||
}
|
||||
configWeight(w) {
|
||||
this.weight = w;
|
||||
return this;
|
||||
}
|
||||
toModel() {
|
||||
return {
|
||||
widthSpec: this.widthSpec,
|
||||
heightSpec: this.heightSpec,
|
||||
margin: this.margin,
|
||||
alignment: this.alignment ? this.alignment.toModel() : undefined,
|
||||
weight: this.weight,
|
||||
};
|
||||
}
|
||||
}
|
||||
export function layoutConfig() {
|
||||
return new LayoutConfigImpl;
|
||||
}
|
3
doric-js/lib/src/util/log.d.ts
vendored
Normal file
3
doric-js/lib/src/util/log.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
export declare function log(...args: any): void;
|
||||
export declare function loge(...message: any): void;
|
||||
export declare function logw(...message: any): void;
|
49
doric-js/lib/src/util/log.js
Normal file
49
doric-js/lib/src/util/log.js
Normal file
@ -0,0 +1,49 @@
|
||||
function toString(message) {
|
||||
if (message instanceof Function) {
|
||||
return message.toString();
|
||||
}
|
||||
else if (message instanceof Object) {
|
||||
try {
|
||||
return JSON.stringify(message);
|
||||
}
|
||||
catch (e) {
|
||||
return message.toString();
|
||||
}
|
||||
}
|
||||
else if (message === undefined) {
|
||||
return "undefined";
|
||||
}
|
||||
else {
|
||||
return message.toString();
|
||||
}
|
||||
}
|
||||
export function log(...args) {
|
||||
let out = "";
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
if (i > 0) {
|
||||
out += ',';
|
||||
}
|
||||
out += toString(arguments[i]);
|
||||
}
|
||||
nativeLog('d', out);
|
||||
}
|
||||
export function loge(...message) {
|
||||
let out = "";
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
if (i > 0) {
|
||||
out += ',';
|
||||
}
|
||||
out += toString(arguments[i]);
|
||||
}
|
||||
nativeLog('e', out);
|
||||
}
|
||||
export function logw(...message) {
|
||||
let out = "";
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
if (i > 0) {
|
||||
out += ',';
|
||||
}
|
||||
out += toString(arguments[i]);
|
||||
}
|
||||
nativeLog('w', out);
|
||||
}
|
19
doric-js/lib/src/util/types.d.ts
vendored
Normal file
19
doric-js/lib/src/util/types.d.ts
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
export interface Modeling {
|
||||
toModel(): Model;
|
||||
}
|
||||
export declare function obj2Model(obj: Model): Model;
|
||||
declare type _M = string | number | boolean | Modeling | {
|
||||
[index: string]: Model;
|
||||
} | undefined;
|
||||
export declare type Model = _M | Array<_M>;
|
||||
export declare type Binder<T> = (v: T) => void;
|
||||
export declare class Mutable<T> {
|
||||
private val;
|
||||
private binders;
|
||||
get: () => T;
|
||||
set: (v: T) => void;
|
||||
private constructor();
|
||||
bind(binder: Binder<T>): void;
|
||||
static of<E>(v: E): Mutable<E>;
|
||||
}
|
||||
export {};
|
43
doric-js/lib/src/util/types.js
Normal file
43
doric-js/lib/src/util/types.js
Normal file
@ -0,0 +1,43 @@
|
||||
export function obj2Model(obj) {
|
||||
if (obj instanceof Array) {
|
||||
return obj.map(e => obj2Model(e));
|
||||
}
|
||||
else if (obj instanceof Object) {
|
||||
if (Reflect.has(obj, 'toModel') && Reflect.get(obj, 'toModel') instanceof Function) {
|
||||
obj = Reflect.apply(Reflect.get(obj, 'toModel'), obj, []);
|
||||
return obj;
|
||||
}
|
||||
else {
|
||||
for (let key in obj) {
|
||||
const val = Reflect.get(obj, key);
|
||||
Reflect.set(obj, key, obj2Model(val));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
export class Mutable {
|
||||
constructor(v) {
|
||||
this.binders = new Set;
|
||||
this.get = () => {
|
||||
return this.val;
|
||||
};
|
||||
this.set = (v) => {
|
||||
this.val = v;
|
||||
this.binders.forEach(e => {
|
||||
Reflect.apply(e, undefined, [this.val]);
|
||||
});
|
||||
};
|
||||
this.val = v;
|
||||
}
|
||||
bind(binder) {
|
||||
this.binders.add(binder);
|
||||
Reflect.apply(binder, undefined, [this.val]);
|
||||
}
|
||||
static of(v) {
|
||||
return new Mutable(v);
|
||||
}
|
||||
}
|
1
doric-js/lib/src/util/uniqueId.d.ts
vendored
Normal file
1
doric-js/lib/src/util/uniqueId.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export declare function uniqueId(prefix: string): string;
|
19
doric-js/lib/src/util/uniqueId.js
Normal file
19
doric-js/lib/src/util/uniqueId.js
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
let __uniqueId__ = 0;
|
||||
export function uniqueId(prefix) {
|
||||
return `__${prefix}_${__uniqueId__++}__`;
|
||||
}
|
43
doric-js/lib/src/widget/flowlayout.d.ts
vendored
Normal file
43
doric-js/lib/src/widget/flowlayout.d.ts
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
import { Stack } from './layouts';
|
||||
import { IView, Superview, View } from '../ui/view';
|
||||
export declare class FlowLayoutItem extends Stack {
|
||||
/**
|
||||
* Set to reuse native view
|
||||
*/
|
||||
identifier?: string;
|
||||
}
|
||||
export interface IFlowLayout extends IView {
|
||||
renderItem: (index: number) => FlowLayoutItem;
|
||||
itemCount: number;
|
||||
batchCount?: number;
|
||||
columnCount?: number;
|
||||
columnSpace?: number;
|
||||
rowSpace?: number;
|
||||
}
|
||||
export declare class FlowLayout extends Superview implements IFlowLayout {
|
||||
private cachedViews;
|
||||
private ignoreDirtyCallOnce;
|
||||
allSubviews(): IterableIterator<FlowLayoutItem> | FlowLayoutItem[];
|
||||
columnCount: number;
|
||||
columnSpace?: number;
|
||||
rowSpace?: number;
|
||||
itemCount: number;
|
||||
renderItem: (index: number) => FlowLayoutItem;
|
||||
batchCount: number;
|
||||
onLoadMore?: () => void;
|
||||
loadMore?: boolean;
|
||||
loadMoreView?: FlowLayoutItem;
|
||||
reset(): void;
|
||||
private getItem;
|
||||
isDirty(): boolean;
|
||||
private renderBunchedItems;
|
||||
toModel(): {
|
||||
id: string;
|
||||
type: string;
|
||||
props: {
|
||||
[index: string]: import("../util/types").Model;
|
||||
};
|
||||
};
|
||||
}
|
||||
export declare function flowlayout(config: IFlowLayout): FlowLayout;
|
||||
export declare function flowItem(item: View): FlowLayoutItem;
|
131
doric-js/lib/src/widget/flowlayout.js
Normal file
131
doric-js/lib/src/widget/flowlayout.js
Normal file
@ -0,0 +1,131 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Stack } from './layouts';
|
||||
import { Property, Superview } from '../ui/view';
|
||||
import { layoutConfig } from '../util/index.util';
|
||||
export class FlowLayoutItem extends Stack {
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", String)
|
||||
], FlowLayoutItem.prototype, "identifier", void 0);
|
||||
export class FlowLayout extends Superview {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.cachedViews = new Map;
|
||||
this.ignoreDirtyCallOnce = false;
|
||||
this.columnCount = 2;
|
||||
this.itemCount = 0;
|
||||
this.batchCount = 15;
|
||||
}
|
||||
allSubviews() {
|
||||
if (this.loadMoreView) {
|
||||
return [...this.cachedViews.values(), this.loadMoreView];
|
||||
}
|
||||
else {
|
||||
return this.cachedViews.values();
|
||||
}
|
||||
}
|
||||
reset() {
|
||||
this.cachedViews.clear();
|
||||
this.itemCount = 0;
|
||||
}
|
||||
getItem(itemIdx) {
|
||||
let view = this.renderItem(itemIdx);
|
||||
view.superview = this;
|
||||
this.cachedViews.set(`${itemIdx}`, view);
|
||||
return view;
|
||||
}
|
||||
isDirty() {
|
||||
if (this.ignoreDirtyCallOnce) {
|
||||
this.ignoreDirtyCallOnce = false;
|
||||
//Ignore the dirty call once.
|
||||
return false;
|
||||
}
|
||||
return super.isDirty();
|
||||
}
|
||||
renderBunchedItems(start, length) {
|
||||
this.ignoreDirtyCallOnce = true;
|
||||
return new Array(Math.min(length, this.itemCount - start)).fill(0).map((_, idx) => {
|
||||
const listItem = this.getItem(start + idx);
|
||||
return listItem.toModel();
|
||||
});
|
||||
}
|
||||
toModel() {
|
||||
if (this.loadMoreView) {
|
||||
this.dirtyProps['loadMoreView'] = this.loadMoreView.viewId;
|
||||
}
|
||||
return super.toModel();
|
||||
}
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], FlowLayout.prototype, "columnCount", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], FlowLayout.prototype, "columnSpace", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], FlowLayout.prototype, "rowSpace", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], FlowLayout.prototype, "itemCount", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], FlowLayout.prototype, "renderItem", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], FlowLayout.prototype, "batchCount", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], FlowLayout.prototype, "onLoadMore", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Boolean)
|
||||
], FlowLayout.prototype, "loadMore", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", FlowLayoutItem)
|
||||
], FlowLayout.prototype, "loadMoreView", void 0);
|
||||
export function flowlayout(config) {
|
||||
const ret = new FlowLayout;
|
||||
for (let key in config) {
|
||||
Reflect.set(ret, key, Reflect.get(config, key, config), ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
export function flowItem(item) {
|
||||
return (new FlowLayoutItem).also((it) => {
|
||||
it.layoutConfig = layoutConfig().fit();
|
||||
it.addChild(item);
|
||||
});
|
||||
}
|
27
doric-js/lib/src/widget/image.d.ts
vendored
Normal file
27
doric-js/lib/src/widget/image.d.ts
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
import { IView, View } from "../ui/view";
|
||||
export declare enum ScaleType {
|
||||
ScaleToFill = 0,
|
||||
ScaleAspectFit = 1,
|
||||
ScaleAspectFill = 2
|
||||
}
|
||||
export interface IImage extends IView {
|
||||
imageUrl?: string;
|
||||
imageBase64?: string;
|
||||
scaleType?: ScaleType;
|
||||
isBlur?: boolean;
|
||||
loadCallback?: (image: {
|
||||
width: number;
|
||||
height: number;
|
||||
} | undefined) => void;
|
||||
}
|
||||
export declare class Image extends View implements IImage {
|
||||
imageUrl?: string;
|
||||
imageBase64?: string;
|
||||
scaleType?: ScaleType;
|
||||
isBlur?: boolean;
|
||||
loadCallback?: (image: {
|
||||
width: number;
|
||||
height: number;
|
||||
} | undefined) => void;
|
||||
}
|
||||
export declare function image(config: IImage): Image;
|
62
doric-js/lib/src/widget/image.js
Normal file
62
doric-js/lib/src/widget/image.js
Normal file
@ -0,0 +1,62 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { View, Property } from "../ui/view";
|
||||
import { layoutConfig } from "../util/layoutconfig";
|
||||
export var ScaleType;
|
||||
(function (ScaleType) {
|
||||
ScaleType[ScaleType["ScaleToFill"] = 0] = "ScaleToFill";
|
||||
ScaleType[ScaleType["ScaleAspectFit"] = 1] = "ScaleAspectFit";
|
||||
ScaleType[ScaleType["ScaleAspectFill"] = 2] = "ScaleAspectFill";
|
||||
})(ScaleType || (ScaleType = {}));
|
||||
export class Image extends View {
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", String)
|
||||
], Image.prototype, "imageUrl", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", String)
|
||||
], Image.prototype, "imageBase64", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], Image.prototype, "scaleType", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Boolean)
|
||||
], Image.prototype, "isBlur", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], Image.prototype, "loadCallback", void 0);
|
||||
export function image(config) {
|
||||
const ret = new Image;
|
||||
ret.layoutConfig = layoutConfig().fit();
|
||||
for (let key in config) {
|
||||
Reflect.set(ret, key, Reflect.get(config, key, config), ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
10
doric-js/lib/src/widget/index.widget.d.ts
vendored
Normal file
10
doric-js/lib/src/widget/index.widget.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
export * from './layouts';
|
||||
export * from './text';
|
||||
export * from './image';
|
||||
export * from './list';
|
||||
export * from './slider';
|
||||
export * from './scroller';
|
||||
export * from './refreshable';
|
||||
export * from './flowlayout';
|
||||
export * from './input';
|
||||
export * from './nestedSlider';
|
25
doric-js/lib/src/widget/index.widget.js
Normal file
25
doric-js/lib/src/widget/index.widget.js
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export * from './layouts';
|
||||
export * from './text';
|
||||
export * from './image';
|
||||
export * from './list';
|
||||
export * from './slider';
|
||||
export * from './scroller';
|
||||
export * from './refreshable';
|
||||
export * from './flowlayout';
|
||||
export * from './input';
|
||||
export * from './nestedSlider';
|
31
doric-js/lib/src/widget/input.d.ts
vendored
Normal file
31
doric-js/lib/src/widget/input.d.ts
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
import { View, IView } from "../ui/view";
|
||||
import { Color } from "../util/color";
|
||||
import { Gravity } from "../util/gravity";
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
export interface IInput extends IView {
|
||||
text?: string;
|
||||
textColor?: Color;
|
||||
textSize?: number;
|
||||
hintText?: string;
|
||||
hintTextColor?: Color;
|
||||
multilines?: boolean;
|
||||
textAlignment?: Gravity;
|
||||
onTextChange?: (text: string) => void;
|
||||
onFocusChange?: (focused: boolean) => void;
|
||||
}
|
||||
export declare class Input extends View implements IInput {
|
||||
text?: string;
|
||||
textColor?: Color;
|
||||
textSize?: number;
|
||||
hintText?: string;
|
||||
hintTextColor?: Color;
|
||||
multiline?: boolean;
|
||||
textAlignment?: Gravity;
|
||||
onTextChange?: (text: string) => void;
|
||||
onFocusChange?: (focused: boolean) => void;
|
||||
getText(context: BridgeContext): Promise<string>;
|
||||
setSelection(context: BridgeContext, start: number, end?: number): Promise<string>;
|
||||
requestFocus(context: BridgeContext): Promise<any>;
|
||||
releaseFocus(context: BridgeContext): Promise<any>;
|
||||
}
|
||||
export declare function input(config: IInput): Input;
|
89
doric-js/lib/src/widget/input.js
Normal file
89
doric-js/lib/src/widget/input.js
Normal file
@ -0,0 +1,89 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { View, Property } from "../ui/view";
|
||||
import { Color } from "../util/color";
|
||||
import { Gravity } from "../util/gravity";
|
||||
import { layoutConfig } from "../util/index.util";
|
||||
export class Input extends View {
|
||||
getText(context) {
|
||||
return this.nativeChannel(context, 'getText')();
|
||||
}
|
||||
setSelection(context, start, end = start) {
|
||||
return this.nativeChannel(context, 'setSelection')({
|
||||
start,
|
||||
end,
|
||||
});
|
||||
}
|
||||
requestFocus(context) {
|
||||
return this.nativeChannel(context, 'requestFocus')();
|
||||
}
|
||||
releaseFocus(context) {
|
||||
return this.nativeChannel(context, 'releaseFocus')();
|
||||
}
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", String)
|
||||
], Input.prototype, "text", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Color)
|
||||
], Input.prototype, "textColor", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], Input.prototype, "textSize", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", String)
|
||||
], Input.prototype, "hintText", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Color)
|
||||
], Input.prototype, "hintTextColor", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Boolean)
|
||||
], Input.prototype, "multiline", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Gravity)
|
||||
], Input.prototype, "textAlignment", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], Input.prototype, "onTextChange", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], Input.prototype, "onFocusChange", void 0);
|
||||
export function input(config) {
|
||||
const ret = new Input;
|
||||
ret.layoutConfig = layoutConfig().just();
|
||||
for (let key in config) {
|
||||
Reflect.set(ret, key, Reflect.get(config, key, config), ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
28
doric-js/lib/src/widget/layouts.d.ts
vendored
Normal file
28
doric-js/lib/src/widget/layouts.d.ts
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
import { Group, IView, View } from "../ui/view";
|
||||
import { Gravity } from "../util/gravity";
|
||||
export interface IStack extends IView {
|
||||
}
|
||||
export declare class Stack extends Group implements IStack {
|
||||
}
|
||||
export declare class Root extends Stack {
|
||||
}
|
||||
declare class LinearLayout extends Group {
|
||||
space?: number;
|
||||
gravity?: Gravity;
|
||||
}
|
||||
export interface IVLayout extends IView {
|
||||
space?: number;
|
||||
gravity?: Gravity;
|
||||
}
|
||||
export declare class VLayout extends LinearLayout implements VLayout {
|
||||
}
|
||||
export interface IHLayout extends IView {
|
||||
space?: number;
|
||||
gravity?: Gravity;
|
||||
}
|
||||
export declare class HLayout extends LinearLayout implements IHLayout {
|
||||
}
|
||||
export declare function stack(views: View[]): Stack;
|
||||
export declare function hlayout(views: View[]): HLayout;
|
||||
export declare function vlayout(views: View[]): VLayout;
|
||||
export {};
|
69
doric-js/lib/src/widget/layouts.js
Normal file
69
doric-js/lib/src/widget/layouts.js
Normal file
@ -0,0 +1,69 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Group, Property } from "../ui/view";
|
||||
import { Gravity } from "../util/gravity";
|
||||
import { layoutConfig } from "../util/layoutconfig";
|
||||
export class Stack extends Group {
|
||||
}
|
||||
export class Root extends Stack {
|
||||
}
|
||||
class LinearLayout extends Group {
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], LinearLayout.prototype, "space", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Gravity)
|
||||
], LinearLayout.prototype, "gravity", void 0);
|
||||
export class VLayout extends LinearLayout {
|
||||
}
|
||||
export class HLayout extends LinearLayout {
|
||||
}
|
||||
export function stack(views) {
|
||||
const ret = new Stack;
|
||||
ret.layoutConfig = layoutConfig().fit();
|
||||
for (let v of views) {
|
||||
ret.addChild(v);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
export function hlayout(views) {
|
||||
const ret = new HLayout;
|
||||
ret.layoutConfig = layoutConfig().fit();
|
||||
for (let v of views) {
|
||||
ret.addChild(v);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
export function vlayout(views) {
|
||||
const ret = new VLayout;
|
||||
ret.layoutConfig = layoutConfig().fit();
|
||||
for (let v of views) {
|
||||
ret.addChild(v);
|
||||
}
|
||||
return ret;
|
||||
}
|
37
doric-js/lib/src/widget/list.d.ts
vendored
Normal file
37
doric-js/lib/src/widget/list.d.ts
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
import { View, Superview, IView } from "../ui/view";
|
||||
import { Stack } from "./layouts";
|
||||
export declare class ListItem extends Stack {
|
||||
/**
|
||||
* Set to reuse native view
|
||||
*/
|
||||
identifier?: string;
|
||||
}
|
||||
export interface IList extends IView {
|
||||
renderItem: (index: number) => ListItem;
|
||||
itemCount: number;
|
||||
batchCount?: number;
|
||||
}
|
||||
export declare class List extends Superview implements IList {
|
||||
private cachedViews;
|
||||
private ignoreDirtyCallOnce;
|
||||
allSubviews(): IterableIterator<ListItem> | ListItem[];
|
||||
itemCount: number;
|
||||
renderItem: (index: number) => ListItem;
|
||||
batchCount: number;
|
||||
onLoadMore?: () => void;
|
||||
loadMore?: boolean;
|
||||
loadMoreView?: ListItem;
|
||||
reset(): void;
|
||||
private getItem;
|
||||
isDirty(): boolean;
|
||||
private renderBunchedItems;
|
||||
toModel(): {
|
||||
id: string;
|
||||
type: string;
|
||||
props: {
|
||||
[index: string]: import("../..").Model;
|
||||
};
|
||||
};
|
||||
}
|
||||
export declare function list(config: IList): List;
|
||||
export declare function listItem(item: View): ListItem;
|
121
doric-js/lib/src/widget/list.js
Normal file
121
doric-js/lib/src/widget/list.js
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
import { Property, Superview } from "../ui/view";
|
||||
import { Stack } from "./layouts";
|
||||
import { layoutConfig, LayoutSpec } from "../util/layoutconfig";
|
||||
export class ListItem extends Stack {
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", String)
|
||||
], ListItem.prototype, "identifier", void 0);
|
||||
export class List extends Superview {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.cachedViews = new Map;
|
||||
this.ignoreDirtyCallOnce = false;
|
||||
this.itemCount = 0;
|
||||
this.batchCount = 15;
|
||||
}
|
||||
allSubviews() {
|
||||
if (this.loadMoreView) {
|
||||
return [...this.cachedViews.values(), this.loadMoreView];
|
||||
}
|
||||
else {
|
||||
return this.cachedViews.values();
|
||||
}
|
||||
}
|
||||
reset() {
|
||||
this.cachedViews.clear();
|
||||
this.itemCount = 0;
|
||||
}
|
||||
getItem(itemIdx) {
|
||||
let view = this.cachedViews.get(`${itemIdx}`);
|
||||
if (view === undefined) {
|
||||
view = this.renderItem(itemIdx);
|
||||
view.superview = this;
|
||||
this.cachedViews.set(`${itemIdx}`, view);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
isDirty() {
|
||||
if (this.ignoreDirtyCallOnce) {
|
||||
this.ignoreDirtyCallOnce = false;
|
||||
//Ignore the dirty call once.
|
||||
return false;
|
||||
}
|
||||
return super.isDirty();
|
||||
}
|
||||
renderBunchedItems(start, length) {
|
||||
this.ignoreDirtyCallOnce = true;
|
||||
return new Array(Math.min(length, this.itemCount - start)).fill(0).map((_, idx) => {
|
||||
const listItem = this.getItem(start + idx);
|
||||
return listItem.toModel();
|
||||
});
|
||||
}
|
||||
toModel() {
|
||||
if (this.loadMoreView) {
|
||||
this.dirtyProps['loadMoreView'] = this.loadMoreView.viewId;
|
||||
}
|
||||
return super.toModel();
|
||||
}
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], List.prototype, "itemCount", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], List.prototype, "renderItem", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], List.prototype, "batchCount", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], List.prototype, "onLoadMore", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Boolean)
|
||||
], List.prototype, "loadMore", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", ListItem)
|
||||
], List.prototype, "loadMoreView", void 0);
|
||||
export function list(config) {
|
||||
const ret = new List;
|
||||
for (let key in config) {
|
||||
Reflect.set(ret, key, Reflect.get(config, key, config), ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
export function listItem(item) {
|
||||
return (new ListItem).also((it) => {
|
||||
it.layoutConfig = layoutConfig().most().configHeight(LayoutSpec.FIT);
|
||||
it.addChild(item);
|
||||
});
|
||||
}
|
8
doric-js/lib/src/widget/nestedSlider.d.ts
vendored
Normal file
8
doric-js/lib/src/widget/nestedSlider.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
import { Group, View } from '../ui/view';
|
||||
import { BridgeContext } from '../runtime/global';
|
||||
export declare class NestedSlider extends Group {
|
||||
onPageSlided?: (index: number) => void;
|
||||
addSlideItem(view: View): void;
|
||||
slidePage(context: BridgeContext, page: number, smooth?: boolean): Promise<any>;
|
||||
getSlidedPage(context: BridgeContext): Promise<number>;
|
||||
}
|
40
doric-js/lib/src/widget/nestedSlider.js
Normal file
40
doric-js/lib/src/widget/nestedSlider.js
Normal file
@ -0,0 +1,40 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Group, Property } from '../ui/view';
|
||||
export class NestedSlider extends Group {
|
||||
addSlideItem(view) {
|
||||
this.addChild(view);
|
||||
}
|
||||
slidePage(context, page, smooth = false) {
|
||||
return this.nativeChannel(context, "slidePage")({ page, smooth });
|
||||
}
|
||||
getSlidedPage(context) {
|
||||
return this.nativeChannel(context, "getSlidedPage")();
|
||||
}
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], NestedSlider.prototype, "onPageSlided", void 0);
|
33
doric-js/lib/src/widget/refreshable.d.ts
vendored
Normal file
33
doric-js/lib/src/widget/refreshable.d.ts
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
import { View, Superview, IView } from "../ui/view";
|
||||
import { List } from "./list";
|
||||
import { Scroller } from "./scroller";
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
export interface IRefreshable extends IView {
|
||||
content: View;
|
||||
header?: View;
|
||||
onRefresh?: () => void;
|
||||
}
|
||||
export declare class Refreshable extends Superview implements IRefreshable {
|
||||
content: List | Scroller;
|
||||
header?: View;
|
||||
onRefresh?: () => void;
|
||||
allSubviews(): View[];
|
||||
setRefreshable(context: BridgeContext, refreshable: boolean): Promise<any>;
|
||||
setRefreshing(context: BridgeContext, refreshing: boolean): Promise<any>;
|
||||
isRefreshable(context: BridgeContext): Promise<boolean>;
|
||||
isRefreshing(context: BridgeContext): Promise<boolean>;
|
||||
toModel(): {
|
||||
id: string;
|
||||
type: string;
|
||||
props: {
|
||||
[index: string]: import("../..").Model;
|
||||
};
|
||||
};
|
||||
}
|
||||
export declare function refreshable(config: IRefreshable): Refreshable;
|
||||
export interface IPullable {
|
||||
startAnimation(): void;
|
||||
stopAnimation(): void;
|
||||
setPullingDistance(distance: number): void;
|
||||
}
|
||||
export declare function pullable(v: View, config: IPullable): View;
|
55
doric-js/lib/src/widget/refreshable.js
Normal file
55
doric-js/lib/src/widget/refreshable.js
Normal file
@ -0,0 +1,55 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
import { Property, Superview } from "../ui/view";
|
||||
import { layoutConfig } from "../util/layoutconfig";
|
||||
export class Refreshable extends Superview {
|
||||
allSubviews() {
|
||||
const ret = [this.content];
|
||||
if (this.header) {
|
||||
ret.push(this.header);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
setRefreshable(context, refreshable) {
|
||||
return this.nativeChannel(context, 'setRefreshable')(refreshable);
|
||||
}
|
||||
setRefreshing(context, refreshing) {
|
||||
return this.nativeChannel(context, 'setRefreshing')(refreshing);
|
||||
}
|
||||
isRefreshable(context) {
|
||||
return this.nativeChannel(context, 'isRefreshable')();
|
||||
}
|
||||
isRefreshing(context) {
|
||||
return this.nativeChannel(context, 'isRefreshing')();
|
||||
}
|
||||
toModel() {
|
||||
this.dirtyProps.content = this.content.viewId;
|
||||
this.dirtyProps.header = (this.header || {}).viewId;
|
||||
return super.toModel();
|
||||
}
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], Refreshable.prototype, "onRefresh", void 0);
|
||||
export function refreshable(config) {
|
||||
const ret = new Refreshable;
|
||||
ret.layoutConfig = layoutConfig().fit();
|
||||
for (let key in config) {
|
||||
Reflect.set(ret, key, Reflect.get(config, key, config), ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
export function pullable(v, config) {
|
||||
Reflect.set(v, 'startAnimation', config.startAnimation);
|
||||
Reflect.set(v, 'stopAnimation', config.stopAnimation);
|
||||
Reflect.set(v, 'setPullingDistance', config.setPullingDistance);
|
||||
return v;
|
||||
}
|
16
doric-js/lib/src/widget/scroller.d.ts
vendored
Normal file
16
doric-js/lib/src/widget/scroller.d.ts
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
import { Superview, View, IView } from '../ui/view';
|
||||
export declare function scroller(content: View): Scroller;
|
||||
export interface IScroller extends IView {
|
||||
content: View;
|
||||
}
|
||||
export declare class Scroller extends Superview implements IScroller {
|
||||
content: View;
|
||||
allSubviews(): View[];
|
||||
toModel(): {
|
||||
id: string;
|
||||
type: string;
|
||||
props: {
|
||||
[index: string]: import("../..").Model;
|
||||
};
|
||||
};
|
||||
}
|
32
doric-js/lib/src/widget/scroller.js
Normal file
32
doric-js/lib/src/widget/scroller.js
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Superview } from '../ui/view';
|
||||
import { layoutConfig } from '../util/layoutconfig';
|
||||
export function scroller(content) {
|
||||
return (new Scroller).also(v => {
|
||||
v.layoutConfig = layoutConfig().fit();
|
||||
v.content = content;
|
||||
});
|
||||
}
|
||||
export class Scroller extends Superview {
|
||||
allSubviews() {
|
||||
return [this.content];
|
||||
}
|
||||
toModel() {
|
||||
this.dirtyProps.content = this.content.viewId;
|
||||
return super.toModel();
|
||||
}
|
||||
}
|
31
doric-js/lib/src/widget/slider.d.ts
vendored
Normal file
31
doric-js/lib/src/widget/slider.d.ts
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
import { Superview, View, IView } from "../ui/view";
|
||||
import { Stack } from "./layouts";
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
export declare class SlideItem extends Stack {
|
||||
/**
|
||||
* Set to reuse native view
|
||||
*/
|
||||
identifier?: string;
|
||||
}
|
||||
export interface ISlider extends IView {
|
||||
renderPage: (index: number) => SlideItem;
|
||||
itemCount: number;
|
||||
batchCount?: number;
|
||||
onPageSlided?: (index: number) => void;
|
||||
}
|
||||
export declare class Slider extends Superview implements ISlider {
|
||||
private cachedViews;
|
||||
private ignoreDirtyCallOnce;
|
||||
allSubviews(): IterableIterator<SlideItem>;
|
||||
itemCount: number;
|
||||
renderPage: (index: number) => SlideItem;
|
||||
batchCount: number;
|
||||
onPageSlided?: (index: number) => void;
|
||||
private getItem;
|
||||
isDirty(): boolean;
|
||||
private renderBunchedItems;
|
||||
slidePage(context: BridgeContext, page: number, smooth?: boolean): Promise<any>;
|
||||
getSlidedPage(context: BridgeContext): Promise<number>;
|
||||
}
|
||||
export declare function slideItem(item: View): SlideItem;
|
||||
export declare function slider(config: ISlider): Slider;
|
89
doric-js/lib/src/widget/slider.js
Normal file
89
doric-js/lib/src/widget/slider.js
Normal file
@ -0,0 +1,89 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
import { Superview, Property } from "../ui/view";
|
||||
import { Stack } from "./layouts";
|
||||
import { layoutConfig } from "../util/layoutconfig";
|
||||
export class SlideItem extends Stack {
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", String)
|
||||
], SlideItem.prototype, "identifier", void 0);
|
||||
export class Slider extends Superview {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.cachedViews = new Map;
|
||||
this.ignoreDirtyCallOnce = false;
|
||||
this.itemCount = 0;
|
||||
this.batchCount = 3;
|
||||
}
|
||||
allSubviews() {
|
||||
return this.cachedViews.values();
|
||||
}
|
||||
getItem(itemIdx) {
|
||||
let view = this.cachedViews.get(`${itemIdx}`);
|
||||
if (view === undefined) {
|
||||
view = this.renderPage(itemIdx);
|
||||
view.superview = this;
|
||||
this.cachedViews.set(`${itemIdx}`, view);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
isDirty() {
|
||||
if (this.ignoreDirtyCallOnce) {
|
||||
this.ignoreDirtyCallOnce = false;
|
||||
//Ignore the dirty call once.
|
||||
return false;
|
||||
}
|
||||
return super.isDirty();
|
||||
}
|
||||
renderBunchedItems(start, length) {
|
||||
this.ignoreDirtyCallOnce = true;
|
||||
return new Array(Math.min(length, this.itemCount - start)).fill(0).map((_, idx) => {
|
||||
const slideItem = this.getItem(start + idx);
|
||||
return slideItem.toModel();
|
||||
});
|
||||
}
|
||||
slidePage(context, page, smooth = false) {
|
||||
return this.nativeChannel(context, "slidePage")({ page, smooth });
|
||||
}
|
||||
getSlidedPage(context) {
|
||||
return this.nativeChannel(context, "getSlidedPage")();
|
||||
}
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], Slider.prototype, "itemCount", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], Slider.prototype, "renderPage", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], Slider.prototype, "batchCount", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], Slider.prototype, "onPageSlided", void 0);
|
||||
export function slideItem(item) {
|
||||
return (new SlideItem).also((it) => {
|
||||
it.layoutConfig = layoutConfig().fit();
|
||||
it.addChild(item);
|
||||
});
|
||||
}
|
||||
export function slider(config) {
|
||||
const ret = new Slider;
|
||||
for (let key in config) {
|
||||
Reflect.set(ret, key, Reflect.get(config, key, config), ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
18
doric-js/lib/src/widget/text.d.ts
vendored
Normal file
18
doric-js/lib/src/widget/text.d.ts
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
import { IView, View } from "../ui/view";
|
||||
import { Color } from "../util/color";
|
||||
import { Gravity } from "../util/gravity";
|
||||
export interface IText extends IView {
|
||||
text?: string;
|
||||
textColor?: Color;
|
||||
textSize?: number;
|
||||
maxLines?: number;
|
||||
textAlignment?: Gravity;
|
||||
}
|
||||
export declare class Text extends View implements IText {
|
||||
text?: string;
|
||||
textColor?: Color;
|
||||
textSize?: number;
|
||||
maxLines?: number;
|
||||
textAlignment?: Gravity;
|
||||
}
|
||||
export declare function text(config: IText): Text;
|
58
doric-js/lib/src/widget/text.js
Normal file
58
doric-js/lib/src/widget/text.js
Normal file
@ -0,0 +1,58 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { View, Property } from "../ui/view";
|
||||
import { Color } from "../util/color";
|
||||
import { Gravity } from "../util/gravity";
|
||||
import { layoutConfig } from "../util/layoutconfig";
|
||||
export class Text extends View {
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", String)
|
||||
], Text.prototype, "text", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Color)
|
||||
], Text.prototype, "textColor", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], Text.prototype, "textSize", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], Text.prototype, "maxLines", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Gravity)
|
||||
], Text.prototype, "textAlignment", void 0);
|
||||
export function text(config) {
|
||||
const ret = new Text;
|
||||
ret.layoutConfig = layoutConfig().fit();
|
||||
for (let key in config) {
|
||||
Reflect.set(ret, key, Reflect.get(config, key, config), ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
@ -1,13 +1,15 @@
|
||||
{
|
||||
"name": "doric",
|
||||
"version": "0.2.1",
|
||||
"version": "0.2.2-alpha.0",
|
||||
"description": "The JS Framework of Doric",
|
||||
"main": "bundle/doric-vm.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "tsc -p .&& rollup -c",
|
||||
"build": "tsc -d -p .&& rollup -c",
|
||||
"dev": "tsc -w -p . & rollup -c -w",
|
||||
"clean": "rm -rf build && rm -rf bundle"
|
||||
"clean": "rm -rf build && rm -rf bundle",
|
||||
"prepublish": "npm run build"
|
||||
},
|
||||
"repository": {
|
||||
"type": "https",
|
||||
|
@ -4,7 +4,7 @@ import resolve from '@rollup/plugin-node-resolve'
|
||||
|
||||
export default [
|
||||
{
|
||||
input: "build/index.runtime.js",
|
||||
input: "lib/index.runtime.js",
|
||||
output: {
|
||||
name: "doric",
|
||||
format: "iife",
|
||||
@ -13,13 +13,13 @@ export default [
|
||||
plugins: [
|
||||
resolve({ mainFields: ["jsnext"] }),
|
||||
],
|
||||
onwarn: function(warning) {
|
||||
if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; }
|
||||
console.warn( warning.message );
|
||||
onwarn: function (warning) {
|
||||
if (warning.code === 'THIS_IS_UNDEFINED') { return; }
|
||||
console.warn(warning.message);
|
||||
}
|
||||
},
|
||||
{
|
||||
input: "build/index.js",
|
||||
input: "lib/index.js",
|
||||
output: {
|
||||
format: "cjs",
|
||||
file: "bundle/doric-lib.js",
|
||||
@ -28,13 +28,13 @@ export default [
|
||||
resolve({ mainFields: ["jsnext"] }),
|
||||
],
|
||||
external: ['reflect-metadata'],
|
||||
onwarn: function(warning) {
|
||||
if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; }
|
||||
console.warn( warning.message );
|
||||
onwarn: function (warning) {
|
||||
if (warning.code === 'THIS_IS_UNDEFINED') { return; }
|
||||
console.warn(warning.message);
|
||||
}
|
||||
},
|
||||
{
|
||||
input: "build/index.debug.js",
|
||||
input: "lib/index.debug.js",
|
||||
output: {
|
||||
format: "cjs",
|
||||
file: "bundle/doric-vm.js",
|
||||
@ -43,9 +43,9 @@ export default [
|
||||
resolve({ mainFields: ["jsnext"] }),
|
||||
],
|
||||
external: ['ws'],
|
||||
onwarn: function(warning) {
|
||||
if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; }
|
||||
console.warn( warning.message );
|
||||
onwarn: function (warning) {
|
||||
if (warning.code === 'THIS_IS_UNDEFINED') { return; }
|
||||
console.warn(warning.message);
|
||||
}
|
||||
},
|
||||
]
|
@ -13,7 +13,7 @@
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
"outDir": "build/", /* Redirect output structure to the directory. */
|
||||
"outDir": "lib/", /* Redirect output structure to the directory. */
|
||||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
||||
|
Reference in New Issue
Block a user