js:add es5 compile option

This commit is contained in:
pengfei.zhou 2020-01-17 10:12:13 +08:00 committed by osborn
parent 7f089b6bcd
commit 83a9b79073
15 changed files with 881 additions and 16519 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1
doric-js/index.d.ts vendored
View File

@ -9,6 +9,7 @@ declare module 'doric' {
export * from 'doric/lib/src/native/index.native';
export * from "doric/lib/src/util/index.util";
export * from "doric/lib/src/pattern/index.pattern";
export * from 'doric/lib/src/ui/view';
}
declare module 'doric/lib/src/runtime/global' {

21
doric-js/index.es5.ts Normal file
View 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 './src/runtime/global'
export * from './src/ui/index.ui.es5'
export * from "./src/widget/index.widget"
export * from './src/native/index.native'
export * from "./src/util/index.util"
export * from "./src/pattern/index.pattern"

View File

@ -54,5 +54,5 @@ class ProxyPolyfill {
const global = Function('return this')()
global.Proxy = ProxyPolyfill
export * from './src/runtime/sandbox'
export * from './src/runtime/sandbox.es5'
export * from 'core-js'

View File

@ -1,2 +0,0 @@
export * from './src/runtime/sandbox';
export * from 'core-js';

View File

@ -1,57 +0,0 @@
/*
* 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.
*/
class ProxyPolyfill {
constructor(target, handler) {
this.__target__ = target;
this.__handler__ = handler;
this.defineProps();
return target;
}
defineProps() {
const keys = Object.keys(this.__target__);
keys.forEach(property => {
if (Object.getOwnPropertyDescriptor(this.__target__, property) !== undefined) {
return;
}
Object.defineProperty(this, property, {
get: () => {
this.defineProps();
if (this.__handler__.get) {
return this.__handler__.get(this.__target__, property, this);
}
else {
return this.__target__[property];
}
},
set: (value) => {
this.defineProps();
if (this.__handler__.set) {
this.__handler__.set(this.__target__, property, value, property);
}
else {
this.__target__[property] = value;
}
},
enumerable: true,
configurable: true,
});
});
}
}
const global = Function('return this')();
global.Proxy = ProxyPolyfill;
export * from './src/runtime/sandbox';
export * from 'core-js';

View File

@ -82,43 +82,32 @@ 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;
fromScaleX: number;
toScaleX: number;
fromScaleY: number;
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;
fromTranslationX: number;
toTranslationX: number;
fromTranslationY: number;
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;
fromRotation: number;
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);
duration: number;
toModel(): {
animations: Model;
delay: number | undefined;

View File

@ -104,21 +104,15 @@ export declare abstract class View implements Modeling, IView {
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);
left: number;
right: number;
top: number;
bottom: number;
centerX: number;
centerY: number;
/** Anchor end*/
private __dirty_props__;
get dirtyProps(): {
readonly dirtyProps: {
[index: string]: Model;
};
nativeViewModel: NativeViewModel;

View File

@ -18,25 +18,6 @@ export default [
console.warn(warning.message);
}
},
{
input: "lib-es5/index.runtime.es5.js",
output: {
name: "doric",
format: "iife",
file: "bundle/doric-sandbox.es5.js",
},
plugins: [
resolve({ mainFields: ["jsnext"] }),
commonjs(),
buble({
transforms: { dangerousForOf: true }
}),
],
onwarn: function (warning) {
if (warning.code === 'THIS_IS_UNDEFINED') { return; }
console.warn(warning.message);
}
},
{
input: "lib/index.js",
output: {
@ -52,24 +33,6 @@ export default [
console.warn(warning.message);
}
},
{
input: "lib-es5/index.js",
output: {
format: "cjs",
file: "bundle/doric-lib.es5.js",
},
plugins: [
resolve({ mainFields: ["jsnext"] }),
buble({
transforms: { dangerousForOf: true }
}),
],
external: ['reflect-metadata'],
onwarn: function (warning) {
if (warning.code === 'THIS_IS_UNDEFINED') { return; }
console.warn(warning.message);
}
},
{
input: "lib/index.debug.js",
output: {
@ -85,4 +48,42 @@ export default [
console.warn(warning.message);
}
},
// {
// input: "lib-es5/index.runtime.es5.js",
// output: {
// name: "doric",
// format: "iife",
// file: "bundle/doric-sandbox.es5.js",
// },
// plugins: [
// resolve({ mainFields: ["jsnext"] }),
// commonjs(),
// buble({
// transforms: { dangerousForOf: true }
// }),
// ],
// onwarn: function (warning) {
// if (warning.code === 'THIS_IS_UNDEFINED') { return; }
// console.warn(warning.message);
// }
// },
// {
// input: "lib-es5/index.es5.js",
// output: {
// format: "cjs",
// file: "bundle/doric-lib.es5.js",
// },
// plugins: [
// resolve({ mainFields: ["jsnext"] }),
// buble({
// transforms: { dangerousForOf: true }
// }),
// ],
// external: ['reflect-metadata'],
// onwarn: function (warning) {
// if (warning.code === 'THIS_IS_UNDEFINED') { return; }
// console.warn(warning.message);
// }
// },
]

View File

@ -0,0 +1,371 @@
/*
* 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"
/**
* ``` TypeScript
* // load script in global scope
* Reflect.apply(
* function(doric,context,Entry,require){
* //Script content
* REG()
* },doric.jsObtainContext(id),[
* undefined,
* doric.jsObtainContext(id),
* doric.jsObtainEntry(id),
* doric.__require__,
* ])
* // load module in global scope
* Reflect.apply(doric.jsRegisterModule,this,[
* moduleName,
* Reflect.apply(function(__module){
* (function(module,exports,require){
* //module content
* })(__module,__module.exports,doric.__require__);
* return __module.exports
* },this,[{exports:{}}])
* ])
*
* ```
*/
declare function nativeRequire(moduleName: string): boolean
declare function nativeBridge(contextId: string, namespace: string, method: string, callbackId?: string, args?: any): boolean
declare function nativeSetTimer(timerId: number, interval: number, repeat: boolean): void
declare function nativeClearTimer(timerId: number): void
function hookBeforeNativeCall(context?: Context) {
if (context) {
Reflect.defineMetadata('__doric_context__', context, global)
context.hookBeforeNativeCall()
}
}
function hookAfterNativeCall(context?: Context) {
if (context) {
context.hookAfterNativeCall()
}
}
function getContext(): Context | undefined {
return Reflect.getMetadata('__doric_context__', global)
}
function setContext(context?: Context) {
Reflect.defineMetadata('__doric_context__', context, global)
}
export function jsCallResolve(contextId: string, callbackId: string, args?: any) {
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: any = []
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: string, callbackId: string, args?: any) {
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: any = []
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 {
entity: any
id: string
callbacks: Map<string, { resolve: Function, reject: Function }> = new Map
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, [])
}
}
constructor(id: string) {
this.id = id
return new Proxy(this, {
get: (target, p: any) => {
if (Reflect.has(target, p)) {
return Reflect.get(target, p)
} else {
const namespace = p
return new Proxy({}, {
get: (target, p: any) => {
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)
}
}
}
})
}
}
})
}
callNative(namespace: string, method: string, args?: any): Promise<any> {
const callbackId = uniqueId('callback')
nativeBridge(this.id, namespace, method, callbackId, args)
return new Promise((resolve, reject) => {
this.callbacks.set(callbackId, {
resolve,
reject,
})
})
}
register(instance: Object) {
this.entity = instance
}
function2Id(func: Function) {
const functionId = uniqueId('function')
this.callbacks.set(functionId, {
resolve: func,
reject: () => { loge("This should not be called") }
})
return functionId
}
removeFuncById(funcId: string) {
this.callbacks.delete(funcId)
}
}
const gContexts: Map<string, Context> = new Map
const gModules: Map<string, any> = new Map
export function jsObtainContext(id: string) {
if (gContexts.has(id)) {
const context = gContexts.get(id)
setContext(context)
return context
} else {
const context: Context = new Context(id)
gContexts.set(id, context)
setContext(context)
return context
}
}
export function jsReleaseContext(id: string) {
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: string): any {
if (gModules.has(name)) {
return gModules.get(name)
} else {
if (nativeRequire(name)) {
return gModules.get(name)
} else {
return undefined
}
}
}
export function jsRegisterModule(name: string, moduleObject: any) {
gModules.set(name, moduleObject)
}
export function jsCallEntityMethod(contextId: string, methodName: string, args?: any) {
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: any = []
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: string) {
const context = jsObtainContext(contextId)
return <T extends { new(...args: any[]): {} }>(constructor: T) => {
const ret = class extends constructor {
context = context
}
if (context) {
context.register(new ret)
}
return ret
}
}
const global = Function('return this')()
let __timerId__ = 0
const timerInfos: Map<number, { callback: () => void, context?: Context }> = new Map
const _setTimeout = global.setTimeout
const _setInterval = global.setInterval
const _clearTimeout = global.clearTimeout
const _clearInterval = global.clearInterval
const doricSetTimeout = function (handler: Function, timeout?: number | undefined, ...args: any[]) {
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: Function, timeout?: number | undefined, ...args: any[]) {
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: number) {
if (global.nativeClearTimer === undefined) {
return Reflect.apply(_clearTimeout, undefined, arguments)
}
timerInfos.delete(timerId)
nativeClearTimer(timerId)
}
const doricClearInterval = function (timerId: number) {
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: number) {
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)
}
}

View 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.es5'
export * from './panel'
export * from './animation'

408
doric-js/src/ui/view.es5.ts Normal file
View File

@ -0,0 +1,408 @@
/*
* 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 { Color, GradientColor } from "../util/color"
import { Modeling, Model, obj2Model } from "../util/types";
import { uniqueId } from "../util/uniqueId";
import { loge } from "../util/log";
import { BridgeContext } from "../runtime/global";
import { LayoutConfig } from '../util/layoutconfig'
import { IAnimation } from "./animation";
export function Property(target: Object, propKey: string) {
Reflect.defineMetadata(propKey, true, target)
}
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
/**----------transform----------*/
}
export type NativeViewModel = {
id: string;
type: string;
props: {
[index: string]: Model;
};
}
export abstract class View implements Modeling, IView {
@Property
width: number = 0
@Property
height: number = 0
@Property
x: number = 0
@Property
y: number = 0
@Property
backgroundColor?: Color | GradientColor
@Property
corners?: number | { leftTop?: number; rightTop?: number; leftBottom?: number; rightBottom?: number }
@Property
border?: { width: number; color: Color; }
@Property
shadow?: { color: Color; opacity: number; radius: number; offsetX: number; offsetY: number }
@Property
alpha?: number
@Property
hidden?: boolean
@Property
viewId = uniqueId('ViewId')
@Property
padding?: {
left?: number,
right?: number,
top?: number,
bottom?: number,
}
@Property
layoutConfig?: LayoutConfig
@Property
onClick?: Function
superview?: Superview
callbacks: Map<String, Function> = new Map
private callback2Id(f: Function) {
const id = uniqueId('Function')
this.callbacks.set(id, f)
return id
}
private id2Callback(id: string) {
let f = this.callbacks.get(id)
if (f === undefined) {
f = Reflect.get(this, id) as Function
}
return f
}
constructor() {
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
}
})
}
/** Anchor start*/
get left() {
return this.x
}
set left(v: number) {
this.x = v
}
get right() {
return this.x + this.width
}
set right(v: number) {
this.x = v - this.width
}
get top() {
return this.y
}
set top(v: number) {
this.y = v
}
get bottom() {
return this.y + this.height
}
set bottom(v: number) {
this.y = v - this.height
}
get centerX() {
return this.x + this.width / 2
}
get centerY() {
return this.y + this.height / 2
}
set centerX(v: number) {
this.x = v - this.width / 2
}
set centerY(v: number) {
this.y = v - this.height / 2
}
/** Anchor end*/
private __dirty_props__: { [index: string]: Model | undefined } = {}
get dirtyProps() {
return this.__dirty_props__
}
nativeViewModel: NativeViewModel = {
id: this.viewId,
type: this.constructor.name,
props: this.__dirty_props__,
}
onPropertyChanged(propKey: string, oldV: Model, newV: Model): void {
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: string, ...args: any) {
const f = this.id2Callback(id)
if (f instanceof Function) {
const argumentsList: any = []
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: (it: this) => void) {
block(this)
}
also(block: (it: this) => void) {
block(this)
return this
}
apply(config: IView) {
for (let key in config) {
Reflect.set(this, key, Reflect.get(config, key, config), this)
}
return this
}
in(group: Group) {
group.addChild(this)
return this
}
nativeChannel(context: any, name: string) {
let thisView: View | undefined = this
return function (args: any = 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]) as Promise<any>
}
}
getWidth(context: BridgeContext) {
return this.nativeChannel(context, 'getWidth')() as Promise<number>
}
getHeight(context: BridgeContext) {
return this.nativeChannel(context, 'getHeight')() as Promise<number>
}
getLocationOnScreen(context: BridgeContext) {
return this.nativeChannel(context, "getLocationOnScreen")() as Promise<{ x: number, y: number }>
}
/**++++++++++transform++++++++++*/
@Property
translationX?: number
@Property
translationY?: number
@Property
scaleX?: number
@Property
scaleY?: number
@Property
pivotX?: number
@Property
pivotY?: number
@Property
rotation?: number
/**----------transform----------*/
doAnimation(context: BridgeContext, animation: IAnimation) {
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)
}
})
}
}
export abstract class Superview extends View {
subviewById(id: string): View | undefined {
for (let v of this.allSubviews()) {
if (v.viewId === id) {
return v
}
}
}
abstract allSubviews(): Iterable<View>
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 abstract class Group extends Superview {
readonly children: View[] = 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: View) {
this.children.push(view)
}
}

View File

@ -58,5 +58,9 @@
},
"include": [
"**/*.ts",
],
"exclude": [
"**/*.es5.ts",
"**/*.d.ts",
]
}