vsn 0.1.24 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/demo/demo.html +18 -7
- package/demo/vsn.js +1 -0
- package/dist/AST/ArithmeticAssignmentNode.d.ts +23 -0
- package/dist/AST/ArithmeticAssignmentNode.js +313 -0
- package/dist/AST/ArithmeticAssignmentNode.js.map +1 -0
- package/dist/AST/ArithmeticNode.d.ts +15 -0
- package/dist/AST/ArithmeticNode.js +114 -0
- package/dist/AST/ArithmeticNode.js.map +1 -0
- package/dist/AST/ArrayNode.d.ts +14 -0
- package/dist/AST/ArrayNode.js +114 -0
- package/dist/AST/ArrayNode.js.map +1 -0
- package/dist/AST/BlockNode.d.ts +11 -0
- package/dist/AST/BlockNode.js +98 -0
- package/dist/AST/BlockNode.js.map +1 -0
- package/dist/AST/BooleanLiteralNode.d.ts +5 -0
- package/dist/AST/BooleanLiteralNode.js +31 -0
- package/dist/AST/BooleanLiteralNode.js.map +1 -0
- package/dist/AST/ComparisonNode.d.ts +15 -0
- package/dist/AST/ComparisonNode.js +120 -0
- package/dist/AST/ComparisonNode.js.map +1 -0
- package/dist/AST/ConditionalNode.d.ts +13 -0
- package/dist/AST/ConditionalNode.js +95 -0
- package/dist/AST/ConditionalNode.js.map +1 -0
- package/dist/AST/ElementAttributeNode.d.ts +18 -0
- package/dist/AST/ElementAttributeNode.js +159 -0
- package/dist/AST/ElementAttributeNode.js.map +1 -0
- package/dist/AST/ElementQueryNode.d.ts +12 -0
- package/dist/AST/ElementQueryNode.js +111 -0
- package/dist/AST/ElementQueryNode.js.map +1 -0
- package/dist/AST/ElementStyleNode.d.ts +18 -0
- package/dist/AST/ElementStyleNode.js +159 -0
- package/dist/AST/ElementStyleNode.js.map +1 -0
- package/dist/AST/ForStatementNode.d.ts +17 -0
- package/dist/AST/ForStatementNode.js +121 -0
- package/dist/AST/ForStatementNode.js.map +1 -0
- package/dist/AST/FunctionArgumentNode.d.ts +11 -0
- package/dist/AST/FunctionArgumentNode.js +100 -0
- package/dist/AST/FunctionArgumentNode.js.map +1 -0
- package/dist/AST/FunctionCallNode.d.ts +13 -0
- package/dist/AST/FunctionCallNode.js +102 -0
- package/dist/AST/FunctionCallNode.js.map +1 -0
- package/dist/AST/IfStatementNode.d.ts +14 -0
- package/dist/AST/IfStatementNode.js +128 -0
- package/dist/AST/IfStatementNode.js.map +1 -0
- package/dist/AST/InNode.d.ts +15 -0
- package/dist/AST/InNode.js +107 -0
- package/dist/AST/InNode.js.map +1 -0
- package/dist/AST/IndexNode.d.ts +16 -0
- package/dist/AST/IndexNode.js +126 -0
- package/dist/AST/IndexNode.js.map +1 -0
- package/dist/AST/LiteralNode.d.ts +10 -0
- package/dist/AST/LiteralNode.js +74 -0
- package/dist/AST/LiteralNode.js.map +1 -0
- package/dist/AST/Node.d.ts +19 -0
- package/dist/AST/Node.js +117 -0
- package/dist/AST/Node.js.map +1 -0
- package/dist/AST/NotNode.d.ts +12 -0
- package/dist/AST/NotNode.js +103 -0
- package/dist/AST/NotNode.js.map +1 -0
- package/dist/AST/NumberLiteralNode.d.ts +5 -0
- package/dist/AST/NumberLiteralNode.js +36 -0
- package/dist/AST/NumberLiteralNode.js.map +1 -0
- package/dist/AST/ObjectNode.d.ts +14 -0
- package/dist/AST/ObjectNode.js +131 -0
- package/dist/AST/ObjectNode.js.map +1 -0
- package/dist/AST/RootScopeMemberNode.d.ts +11 -0
- package/dist/AST/RootScopeMemberNode.js +87 -0
- package/dist/AST/RootScopeMemberNode.js.map +1 -0
- package/dist/AST/ScopeMemberNode.d.ts +12 -0
- package/dist/AST/ScopeMemberNode.js +128 -0
- package/dist/AST/ScopeMemberNode.js.map +1 -0
- package/dist/AST/UnitLiteralNode.d.ts +15 -0
- package/dist/AST/UnitLiteralNode.js +72 -0
- package/dist/AST/UnitLiteralNode.js.map +1 -0
- package/dist/AST.d.ts +9 -61
- package/dist/AST.js +84 -1413
- package/dist/AST.js.map +1 -1
- package/dist/Attribute.d.ts +1 -1
- package/dist/Attribute.js +3 -3
- package/dist/Attribute.js.map +1 -1
- package/dist/Configuration.d.ts +1 -1
- package/dist/Configuration.js +4 -4
- package/dist/Configuration.js.map +1 -1
- package/dist/Controller.d.ts +12 -4
- package/dist/Controller.js +38 -6
- package/dist/Controller.js.map +1 -1
- package/dist/DOM/DOMObject.d.ts +1 -1
- package/dist/DOM/DOMObject.js +2 -2
- package/dist/DOM/DOMObject.js.map +1 -1
- package/dist/DOM.d.ts +1 -1
- package/dist/DOM.js +4 -4
- package/dist/DOM.js.map +1 -1
- package/dist/EventDispatcher.d.ts +29 -0
- package/dist/EventDispatcher.js +132 -0
- package/dist/EventDispatcher.js.map +1 -0
- package/dist/Formats.js +2 -2
- package/dist/Formats.js.map +1 -1
- package/dist/MessageList.d.ts +14 -0
- package/dist/MessageList.js +88 -0
- package/dist/MessageList.js.map +1 -0
- package/dist/Model/Field.d.ts +8 -0
- package/dist/Model/Field.js +38 -0
- package/dist/Model/Field.js.map +1 -0
- package/dist/Model.d.ts +12 -0
- package/dist/Model.js +61 -0
- package/dist/Model.js.map +1 -0
- package/dist/Registry.d.ts +5 -2
- package/dist/Registry.js +17 -16
- package/dist/Registry.js.map +1 -1
- package/dist/Scope/DynamicScopeData.d.ts +6 -0
- package/dist/Scope/DynamicScopeData.js +54 -0
- package/dist/Scope/DynamicScopeData.js.map +1 -0
- package/dist/Scope/QueryReference.d.ts +10 -0
- package/dist/Scope/QueryReference.js +103 -0
- package/dist/Scope/QueryReference.js.map +1 -0
- package/dist/Scope/ScopeData.d.ts +4 -0
- package/dist/Scope/ScopeData.js +40 -0
- package/dist/Scope/ScopeData.js.map +1 -0
- package/dist/Scope/ScopeDataAbstract.d.ts +22 -0
- package/dist/Scope/ScopeDataAbstract.js +137 -0
- package/dist/Scope/ScopeDataAbstract.js.map +1 -0
- package/dist/Scope/ScopeReference.d.ts +10 -0
- package/dist/Scope/ScopeReference.js +73 -0
- package/dist/Scope/ScopeReference.js.map +1 -0
- package/dist/Scope/ScopedVariableType.d.ts +6 -0
- package/dist/Scope/ScopedVariableType.js +14 -0
- package/dist/Scope/ScopedVariableType.js.map +1 -0
- package/dist/Scope/WrappedArray.d.ts +16 -0
- package/dist/Scope/WrappedArray.js +121 -0
- package/dist/Scope/WrappedArray.js.map +1 -0
- package/dist/Scope/properties/Property.d.ts +18 -0
- package/dist/Scope/properties/Property.js +93 -0
- package/dist/Scope/properties/Property.js.map +1 -0
- package/dist/Scope.d.ts +4 -48
- package/dist/Scope.js +39 -324
- package/dist/Scope.js.map +1 -1
- package/dist/SimplePromise.d.ts +42 -0
- package/dist/SimplePromise.js +217 -0
- package/dist/SimplePromise.js.map +1 -0
- package/dist/Tag.js +11 -5
- package/dist/Tag.js.map +1 -1
- package/dist/Types.d.ts +1 -0
- package/dist/Types.js +8 -1
- package/dist/Types.js.map +1 -1
- package/dist/Validators.d.ts +7 -0
- package/dist/Validators.js +54 -0
- package/dist/Validators.js.map +1 -0
- package/dist/attributes/Bind.js +1 -1
- package/dist/attributes/Bind.js.map +1 -1
- package/dist/attributes/JSONAttribute.js.map +1 -1
- package/dist/attributes/List.js +7 -7
- package/dist/attributes/List.js.map +1 -1
- package/dist/attributes/On.js +4 -1
- package/dist/attributes/On.js.map +1 -1
- package/dist/attributes/Radio.js +4 -2
- package/dist/attributes/Radio.js.map +1 -1
- package/dist/attributes/ScopeChange.js +1 -1
- package/dist/attributes/ScopeChange.js.map +1 -1
- package/dist/attributes/SetAttribute.js.map +1 -1
- package/dist/attributes/StandardAttribute.js +1 -1
- package/dist/attributes/StandardAttribute.js.map +1 -1
- package/dist/attributes/StyleAttribute.js +1 -1
- package/dist/attributes/StyleAttribute.js.map +1 -1
- package/dist/{Vision.d.ts → vsn.d.ts} +7 -2
- package/dist/{Vision.js → vsn.js} +21 -12
- package/dist/vsn.js.map +1 -0
- package/package.json +9 -13
- package/src/AST/ArithmeticAssignmentNode.ts +236 -0
- package/src/AST/ArithmeticNode.ts +52 -0
- package/src/AST/ArrayNode.ts +39 -0
- package/src/AST/BlockNode.ts +25 -0
- package/src/AST/BooleanLiteralNode.ts +10 -0
- package/src/AST/ComparisonNode.ts +57 -0
- package/src/AST/ConditionalNode.ts +36 -0
- package/src/AST/ElementAttributeNode.ts +63 -0
- package/src/AST/ElementQueryNode.ts +25 -0
- package/src/AST/ElementStyleNode.ts +63 -0
- package/src/AST/ForStatementNode.ts +59 -0
- package/src/AST/FunctionArgumentNode.ts +27 -0
- package/src/AST/FunctionCallNode.ts +32 -0
- package/src/AST/IfStatementNode.ts +67 -0
- package/src/AST/InNode.ts +46 -0
- package/src/AST/IndexNode.ts +61 -0
- package/src/AST/LiteralNode.ts +17 -0
- package/src/AST/Node.ts +71 -0
- package/src/AST/NotNode.ts +41 -0
- package/src/AST/NumberLiteralNode.ts +14 -0
- package/src/AST/ObjectNode.ts +55 -0
- package/src/AST/RootScopeMemberNode.ts +25 -0
- package/src/AST/ScopeMemberNode.ts +53 -0
- package/src/AST/UnitLiteralNode.ts +51 -0
- package/src/AST.ts +45 -1014
- package/src/Attribute.ts +2 -2
- package/src/Configuration.ts +3 -3
- package/src/Controller.ts +31 -6
- package/src/DOM/DOMObject.ts +1 -1
- package/src/DOM.ts +4 -4
- package/src/EventDispatcher.ts +134 -0
- package/src/Formats.ts +2 -2
- package/src/MessageList.ts +81 -0
- package/src/Model/Field.ts +20 -0
- package/src/Model.ts +43 -0
- package/src/Registry.ts +13 -5
- package/src/Scope/DynamicScopeData.ts +29 -0
- package/src/Scope/QueryReference.ts +29 -0
- package/src/Scope/ScopeData.ts +21 -0
- package/src/Scope/ScopeDataAbstract.ts +126 -0
- package/src/Scope/ScopeReference.ts +30 -0
- package/src/Scope/ScopedVariableType.ts +7 -0
- package/src/Scope/WrappedArray.ts +88 -0
- package/src/Scope/properties/Property.ts +79 -0
- package/src/Scope.ts +35 -251
- package/src/SimplePromise.ts +219 -0
- package/src/Tag.ts +9 -5
- package/src/Types.ts +6 -1
- package/src/Validators.ts +45 -0
- package/src/attributes/Bind.ts +3 -2
- package/src/attributes/JSONAttribute.ts +2 -1
- package/src/attributes/List.ts +4 -4
- package/src/attributes/On.ts +2 -0
- package/src/attributes/Radio.ts +5 -3
- package/src/attributes/ScopeChange.ts +2 -2
- package/src/attributes/SetAttribute.ts +2 -1
- package/src/attributes/StandardAttribute.ts +1 -1
- package/src/attributes/StyleAttribute.ts +3 -2
- package/src/attributes/TypeAttribute.ts +1 -1
- package/src/{Vision.ts → vsn.ts} +12 -5
- package/test/AST/ArithmeticAssignmentNode.spec.ts +47 -0
- package/test/AST.spec.ts +3 -2
- package/test/Controller.spec.ts +44 -0
- package/test/DOM.spec.ts +1 -1
- package/test/MessageList.spec.ts +101 -0
- package/test/Model/DataModel.spec.ts +0 -0
- package/test/Scope/DynamicScopeData.spec.ts +141 -0
- package/test/Scope.spec.ts +15 -3
- package/test/SimplePromise.spec.ts +271 -0
- package/test/Tag/TagList.spec.ts +1 -1
- package/test/attributes/Bind.spec.ts +5 -5
- package/test/attributes/JSONAttribute.spec.ts +1 -1
- package/test/attributes/ListItem.spec.ts +1 -1
- package/webpack.config.js +2 -2
- package/demo/vision.js +0 -1
- package/dist/Vision.js.map +0 -1
- package/main.py +0 -16
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {Scope} from "../Scope";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export class ScopeReference {
|
|
5
|
+
private _scope: Scope;
|
|
6
|
+
private _key: string;
|
|
7
|
+
private _value: any;
|
|
8
|
+
|
|
9
|
+
constructor(
|
|
10
|
+
scope: Scope = null,
|
|
11
|
+
key: string = null,
|
|
12
|
+
value: any = null
|
|
13
|
+
) {
|
|
14
|
+
this._scope = scope;
|
|
15
|
+
this._key = key;
|
|
16
|
+
this._value = value;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public async getScope() {
|
|
20
|
+
return this._scope;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public async getKey() {
|
|
24
|
+
return this._key;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public async getValue() {
|
|
28
|
+
return this._value;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import {EventDispatcher, EventDispatcherCallback} from "../EventDispatcher";
|
|
2
|
+
|
|
3
|
+
export class WrappedArray<T> extends Array<T> {
|
|
4
|
+
private dispatcher: EventDispatcher;
|
|
5
|
+
public readonly $wrapped: boolean = true;
|
|
6
|
+
|
|
7
|
+
constructor(...items: T[]) {
|
|
8
|
+
super(...items);
|
|
9
|
+
Object.setPrototypeOf(this, WrappedArray.prototype);
|
|
10
|
+
this.dispatcher = new EventDispatcher();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
dispatch(event: string, ...args: any[]) {
|
|
14
|
+
this.dispatcher.dispatch(event, ...args);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
on(event: string, callback: EventDispatcherCallback) {
|
|
18
|
+
this.dispatcher.on(event, callback);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
off(event: string, key?: number) {
|
|
22
|
+
this.dispatcher.off(event, key);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
once(event: string, callback: EventDispatcherCallback) {
|
|
26
|
+
this.dispatcher.once(event, callback);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
push(...items: T[]): number {
|
|
30
|
+
const num: number = super.push(...items);
|
|
31
|
+
|
|
32
|
+
this.dispatch('push', ...items);
|
|
33
|
+
this.dispatch('change', {
|
|
34
|
+
'added': items
|
|
35
|
+
});
|
|
36
|
+
for (const item of items) {
|
|
37
|
+
this.dispatch('add', item);
|
|
38
|
+
}
|
|
39
|
+
return num;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
splice(start: number, deleteCount?: number): T[] {
|
|
43
|
+
const removed: T[] = super.splice(start, deleteCount);
|
|
44
|
+
|
|
45
|
+
this.dispatch('change', {
|
|
46
|
+
'removed': removed
|
|
47
|
+
});
|
|
48
|
+
for (const item of removed) {
|
|
49
|
+
this.dispatch('remove', item);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return removed;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get(key: string) {
|
|
56
|
+
const keys: string[] = [
|
|
57
|
+
'length'
|
|
58
|
+
];
|
|
59
|
+
return keys.indexOf(key) > -1 ? this[key] : undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
get length(): number {
|
|
63
|
+
let c: number = 0;
|
|
64
|
+
for (const item of this) {
|
|
65
|
+
c += 1;
|
|
66
|
+
}
|
|
67
|
+
return c;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
set length(num: number) {
|
|
71
|
+
this.setLength(num);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
setLength(num: number) {
|
|
75
|
+
let c: number = 0;
|
|
76
|
+
const toRemove: T[] = [];
|
|
77
|
+
for (const item of this) {
|
|
78
|
+
c += 1;
|
|
79
|
+
if (c >= num) {
|
|
80
|
+
toRemove.push(item);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
for (const item of toRemove) {
|
|
85
|
+
this.splice(this.indexOf(item), 1);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import {EventDispatcher} from "../../EventDispatcher";
|
|
2
|
+
import {Registry} from "../../Registry";
|
|
3
|
+
|
|
4
|
+
export function property(propertyType = Property, config: {} | null = {}) {
|
|
5
|
+
return function(target: any, key: string) {
|
|
6
|
+
if(target.__properties__ == undefined) {
|
|
7
|
+
target.__properties__ = [];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Abstract/extended classes share __properties__
|
|
11
|
+
if(target.__properties__.indexOf(key) == -1)
|
|
12
|
+
target.__properties__.push(key);
|
|
13
|
+
|
|
14
|
+
const getter = function() {
|
|
15
|
+
return [propertyType, config];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
Object.defineProperty(target, '__'+key+'__', {
|
|
19
|
+
get: getter,
|
|
20
|
+
set: v => {},
|
|
21
|
+
enumerable:false,
|
|
22
|
+
configurable: true
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface IPropertyConfig {
|
|
28
|
+
type?: string;
|
|
29
|
+
default?: any;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class Property extends EventDispatcher {
|
|
33
|
+
_type: string = 'any';
|
|
34
|
+
_value: any;
|
|
35
|
+
config: IPropertyConfig;
|
|
36
|
+
|
|
37
|
+
constructor(value?:any, config?: IPropertyConfig) {
|
|
38
|
+
super();
|
|
39
|
+
this.config = config;
|
|
40
|
+
this.type = config.type || 'any';
|
|
41
|
+
|
|
42
|
+
this.value = value;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
castType(value) {
|
|
46
|
+
const caster = Registry.instance.types.getSynchronous(this.type);
|
|
47
|
+
return caster(value);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
set value(v:any) {
|
|
51
|
+
const oldValue = this._value;
|
|
52
|
+
this._value = this.castType(v);
|
|
53
|
+
if (this._value !== oldValue) {
|
|
54
|
+
this.dispatch('change', {
|
|
55
|
+
oldValue:oldValue,
|
|
56
|
+
value:v
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get value() {
|
|
62
|
+
return this._value;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
getData() {
|
|
66
|
+
return this.value;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
set type(type: string) {
|
|
70
|
+
if (this._type != type) {
|
|
71
|
+
this._type = type;
|
|
72
|
+
this.value = this.value; // Need to reset value to have it cast to the new type
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
get type(): string {
|
|
77
|
+
return this._type;
|
|
78
|
+
}
|
|
79
|
+
}
|
package/src/Scope.ts
CHANGED
|
@@ -1,218 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import {EventDispatcher} from "./EventDispatcher";
|
|
2
|
+
import {ScopeReference} from "./Scope/ScopeReference";
|
|
3
|
+
import {QueryReference} from "./Scope/QueryReference";
|
|
4
|
+
import {WrappedArray} from "./Scope/WrappedArray";
|
|
5
|
+
import {ScopeData} from "./Scope/ScopeData";
|
|
6
|
+
import {DynamicScopeData} from "./Scope/DynamicScopeData";
|
|
5
7
|
|
|
6
|
-
export class ScopeReference {
|
|
7
|
-
private _scope: Scope;
|
|
8
|
-
private _key: string;
|
|
9
|
-
private _value: any;
|
|
10
|
-
|
|
11
|
-
constructor(
|
|
12
|
-
scope: Scope = null,
|
|
13
|
-
key: string = null,
|
|
14
|
-
value: any = null
|
|
15
|
-
) {
|
|
16
|
-
this._scope = scope;
|
|
17
|
-
this._key = key;
|
|
18
|
-
this._value = value;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
public async getScope() {
|
|
22
|
-
return this._scope;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
public async getKey() {
|
|
26
|
-
return this._key;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
public async getValue() {
|
|
30
|
-
return this._value;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export class QueryReference extends ScopeReference {
|
|
35
|
-
constructor(
|
|
36
|
-
public readonly path: string,
|
|
37
|
-
public readonly scope: Scope
|
|
38
|
-
) {
|
|
39
|
-
super();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
public async getScope() {
|
|
43
|
-
let parts: string[] = this.path.split('.');
|
|
44
|
-
parts = parts.splice(0, parts.length - 1);
|
|
45
|
-
const qResult = await DOM.instance.eval(parts.join('.'));
|
|
46
|
-
return qResult.length === 1 ? qResult[0].scope : qResult.map((dobj) => dobj.scope);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public async getKey() {
|
|
50
|
-
const parts: string[] = this.path.split('.');
|
|
51
|
-
return parts[parts.length - 1];
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
public async getValue() {
|
|
55
|
-
return await DOM.instance.eval(this.path);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export class ScopeVariableType {
|
|
60
|
-
public static readonly Integer: string = 'integer';
|
|
61
|
-
public static readonly Float: string = 'float';
|
|
62
|
-
public static readonly Boolean: string = 'boolean';
|
|
63
|
-
public static readonly String: string = 'string';
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export class WrappedArray<T> extends Array<T> {
|
|
67
|
-
private _listeners: EventCallbackList;
|
|
68
|
-
private _lastKey: number;
|
|
69
|
-
public readonly $wrapped: boolean = true;
|
|
70
|
-
|
|
71
|
-
constructor(...items: T[]) {
|
|
72
|
-
super(...items);
|
|
73
|
-
Object.setPrototypeOf(this, WrappedArray.prototype);
|
|
74
|
-
this._lastKey = 0;
|
|
75
|
-
this._listeners = {};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
push(...items: T[]): number {
|
|
79
|
-
const num: number = super.push(...items);
|
|
80
|
-
|
|
81
|
-
this.trigger('push', ...items);
|
|
82
|
-
this.trigger('change', {
|
|
83
|
-
'added': items
|
|
84
|
-
});
|
|
85
|
-
for (const item of items) {
|
|
86
|
-
this.trigger('add', item);
|
|
87
|
-
}
|
|
88
|
-
return num;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
splice(start: number, deleteCount?: number): T[] {
|
|
92
|
-
const removed: T[] = super.splice(start, deleteCount);
|
|
93
|
-
|
|
94
|
-
this.trigger('change', {
|
|
95
|
-
'removed': removed
|
|
96
|
-
});
|
|
97
|
-
for (const item of removed) {
|
|
98
|
-
this.trigger('remove', item);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return removed;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
get(key: string) {
|
|
105
|
-
const keys: string[] = [
|
|
106
|
-
'length'
|
|
107
|
-
];
|
|
108
|
-
return keys.indexOf(key) > -1 ? this[key] : undefined;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
get length(): number {
|
|
112
|
-
let c: number = 0;
|
|
113
|
-
for (const item of this) {
|
|
114
|
-
c += 1;
|
|
115
|
-
}
|
|
116
|
-
return c;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
set length(num: number) {
|
|
120
|
-
this.setLength(num);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
setLength(num: number) {
|
|
124
|
-
let c: number = 0;
|
|
125
|
-
const toRemove: T[] = [];
|
|
126
|
-
for (const item of this) {
|
|
127
|
-
c += 1;
|
|
128
|
-
if (c >= num) {
|
|
129
|
-
toRemove.push(item);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
for (const item of toRemove) {
|
|
134
|
-
this.splice(this.indexOf(item), 1);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
bind(event: string, fct: EventDispatcherCallback, context?: any, once?: boolean): number {
|
|
139
|
-
once = once || false;
|
|
140
|
-
this._lastKey++;
|
|
141
|
-
this._listeners[event] = this._listeners[event] || [];
|
|
142
|
-
this._listeners[event].push(new EventCallback(fct, this._lastKey, once, context));
|
|
143
|
-
return this._lastKey;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
once(event: string, fct: EventDispatcherCallback, context?: any): number {
|
|
147
|
-
return this.bind(event, fct, context, true);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
unbind(event: string, key?: number): boolean {
|
|
151
|
-
if(!(event in this._listeners)) return false;
|
|
152
|
-
if(key) {
|
|
153
|
-
for(const cb of this._listeners[event]) {
|
|
154
|
-
if(key == cb.key) {
|
|
155
|
-
this._listeners[event].splice(this._listeners[event].indexOf(cb), 1);
|
|
156
|
-
return true;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
} else {
|
|
160
|
-
this._listeners[event] = [];
|
|
161
|
-
return true;
|
|
162
|
-
}
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
unbindWithContext(event: string, context: any): number {
|
|
167
|
-
if(!(event in this._listeners)) return 0;
|
|
168
|
-
let toRemove: EventCallback[] = [],
|
|
169
|
-
cnt = 0;
|
|
170
|
-
|
|
171
|
-
for(const cb of this._listeners[event]) {
|
|
172
|
-
if(context == cb.context) {
|
|
173
|
-
toRemove.push(cb);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
for(const cb of toRemove) {
|
|
178
|
-
this._listeners[event].splice(this._listeners[event].indexOf(cb), 1);
|
|
179
|
-
cnt++;
|
|
180
|
-
}
|
|
181
|
-
return cnt;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
getListener(event: string, key: number): EventCallback | undefined {
|
|
185
|
-
for(const cb of this._listeners[event]) {
|
|
186
|
-
if(key == cb.key)
|
|
187
|
-
return cb;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
trigger(event: string, ...args: any[]): void {
|
|
192
|
-
if(!(event in this._listeners)) return;
|
|
193
|
-
|
|
194
|
-
for(let i = 0; i < this._listeners[event].length; i++) {
|
|
195
|
-
const cb: EventCallback = this._listeners[event][i];
|
|
196
|
-
|
|
197
|
-
// We need to unbind callbacks before they're called to prevent
|
|
198
|
-
// infinite loops if the event is somehow triggered within the
|
|
199
|
-
// callback
|
|
200
|
-
if(cb.once) {
|
|
201
|
-
this.unbind(event, cb.key);
|
|
202
|
-
i--;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
cb.call(args);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
8
|
|
|
210
9
|
export class Scope extends EventDispatcher {
|
|
211
10
|
public wrapped: any;
|
|
212
|
-
protected data:
|
|
213
|
-
protected types: {[key: string]: string;} = {};
|
|
11
|
+
protected data: ScopeData;
|
|
214
12
|
protected children: Scope[];
|
|
215
|
-
protected _keys: string[];
|
|
216
13
|
protected _parentScope: Scope;
|
|
217
14
|
|
|
218
15
|
constructor(
|
|
@@ -222,8 +19,8 @@ export class Scope extends EventDispatcher {
|
|
|
222
19
|
if (parent)
|
|
223
20
|
this.parentScope = parent;
|
|
224
21
|
this.children = [];
|
|
225
|
-
this.data = new
|
|
226
|
-
this.
|
|
22
|
+
this.data = new DynamicScopeData({});
|
|
23
|
+
this.data.addRelay(this);
|
|
227
24
|
}
|
|
228
25
|
|
|
229
26
|
public get parentScope(): Scope {
|
|
@@ -283,54 +80,30 @@ export class Scope extends EventDispatcher {
|
|
|
283
80
|
}
|
|
284
81
|
|
|
285
82
|
set(key: string, value: any) {
|
|
286
|
-
if (this.data
|
|
287
|
-
this.data.
|
|
288
|
-
|
|
289
|
-
if (typeof value === 'string') {
|
|
290
|
-
const valueType = this.getType(key);
|
|
291
|
-
const caster = Registry.instance.types.getSynchronous(valueType);
|
|
292
|
-
if (caster) {
|
|
293
|
-
value = caster(value);
|
|
294
|
-
}
|
|
83
|
+
if (!this.data.hasProperty(key))
|
|
84
|
+
this.data.createProperty(key);
|
|
295
85
|
|
|
296
|
-
|
|
297
|
-
value = null;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (this.data[key] !== value) {
|
|
302
|
-
const previousValue = this.data[key];
|
|
303
|
-
this.data[key] = value;
|
|
304
|
-
const event = {
|
|
305
|
-
value: value,
|
|
306
|
-
previousValue: previousValue,
|
|
307
|
-
key: key
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
this.trigger(`change:${key}`, event);
|
|
311
|
-
this.trigger('change', key, event);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
if (this._keys.indexOf(key) === -1)
|
|
315
|
-
this._keys.push(key);
|
|
86
|
+
this.data[key] = value;
|
|
316
87
|
}
|
|
317
88
|
|
|
318
89
|
get keys(): string[] {
|
|
319
|
-
return
|
|
90
|
+
return this.data.keys;
|
|
320
91
|
}
|
|
321
92
|
|
|
322
93
|
has(key: string): boolean {
|
|
323
|
-
return this.
|
|
94
|
+
return this.data.hasProperty(key);
|
|
324
95
|
}
|
|
325
96
|
|
|
326
97
|
setType(key: string, type: string) {
|
|
327
|
-
this.
|
|
98
|
+
const property = this.data.getProperty(key, true);
|
|
99
|
+
property.type = type;
|
|
328
100
|
if (this.has(key))
|
|
329
101
|
this.set(key, this.get(key));
|
|
330
102
|
}
|
|
331
103
|
|
|
332
104
|
getType(key: string): string {
|
|
333
|
-
|
|
105
|
+
const property = this.data.getProperty(key);
|
|
106
|
+
return property.type;
|
|
334
107
|
}
|
|
335
108
|
|
|
336
109
|
extend(data) {
|
|
@@ -340,7 +113,7 @@ export class Scope extends EventDispatcher {
|
|
|
340
113
|
}
|
|
341
114
|
|
|
342
115
|
clear() {
|
|
343
|
-
for (const key of this.
|
|
116
|
+
for (const key of this.data.keys) {
|
|
344
117
|
if (['function', 'object'].indexOf(typeof this.get(key)) > -1) continue;
|
|
345
118
|
this.set(key, null);
|
|
346
119
|
}
|
|
@@ -352,6 +125,17 @@ export class Scope extends EventDispatcher {
|
|
|
352
125
|
}
|
|
353
126
|
|
|
354
127
|
public wrap(toWrap: any, triggerUpdates: boolean = false, updateFromWrapped: boolean = true) {
|
|
128
|
+
if (toWrap instanceof ScopeData) {
|
|
129
|
+
if (this.data instanceof EventDispatcher) {
|
|
130
|
+
this.data.removeRelay(this);
|
|
131
|
+
this.data.deconstruct();
|
|
132
|
+
}
|
|
133
|
+
this.wrapped = toWrap;
|
|
134
|
+
this.data = toWrap;
|
|
135
|
+
this.data.addRelay(this);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
355
139
|
if (toWrap instanceof Scope)
|
|
356
140
|
toWrap = toWrap.data;
|
|
357
141
|
|
|
@@ -381,8 +165,8 @@ export class Scope extends EventDispatcher {
|
|
|
381
165
|
if (!(this.wrapped[field] instanceof WrappedArray)) {
|
|
382
166
|
this.wrapped[field] = new WrappedArray(...toWrap[field]);
|
|
383
167
|
}
|
|
384
|
-
this.wrapped[field].
|
|
385
|
-
this.
|
|
168
|
+
this.wrapped[field].on('change', (...args) => {
|
|
169
|
+
this.dispatch(`change:${field}`, ...args);
|
|
386
170
|
})
|
|
387
171
|
}
|
|
388
172
|
|
|
@@ -413,14 +197,14 @@ export class Scope extends EventDispatcher {
|
|
|
413
197
|
});
|
|
414
198
|
|
|
415
199
|
if (triggerUpdates)
|
|
416
|
-
this.
|
|
200
|
+
this.dispatch(`change:${field}`);
|
|
417
201
|
}
|
|
418
202
|
|
|
419
203
|
this.wrapped.get = this.get.bind(this);
|
|
420
204
|
this.wrapped.set = this.set.bind(this);
|
|
421
|
-
this.wrapped.
|
|
205
|
+
this.wrapped.on = this.on.bind(this);
|
|
422
206
|
this.wrapped.once = this.once.bind(this);
|
|
423
|
-
this.wrapped.
|
|
207
|
+
this.wrapped.off = this.off.bind(this);
|
|
424
208
|
}
|
|
425
209
|
|
|
426
210
|
public unwrap(): void {
|