vsn 0.1.75 → 0.1.78

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 (65) hide show
  1. package/demo/vsn.js +3 -2
  2. package/dist/AST/ClassNode.d.ts +2 -2
  3. package/dist/AST/ClassNode.js +23 -18
  4. package/dist/AST/ClassNode.js.map +1 -1
  5. package/dist/Attribute.d.ts +5 -2
  6. package/dist/Attribute.js +39 -8
  7. package/dist/Attribute.js.map +1 -1
  8. package/dist/Component.d.ts +4 -0
  9. package/dist/Component.js +42 -0
  10. package/dist/Component.js.map +1 -0
  11. package/dist/DOM/DOMObject.d.ts +3 -0
  12. package/dist/DOM/DOMObject.js +14 -0
  13. package/dist/DOM/DOMObject.js.map +1 -1
  14. package/dist/DOM.d.ts +2 -0
  15. package/dist/DOM.js +36 -28
  16. package/dist/DOM.js.map +1 -1
  17. package/dist/Registry.d.ts +4 -2
  18. package/dist/Registry.js +6 -0
  19. package/dist/Registry.js.map +1 -1
  20. package/dist/Tag.d.ts +4 -2
  21. package/dist/Tag.js +163 -99
  22. package/dist/Tag.js.map +1 -1
  23. package/dist/attributes/ComponentAttribute.d.ts +5 -0
  24. package/dist/attributes/ComponentAttribute.js +105 -0
  25. package/dist/attributes/ComponentAttribute.js.map +1 -0
  26. package/dist/attributes/ListItem.d.ts +0 -1
  27. package/dist/attributes/ListItem.js +0 -7
  28. package/dist/attributes/ListItem.js.map +1 -1
  29. package/dist/attributes/RootAttribute.js.map +1 -1
  30. package/dist/attributes/TemplateAttribute.d.ts +5 -0
  31. package/dist/attributes/TemplateAttribute.js +89 -0
  32. package/dist/attributes/TemplateAttribute.js.map +1 -0
  33. package/dist/attributes/_imports.d.ts +2 -1
  34. package/dist/attributes/_imports.js +5 -3
  35. package/dist/attributes/_imports.js.map +1 -1
  36. package/dist/custom-elements.d.ts +9 -0
  37. package/dist/custom-elements.js +44 -0
  38. package/dist/custom-elements.js.map +1 -0
  39. package/dist/version.d.ts +1 -1
  40. package/dist/version.js +1 -1
  41. package/dist/vsn.d.ts +2 -0
  42. package/dist/vsn.js +5 -0
  43. package/dist/vsn.js.map +1 -1
  44. package/dist/vsn.min.js +3 -0
  45. package/dist/vsn.min.js.LICENSE.txt +9 -0
  46. package/package.json +1 -1
  47. package/src/AST/ClassNode.ts +12 -9
  48. package/src/Attribute.ts +19 -8
  49. package/src/Component.ts +24 -0
  50. package/src/DOM/DOMObject.ts +11 -0
  51. package/src/DOM.ts +19 -11
  52. package/src/Registry.ts +9 -3
  53. package/src/Tag.ts +70 -50
  54. package/src/attributes/ComponentAttribute.ts +24 -0
  55. package/src/attributes/ListItem.ts +0 -4
  56. package/src/attributes/RootAttribute.ts +0 -1
  57. package/src/attributes/TemplateAttribute.ts +12 -0
  58. package/src/attributes/_imports.ts +2 -1
  59. package/src/custom-elements.ts +46 -0
  60. package/src/version.ts +1 -1
  61. package/src/vsn.ts +6 -0
  62. package/dist/attributes/Template.d.ts +0 -4
  63. package/dist/attributes/Template.js +0 -39
  64. package/dist/attributes/Template.js.map +0 -1
  65. package/src/attributes/Template.ts +0 -7
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
4
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7
+ * Code distributed by Google as part of the polymer project is also
8
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9
+ */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vsn",
3
- "version": "0.1.75",
3
+ "version": "0.1.78",
4
4
  "description": "SEO Friendly Javascript/Typescript Framework",
5
5
  "keywords": [
6
6
  "framework",
@@ -66,7 +66,10 @@ export class ClassNode extends Node implements TreeNode {
66
66
  Registry.class(this);
67
67
 
68
68
  if (root) {
69
- await this.findClassElements(dom);
69
+ if (dom.built)
70
+ await this.findClassElements(dom);
71
+ else
72
+ dom.once('builtRoot', () => this.findClassElements(dom));
70
73
  }
71
74
  } else {
72
75
  await this.block.prepare(this.classScope, dom, tag, meta);
@@ -84,14 +87,14 @@ export class ClassNode extends Node implements TreeNode {
84
87
  }
85
88
  }
86
89
 
87
- public async constructTag(tag: Tag, dom: DOM, hasConstructor: boolean | null = null) {
88
- if (hasConstructor === null)
89
- hasConstructor = this.classScope.has('construct');
90
+ public async constructTag(tag: Tag, dom: DOM, hasConstruct: boolean | null = null) {
91
+ if (hasConstruct === null)
92
+ hasConstruct = this.classScope.has('construct');
90
93
 
91
94
  tag.createScope(true);
92
95
  const meta = this.updateMeta();
93
96
  await this.block.prepare(tag.scope, dom, tag, meta);
94
- if (hasConstructor) {
97
+ if (hasConstruct) {
95
98
  const fncCls: FunctionNode = this.classScope.get('construct') as FunctionNode;
96
99
  const fnc = await fncCls.getFunction(tag.scope, dom, tag, false);
97
100
  await fnc();
@@ -101,11 +104,11 @@ export class ClassNode extends Node implements TreeNode {
101
104
  ClassNode.addPreparedClassToElement(tag.element, this.fullSelector);
102
105
  }
103
106
 
104
- public async deconstructTag(tag: Tag, dom: DOM, hasDeconstructor: boolean | null = null) {
105
- if (hasDeconstructor === null)
106
- hasDeconstructor = this.classScope.has('deconstruct');
107
+ public async deconstructTag(tag: Tag, dom: DOM, hasDeconstruct: boolean | null = null) {
108
+ if (hasDeconstruct === null)
109
+ hasDeconstruct = this.classScope.has('deconstruct');
107
110
 
108
- if (hasDeconstructor) {
111
+ if (hasDeconstruct) {
109
112
  const fncCls: FunctionNode = this.classScope.get('deconstruct') as FunctionNode;
110
113
  const fnc = await fncCls.getFunction(tag.scope, dom, tag, false);
111
114
  await fnc();
package/src/Attribute.ts CHANGED
@@ -19,13 +19,18 @@ export abstract class Attribute extends EventDispatcher {
19
19
 
20
20
  constructor(
21
21
  public readonly tag: Tag,
22
- public readonly attributeName: string
22
+ public readonly attributeName: string,
23
+ public readonly slot?: Tag
23
24
  ) {
24
25
  super();
25
26
  this.configure();
26
27
  if (VisionHelper.window) VisionHelper.window['Attributes'].push(this);
27
28
  }
28
29
 
30
+ public get origin(): Tag {
31
+ return this.slot || this.tag;
32
+ }
33
+
29
34
  public get state(): AttributeState {
30
35
  return this._state;
31
36
  }
@@ -54,15 +59,15 @@ export abstract class Attribute extends EventDispatcher {
54
59
  };
55
60
 
56
61
  public getAttributeValue(fallback: any = null) {
57
- return this.tag.getRawAttributeValue(this.attributeName, fallback);
62
+ return this.origin.getRawAttributeValue(this.attributeName, fallback);
58
63
  }
59
64
 
60
65
  public getAttributeBinding(fallback: any = null): string {
61
- return this.tag.getAttributeBinding(this.attributeName) || fallback;
66
+ return this.origin.getAttributeBinding(this.attributeName) || fallback;
62
67
  }
63
68
 
64
69
  public getAttributeModifiers(fallback: any = []): string[] {
65
- const modifiers = this.tag.getAttributeModifiers(this.attributeName);
70
+ const modifiers = this.origin.getAttributeModifiers(this.attributeName);
66
71
  return modifiers.length && modifiers || fallback;
67
72
  }
68
73
 
@@ -73,11 +78,17 @@ export abstract class Attribute extends EventDispatcher {
73
78
  public mutate(mutation: MutationRecord): void {}
74
79
 
75
80
  public set value(value: string) {
76
- this.tag.element.setAttribute(this.attributeName, value);
81
+ this.origin.element.setAttribute(this.attributeName, value);
77
82
  }
78
83
 
79
84
  public get value(): string {
80
- return this.tag.element.getAttribute(this.attributeName) || '';
85
+ return this.origin.element.getAttribute(this.attributeName) || '';
86
+ }
87
+
88
+ public async apply(fnc: Function) {
89
+ for (const element of this.origin.delegates) {
90
+ await fnc(element);
91
+ }
81
92
  }
82
93
 
83
94
  private setState(state: AttributeState) {
@@ -90,7 +101,7 @@ export abstract class Attribute extends EventDispatcher {
90
101
  });
91
102
  }
92
103
 
93
- public static create(tag: Tag, attributeName: string, cls: any): Attribute {
94
- return new cls(tag, attributeName);
104
+ public static create(tag: Tag, attributeName: string, cls: any, slot?: Tag): Attribute {
105
+ return new cls(tag, attributeName, slot);
95
106
  }
96
107
  }
@@ -0,0 +1,24 @@
1
+ import {Registry} from "./Registry";
2
+ import {DOM} from "./DOM";
3
+
4
+ export class Component extends HTMLElement {
5
+ protected readonly shadow: ShadowRoot;
6
+
7
+ constructor() {
8
+ super();
9
+ Object.setPrototypeOf(this, Component.prototype);
10
+
11
+ this.shadow = this.attachShadow({mode: 'open'});
12
+ const templateId = this.getAttribute('template');
13
+ let template: HTMLTemplateElement;
14
+
15
+ if (templateId) {
16
+ template = document.getElementById(templateId) as HTMLTemplateElement;
17
+ } else {
18
+ template = Registry.instance.templates.getSynchronous(this.tagName.toLowerCase());
19
+ }
20
+
21
+ this.shadow.appendChild(template.content.cloneNode(true));
22
+ DOM.instance.buildFrom(this.shadow);
23
+ }
24
+ }
@@ -11,12 +11,23 @@ export abstract class DOMObject extends EventDispatcher {
11
11
  protected _scope: Scope;
12
12
  protected onEventHandlers: {[key:string]: IEventHandler[]};
13
13
  protected _uniqueScope: boolean = false;
14
+ protected slot: HTMLSlotElement;
15
+ public readonly delegates: HTMLElement[] = [];
14
16
 
15
17
  constructor(
16
18
  public readonly element: HTMLElement,
17
19
  props
18
20
  ) {
19
21
  super();
22
+ if (this.isSlot) {
23
+ this.delegates.push(...(element as HTMLSlotElement).assignedNodes() as HTMLElement[]);
24
+ }
25
+ if (element.assignedSlot)
26
+ this.slot = element.assignedSlot;
27
+ }
28
+
29
+ public get isSlot(): boolean {
30
+ return this.element instanceof HTMLSlotElement;
20
31
  }
21
32
 
22
33
  public get scope(): Scope {
package/src/DOM.ts CHANGED
@@ -8,6 +8,7 @@ import {WrappedDocument} from "./DOM/WrappedDocument";
8
8
  import {Scope} from "./Scope";
9
9
  import {EventDispatcher} from "./EventDispatcher";
10
10
  import {ClassNode} from "./AST/ClassNode";
11
+ import {Registry} from "./Registry";
11
12
 
12
13
  export enum EQuerySelectDirection {
13
14
  ALL,
@@ -25,6 +26,7 @@ export class DOM extends EventDispatcher {
25
26
  protected queued: HTMLElement[] = [];
26
27
  protected window: WrappedWindow;
27
28
  protected document: WrappedDocument;
29
+ protected _built: boolean = false;
28
30
  public selected: Tag;
29
31
 
30
32
  constructor(
@@ -52,12 +54,16 @@ export class DOM extends EventDispatcher {
52
54
  Configuration.instance.on('change', this.evaluate.bind(this));
53
55
  }
54
56
 
57
+ public get built(): boolean {
58
+ return this._built;
59
+ }
60
+
55
61
  public get root(): Tag {
56
62
  return this._root;
57
63
  }
58
64
 
59
65
  public get ready(): Promise<boolean> {
60
- return
66
+ return this.promise('builtRoot');
61
67
  }
62
68
 
63
69
  public async get(selector: string, create: boolean = false, tag: Tag = null, direction: EQuerySelectDirection = EQuerySelectDirection.DOWN): Promise<TagList> {
@@ -235,17 +241,21 @@ export class DOM extends EventDispatcher {
235
241
  await ClassNode.checkForClassChanges(tag.element, this, tag);
236
242
  }
237
243
 
238
- this.dispatch('built');
244
+ if (isRoot) {
245
+ this._built = true;
246
+ this.dispatch('builtRoot')
247
+ }
248
+ this.dispatch('built', newTags);
239
249
  }
240
250
 
241
251
  async getTagsForElements(elements: Element[], create: boolean = false) {
242
252
  const tags: TagList = new TagList();
243
253
  const found: Element[] = [];
244
- for (const tag of this.tags)
245
- {
246
- if (!found.includes(tag.element) && elements.indexOf(tag.element) > -1) {
247
- tags.push(tag);
248
- found.push(tag.element);
254
+
255
+ for (const element of elements) {
256
+ if (element[Tag.TaggedVariable]) {
257
+ tags.push(element[Tag.TaggedVariable]);
258
+ found.push(element);
249
259
  }
250
260
  }
251
261
 
@@ -267,10 +277,8 @@ export class DOM extends EventDispatcher {
267
277
  }
268
278
 
269
279
  async getTagForElement(element: Element, create: boolean = false) {
270
- for (const tag of this.tags) {
271
- if (tag.element === element)
272
- return tag;
273
- }
280
+ if (element[Tag.TaggedVariable])
281
+ return element[Tag.TaggedVariable];
274
282
 
275
283
  if (element && create) {
276
284
  if (element instanceof HTMLElement)
package/src/Registry.ts CHANGED
@@ -13,9 +13,9 @@ export function register(store: string, key: string = null, setup: () => void =
13
13
  }
14
14
  }
15
15
 
16
- export class RegistryStore extends EventDispatcher {
16
+ export class RegistryStore<T = any> extends EventDispatcher {
17
17
  private timeouts = {};
18
- private readonly store: {[key: string]: any};
18
+ private readonly store: {[key: string]: T};
19
19
 
20
20
  constructor(defaults = null) {
21
21
  super();
@@ -62,6 +62,7 @@ export class RegistryStore extends EventDispatcher {
62
62
 
63
63
  export class Registry extends EventDispatcher {
64
64
  protected static _instance: Registry;
65
+ public readonly components: RegistryStore;
65
66
  public readonly functions: RegistryStore;
66
67
  public readonly controllers: RegistryStore;
67
68
  public readonly classes: RegistryStore;
@@ -74,17 +75,22 @@ export class Registry extends EventDispatcher {
74
75
 
75
76
  constructor() {
76
77
  super();
78
+ this.components = new RegistryStore();
77
79
  this.functions = new RegistryStore();
78
80
  this.controllers = new RegistryStore();
79
81
  this.classes = new RegistryStore();
80
82
  this.models = new RegistryStore();
81
- this.templates = new RegistryStore();
83
+ this.templates = new RegistryStore<HTMLTemplateElement>();
82
84
  this.types = new RegistryStore();
83
85
  this.validators = new RegistryStore();
84
86
  this.formats = new RegistryStore();
85
87
  this.attributes = new RegistryStore();
86
88
  }
87
89
 
90
+ public static component(key: string = null, setup = null) {
91
+ return register('components', key, setup);
92
+ }
93
+
88
94
  public static function(key: string = null, setup = null) {
89
95
  return register('functions', key, setup);
90
96
  }
package/src/Tag.ts CHANGED
@@ -6,7 +6,6 @@ import {VisionHelper} from "./helpers/VisionHelper";
6
6
  import {StandardAttribute} from "./attributes/StandardAttribute";
7
7
  import {On} from "./attributes/On";
8
8
  import {Registry} from "./Registry";
9
- import {benchmarkEnd, benchmarkStart} from "./Bencmark";
10
9
  import {DOMObject} from "./DOM/DOMObject";
11
10
  import {Tree} from "./AST";
12
11
  import {StyleAttribute} from "./attributes/StyleAttribute";
@@ -73,10 +72,14 @@ export class Tag extends DOMObject {
73
72
  }
74
73
 
75
74
  protected onAttributeStateChange(event) {
76
- if (event.previouseState === AttributeState.Deferred)
75
+ if (event.previouseState === AttributeState.Deferred) // @todo: what is this?
77
76
  this._nonDeferredAttributes.length = 0;
78
77
  }
79
78
 
79
+ public getAttributesWithState(state: AttributeState): Attribute[] {
80
+ return this.attributes.filter(attr => attr.state === state);
81
+ }
82
+
80
83
  public get nonDeferredAttributes(): Attribute[] {
81
84
  if (this._nonDeferredAttributes.length > 0)
82
85
  return this._nonDeferredAttributes;
@@ -408,6 +411,14 @@ export class Tag extends DOMObject {
408
411
  return this.parsedAttributes[key] && this.parsedAttributes[key][index] || fallback;
409
412
  }
410
413
 
414
+ public async getTagsToBuild() {
415
+ if (this.isSlot) {
416
+ return await DOM.instance.getTagsForElements(this.delegates, true);
417
+ } else {
418
+ return [this];
419
+ }
420
+ }
421
+
411
422
  public async buildAttributes() {
412
423
  let requiresScope = false;
413
424
  let defer: boolean = false;
@@ -420,81 +431,93 @@ export class Tag extends DOMObject {
420
431
  defer = true;
421
432
  }
422
433
 
423
- for (let attr in this.rawAttributes) {
424
- if (this.hasModifier(attr, 'mobile')) {
425
- if (!isMobile) {
426
- continue;
434
+ const tags: Tag[] = await this.getTagsToBuild() as Tag[];
435
+ const slot: Tag = this.isSlot ? this : null;
436
+ for (const tag of tags) {
437
+ for (let attr in this.rawAttributes) {
438
+ if (this.hasModifier(attr, 'mobile')) {
439
+ if (!isMobile) {
440
+ continue;
441
+ }
427
442
  }
428
- }
429
443
 
430
- if (this.hasModifier(attr, 'desktop')) {
431
- if (isMobile) {
432
- continue;
444
+ if (this.hasModifier(attr, 'desktop')) {
445
+ if (isMobile) {
446
+ continue;
447
+ }
433
448
  }
434
- }
435
449
 
436
- const attrClass = await this.getAttributeClass(attr);
437
- if (attrClass) {
438
- if (attrClass.scoped)
439
- requiresScope = true;
440
- const attrObj = attrClass.create(this, attr, attrClass);
441
- this.attributes.push(attrObj);
442
-
443
- if (defer && attrClass.canDefer) {
444
- await attrObj.defer();
445
- this.deferredAttributes.push(attrObj);
446
- attrObj.on('state', this.onAttributeStateChange.bind(this));
450
+ const attrClass = await this.getAttributeClass(attr);
451
+ if (attrClass) {
452
+ if (attrClass.scoped)
453
+ requiresScope = true;
454
+
455
+ const attrObj = attrClass.create(tag, attr, attrClass, slot);
456
+ tag.attributes.push(attrObj);
457
+ if (defer && attrClass.canDefer) {
458
+ await attrObj.defer();
459
+ tag.deferredAttributes.push(attrObj);
460
+ attrObj.on('state', tag.onAttributeStateChange, tag);
461
+ }
447
462
  }
448
463
  }
449
- }
450
464
 
451
- if (this.element.getAttribute('id'))
452
- requiresScope = true;
465
+ if (tag.element.getAttribute('id'))
466
+ requiresScope = true;
453
467
 
454
- if (requiresScope && !this.uniqueScope) {
455
- this._uniqueScope = true;
456
- }
468
+ if (requiresScope && !tag.uniqueScope) {
469
+ tag._uniqueScope = true;
470
+ }
457
471
 
472
+ }
458
473
  this._state = TagState.AttributesBuilt;
459
474
  }
460
475
 
461
476
  public async compileAttributes() {
462
- for (const attr of this.nonDeferredAttributes) {
463
- await attr.compile();
464
- }
477
+ const tags: Tag[] = await this.getTagsToBuild() as Tag[];
478
+ for (const tag of tags) {
479
+ for (const attr of tag.getAttributesWithState(AttributeState.Instantiated)) {
480
+ await attr.compile();
481
+ }
465
482
 
483
+ }
466
484
  this._state = TagState.AttributesCompiled;
467
485
  }
468
486
 
469
487
  public async setupAttributes() {
470
- if (VisionHelper.doBenchmark) benchmarkStart('Tag.setupAttributes');
471
- for (const attr of this.nonDeferredAttributes) {
472
- await attr.setup();
488
+ const tags: Tag[] = await this.getTagsToBuild() as Tag[];
489
+ for (const tag of tags) {
490
+ for (const attr of tag.getAttributesWithState(AttributeState.Compiled)) {
491
+ await attr.setup();
492
+ }
473
493
  }
474
- if (VisionHelper.doBenchmark) benchmarkEnd('Tag.setupAttributes', 'Attribute.setup');
475
- this.dom.registerElementInRoot(this);
476
- if (VisionHelper.doBenchmark) benchmarkEnd('Tag.setupAttributes', 'register');
477
-
494
+ if (!this.isSlot)
495
+ this.dom.registerElementInRoot(this);
478
496
  this._state = TagState.AttributesSetup;
479
497
  this.callOnWrapped('$setup');
480
- if (VisionHelper.doBenchmark) benchmarkEnd('Tag.setupAttributes', '$setup');
481
498
  }
482
499
 
483
500
  public async extractAttributes() {
484
- for (const attr of this.nonDeferredAttributes) {
485
- await attr.extract();
501
+ const tags: Tag[] = await this.getTagsToBuild() as Tag[];
502
+ for (const tag of tags) {
503
+ for (const attr of tag.getAttributesWithState(AttributeState.Setup)) {
504
+ await attr.extract();
505
+ }
486
506
  }
487
507
  this._state = TagState.AttributesExtracted;
488
508
  this.callOnWrapped('$extracted');
489
509
  }
490
510
 
491
511
  public async connectAttributes() {
492
- if (this.isInput) {
493
- this.addEventHandler('input', [], this.inputMutation, this);
494
- }
512
+ const tags: Tag[] = await this.getTagsToBuild() as Tag[];
513
+ for (const tag of tags) {
514
+ if (tag.isInput) {
515
+ tag.addEventHandler('input', [], tag.inputMutation, tag);
516
+ }
495
517
 
496
- for (const attr of this.nonDeferredAttributes) {
497
- await attr.connect();
518
+ for (const attr of tag.getAttributesWithState(AttributeState.Extracted)) {
519
+ await attr.connect();
520
+ }
498
521
  }
499
522
  this._state = TagState.AttributesConnected;
500
523
  this.callOnWrapped('$bound');
@@ -514,16 +537,13 @@ export class Tag extends DOMObject {
514
537
  option.removeAttribute('selected');
515
538
  }
516
539
  }
517
- //this.element.setAttribute('value', );
518
540
  this.value = values.join(',');
519
541
  } else {
520
- //this.element.setAttribute('value', e.target.value);
521
- //(this.element as any).value = e.target.value;
522
542
  this.value = e.target.value;
523
543
  }
524
544
  }
525
545
 
526
- public finalize(): void {
546
+ public async finalize() {
527
547
  this._state = TagState.Built;
528
548
  this.callOnWrapped('$built', this, this.scope, this.element);
529
549
  VisionHelper.nice(this.setupDeferredAttributes.bind(this));
@@ -0,0 +1,24 @@
1
+ import {Registry} from "../Registry";
2
+ import {TemplateAttribute} from "./TemplateAttribute";
3
+ import {Component} from "../Component";
4
+
5
+ @Registry.attribute('vsn-component')
6
+ export class ComponentAttribute extends TemplateAttribute {
7
+ public static readonly scoped: boolean = true;
8
+
9
+ public async extract() {
10
+ const name = this.getAttributeBinding();
11
+ if (!Registry.instance.components.has(name)) {
12
+ await super.extract();
13
+ const clsName = this.getAttributeValue();
14
+ let cls = Component;
15
+ if (clsName) {
16
+ cls = await Registry.instance.components.get(clsName);
17
+ if (!cls) {
18
+ throw new Error(`Component ${clsName} not found`);
19
+ }
20
+ }
21
+ Registry.instance.components.register(name, cls);
22
+ }
23
+ }
24
+ }
@@ -34,10 +34,6 @@ export class ListItem extends Attribute {
34
34
  return await this._list.getAttribute<List>('vsn-list');
35
35
  }
36
36
 
37
- protected async configure() {
38
-
39
- }
40
-
41
37
  private instantiateModel(model: any) {
42
38
  this.tag.wrap(model, false, true);
43
39
  }
@@ -9,7 +9,6 @@ export class RootAttribute extends Attribute {
9
9
 
10
10
  public async setup() {
11
11
  this.tag.scope.set('$mobile', VisionHelper.isMobile());
12
-
13
12
  for (const key of Registry.instance.functions.keys) {
14
13
  const fn = Registry.instance.functions.get(key);
15
14
  this.tag.scope.set(key, fn);
@@ -0,0 +1,12 @@
1
+ import {Registry} from "../Registry";
2
+ import {Attribute} from "../Attribute";
3
+
4
+ @Registry.attribute('vsn-template')
5
+ export class TemplateAttribute extends Attribute {
6
+ public static readonly canDefer: boolean = false;
7
+
8
+ public async extract() {
9
+ Registry.instance.templates.register(this.getAttributeBinding(), this.tag.element);
10
+ await super.extract();
11
+ }
12
+ }
@@ -1,5 +1,6 @@
1
1
  export {AddClassIf} from "./AddClassIf";
2
2
  export {Bind} from "./Bind";
3
+ export {ComponentAttribute} from './ComponentAttribute';
3
4
  export {ControllerAttribute} from "./ControllerAttribute";
4
5
  export {DisableIf} from "./DisableIf";
5
6
  export {Exec} from "./Exec";
@@ -23,5 +24,5 @@ export {ScriptAttribute} from "./ScriptAttribute";
23
24
  export {SetAttribute} from "./SetAttribute";
24
25
  export {StandardAttribute} from "./StandardAttribute";
25
26
  export {StyleAttribute} from "./StyleAttribute";
26
- export {Template} from "./Template";
27
+ export {TemplateAttribute} from "./TemplateAttribute";
27
28
  export {TypeAttribute} from "./TypeAttribute";
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
4
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7
+ * Code distributed by Google as part of the polymer project is also
8
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9
+ */
10
+
11
+ /**
12
+ * This shim allows elements written in, or compiled to, ES5 to work on native
13
+ * implementations of Custom Elements v1. It sets new.target to the value of
14
+ * this.constructor so that the native HTMLElement constructor can access the
15
+ * current under-construction element's definition.
16
+ */
17
+ (function() {
18
+ if (
19
+ // No Reflect, no classes, no need for shim because native custom elements
20
+ // require ES2015 classes or Reflect.
21
+ window.Reflect === undefined ||
22
+ window.customElements === undefined ||
23
+ // The webcomponentsjs custom elements polyfill doesn't require
24
+ // ES2015-compatible construction (`super()` or `Reflect.construct`).
25
+ window.customElements['polyfillWrapFlushCallback']
26
+ ) {
27
+ return;
28
+ }
29
+ const BuiltInHTMLElement = HTMLElement;
30
+ /**
31
+ * With jscompiler's RECOMMENDED_FLAGS the function name will be optimized away.
32
+ * However, if we declare the function as a property on an object literal, and
33
+ * use quotes for the property name, then closure will leave that much intact,
34
+ * which is enough for the JS VM to correctly set Function.prototype.name.
35
+ */
36
+ const wrapperForTheName = {
37
+ 'HTMLElement': /** @this {!Object} */ function HTMLElement() {
38
+ return Reflect.construct(
39
+ BuiltInHTMLElement, [], /** @type {!Function} */ (this.constructor));
40
+ }
41
+ };
42
+ window.HTMLElement = wrapperForTheName['HTMLElement'] as any;
43
+ HTMLElement.prototype = BuiltInHTMLElement.prototype;
44
+ HTMLElement.prototype.constructor = HTMLElement;
45
+ Object.setPrototypeOf(HTMLElement, BuiltInHTMLElement);
46
+ })();
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = '0.1.75';
1
+ export const VERSION = '0.1.78';
package/src/vsn.ts CHANGED
@@ -9,6 +9,7 @@ import {EventDispatcher} from "./EventDispatcher";
9
9
  import {DynamicScopeData} from "./Scope/DynamicScopeData";
10
10
  import {Controller} from "./Controller";
11
11
  import {VERSION} from "./version";
12
+ import './custom-elements';
12
13
 
13
14
  export class Vision extends EventDispatcher {
14
15
  protected static _instance: Vision;
@@ -18,6 +19,7 @@ export class Vision extends EventDispatcher {
18
19
 
19
20
  constructor() {
20
21
  super();
22
+ Registry.instance.components.on('register', this.defineComponent, this);
21
23
  if (VisionHelper.document) {
22
24
  document.addEventListener(
23
25
  "DOMContentLoaded",
@@ -44,6 +46,10 @@ export class Vision extends EventDispatcher {
44
46
  }
45
47
  }
46
48
 
49
+ protected defineComponent(name, cls) {
50
+ customElements.define(name, cls);
51
+ }
52
+
47
53
  public get dom(): DOM {
48
54
  return this._dom;
49
55
  }
@@ -1,4 +0,0 @@
1
- import { Attribute } from "../Attribute";
2
- export declare class Template extends Attribute {
3
- static readonly canDefer: boolean;
4
- }