diff --git a/demo/.vscode/launch.json b/demo/.vscode/launch.json new file mode 100644 index 00000000..39c84064 --- /dev/null +++ b/demo/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Debug TS", + "program": "${workspaceFolder}/${relativeFile}", + "preLaunchTask": "Doric Build", + "sourceMaps": true, + "serverReadyAction": { + "pattern": "listening on port ([0-9]+)", + "uriFormat": "http://localhost:%s", + "action": "openExternally" + }, + "outFiles": [ + "${workspaceFolder}/bundle/**/*.js" + ] + } + ] +} \ No newline at end of file diff --git a/demo/.vscode/tasks.json b/demo/.vscode/tasks.json new file mode 100644 index 00000000..d51f6710 --- /dev/null +++ b/demo/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Doric Build", + "type": "shell", + "command": "doric build", + "group": "build", + "problemMatcher": [] + }, + { + "label": "Doric Clean", + "type": "shell", + "command": "doric clean", + "group": "build", + "problemMatcher": [] + }, + { + "label": "Doric Dev", + "type": "shell", + "command": "doric dev", + "group": "build", + "problemMatcher": [] + } + ] +} \ No newline at end of file diff --git a/demo/debug/Counter.js b/demo/debug/Counter.js new file mode 100644 index 00000000..01901220 --- /dev/null +++ b/demo/debug/Counter.js @@ -0,0 +1,119 @@ +'use strict'; + +var doric = require('doric'); + +var __decorate = (undefined && undefined.__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 = (undefined && undefined.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +class CounterView extends doric.ViewHolder { + constructor() { + super(...arguments); + this.number = new doric.Text; + this.counter = new doric.Text; + } + build(root) { + const vlayout = new doric.VLayout; + vlayout.width = 200; + vlayout.height = 200; + vlayout.gravity = new doric.Gravity().center(); + this.number.textSize = 40; + this.number.layoutConfig = { + alignment: new doric.Gravity().center() + }; + this.counter = new doric.Text; + this.counter.text = "点击计数"; + this.counter.border = { + width: 1, + color: doric.Color.parse('#000000'), + }; + this.counter.textSize = 20; + this.counter.corners = 5; + vlayout.space = 20; + vlayout.layoutConfig = { + alignment: new doric.Gravity().center() + }; + vlayout.border = { + width: 1, + color: doric.Color.parse("#000000"), + }; + this.counter.shadow = { + color: doric.Color.parse("#00ff00"), + opacity: 0.5, + radius: 20, + offsetX: 10, + offsetY: 10, + }; + vlayout.shadow = { + color: doric.Color.parse("#ffff00"), + opacity: 0.5, + radius: 20, + offsetX: 10, + offsetY: 10, + }; + vlayout.corners = 20; + vlayout.addChild(this.number); + vlayout.addChild(this.counter); + // root.bgColor = Color.parse('#00ff00') + vlayout.bgColor = doric.Color.parse('#ff00ff'); + root.addChild(vlayout); + const iv = new doric.Image; + // iv.width = iv.height = 100 + iv.imageUrl = "https://misc.aotu.io/ONE-SUNDAY/SteamEngine.png"; + //iv.bgColor = Color.parse('#00ff00') + root.addChild(iv); + } + setNumber(n) { + this.number.text = n.toString(); + } + setCounter(v) { + this.counter.onClick = v; + } +} +class CounterVM extends doric.ViewModel { + binding(v, model) { + v.setNumber(model.count); + v.setCounter(() => { + this.getModel().count++; + }); + } +} +let MyPage = class MyPage extends doric.VMPanel { + getVMClass() { + return CounterVM; + } + getModel() { + return { + count: 0, + add: function () { + this.count++; + }, + }; + } + getViewHolder() { + return new CounterView; + } + log() { + doric.log("Hello.HEGO"); + doric.logw("Hello.HEGO"); + doric.loge("Hello.HEGO"); + context.modal.toast('This is a toast.').then((r) => { + doric.loge(r); + }); + } +}; +__decorate([ + doric.NativeCall, + __metadata("design:type", Function), + __metadata("design:paramtypes", []), + __metadata("design:returntype", void 0) +], MyPage.prototype, "log", null); +MyPage = __decorate([ + Entry +], MyPage); +//# sourceMappingURL=Counter.js.map diff --git a/demo/debug/Snake.js b/demo/debug/Snake.js new file mode 100644 index 00000000..f6263b21 --- /dev/null +++ b/demo/debug/Snake.js @@ -0,0 +1,281 @@ +'use strict'; + +var doric = require('doric'); + +var __decorate = (undefined && undefined.__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 Direction; +(function (Direction) { + Direction[Direction["left"] = 0] = "left"; + Direction[Direction["right"] = 1] = "right"; + Direction[Direction["up"] = 2] = "up"; + Direction[Direction["down"] = 3] = "down"; +})(Direction || (Direction = {})); +var State; +(function (State) { + State[State["idel"] = 0] = "idel"; + State[State["run"] = 1] = "run"; + State[State["fail"] = 2] = "fail"; +})(State || (State = {})); +class SnakeModel { + constructor(w, h) { + this.state = State.idel; + this.direction = Direction.right; + this.food = { x: -1, y: -1 }; + this.head = { + x: 0, + y: 0, + }; + this.width = w; + this.height = h; + } + refreshFood() { + this.food.x = Math.floor(Math.random() * (this.width - 1)); + this.food.y = Math.floor(Math.random() * (this.height - 1)); + } + get tail() { + let node = this.head; + while (node.next !== undefined) { + node = node.next; + } + return node; + } + get score() { + let node = this.head; + let n = 0; + while (node.next !== undefined) { + n++; + node = node.next; + } + return n; + } + forward(node) { + switch (this.direction) { + case Direction.left: + node.x -= 1; + break; + case Direction.right: + node.x += 1; + break; + case Direction.up: + node.y -= 1; + break; + case Direction.down: + node.y += 1; + break; + } + } + step() { + if (this.state !== State.run) { + return; + } + let tail = this.tail; + while (tail.prev != undefined) { + tail.x = tail.prev.x; + tail.y = tail.prev.y; + tail = tail.prev; + } + this.forward(this.head); + if (this.head.x < 0 || this.head.x >= this.width + || this.head.y < 0 || this.head.y >= this.height) { + //If out of bound + doric.loge('out of bound'); + this.state = State.fail; + } + else if (this.head.x == this.food.x && this.head.y == this.food.y) { + //If eat food + let head = { x: this.food.x, y: this.food.y }; + doric.log('eat food', head); + this.forward(head); + this.head.prev = head; + head.next = this.head; + this.head = head; + this.refreshFood(); + } + if (this.crashAtSelf()) { + //If crash at self + doric.loge('crash at self'); + this.state = State.fail; + } + } + crashAtSelf() { + let cur = this.head.next; + while (cur !== undefined) { + if (cur.x == this.head.x && cur.y == this.head.y) { + return true; + } + cur = cur.next; + } + return false; + } + reset() { + this.direction = Direction.right; + this.state = State.run; + this.head.x = 0; + this.head.y = 0; + this.head.next = undefined; + this.refreshFood(); + } +} +class SnakeView extends doric.ViewHolder { + constructor() { + super(...arguments); + this.panel = new doric.Stack; + this.start = new doric.Text; + } + build(root) { + root.bgColor = doric.Color.parse('#000000'); + const vlayout = new doric.VLayout; + const title = new doric.Text; + title.text = "Snake"; + title.textSize = 20; + title.textColor = doric.Color.parse("#ffffff"); + title.layoutConfig = { + alignment: new doric.Gravity().centerX(), + margin: { + top: 20 + }, + }; + vlayout.space = 20; + vlayout.layoutConfig = { + alignment: new doric.Gravity().centerX().top() + }; + this.panel.bgColor = doric.Color.parse('#00ff00'); + vlayout.addChild(title); + vlayout.addChild(this.panel); + root.addChild(vlayout); + const hlayout = new doric.HLayout; + this.start.text = "Start"; + this.start.textSize = 30; + this.start.textColor = doric.Color.parse("#ffffff"); + hlayout.addChild(this.start); + vlayout.addChild(hlayout); + this.up = this.buildController("↑"); + this.down = this.buildController("↓"); + this.left = this.buildController("←"); + this.right = this.buildController("→"); + const controlArea = new doric.VLayout; + controlArea.gravity = new doric.Gravity().centerX(); + controlArea.space = 10; + controlArea.layoutConfig = { + alignment: new doric.Gravity().centerX() + }; + const line1 = new doric.HLayout; + const line2 = new doric.HLayout; + line2.space = 10; + line1.addChild(this.up); + line2.addChild(this.left); + line2.addChild(this.down); + line2.addChild(this.right); + controlArea.addChild(line1); + controlArea.addChild(line2); + vlayout.addChild(controlArea); + } + buildController(text) { + const ret = new doric.Text; + ret.width = ret.height = 50; + ret.bgColor = doric.Color.parse('#ffff00'); + ret.text = text; + ret.textSize = 30; + ret.textAlignment = new doric.Gravity().center(); + return ret; + } +} +class SnakeVM extends doric.ViewModel { + constructor() { + super(...arguments); + this.start = () => { + if (this.timerId !== undefined) { + clearInterval(this.timerId); + } + this.getModel().reset(); + this.timerId = setInterval(() => { + this.getModel().step(); + }, 500); + }; + this.stop = () => { + if (this.timerId !== undefined) { + clearInterval(this.timerId); + this.timerId = undefined; + } + }; + this.left = () => { + this.getModel().direction = Direction.left; + }; + this.right = () => { + this.getModel().direction = Direction.right; + }; + this.up = () => { + this.getModel().direction = Direction.up; + }; + this.down = () => { + this.getModel().direction = Direction.down; + }; + } + binding(v, model) { + if (model.state === State.fail) { + doric.loge('Game Over'); + this.stop(); + } + v.start.onClick = this.start; + v.panel.width = model.width * 10; + v.panel.height = model.height * 10; + let node = model.head; + let nodes = []; + while (node != undefined) { + nodes.push(node); + node = node.next; + } + nodes.push(model.food); + nodes.forEach((e, index) => { + let item = v.panel.children[index]; + if (item === undefined) { + item = new doric.Stack; + item.width = item.height = 10; + v.panel.addChild(item); + } + if (index === nodes.length - 1) { + item.bgColor = doric.Color.parse('#ffff00'); + } + else { + item.bgColor = doric.Color.parse('#ff0000'); + } + item.x = e.x * 10; + item.y = e.y * 10; + }); + if (nodes.length < v.panel.children.length) { + v.panel.children.length = nodes.length; + } + if (v.left) { + v.left.onClick = this.left; + } + if (v.right) { + v.right.onClick = this.right; + } + if (v.up) { + v.up.onClick = this.up; + } + if (v.down) { + v.down.onClick = this.down; + } + } +} +let SnakePanel = class SnakePanel extends doric.VMPanel { + getVMClass() { + return SnakeVM; + } + getModel() { + return new SnakeModel(35, 35); + } + getViewHolder() { + return new SnakeView; + } +}; +SnakePanel = __decorate([ + Entry +], SnakePanel); +//# sourceMappingURL=Snake.js.map diff --git a/demo/debug/debug.js b/demo/debug/debug.js new file mode 100644 index 00000000..e69de29b diff --git a/demo/debug/doric-lib.js b/demo/debug/doric-lib.js new file mode 100644 index 00000000..058c696a --- /dev/null +++ b/demo/debug/doric-lib.js @@ -0,0 +1,754 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +/** + * Store color as format AARRGGBB or RRGGBB + */ +class Color { + constructor(v) { + this._value = 0; + this._value = v; + } + 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; + } + } + toModel() { + return this._value; + } +} +Color.TRANSPARENT = new Color(0); +(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"; +})(exports.GradientOrientation || (exports.GradientOrientation = {})); + +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; + } +} +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); + } +} + +/* + * 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; +function uniqueId(prefix) { + return `__${prefix}_${__uniqueId__++}__`; +} + +const SPECIFIED = 1; +const START = 1 << 1; +const END = 1 << 2; +const SHIFT_X = 0; +const SHIFT_Y = 4; +const LEFT = (START | SPECIFIED) << SHIFT_X; +const RIGHT = (END | SPECIFIED) << SHIFT_X; +const TOP = (START | SPECIFIED) << SHIFT_Y; +const BOTTOM = (END | SPECIFIED) << SHIFT_Y; +const CENTER_X = SPECIFIED << SHIFT_X; +const CENTER_Y = SPECIFIED << SHIFT_Y; +const CENTER = CENTER_X | CENTER_Y; +class Gravity { + constructor() { + this.val = 0; + } + left() { + this.val |= LEFT; + return this; + } + right() { + this.val |= RIGHT; + return this; + } + top() { + this.val |= TOP; + return this; + } + bottom() { + this.val |= BOTTOM; + return this; + } + center() { + this.val |= CENTER; + return this; + } + centerX() { + this.val |= CENTER_X; + return this; + } + centerY() { + this.val |= CENTER_Y; + return this; + } + toModel() { + return this.val; + } +} + +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(); + } +} +function log(...args) { + let out = ""; + for (let i = 0; i < arguments.length; i++) { + if (i > 0) { + out += ','; + } + out += toString(arguments[i]); + } + nativeLog('d', out); +} +function loge(...message) { + let out = ""; + for (let i = 0; i < arguments.length; i++) { + if (i > 0) { + out += ','; + } + out += toString(arguments[i]); + } + nativeLog('e', out); +} +function logw(...message) { + let out = ""; + for (let i = 0; i < arguments.length; i++) { + if (i > 0) { + out += ','; + } + out += toString(arguments[i]); + } + nativeLog('w', out); +} + +var __decorate = (undefined && undefined.__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 = (undefined && undefined.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +const MATCH_PARENT = -1; +const WRAP_CONTENT = -2; +function Property(target, propKey) { + Reflect.defineMetadata(propKey, true, target); +} +class View { + constructor() { + this.width = WRAP_CONTENT; + this.height = WRAP_CONTENT; + 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) { + const f = this.callbacks.get(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; + } + onPropertyChanged(propKey, oldV, newV) { + if (newV instanceof Function) { + newV = this.callback2Id(newV); + } + else { + newV = obj2Model(newV); + } + this.__dirty_props__[propKey] = newV; + if (this.parent instanceof Group) { + this.parent.onChildPropertyChanged(this); + } + } + 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]); + } + Reflect.apply(f, this, argumentsList); + } + else { + loge(`Cannot find callback:${id} for ${JSON.stringify(this.toModel())}`); + } + } + toModel() { + return this.nativeViewModel; + } +} +__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, "bgColor", 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); +class Group extends View { + constructor() { + super(...arguments); + this.children = new Proxy([], { + set: (target, index, value) => { + if (index === 'length') { + this.getDirtyChildrenModel().length = value; + } + else if (typeof index === 'string' + && parseInt(index) >= 0 + && value instanceof View) { + value.parent = this; + const childrenModel = this.getDirtyChildrenModel(); + childrenModel[parseInt(index)] = value.nativeViewModel; + } + if (this.parent) { + this.parent.onChildPropertyChanged(this); + } + return Reflect.set(target, index, value); + } + }); + } + addChild(view) { + this.children.push(view); + } + clean() { + this.children.forEach(e => { e.clean(); }); + super.clean(); + } + getDirtyChildrenModel() { + if (this.__dirty_props__.children === undefined) { + this.__dirty_props__.children = []; + } + return this.__dirty_props__.children; + } + toModel() { + if (this.__dirty_props__.children != undefined) { + this.__dirty_props__.children.length = this.children.length; + } + return super.toModel(); + } + onChildPropertyChanged(child) { + this.getDirtyChildrenModel()[this.children.indexOf(child)] = child.nativeViewModel; + this.getDirtyChildrenModel().length = this.children.length; + if (this.parent) { + this.parent.onChildPropertyChanged(this); + } + } + isDirty() { + return super.isDirty(); + } +} +__decorate([ + Property, + __metadata("design:type", Array) +], Group.prototype, "children", void 0); +class Stack extends Group { +} +__decorate([ + Property, + __metadata("design:type", Gravity) +], Stack.prototype, "gravity", void 0); +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); +class VLayout extends LinearLayout { +} +class HLayout extends LinearLayout { +} +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); +class Image extends View { +} +__decorate([ + Property, + __metadata("design:type", String) +], Image.prototype, "imageUrl", void 0); +class List extends View { +} +class Slide extends View { +} +function stack() { +} +function vlayout(providers, config) { + const vlayout = new VLayout; + vlayout.width = config.width; + vlayout.height = config.height; + if (config.space !== undefined) { + vlayout.space = config.space; + } + providers.forEach(e => { + vlayout.addChild(e()); + }); + return vlayout; +} + +var __decorate$1 = (undefined && undefined.__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$1 = (undefined && undefined.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +function NativeCall(target, propertyKey, descriptor) { + const originVal = descriptor.value; + descriptor.value = function () { + const ret = Reflect.apply(originVal, this, arguments); + return ret; + }; + return descriptor; +} +class Panel { + constructor() { + this.__root__ = new Root; + } + onCreate() { } + onDestroy() { } + onShow() { } + onHidden() { } + getRootView() { + return this.__root__; + } + getInitData() { + return this.__data__; + } + __init__(frame, data) { + this.__data__ = data; + this.__root__.width = frame.width; + this.__root__.height = frame.height; + 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}`); + } + const argumentsList = [callbackId]; + for (let i = 2; i < arguments.length; i++) { + argumentsList.push(arguments[i]); + } + Reflect.apply(v.responseCallback, v, argumentsList); + } + retrospectView(ids) { + return ids.reduce((acc, cur) => { + if (acc instanceof Group) { + return acc.children.filter(e => e.viewId === cur)[0]; + } + return acc; + }, this.__root__); + } + nativeRender(model) { + if (this.context) { + this.context.shader.render(model); + } + } + hookBeforeNativeCall() { + } + hookAfterNativeCall() { + if (this.__root__.isDirty()) { + const model = this.__root__.toModel(); + this.nativeRender(model); + this.__root__.clean(); + } + } +} +__decorate$1([ + NativeCall, + __metadata$1("design:type", Function), + __metadata$1("design:paramtypes", [Object, Object]), + __metadata$1("design:returntype", void 0) +], Panel.prototype, "__init__", null); +__decorate$1([ + NativeCall, + __metadata$1("design:type", Function), + __metadata$1("design:paramtypes", []), + __metadata$1("design:returntype", void 0) +], Panel.prototype, "__onCreate__", null); +__decorate$1([ + NativeCall, + __metadata$1("design:type", Function), + __metadata$1("design:paramtypes", []), + __metadata$1("design:returntype", void 0) +], Panel.prototype, "__onDestroy__", null); +__decorate$1([ + NativeCall, + __metadata$1("design:type", Function), + __metadata$1("design:paramtypes", []), + __metadata$1("design:returntype", void 0) +], Panel.prototype, "__onShow__", null); +__decorate$1([ + NativeCall, + __metadata$1("design:type", Function), + __metadata$1("design:paramtypes", []), + __metadata$1("design:returntype", void 0) +], Panel.prototype, "__onHidden__", null); +__decorate$1([ + NativeCall, + __metadata$1("design:type", Function), + __metadata$1("design:paramtypes", []), + __metadata$1("design:returntype", void 0) +], Panel.prototype, "__build__", null); +__decorate$1([ + NativeCall, + __metadata$1("design:type", Function), + __metadata$1("design:paramtypes", [Array, String]), + __metadata$1("design:returntype", void 0) +], Panel.prototype, "__response__", null); + +function listen(obj, listener) { + return new Proxy(obj, { + get: (target, prop, receiver) => { + const ret = Reflect.get(target, prop, receiver); + if (ret instanceof Function) { + return Reflect.get(target, prop, receiver); + } + else if (ret instanceof Object) { + return listen(ret, listener); + } + else { + return ret; + } + }, + set: (target, prop, value, receiver) => { + const ret = Reflect.set(target, prop, value, receiver); + Reflect.apply(listener, undefined, []); + return ret; + }, + }); +} +class ViewHolder { +} +class VMPanel extends Panel { + getVM() { + return this.vm; + } + build(root) { + this.vm = new (this.getVMClass())(this.getModel(), this.getViewHolder()); + this.vm.build(root); + } +} +class ViewModel { + constructor(obj, v) { + this.listeners = []; + this.model = listen(obj, () => { + this.listeners.forEach(e => { + Reflect.apply(e, this.model, [this.model]); + }); + }); + this.viewHolder = v; + } + build(root) { + this.viewHolder.build(root); + this.bind((data) => { + this.binding(this.viewHolder, data); + }); + } + getModel() { + return this.model; + } + bind(f) { + Reflect.apply(f, this.model, [this.model]); + this.listeners.push(f); + } +} + +exports.BOTTOM = BOTTOM; +exports.CENTER = CENTER; +exports.CENTER_X = CENTER_X; +exports.CENTER_Y = CENTER_Y; +exports.Color = Color; +exports.Gravity = Gravity; +exports.Group = Group; +exports.HLayout = HLayout; +exports.Image = Image; +exports.LEFT = LEFT; +exports.List = List; +exports.MATCH_PARENT = MATCH_PARENT; +exports.Mutable = Mutable; +exports.NativeCall = NativeCall; +exports.Panel = Panel; +exports.Property = Property; +exports.RIGHT = RIGHT; +exports.Root = Root; +exports.Slide = Slide; +exports.Stack = Stack; +exports.TOP = TOP; +exports.Text = Text; +exports.VLayout = VLayout; +exports.VMPanel = VMPanel; +exports.View = View; +exports.ViewHolder = ViewHolder; +exports.ViewModel = ViewModel; +exports.WRAP_CONTENT = WRAP_CONTENT; +exports.log = log; +exports.loge = loge; +exports.logw = logw; +exports.obj2Model = obj2Model; +exports.stack = stack; +exports.vlayout = vlayout; diff --git a/demo/debug/doric-sandbox.js b/demo/debug/doric-sandbox.js new file mode 100644 index 00000000..3d4b0e8d --- /dev/null +++ b/demo/debug/doric-sandbox.js @@ -0,0 +1,1446 @@ +var doric = (function (exports) { + 'use strict'; + + /* + * 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; + function uniqueId(prefix) { + return `__${prefix}_${__uniqueId__++}__`; + } + + 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(); + } + } + function loge(...message) { + let out = ""; + for (let i = 0; i < arguments.length; i++) { + if (i > 0) { + out += ','; + } + out += toString(arguments[i]); + } + nativeLog('e', out); + } + + /*! ***************************************************************************** + Copyright (C) Microsoft. All rights reserved. + 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 + + THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED + WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, + MERCHANTABLITY OR NON-INFRINGEMENT. + + See the Apache Version 2.0 License for specific language governing permissions + and limitations under the License. + ***************************************************************************** */ + var Reflect$1; + (function (Reflect) { + // Metadata Proposal + // https://rbuckton.github.io/reflect-metadata/ + (function (factory) { + var root = typeof global === "object" ? global : + typeof self === "object" ? self : + typeof this === "object" ? this : + Function("return this;")(); + var exporter = makeExporter(Reflect); + if (typeof root.Reflect === "undefined") { + root.Reflect = Reflect; + } + else { + exporter = makeExporter(root.Reflect, exporter); + } + factory(exporter); + function makeExporter(target, previous) { + return function (key, value) { + if (typeof target[key] !== "function") { + Object.defineProperty(target, key, { configurable: true, writable: true, value: value }); + } + if (previous) + previous(key, value); + }; + } + })(function (exporter) { + var hasOwn = Object.prototype.hasOwnProperty; + // feature test for Symbol support + var supportsSymbol = typeof Symbol === "function"; + var toPrimitiveSymbol = supportsSymbol && typeof Symbol.toPrimitive !== "undefined" ? Symbol.toPrimitive : "@@toPrimitive"; + var iteratorSymbol = supportsSymbol && typeof Symbol.iterator !== "undefined" ? Symbol.iterator : "@@iterator"; + var supportsCreate = typeof Object.create === "function"; // feature test for Object.create support + var supportsProto = { __proto__: [] } instanceof Array; // feature test for __proto__ support + var downLevel = !supportsCreate && !supportsProto; + var HashMap = { + // create an object in dictionary mode (a.k.a. "slow" mode in v8) + create: supportsCreate + ? function () { return MakeDictionary(Object.create(null)); } + : supportsProto + ? function () { return MakeDictionary({ __proto__: null }); } + : function () { return MakeDictionary({}); }, + has: downLevel + ? function (map, key) { return hasOwn.call(map, key); } + : function (map, key) { return key in map; }, + get: downLevel + ? function (map, key) { return hasOwn.call(map, key) ? map[key] : undefined; } + : function (map, key) { return map[key]; }, + }; + // Load global or shim versions of Map, Set, and WeakMap + var functionPrototype = Object.getPrototypeOf(Function); + var usePolyfill = typeof process === "object" && process.env && process.env["REFLECT_METADATA_USE_MAP_POLYFILL"] === "true"; + var _Map = !usePolyfill && typeof Map === "function" && typeof Map.prototype.entries === "function" ? Map : CreateMapPolyfill(); + var _Set = !usePolyfill && typeof Set === "function" && typeof Set.prototype.entries === "function" ? Set : CreateSetPolyfill(); + var _WeakMap = !usePolyfill && typeof WeakMap === "function" ? WeakMap : CreateWeakMapPolyfill(); + // [[Metadata]] internal slot + // https://rbuckton.github.io/reflect-metadata/#ordinary-object-internal-methods-and-internal-slots + var Metadata = new _WeakMap(); + /** + * Applies a set of decorators to a property of a target object. + * @param decorators An array of decorators. + * @param target The target object. + * @param propertyKey (Optional) The property key to decorate. + * @param attributes (Optional) The property descriptor for the target key. + * @remarks Decorators are applied in reverse order. + * @example + * + * class Example { + * // property declarations are not part of ES6, though they are valid in TypeScript: + * // static staticProperty; + * // property; + * + * constructor(p) { } + * static staticMethod(p) { } + * method(p) { } + * } + * + * // constructor + * Example = Reflect.decorate(decoratorsArray, Example); + * + * // property (on constructor) + * Reflect.decorate(decoratorsArray, Example, "staticProperty"); + * + * // property (on prototype) + * Reflect.decorate(decoratorsArray, Example.prototype, "property"); + * + * // method (on constructor) + * Object.defineProperty(Example, "staticMethod", + * Reflect.decorate(decoratorsArray, Example, "staticMethod", + * Object.getOwnPropertyDescriptor(Example, "staticMethod"))); + * + * // method (on prototype) + * Object.defineProperty(Example.prototype, "method", + * Reflect.decorate(decoratorsArray, Example.prototype, "method", + * Object.getOwnPropertyDescriptor(Example.prototype, "method"))); + * + */ + function decorate(decorators, target, propertyKey, attributes) { + if (!IsUndefined(propertyKey)) { + if (!IsArray(decorators)) + throw new TypeError(); + if (!IsObject(target)) + throw new TypeError(); + if (!IsObject(attributes) && !IsUndefined(attributes) && !IsNull(attributes)) + throw new TypeError(); + if (IsNull(attributes)) + attributes = undefined; + propertyKey = ToPropertyKey(propertyKey); + return DecorateProperty(decorators, target, propertyKey, attributes); + } + else { + if (!IsArray(decorators)) + throw new TypeError(); + if (!IsConstructor(target)) + throw new TypeError(); + return DecorateConstructor(decorators, target); + } + } + exporter("decorate", decorate); + // 4.1.2 Reflect.metadata(metadataKey, metadataValue) + // https://rbuckton.github.io/reflect-metadata/#reflect.metadata + /** + * A default metadata decorator factory that can be used on a class, class member, or parameter. + * @param metadataKey The key for the metadata entry. + * @param metadataValue The value for the metadata entry. + * @returns A decorator function. + * @remarks + * If `metadataKey` is already defined for the target and target key, the + * metadataValue for that key will be overwritten. + * @example + * + * // constructor + * @Reflect.metadata(key, value) + * class Example { + * } + * + * // property (on constructor, TypeScript only) + * class Example { + * @Reflect.metadata(key, value) + * static staticProperty; + * } + * + * // property (on prototype, TypeScript only) + * class Example { + * @Reflect.metadata(key, value) + * property; + * } + * + * // method (on constructor) + * class Example { + * @Reflect.metadata(key, value) + * static staticMethod() { } + * } + * + * // method (on prototype) + * class Example { + * @Reflect.metadata(key, value) + * method() { } + * } + * + */ + function metadata(metadataKey, metadataValue) { + function decorator(target, propertyKey) { + if (!IsObject(target)) + throw new TypeError(); + if (!IsUndefined(propertyKey) && !IsPropertyKey(propertyKey)) + throw new TypeError(); + OrdinaryDefineOwnMetadata(metadataKey, metadataValue, target, propertyKey); + } + return decorator; + } + exporter("metadata", metadata); + /** + * Define a unique metadata entry on the target. + * @param metadataKey A key used to store and retrieve metadata. + * @param metadataValue A value that contains attached metadata. + * @param target The target object on which to define metadata. + * @param propertyKey (Optional) The property key for the target. + * @example + * + * class Example { + * // property declarations are not part of ES6, though they are valid in TypeScript: + * // static staticProperty; + * // property; + * + * constructor(p) { } + * static staticMethod(p) { } + * method(p) { } + * } + * + * // constructor + * Reflect.defineMetadata("custom:annotation", options, Example); + * + * // property (on constructor) + * Reflect.defineMetadata("custom:annotation", options, Example, "staticProperty"); + * + * // property (on prototype) + * Reflect.defineMetadata("custom:annotation", options, Example.prototype, "property"); + * + * // method (on constructor) + * Reflect.defineMetadata("custom:annotation", options, Example, "staticMethod"); + * + * // method (on prototype) + * Reflect.defineMetadata("custom:annotation", options, Example.prototype, "method"); + * + * // decorator factory as metadata-producing annotation. + * function MyAnnotation(options): Decorator { + * return (target, key?) => Reflect.defineMetadata("custom:annotation", options, target, key); + * } + * + */ + function defineMetadata(metadataKey, metadataValue, target, propertyKey) { + if (!IsObject(target)) + throw new TypeError(); + if (!IsUndefined(propertyKey)) + propertyKey = ToPropertyKey(propertyKey); + return OrdinaryDefineOwnMetadata(metadataKey, metadataValue, target, propertyKey); + } + exporter("defineMetadata", defineMetadata); + /** + * Gets a value indicating whether the target object or its prototype chain has the provided metadata key defined. + * @param metadataKey A key used to store and retrieve metadata. + * @param target The target object on which the metadata is defined. + * @param propertyKey (Optional) The property key for the target. + * @returns `true` if the metadata key was defined on the target object or its prototype chain; otherwise, `false`. + * @example + * + * class Example { + * // property declarations are not part of ES6, though they are valid in TypeScript: + * // static staticProperty; + * // property; + * + * constructor(p) { } + * static staticMethod(p) { } + * method(p) { } + * } + * + * // constructor + * result = Reflect.hasMetadata("custom:annotation", Example); + * + * // property (on constructor) + * result = Reflect.hasMetadata("custom:annotation", Example, "staticProperty"); + * + * // property (on prototype) + * result = Reflect.hasMetadata("custom:annotation", Example.prototype, "property"); + * + * // method (on constructor) + * result = Reflect.hasMetadata("custom:annotation", Example, "staticMethod"); + * + * // method (on prototype) + * result = Reflect.hasMetadata("custom:annotation", Example.prototype, "method"); + * + */ + function hasMetadata(metadataKey, target, propertyKey) { + if (!IsObject(target)) + throw new TypeError(); + if (!IsUndefined(propertyKey)) + propertyKey = ToPropertyKey(propertyKey); + return OrdinaryHasMetadata(metadataKey, target, propertyKey); + } + exporter("hasMetadata", hasMetadata); + /** + * Gets a value indicating whether the target object has the provided metadata key defined. + * @param metadataKey A key used to store and retrieve metadata. + * @param target The target object on which the metadata is defined. + * @param propertyKey (Optional) The property key for the target. + * @returns `true` if the metadata key was defined on the target object; otherwise, `false`. + * @example + * + * class Example { + * // property declarations are not part of ES6, though they are valid in TypeScript: + * // static staticProperty; + * // property; + * + * constructor(p) { } + * static staticMethod(p) { } + * method(p) { } + * } + * + * // constructor + * result = Reflect.hasOwnMetadata("custom:annotation", Example); + * + * // property (on constructor) + * result = Reflect.hasOwnMetadata("custom:annotation", Example, "staticProperty"); + * + * // property (on prototype) + * result = Reflect.hasOwnMetadata("custom:annotation", Example.prototype, "property"); + * + * // method (on constructor) + * result = Reflect.hasOwnMetadata("custom:annotation", Example, "staticMethod"); + * + * // method (on prototype) + * result = Reflect.hasOwnMetadata("custom:annotation", Example.prototype, "method"); + * + */ + function hasOwnMetadata(metadataKey, target, propertyKey) { + if (!IsObject(target)) + throw new TypeError(); + if (!IsUndefined(propertyKey)) + propertyKey = ToPropertyKey(propertyKey); + return OrdinaryHasOwnMetadata(metadataKey, target, propertyKey); + } + exporter("hasOwnMetadata", hasOwnMetadata); + /** + * Gets the metadata value for the provided metadata key on the target object or its prototype chain. + * @param metadataKey A key used to store and retrieve metadata. + * @param target The target object on which the metadata is defined. + * @param propertyKey (Optional) The property key for the target. + * @returns The metadata value for the metadata key if found; otherwise, `undefined`. + * @example + * + * class Example { + * // property declarations are not part of ES6, though they are valid in TypeScript: + * // static staticProperty; + * // property; + * + * constructor(p) { } + * static staticMethod(p) { } + * method(p) { } + * } + * + * // constructor + * result = Reflect.getMetadata("custom:annotation", Example); + * + * // property (on constructor) + * result = Reflect.getMetadata("custom:annotation", Example, "staticProperty"); + * + * // property (on prototype) + * result = Reflect.getMetadata("custom:annotation", Example.prototype, "property"); + * + * // method (on constructor) + * result = Reflect.getMetadata("custom:annotation", Example, "staticMethod"); + * + * // method (on prototype) + * result = Reflect.getMetadata("custom:annotation", Example.prototype, "method"); + * + */ + function getMetadata(metadataKey, target, propertyKey) { + if (!IsObject(target)) + throw new TypeError(); + if (!IsUndefined(propertyKey)) + propertyKey = ToPropertyKey(propertyKey); + return OrdinaryGetMetadata(metadataKey, target, propertyKey); + } + exporter("getMetadata", getMetadata); + /** + * Gets the metadata value for the provided metadata key on the target object. + * @param metadataKey A key used to store and retrieve metadata. + * @param target The target object on which the metadata is defined. + * @param propertyKey (Optional) The property key for the target. + * @returns The metadata value for the metadata key if found; otherwise, `undefined`. + * @example + * + * class Example { + * // property declarations are not part of ES6, though they are valid in TypeScript: + * // static staticProperty; + * // property; + * + * constructor(p) { } + * static staticMethod(p) { } + * method(p) { } + * } + * + * // constructor + * result = Reflect.getOwnMetadata("custom:annotation", Example); + * + * // property (on constructor) + * result = Reflect.getOwnMetadata("custom:annotation", Example, "staticProperty"); + * + * // property (on prototype) + * result = Reflect.getOwnMetadata("custom:annotation", Example.prototype, "property"); + * + * // method (on constructor) + * result = Reflect.getOwnMetadata("custom:annotation", Example, "staticMethod"); + * + * // method (on prototype) + * result = Reflect.getOwnMetadata("custom:annotation", Example.prototype, "method"); + * + */ + function getOwnMetadata(metadataKey, target, propertyKey) { + if (!IsObject(target)) + throw new TypeError(); + if (!IsUndefined(propertyKey)) + propertyKey = ToPropertyKey(propertyKey); + return OrdinaryGetOwnMetadata(metadataKey, target, propertyKey); + } + exporter("getOwnMetadata", getOwnMetadata); + /** + * Gets the metadata keys defined on the target object or its prototype chain. + * @param target The target object on which the metadata is defined. + * @param propertyKey (Optional) The property key for the target. + * @returns An array of unique metadata keys. + * @example + * + * class Example { + * // property declarations are not part of ES6, though they are valid in TypeScript: + * // static staticProperty; + * // property; + * + * constructor(p) { } + * static staticMethod(p) { } + * method(p) { } + * } + * + * // constructor + * result = Reflect.getMetadataKeys(Example); + * + * // property (on constructor) + * result = Reflect.getMetadataKeys(Example, "staticProperty"); + * + * // property (on prototype) + * result = Reflect.getMetadataKeys(Example.prototype, "property"); + * + * // method (on constructor) + * result = Reflect.getMetadataKeys(Example, "staticMethod"); + * + * // method (on prototype) + * result = Reflect.getMetadataKeys(Example.prototype, "method"); + * + */ + function getMetadataKeys(target, propertyKey) { + if (!IsObject(target)) + throw new TypeError(); + if (!IsUndefined(propertyKey)) + propertyKey = ToPropertyKey(propertyKey); + return OrdinaryMetadataKeys(target, propertyKey); + } + exporter("getMetadataKeys", getMetadataKeys); + /** + * Gets the unique metadata keys defined on the target object. + * @param target The target object on which the metadata is defined. + * @param propertyKey (Optional) The property key for the target. + * @returns An array of unique metadata keys. + * @example + * + * class Example { + * // property declarations are not part of ES6, though they are valid in TypeScript: + * // static staticProperty; + * // property; + * + * constructor(p) { } + * static staticMethod(p) { } + * method(p) { } + * } + * + * // constructor + * result = Reflect.getOwnMetadataKeys(Example); + * + * // property (on constructor) + * result = Reflect.getOwnMetadataKeys(Example, "staticProperty"); + * + * // property (on prototype) + * result = Reflect.getOwnMetadataKeys(Example.prototype, "property"); + * + * // method (on constructor) + * result = Reflect.getOwnMetadataKeys(Example, "staticMethod"); + * + * // method (on prototype) + * result = Reflect.getOwnMetadataKeys(Example.prototype, "method"); + * + */ + function getOwnMetadataKeys(target, propertyKey) { + if (!IsObject(target)) + throw new TypeError(); + if (!IsUndefined(propertyKey)) + propertyKey = ToPropertyKey(propertyKey); + return OrdinaryOwnMetadataKeys(target, propertyKey); + } + exporter("getOwnMetadataKeys", getOwnMetadataKeys); + /** + * Deletes the metadata entry from the target object with the provided key. + * @param metadataKey A key used to store and retrieve metadata. + * @param target The target object on which the metadata is defined. + * @param propertyKey (Optional) The property key for the target. + * @returns `true` if the metadata entry was found and deleted; otherwise, false. + * @example + * + * class Example { + * // property declarations are not part of ES6, though they are valid in TypeScript: + * // static staticProperty; + * // property; + * + * constructor(p) { } + * static staticMethod(p) { } + * method(p) { } + * } + * + * // constructor + * result = Reflect.deleteMetadata("custom:annotation", Example); + * + * // property (on constructor) + * result = Reflect.deleteMetadata("custom:annotation", Example, "staticProperty"); + * + * // property (on prototype) + * result = Reflect.deleteMetadata("custom:annotation", Example.prototype, "property"); + * + * // method (on constructor) + * result = Reflect.deleteMetadata("custom:annotation", Example, "staticMethod"); + * + * // method (on prototype) + * result = Reflect.deleteMetadata("custom:annotation", Example.prototype, "method"); + * + */ + function deleteMetadata(metadataKey, target, propertyKey) { + if (!IsObject(target)) + throw new TypeError(); + if (!IsUndefined(propertyKey)) + propertyKey = ToPropertyKey(propertyKey); + var metadataMap = GetOrCreateMetadataMap(target, propertyKey, /*Create*/ false); + if (IsUndefined(metadataMap)) + return false; + if (!metadataMap.delete(metadataKey)) + return false; + if (metadataMap.size > 0) + return true; + var targetMetadata = Metadata.get(target); + targetMetadata.delete(propertyKey); + if (targetMetadata.size > 0) + return true; + Metadata.delete(target); + return true; + } + exporter("deleteMetadata", deleteMetadata); + function DecorateConstructor(decorators, target) { + for (var i = decorators.length - 1; i >= 0; --i) { + var decorator = decorators[i]; + var decorated = decorator(target); + if (!IsUndefined(decorated) && !IsNull(decorated)) { + if (!IsConstructor(decorated)) + throw new TypeError(); + target = decorated; + } + } + return target; + } + function DecorateProperty(decorators, target, propertyKey, descriptor) { + for (var i = decorators.length - 1; i >= 0; --i) { + var decorator = decorators[i]; + var decorated = decorator(target, propertyKey, descriptor); + if (!IsUndefined(decorated) && !IsNull(decorated)) { + if (!IsObject(decorated)) + throw new TypeError(); + descriptor = decorated; + } + } + return descriptor; + } + function GetOrCreateMetadataMap(O, P, Create) { + var targetMetadata = Metadata.get(O); + if (IsUndefined(targetMetadata)) { + if (!Create) + return undefined; + targetMetadata = new _Map(); + Metadata.set(O, targetMetadata); + } + var metadataMap = targetMetadata.get(P); + if (IsUndefined(metadataMap)) { + if (!Create) + return undefined; + metadataMap = new _Map(); + targetMetadata.set(P, metadataMap); + } + return metadataMap; + } + // 3.1.1.1 OrdinaryHasMetadata(MetadataKey, O, P) + // https://rbuckton.github.io/reflect-metadata/#ordinaryhasmetadata + function OrdinaryHasMetadata(MetadataKey, O, P) { + var hasOwn = OrdinaryHasOwnMetadata(MetadataKey, O, P); + if (hasOwn) + return true; + var parent = OrdinaryGetPrototypeOf(O); + if (!IsNull(parent)) + return OrdinaryHasMetadata(MetadataKey, parent, P); + return false; + } + // 3.1.2.1 OrdinaryHasOwnMetadata(MetadataKey, O, P) + // https://rbuckton.github.io/reflect-metadata/#ordinaryhasownmetadata + function OrdinaryHasOwnMetadata(MetadataKey, O, P) { + var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false); + if (IsUndefined(metadataMap)) + return false; + return ToBoolean(metadataMap.has(MetadataKey)); + } + // 3.1.3.1 OrdinaryGetMetadata(MetadataKey, O, P) + // https://rbuckton.github.io/reflect-metadata/#ordinarygetmetadata + function OrdinaryGetMetadata(MetadataKey, O, P) { + var hasOwn = OrdinaryHasOwnMetadata(MetadataKey, O, P); + if (hasOwn) + return OrdinaryGetOwnMetadata(MetadataKey, O, P); + var parent = OrdinaryGetPrototypeOf(O); + if (!IsNull(parent)) + return OrdinaryGetMetadata(MetadataKey, parent, P); + return undefined; + } + // 3.1.4.1 OrdinaryGetOwnMetadata(MetadataKey, O, P) + // https://rbuckton.github.io/reflect-metadata/#ordinarygetownmetadata + function OrdinaryGetOwnMetadata(MetadataKey, O, P) { + var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false); + if (IsUndefined(metadataMap)) + return undefined; + return metadataMap.get(MetadataKey); + } + // 3.1.5.1 OrdinaryDefineOwnMetadata(MetadataKey, MetadataValue, O, P) + // https://rbuckton.github.io/reflect-metadata/#ordinarydefineownmetadata + function OrdinaryDefineOwnMetadata(MetadataKey, MetadataValue, O, P) { + var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ true); + metadataMap.set(MetadataKey, MetadataValue); + } + // 3.1.6.1 OrdinaryMetadataKeys(O, P) + // https://rbuckton.github.io/reflect-metadata/#ordinarymetadatakeys + function OrdinaryMetadataKeys(O, P) { + var ownKeys = OrdinaryOwnMetadataKeys(O, P); + var parent = OrdinaryGetPrototypeOf(O); + if (parent === null) + return ownKeys; + var parentKeys = OrdinaryMetadataKeys(parent, P); + if (parentKeys.length <= 0) + return ownKeys; + if (ownKeys.length <= 0) + return parentKeys; + var set = new _Set(); + var keys = []; + for (var _i = 0, ownKeys_1 = ownKeys; _i < ownKeys_1.length; _i++) { + var key = ownKeys_1[_i]; + var hasKey = set.has(key); + if (!hasKey) { + set.add(key); + keys.push(key); + } + } + for (var _a = 0, parentKeys_1 = parentKeys; _a < parentKeys_1.length; _a++) { + var key = parentKeys_1[_a]; + var hasKey = set.has(key); + if (!hasKey) { + set.add(key); + keys.push(key); + } + } + return keys; + } + // 3.1.7.1 OrdinaryOwnMetadataKeys(O, P) + // https://rbuckton.github.io/reflect-metadata/#ordinaryownmetadatakeys + function OrdinaryOwnMetadataKeys(O, P) { + var keys = []; + var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false); + if (IsUndefined(metadataMap)) + return keys; + var keysObj = metadataMap.keys(); + var iterator = GetIterator(keysObj); + var k = 0; + while (true) { + var next = IteratorStep(iterator); + if (!next) { + keys.length = k; + return keys; + } + var nextValue = IteratorValue(next); + try { + keys[k] = nextValue; + } + catch (e) { + try { + IteratorClose(iterator); + } + finally { + throw e; + } + } + k++; + } + } + // 6 ECMAScript Data Typ0es and Values + // https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values + function Type(x) { + if (x === null) + return 1 /* Null */; + switch (typeof x) { + case "undefined": return 0 /* Undefined */; + case "boolean": return 2 /* Boolean */; + case "string": return 3 /* String */; + case "symbol": return 4 /* Symbol */; + case "number": return 5 /* Number */; + case "object": return x === null ? 1 /* Null */ : 6 /* Object */; + default: return 6 /* Object */; + } + } + // 6.1.1 The Undefined Type + // https://tc39.github.io/ecma262/#sec-ecmascript-language-types-undefined-type + function IsUndefined(x) { + return x === undefined; + } + // 6.1.2 The Null Type + // https://tc39.github.io/ecma262/#sec-ecmascript-language-types-null-type + function IsNull(x) { + return x === null; + } + // 6.1.5 The Symbol Type + // https://tc39.github.io/ecma262/#sec-ecmascript-language-types-symbol-type + function IsSymbol(x) { + return typeof x === "symbol"; + } + // 6.1.7 The Object Type + // https://tc39.github.io/ecma262/#sec-object-type + function IsObject(x) { + return typeof x === "object" ? x !== null : typeof x === "function"; + } + // 7.1 Type Conversion + // https://tc39.github.io/ecma262/#sec-type-conversion + // 7.1.1 ToPrimitive(input [, PreferredType]) + // https://tc39.github.io/ecma262/#sec-toprimitive + function ToPrimitive(input, PreferredType) { + switch (Type(input)) { + case 0 /* Undefined */: return input; + case 1 /* Null */: return input; + case 2 /* Boolean */: return input; + case 3 /* String */: return input; + case 4 /* Symbol */: return input; + case 5 /* Number */: return input; + } + var hint = PreferredType === 3 /* String */ ? "string" : PreferredType === 5 /* Number */ ? "number" : "default"; + var exoticToPrim = GetMethod(input, toPrimitiveSymbol); + if (exoticToPrim !== undefined) { + var result = exoticToPrim.call(input, hint); + if (IsObject(result)) + throw new TypeError(); + return result; + } + return OrdinaryToPrimitive(input, hint === "default" ? "number" : hint); + } + // 7.1.1.1 OrdinaryToPrimitive(O, hint) + // https://tc39.github.io/ecma262/#sec-ordinarytoprimitive + function OrdinaryToPrimitive(O, hint) { + if (hint === "string") { + var toString_1 = O.toString; + if (IsCallable(toString_1)) { + var result = toString_1.call(O); + if (!IsObject(result)) + return result; + } + var valueOf = O.valueOf; + if (IsCallable(valueOf)) { + var result = valueOf.call(O); + if (!IsObject(result)) + return result; + } + } + else { + var valueOf = O.valueOf; + if (IsCallable(valueOf)) { + var result = valueOf.call(O); + if (!IsObject(result)) + return result; + } + var toString_2 = O.toString; + if (IsCallable(toString_2)) { + var result = toString_2.call(O); + if (!IsObject(result)) + return result; + } + } + throw new TypeError(); + } + // 7.1.2 ToBoolean(argument) + // https://tc39.github.io/ecma262/2016/#sec-toboolean + function ToBoolean(argument) { + return !!argument; + } + // 7.1.12 ToString(argument) + // https://tc39.github.io/ecma262/#sec-tostring + function ToString(argument) { + return "" + argument; + } + // 7.1.14 ToPropertyKey(argument) + // https://tc39.github.io/ecma262/#sec-topropertykey + function ToPropertyKey(argument) { + var key = ToPrimitive(argument, 3 /* String */); + if (IsSymbol(key)) + return key; + return ToString(key); + } + // 7.2 Testing and Comparison Operations + // https://tc39.github.io/ecma262/#sec-testing-and-comparison-operations + // 7.2.2 IsArray(argument) + // https://tc39.github.io/ecma262/#sec-isarray + function IsArray(argument) { + return Array.isArray + ? Array.isArray(argument) + : argument instanceof Object + ? argument instanceof Array + : Object.prototype.toString.call(argument) === "[object Array]"; + } + // 7.2.3 IsCallable(argument) + // https://tc39.github.io/ecma262/#sec-iscallable + function IsCallable(argument) { + // NOTE: This is an approximation as we cannot check for [[Call]] internal method. + return typeof argument === "function"; + } + // 7.2.4 IsConstructor(argument) + // https://tc39.github.io/ecma262/#sec-isconstructor + function IsConstructor(argument) { + // NOTE: This is an approximation as we cannot check for [[Construct]] internal method. + return typeof argument === "function"; + } + // 7.2.7 IsPropertyKey(argument) + // https://tc39.github.io/ecma262/#sec-ispropertykey + function IsPropertyKey(argument) { + switch (Type(argument)) { + case 3 /* String */: return true; + case 4 /* Symbol */: return true; + default: return false; + } + } + // 7.3 Operations on Objects + // https://tc39.github.io/ecma262/#sec-operations-on-objects + // 7.3.9 GetMethod(V, P) + // https://tc39.github.io/ecma262/#sec-getmethod + function GetMethod(V, P) { + var func = V[P]; + if (func === undefined || func === null) + return undefined; + if (!IsCallable(func)) + throw new TypeError(); + return func; + } + // 7.4 Operations on Iterator Objects + // https://tc39.github.io/ecma262/#sec-operations-on-iterator-objects + function GetIterator(obj) { + var method = GetMethod(obj, iteratorSymbol); + if (!IsCallable(method)) + throw new TypeError(); // from Call + var iterator = method.call(obj); + if (!IsObject(iterator)) + throw new TypeError(); + return iterator; + } + // 7.4.4 IteratorValue(iterResult) + // https://tc39.github.io/ecma262/2016/#sec-iteratorvalue + function IteratorValue(iterResult) { + return iterResult.value; + } + // 7.4.5 IteratorStep(iterator) + // https://tc39.github.io/ecma262/#sec-iteratorstep + function IteratorStep(iterator) { + var result = iterator.next(); + return result.done ? false : result; + } + // 7.4.6 IteratorClose(iterator, completion) + // https://tc39.github.io/ecma262/#sec-iteratorclose + function IteratorClose(iterator) { + var f = iterator["return"]; + if (f) + f.call(iterator); + } + // 9.1 Ordinary Object Internal Methods and Internal Slots + // https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots + // 9.1.1.1 OrdinaryGetPrototypeOf(O) + // https://tc39.github.io/ecma262/#sec-ordinarygetprototypeof + function OrdinaryGetPrototypeOf(O) { + var proto = Object.getPrototypeOf(O); + if (typeof O !== "function" || O === functionPrototype) + return proto; + // TypeScript doesn't set __proto__ in ES5, as it's non-standard. + // Try to determine the superclass constructor. Compatible implementations + // must either set __proto__ on a subclass constructor to the superclass constructor, + // or ensure each class has a valid `constructor` property on its prototype that + // points back to the constructor. + // If this is not the same as Function.[[Prototype]], then this is definately inherited. + // This is the case when in ES6 or when using __proto__ in a compatible browser. + if (proto !== functionPrototype) + return proto; + // If the super prototype is Object.prototype, null, or undefined, then we cannot determine the heritage. + var prototype = O.prototype; + var prototypeProto = prototype && Object.getPrototypeOf(prototype); + if (prototypeProto == null || prototypeProto === Object.prototype) + return proto; + // If the constructor was not a function, then we cannot determine the heritage. + var constructor = prototypeProto.constructor; + if (typeof constructor !== "function") + return proto; + // If we have some kind of self-reference, then we cannot determine the heritage. + if (constructor === O) + return proto; + // we have a pretty good guess at the heritage. + return constructor; + } + // naive Map shim + function CreateMapPolyfill() { + var cacheSentinel = {}; + var arraySentinel = []; + var MapIterator = /** @class */ (function () { + function MapIterator(keys, values, selector) { + this._index = 0; + this._keys = keys; + this._values = values; + this._selector = selector; + } + MapIterator.prototype["@@iterator"] = function () { return this; }; + MapIterator.prototype[iteratorSymbol] = function () { return this; }; + MapIterator.prototype.next = function () { + var index = this._index; + if (index >= 0 && index < this._keys.length) { + var result = this._selector(this._keys[index], this._values[index]); + if (index + 1 >= this._keys.length) { + this._index = -1; + this._keys = arraySentinel; + this._values = arraySentinel; + } + else { + this._index++; + } + return { value: result, done: false }; + } + return { value: undefined, done: true }; + }; + MapIterator.prototype.throw = function (error) { + if (this._index >= 0) { + this._index = -1; + this._keys = arraySentinel; + this._values = arraySentinel; + } + throw error; + }; + MapIterator.prototype.return = function (value) { + if (this._index >= 0) { + this._index = -1; + this._keys = arraySentinel; + this._values = arraySentinel; + } + return { value: value, done: true }; + }; + return MapIterator; + }()); + return /** @class */ (function () { + function Map() { + this._keys = []; + this._values = []; + this._cacheKey = cacheSentinel; + this._cacheIndex = -2; + } + Object.defineProperty(Map.prototype, "size", { + get: function () { return this._keys.length; }, + enumerable: true, + configurable: true + }); + Map.prototype.has = function (key) { return this._find(key, /*insert*/ false) >= 0; }; + Map.prototype.get = function (key) { + var index = this._find(key, /*insert*/ false); + return index >= 0 ? this._values[index] : undefined; + }; + Map.prototype.set = function (key, value) { + var index = this._find(key, /*insert*/ true); + this._values[index] = value; + return this; + }; + Map.prototype.delete = function (key) { + var index = this._find(key, /*insert*/ false); + if (index >= 0) { + var size = this._keys.length; + for (var i = index + 1; i < size; i++) { + this._keys[i - 1] = this._keys[i]; + this._values[i - 1] = this._values[i]; + } + this._keys.length--; + this._values.length--; + if (key === this._cacheKey) { + this._cacheKey = cacheSentinel; + this._cacheIndex = -2; + } + return true; + } + return false; + }; + Map.prototype.clear = function () { + this._keys.length = 0; + this._values.length = 0; + this._cacheKey = cacheSentinel; + this._cacheIndex = -2; + }; + Map.prototype.keys = function () { return new MapIterator(this._keys, this._values, getKey); }; + Map.prototype.values = function () { return new MapIterator(this._keys, this._values, getValue); }; + Map.prototype.entries = function () { return new MapIterator(this._keys, this._values, getEntry); }; + Map.prototype["@@iterator"] = function () { return this.entries(); }; + Map.prototype[iteratorSymbol] = function () { return this.entries(); }; + Map.prototype._find = function (key, insert) { + if (this._cacheKey !== key) { + this._cacheIndex = this._keys.indexOf(this._cacheKey = key); + } + if (this._cacheIndex < 0 && insert) { + this._cacheIndex = this._keys.length; + this._keys.push(key); + this._values.push(undefined); + } + return this._cacheIndex; + }; + return Map; + }()); + function getKey(key, _) { + return key; + } + function getValue(_, value) { + return value; + } + function getEntry(key, value) { + return [key, value]; + } + } + // naive Set shim + function CreateSetPolyfill() { + return /** @class */ (function () { + function Set() { + this._map = new _Map(); + } + Object.defineProperty(Set.prototype, "size", { + get: function () { return this._map.size; }, + enumerable: true, + configurable: true + }); + Set.prototype.has = function (value) { return this._map.has(value); }; + Set.prototype.add = function (value) { return this._map.set(value, value), this; }; + Set.prototype.delete = function (value) { return this._map.delete(value); }; + Set.prototype.clear = function () { this._map.clear(); }; + Set.prototype.keys = function () { return this._map.keys(); }; + Set.prototype.values = function () { return this._map.values(); }; + Set.prototype.entries = function () { return this._map.entries(); }; + Set.prototype["@@iterator"] = function () { return this.keys(); }; + Set.prototype[iteratorSymbol] = function () { return this.keys(); }; + return Set; + }()); + } + // naive WeakMap shim + function CreateWeakMapPolyfill() { + var UUID_SIZE = 16; + var keys = HashMap.create(); + var rootKey = CreateUniqueKey(); + return /** @class */ (function () { + function WeakMap() { + this._key = CreateUniqueKey(); + } + WeakMap.prototype.has = function (target) { + var table = GetOrCreateWeakMapTable(target, /*create*/ false); + return table !== undefined ? HashMap.has(table, this._key) : false; + }; + WeakMap.prototype.get = function (target) { + var table = GetOrCreateWeakMapTable(target, /*create*/ false); + return table !== undefined ? HashMap.get(table, this._key) : undefined; + }; + WeakMap.prototype.set = function (target, value) { + var table = GetOrCreateWeakMapTable(target, /*create*/ true); + table[this._key] = value; + return this; + }; + WeakMap.prototype.delete = function (target) { + var table = GetOrCreateWeakMapTable(target, /*create*/ false); + return table !== undefined ? delete table[this._key] : false; + }; + WeakMap.prototype.clear = function () { + // NOTE: not a real clear, just makes the previous data unreachable + this._key = CreateUniqueKey(); + }; + return WeakMap; + }()); + function CreateUniqueKey() { + var key; + do + key = "@@WeakMap@@" + CreateUUID(); + while (HashMap.has(keys, key)); + keys[key] = true; + return key; + } + function GetOrCreateWeakMapTable(target, create) { + if (!hasOwn.call(target, rootKey)) { + if (!create) + return undefined; + Object.defineProperty(target, rootKey, { value: HashMap.create() }); + } + return target[rootKey]; + } + function FillRandomBytes(buffer, size) { + for (var i = 0; i < size; ++i) + buffer[i] = Math.random() * 0xff | 0; + return buffer; + } + function GenRandomBytes(size) { + if (typeof Uint8Array === "function") { + if (typeof crypto !== "undefined") + return crypto.getRandomValues(new Uint8Array(size)); + if (typeof msCrypto !== "undefined") + return msCrypto.getRandomValues(new Uint8Array(size)); + return FillRandomBytes(new Uint8Array(size), size); + } + return FillRandomBytes(new Array(size), size); + } + function CreateUUID() { + var data = GenRandomBytes(UUID_SIZE); + // mark as random - RFC 4122 § 4.4 + data[6] = data[6] & 0x4f | 0x40; + data[8] = data[8] & 0xbf | 0x80; + var result = ""; + for (var offset = 0; offset < UUID_SIZE; ++offset) { + var byte = data[offset]; + if (offset === 4 || offset === 6 || offset === 8) + result += "-"; + if (byte < 16) + result += "0"; + result += byte.toString(16).toLowerCase(); + } + return result; + } + } + // uses a heuristic used by v8 and chakra to force an object into dictionary mode. + function MakeDictionary(obj) { + obj.__ = undefined; + delete obj.__; + return obj; + } + }); + })(Reflect$1 || (Reflect$1 = {})); + + /* + * 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. + */ + function hookBeforeNativeCall(context) { + if (context) { + Reflect.defineMetadata('__doric_context__', context, global$1); + context.hookBeforeNativeCall(); + } + } + function hookAfterNativeCall(context) { + if (context) { + context.hookAfterNativeCall(); + } + } + function getContext() { + return Reflect.getMetadata('__doric_context__', global$1); + } + function setContext(context) { + Reflect.defineMetadata('__doric_context__', context, global$1); + } + 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); + } + 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); + } + 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; + 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; + } + } + function jsReleaseContext(id) { + gContexts.delete(id); + } + function __require__(name) { + if (gModules.has(name)) { + return gModules.get(name); + } + else { + if (nativeRequire(name)) { + return gModules.get(name); + } + else { + return undefined; + } + } + } + function jsRegisterModule(name, moduleObject) { + gModules.set(name, moduleObject); + } + 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}`); + } + } + 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$1 = Function('return this')(); + let __timerId__ = 0; + const timerInfos = new Map; + global$1.setTimeout = (handler, timeout, ...args) => { + const id = __timerId__++; + timerInfos.set(id, { + callback: () => { + Reflect.apply(handler, undefined, args); + timerInfos.delete(id); + }, + context: getContext(), + }); + nativeSetTimer(id, timeout || 0, false); + return id; + }; + global$1.setInterval = (handler, timeout, ...args) => { + const id = __timerId__++; + timerInfos.set(id, { + callback: () => { + Reflect.apply(handler, undefined, args); + }, + context: getContext(), + }); + nativeSetTimer(id, timeout || 0, true); + return id; + }; + global$1.clearTimeout = (timerId) => { + timerInfos.delete(timerId); + nativeClearTimer(timerId); + }; + global$1.clearInterval = (timerId) => { + timerInfos.delete(timerId); + nativeClearTimer(timerId); + }; + 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); + } + } + + exports.Context = Context; + exports.__require__ = __require__; + exports.jsCallEntityMethod = jsCallEntityMethod; + exports.jsCallReject = jsCallReject; + exports.jsCallResolve = jsCallResolve; + exports.jsCallbackTimer = jsCallbackTimer; + exports.jsObtainContext = jsObtainContext; + exports.jsObtainEntry = jsObtainEntry; + exports.jsRegisterModule = jsRegisterModule; + exports.jsReleaseContext = jsReleaseContext; + + return exports; + +}({})); diff --git a/demo/src/Counter.ts b/demo/src/Counter.ts index 725c2e38..45d06333 100644 --- a/demo/src/Counter.ts +++ b/demo/src/Counter.ts @@ -1,6 +1,5 @@ import { vlayout, Image, ViewHolder, VMPanel, ViewModel, Gravity, NativeCall, Text, Color, log, logw, loge, Group, LayoutSpec, } from "doric" - interface CountModel { count: number } @@ -97,6 +96,7 @@ class CounterVM extends ViewModel { @Entry class MyPage extends VMPanel{ +<<<<<<< HEAD getViewHolderClass() { @@ -104,6 +104,9 @@ class MyPage extends VMPanel{ } getViewModelClass() { +======= + getVMClass() { +>>>>>>> debug ts code return CounterVM } diff --git a/js-framework/index.debug.ts b/js-framework/index.debug.ts new file mode 100644 index 00000000..34096d37 --- /dev/null +++ b/js-framework/index.debug.ts @@ -0,0 +1,34 @@ +/* + * 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' +let global = new Function('return this')() +global.doric = doric +const contextId = "DoricDebug" +global.context = doric.jsObtainContext(contextId) +global.Entry = doric.jsObtainEntry(contextId) +console.log('Start Server') + +global.injectGlobal = (objName: string, obj: string) => { + Reflect.set(global, objName, JSON.parse(obj)) +} + +global.sendToNative = () => { + +} +global.receiveFromNative = (funcName, ) => { + +} +export * from './index' \ No newline at end of file diff --git a/js-framework/package.json b/js-framework/package.json index 3e32bdd0..175aae88 100644 --- a/js-framework/package.json +++ b/js-framework/package.json @@ -2,7 +2,7 @@ "name": "doric", "version": "0.1.0", "description": "The JS Framework of Doric", - "main": "build/index.js", + "main": "bundle/doric-vm.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "tsc -p .&& rollup -c", @@ -27,4 +27,4 @@ "tslib": "^1.10.0", "typescript": "^3.5.3" } -} +} \ No newline at end of file diff --git a/js-framework/rollup.config.js b/js-framework/rollup.config.js index 519ab4db..3e569840 100644 --- a/js-framework/rollup.config.js +++ b/js-framework/rollup.config.js @@ -25,4 +25,14 @@ export default [ ], external: ['reflect-metadata'] }, + { + input: "build/index.debug.js", + output: { + format: "cjs", + file: "bundle/doric-vm.js", + }, + plugins: [ + resolve({ jsnext: true, main: true }), + ] + }, ] \ No newline at end of file diff --git a/js-framework/src/runtime/sandbox.ts b/js-framework/src/runtime/sandbox.ts index 8db4c38a..4e885ada 100644 --- a/js-framework/src/runtime/sandbox.ts +++ b/js-framework/src/runtime/sandbox.ts @@ -21,17 +21,17 @@ import "reflect-metadata" * ``` TypeScript * // load script in global scope * Reflect.apply( - * function(hego,context,Entry,require){ + * function(doric,context,Entry,require){ * //Script content * REG() - * },hego.jsObtainContext(id),[ + * },doric.jsObtainContext(id),[ * undefined, - * hego.jsObtainContext(id), - * hego.jsObtainEntry(id), - * hego.__require__, + * doric.jsObtainContext(id), + * doric.jsObtainEntry(id), + * doric.__require__, * ]) * // load module in global scope - * Reflect.apply(hego.jsRegisterModule,this,[ + * Reflect.apply(doric.jsRegisterModule,this,[ * moduleName, * Reflect.apply(function(__module){ * (function(module,exports,require){ diff --git a/remote/.vscode/launch.json b/remote/.vscode/launch.json new file mode 100644 index 00000000..b5b7c1f1 --- /dev/null +++ b/remote/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Launch Program", + "program": "${workspaceFolder}/index.ts", + "preLaunchTask": "tsc: build - tsconfig.json", + }, + { + "type": "node", + "request": "attach", + "name": "Attach", + "port": 9229 + } + ] +} \ No newline at end of file diff --git a/remote/index.js b/remote/index.js index 78d2ee68..1b3a1c20 100644 --- a/remote/index.js +++ b/remote/index.js @@ -8,13 +8,14 @@ var context = vm.createContext(sandbox) wss.on('connection', function connection(ws) { ws.on('message', function incoming(message) { let messageObject = JSON.parse(message) - switch(messageObject.cmd) { + switch (messageObject.cmd) { case "loadJS": let result = vm.runInContext(messageObject.script, sandbox) - ws.send(JSON.stringify({cmd: 'loadJS', result: String(result)})) + ws.send(JSON.stringify({ cmd: 'loadJS', result: String(result) })) break case "evaluateJS": break } }) -}) \ No newline at end of file +}) +