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.
Files changed (46) hide show
  1. package/demo/demo.html +2 -0
  2. package/demo/examples/component-slots.html +12 -10
  3. package/demo/vsn.js +2 -2
  4. package/dist/AST/FunctionCallNode.js +54 -47
  5. package/dist/AST/FunctionCallNode.js.map +1 -1
  6. package/dist/AST/ScopeMemberNode.js +2 -0
  7. package/dist/AST/ScopeMemberNode.js.map +1 -1
  8. package/dist/Component.js +51 -30
  9. package/dist/Component.js.map +1 -1
  10. package/dist/Controller.d.ts +1 -2
  11. package/dist/Controller.js +7 -9
  12. package/dist/Controller.js.map +1 -1
  13. package/dist/DOM.js +1 -1
  14. package/dist/DOM.js.map +1 -1
  15. package/dist/Scope/ScopeDataAbstract.js +2 -1
  16. package/dist/Scope/ScopeDataAbstract.js.map +1 -1
  17. package/dist/Tag/SlottedTag.js +4 -13
  18. package/dist/Tag/SlottedTag.js.map +1 -1
  19. package/dist/Tag.js +13 -1
  20. package/dist/Tag.js.map +1 -1
  21. package/dist/attributes/Bind.d.ts +0 -1
  22. package/dist/attributes/Bind.js +3 -16
  23. package/dist/attributes/Bind.js.map +1 -1
  24. package/dist/attributes/ControllerAttribute.d.ts +0 -1
  25. package/dist/attributes/ControllerAttribute.js +13 -12
  26. package/dist/attributes/ControllerAttribute.js.map +1 -1
  27. package/dist/attributes/SetAttribute.d.ts +0 -1
  28. package/dist/attributes/SetAttribute.js +16 -27
  29. package/dist/attributes/SetAttribute.js.map +1 -1
  30. package/dist/version.d.ts +1 -1
  31. package/dist/version.js +1 -1
  32. package/dist/vsn.min.js +2 -2
  33. package/package.json +1 -1
  34. package/src/AST/FunctionCallNode.ts +5 -0
  35. package/src/AST/ScopeMemberNode.ts +2 -0
  36. package/src/Component.ts +22 -10
  37. package/src/Controller.ts +9 -8
  38. package/src/DOM.ts +2 -2
  39. package/src/Scope/ScopeDataAbstract.ts +4 -4
  40. package/src/Tag/SlottedTag.ts +1 -3
  41. package/src/Tag.ts +10 -1
  42. package/src/attributes/Bind.ts +2 -5
  43. package/src/attributes/ControllerAttribute.ts +10 -12
  44. package/src/attributes/SetAttribute.ts +1 -5
  45. package/src/version.ts +1 -1
  46. package/test/Controller.spec.ts +8 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vsn",
3
- "version": "0.1.110",
3
+ "version": "0.1.112",
4
4
  "description": "SEO Friendly Javascript/Typescript Framework",
5
5
  "keywords": [
6
6
  "framework",
@@ -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
- slot.addEventListener('slotchange', (e) => {
31
- slotTagPromise.then(async (slotTag) => {
32
- for (const child of slot.assignedNodes()) {
33
- const t = await DOM.instance.buildTag<SlottedTag>(child as HTMLElement, false, SlottedTag);
34
- await t?.slotted(slotTag);
35
- }
36
- await DOM.instance.setupTags([slotTag]);
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 DOM.instance.resetBranch(tag);
47
- await DOM.instance.setupTags([tag]);
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
- await this.setupTags(newTags);
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
- propDesc = Object.getOwnPropertyDescriptor(this, name);
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
 
@@ -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.parentTag = slot;
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);
@@ -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 extract() {
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 && obj) {
27
- if (this.assignToParent && parentScope) {
28
- parentScope.set(this.attributeKey, obj);
29
- } else {
30
- this.tag.scope.set(this.attributeKey, obj);
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 setup() {
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.110';
1
+ export const VERSION = '0.1.112';
2
2
 
@@ -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
- expect(await dom.exec('test.test')).toBe('notTest');
37
- expect(await dom.exec('test.isValid()')).toBe(false);
38
- await dom.exec('test.test = "test"');
39
- expect(await dom.exec('test.isValid()')).toBe(true);
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;