vsn 0.1.110 → 0.1.112
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 +2 -0
- package/demo/examples/component-slots.html +12 -10
- package/demo/vsn.js +2 -2
- package/dist/AST/FunctionCallNode.js +54 -47
- package/dist/AST/FunctionCallNode.js.map +1 -1
- package/dist/AST/ScopeMemberNode.js +2 -0
- package/dist/AST/ScopeMemberNode.js.map +1 -1
- package/dist/Component.js +51 -30
- package/dist/Component.js.map +1 -1
- package/dist/Controller.d.ts +1 -2
- package/dist/Controller.js +7 -9
- package/dist/Controller.js.map +1 -1
- package/dist/DOM.js +1 -1
- package/dist/DOM.js.map +1 -1
- package/dist/Scope/ScopeDataAbstract.js +2 -1
- package/dist/Scope/ScopeDataAbstract.js.map +1 -1
- package/dist/Tag/SlottedTag.js +4 -13
- package/dist/Tag/SlottedTag.js.map +1 -1
- package/dist/Tag.js +13 -1
- package/dist/Tag.js.map +1 -1
- package/dist/attributes/Bind.d.ts +0 -1
- package/dist/attributes/Bind.js +3 -16
- package/dist/attributes/Bind.js.map +1 -1
- package/dist/attributes/ControllerAttribute.d.ts +0 -1
- package/dist/attributes/ControllerAttribute.js +13 -12
- package/dist/attributes/ControllerAttribute.js.map +1 -1
- package/dist/attributes/SetAttribute.d.ts +0 -1
- package/dist/attributes/SetAttribute.js +16 -27
- package/dist/attributes/SetAttribute.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/vsn.min.js +2 -2
- package/package.json +1 -1
- package/src/AST/FunctionCallNode.ts +5 -0
- package/src/AST/ScopeMemberNode.ts +2 -0
- package/src/Component.ts +22 -10
- package/src/Controller.ts +9 -8
- package/src/DOM.ts +2 -2
- package/src/Scope/ScopeDataAbstract.ts +4 -4
- package/src/Tag/SlottedTag.ts +1 -3
- package/src/Tag.ts +10 -1
- package/src/attributes/Bind.ts +2 -5
- package/src/attributes/ControllerAttribute.ts +10 -12
- package/src/attributes/SetAttribute.ts +1 -5
- package/src/version.ts +1 -1
- package/test/Controller.spec.ts +8 -5
package/package.json
CHANGED
|
@@ -29,8 +29,12 @@ export class FunctionCallNode<T = any> extends Node implements TreeNode {
|
|
|
29
29
|
// @todo: Need to rewrite/refactor this. It's a bit of a mess with element queries.
|
|
30
30
|
let tags: Tag[] = [];
|
|
31
31
|
let functionScope: Scope = scope;
|
|
32
|
+
let functionName: string = '';
|
|
33
|
+
let instanceOfScopeMemberNode = false;
|
|
32
34
|
if (this.fnc instanceof ScopeMemberNode) {
|
|
35
|
+
instanceOfScopeMemberNode = true
|
|
33
36
|
functionScope = await this.fnc.scope.evaluate(scope, dom, tag);
|
|
37
|
+
functionName = await this.fnc.name.evaluate(scope, dom, tag);
|
|
34
38
|
if (this.fnc.scope instanceof ElementQueryNode) {
|
|
35
39
|
const _tags = await this.fnc.scope.evaluate(scope, dom, tag);
|
|
36
40
|
if (_tags instanceof Array) {
|
|
@@ -47,6 +51,7 @@ export class FunctionCallNode<T = any> extends Node implements TreeNode {
|
|
|
47
51
|
|
|
48
52
|
const values = await this.args.evaluate(scope, dom, tag);
|
|
49
53
|
let func = await this.fnc.evaluate(scope, dom, tag);
|
|
54
|
+
console.log(tag?.element, functionName, func, scope.keys, functionScope?.keys, instanceOfScopeMemberNode);
|
|
50
55
|
if (!func || func instanceof Array) {
|
|
51
56
|
const functionName = await (this.fnc as any).name.evaluate(scope, dom, tag);
|
|
52
57
|
const returnValues = [];
|
|
@@ -51,6 +51,8 @@ export class ScopeMemberNode extends ScopeNodeAbstract implements TreeNode {
|
|
|
51
51
|
}
|
|
52
52
|
const name = await this.name.evaluate(scope, dom, tag);
|
|
53
53
|
await this.applyModifiers(name, parent, dom, tag);
|
|
54
|
+
if (!parent.get)
|
|
55
|
+
console.log('nani?', parent);
|
|
54
56
|
const value: any = parent.get(name, false);
|
|
55
57
|
values.push(value instanceof Scope && value.wrapped || value);
|
|
56
58
|
}
|
package/src/Component.ts
CHANGED
|
@@ -25,17 +25,29 @@ export class Component extends HTMLElement {
|
|
|
25
25
|
for (const child of Array.from(this.shadow.children)) {
|
|
26
26
|
child['shadowParent'] = this;
|
|
27
27
|
}
|
|
28
|
+
const slotPromises = [];
|
|
29
|
+
const tagsToSetup = [];
|
|
28
30
|
this.shadow.querySelectorAll('slot').forEach((slot) => {
|
|
29
31
|
const slotTagPromise = DOM.instance.buildTag(slot,false, SlotTag);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
const promise = new Promise<SlotTag>((resolve, reject) => {
|
|
33
|
+
slot.addEventListener('slotchange', (e) => {
|
|
34
|
+
slotTagPromise.then(async (slotTag) => {
|
|
35
|
+
|
|
36
|
+
for (const child of slot.assignedNodes()) {
|
|
37
|
+
const t = await DOM.instance.buildTag<SlottedTag>(child as HTMLElement, false, SlottedTag);
|
|
38
|
+
await t?.slotted(slotTag);
|
|
39
|
+
tagsToSetup.push(t);
|
|
40
|
+
}
|
|
41
|
+
resolve(slotTag);
|
|
42
|
+
});
|
|
37
43
|
});
|
|
38
|
-
})
|
|
44
|
+
})
|
|
45
|
+
slotPromises.push(promise);
|
|
46
|
+
});
|
|
47
|
+
Promise.all(slotPromises).then(async (slotTags: SlotTag[]) => {
|
|
48
|
+
await DOM.instance.buildFrom(this, false, true);
|
|
49
|
+
await DOM.instance.setupTags(slotTags);
|
|
50
|
+
await DOM.instance.setupTags(tagsToSetup);
|
|
39
51
|
});
|
|
40
52
|
}
|
|
41
53
|
|
|
@@ -43,7 +55,7 @@ export class Component extends HTMLElement {
|
|
|
43
55
|
const tag = await DOM.instance.buildTag(this, true);
|
|
44
56
|
tag.createScope(true);
|
|
45
57
|
await DOM.instance.buildFrom(this.shadow);
|
|
46
|
-
await
|
|
47
|
-
await
|
|
58
|
+
await tag.dom.resetBranch(tag);
|
|
59
|
+
await tag.dom.setupTags([tag]);
|
|
48
60
|
}
|
|
49
61
|
}
|
package/src/Controller.ts
CHANGED
|
@@ -7,6 +7,15 @@ export abstract class Controller extends ScopeData {
|
|
|
7
7
|
protected _tag: Tag;
|
|
8
8
|
protected _element: HTMLElement;
|
|
9
9
|
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
for (const k in this) {
|
|
13
|
+
if (this[k] as any instanceof Function) {
|
|
14
|
+
this.__properties__.push(k);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
10
19
|
public get scope(): Scope {
|
|
11
20
|
return this._scope;
|
|
12
21
|
}
|
|
@@ -24,12 +33,4 @@ export abstract class Controller extends ScopeData {
|
|
|
24
33
|
this._tag = tag;
|
|
25
34
|
this._element = element;
|
|
26
35
|
}
|
|
27
|
-
|
|
28
|
-
public get(key: string): any {
|
|
29
|
-
return this._scope?.get(key);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
public set(key: string, value: any): void {
|
|
33
|
-
this._scope?.set(key, value);
|
|
34
|
-
}
|
|
35
36
|
}
|
package/src/DOM.ts
CHANGED
|
@@ -298,7 +298,7 @@ export class DOM extends EventDispatcher {
|
|
|
298
298
|
newTags.push(tag);
|
|
299
299
|
}
|
|
300
300
|
|
|
301
|
-
|
|
301
|
+
await this.setupTags(newTags);
|
|
302
302
|
|
|
303
303
|
if (isRoot) {
|
|
304
304
|
this._built = true;
|
|
@@ -352,7 +352,7 @@ export class DOM extends EventDispatcher {
|
|
|
352
352
|
|
|
353
353
|
async getTagForScope(scope: Scope) {
|
|
354
354
|
for (const tag of this.tags) {
|
|
355
|
-
if (tag.scope === scope)
|
|
355
|
+
if (tag.uniqueScope && tag.scope === scope)
|
|
356
356
|
return tag;
|
|
357
357
|
}
|
|
358
358
|
|
|
@@ -23,8 +23,8 @@ export class ScopeDataAbstract extends EventDispatcher {
|
|
|
23
23
|
return this.getProperty(name);
|
|
24
24
|
}
|
|
25
25
|
config = config || {};
|
|
26
|
-
const instance = new propertyType(config.default, config)
|
|
27
|
-
|
|
26
|
+
const instance = new propertyType(config.default, config);
|
|
27
|
+
const propDesc = Object.getOwnPropertyDescriptor(this, name);
|
|
28
28
|
this['__'+name] = instance;
|
|
29
29
|
this.__properties__.push(name);
|
|
30
30
|
|
|
@@ -101,11 +101,11 @@ export class ScopeDataAbstract extends EventDispatcher {
|
|
|
101
101
|
return data;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
get(key: string) {
|
|
104
|
+
public get(key: string) {
|
|
105
105
|
return this[key];
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
set(key: string, value: any) {
|
|
108
|
+
public set(key: string, value: any) {
|
|
109
109
|
this[key] = value;
|
|
110
110
|
}
|
|
111
111
|
|
package/src/Tag/SlottedTag.ts
CHANGED
|
@@ -7,9 +7,7 @@ export class SlottedTag extends Tag {
|
|
|
7
7
|
public async slotted(slot: SlotTag) {
|
|
8
8
|
this.slotTag = slot;
|
|
9
9
|
this.slot = slot.element as HTMLSlotElement;
|
|
10
|
-
this.
|
|
11
|
-
await this.dom.setupTags([this]);
|
|
12
|
-
await this.dom.buildFrom(this.element, false, true);
|
|
10
|
+
this.findParentTag();
|
|
13
11
|
}
|
|
14
12
|
|
|
15
13
|
findParentTag(): Tag {
|
package/src/Tag.ts
CHANGED
|
@@ -38,7 +38,8 @@ export class Tag extends DOMObject {
|
|
|
38
38
|
'@text',
|
|
39
39
|
'@html',
|
|
40
40
|
'@class',
|
|
41
|
-
'@value'
|
|
41
|
+
'@value',
|
|
42
|
+
'@disabled'
|
|
42
43
|
];
|
|
43
44
|
|
|
44
45
|
protected inputTags: string[] = [
|
|
@@ -395,6 +396,12 @@ export class Tag extends DOMObject {
|
|
|
395
396
|
const classes: string[] = value instanceof Array ? value : [value];
|
|
396
397
|
if (classes.length)
|
|
397
398
|
this.element.classList.add(...classes);
|
|
399
|
+
} else if (key === '@disabled') {
|
|
400
|
+
if (!!value) {
|
|
401
|
+
this.element.setAttribute('disabled', '');
|
|
402
|
+
} else {
|
|
403
|
+
this.element.removeAttribute('disabled');
|
|
404
|
+
}
|
|
398
405
|
}
|
|
399
406
|
} else {
|
|
400
407
|
this.element.setAttribute(key, value);
|
|
@@ -411,6 +418,8 @@ export class Tag extends DOMObject {
|
|
|
411
418
|
return this.value;
|
|
412
419
|
else if (key === '@class') {
|
|
413
420
|
return Array.from(this.element.classList);
|
|
421
|
+
} else if (key === '@disabled') {
|
|
422
|
+
return this.element.hasAttribute('disabled');
|
|
414
423
|
}
|
|
415
424
|
}
|
|
416
425
|
return this.element.getAttribute(key);
|
package/src/attributes/Bind.ts
CHANGED
|
@@ -16,6 +16,7 @@ export class Bind extends Attribute {
|
|
|
16
16
|
public async compile() {
|
|
17
17
|
const tree: Tree = new Tree(this.getAttributeValue());
|
|
18
18
|
await tree.prepare(this.tag.scope, this.tag.dom, this.tag);
|
|
19
|
+
|
|
19
20
|
await super.compile();
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -32,7 +33,7 @@ export class Bind extends Attribute {
|
|
|
32
33
|
await super.setup();
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
public async
|
|
36
|
+
public async connect() {
|
|
36
37
|
let scopeKey: string = this.getAttributeValue();
|
|
37
38
|
let ref: ScopeReference;
|
|
38
39
|
try {
|
|
@@ -47,10 +48,6 @@ export class Bind extends Attribute {
|
|
|
47
48
|
if (!!this.valueFromElement)
|
|
48
49
|
this.updateFrom();
|
|
49
50
|
|
|
50
|
-
await super.extract();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public async connect() {
|
|
54
51
|
if (this.doUpdateTo) {
|
|
55
52
|
this.updateTo();
|
|
56
53
|
this.boundScope.on(`change:${this.key}`, this.updateTo, this);
|
|
@@ -1,34 +1,32 @@
|
|
|
1
1
|
import {Scope} from "../Scope";
|
|
2
2
|
import {Attribute} from "../Attribute";
|
|
3
3
|
import {Registry} from "../Registry";
|
|
4
|
+
import {Controller} from "../Controller";
|
|
4
5
|
|
|
5
6
|
@Registry.attribute('vsn-controller')
|
|
6
7
|
export class ControllerAttribute extends Attribute {
|
|
7
8
|
public static readonly canDefer: boolean = false;
|
|
8
9
|
public static readonly scoped: boolean = true;
|
|
9
10
|
public readonly registryName: string = 'controllers'
|
|
10
|
-
public readonly assignToParent: boolean = true;
|
|
11
11
|
protected attributeKey: string;
|
|
12
12
|
protected className: string;
|
|
13
13
|
protected defaultClassName: string;
|
|
14
14
|
|
|
15
15
|
public async setup() {
|
|
16
|
-
const parentScope: Scope = this.tag.parentTag.scope;
|
|
17
|
-
if (!parentScope)
|
|
18
|
-
return;
|
|
19
|
-
|
|
20
16
|
this.attributeKey = this.getAttributeBinding();
|
|
21
17
|
this.className = this.getAttributeValue(this.defaultClassName);
|
|
22
|
-
|
|
23
18
|
const cls = await Registry.instance[this.registryName].get(this.className);
|
|
24
|
-
const obj = this.instantiateClass(cls);
|
|
25
19
|
|
|
26
|
-
if (this.attributeKey
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this.tag.scope
|
|
20
|
+
if (this.attributeKey) {
|
|
21
|
+
const controllerScope = new Scope(this.tag.scope);
|
|
22
|
+
const obj = new cls();
|
|
23
|
+
if (obj instanceof Controller) {
|
|
24
|
+
obj.init(this.tag.scope, this.tag, this.tag.element);
|
|
31
25
|
}
|
|
26
|
+
controllerScope.wrap(obj);
|
|
27
|
+
this.tag.scope.set(this.attributeKey, controllerScope);
|
|
28
|
+
} else {
|
|
29
|
+
this.instantiateClass(cls);
|
|
32
30
|
}
|
|
33
31
|
await super.setup();
|
|
34
32
|
}
|
|
@@ -21,7 +21,7 @@ export class SetAttribute extends Attribute {
|
|
|
21
21
|
return this.boundScope.get(this.key, false);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
public async
|
|
24
|
+
public async extract() {
|
|
25
25
|
this.property = this.getAttributeBinding();
|
|
26
26
|
let ref: ScopeReference;
|
|
27
27
|
try {
|
|
@@ -31,10 +31,6 @@ export class SetAttribute extends Attribute {
|
|
|
31
31
|
}
|
|
32
32
|
this.key = await ref.getKey();
|
|
33
33
|
this.boundScope = await ref.getScope();
|
|
34
|
-
await super.setup();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
public async extract() {
|
|
38
34
|
let value = this.getAttributeValue(null);
|
|
39
35
|
for (const m of this.getAttributeModifiers()) {
|
|
40
36
|
const t = Registry.instance.types.getSynchronous(m);
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '0.1.
|
|
1
|
+
export const VERSION = '0.1.112';
|
|
2
2
|
|
package/test/Controller.spec.ts
CHANGED
|
@@ -28,15 +28,18 @@ class TestController extends Controller {
|
|
|
28
28
|
describe('Controller', () => {
|
|
29
29
|
it("methods should be callable from vsn-script", async () => {
|
|
30
30
|
document.body.innerHTML = `
|
|
31
|
-
<div vsn-controller:test="ControllerTestController" vsn-set:test.test="notTest" vsn-bind="test.test"></div>
|
|
31
|
+
<div id="controller" vsn-controller:test="ControllerTestController" vsn-set:test.test="notTest" vsn-bind="test.test"></div>
|
|
32
32
|
`;
|
|
33
33
|
const dom = new DOM(document);
|
|
34
34
|
const deferred = SimplePromise.defer();
|
|
35
35
|
dom.once('built', async () => {
|
|
36
|
-
|
|
37
|
-
expect(
|
|
38
|
-
|
|
39
|
-
expect(await
|
|
36
|
+
const tag = await dom.exec('#controller');
|
|
37
|
+
expect(tag.scope.keys).toEqual(['test']);
|
|
38
|
+
expect(tag.scope.get('test').wrapped).toBeInstanceOf(TestController);
|
|
39
|
+
expect(await tag.exec('test.isValid()')).toBe(false);
|
|
40
|
+
expect(await tag.exec('test.test')).toBe('notTest');
|
|
41
|
+
await tag.exec('test.test = "test"');
|
|
42
|
+
expect(await tag.exec('test.isValid()')).toBe(true);
|
|
40
43
|
deferred.resolve();
|
|
41
44
|
});
|
|
42
45
|
await deferred.promise;
|