@joist/element 4.0.0-next.5 → 4.0.0-next.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@joist/element",
3
- "version": "4.0.0-next.5",
3
+ "version": "4.0.0-next.7",
4
4
  "type": "module",
5
5
  "main": "./target/lib.js",
6
6
  "module": "./target/lib.js",
@@ -9,7 +9,7 @@
9
9
  "import": "./target/lib.js"
10
10
  },
11
11
  "./*": {
12
- "import": "./target/lib/*.js"
12
+ "import": "./target/lib"
13
13
  }
14
14
  },
15
15
  "files": [
@@ -43,7 +43,7 @@ export function element<
43
43
  }
44
44
  }
45
45
 
46
- for (let [event, { cb, root }] of meta.listeners) {
46
+ for (let [event, { cb, selector: root }] of meta.listeners) {
47
47
  root(this).addEventListener(event, cb.bind(this));
48
48
  }
49
49
 
@@ -0,0 +1,87 @@
1
+ import { assert } from 'chai';
2
+ import { element } from './element.js';
3
+ import { listen } from './listen.js';
4
+
5
+ describe('@listen()', () => {
6
+ it('should add listener to an outer HTMLElement', (done) => {
7
+ @element({
8
+ tagName: 'listener-1'
9
+ })
10
+ class MyElement extends HTMLElement {
11
+ @listen('click')
12
+ onClick(e: Event) {
13
+ assert.equal(e.type, 'click');
14
+
15
+ done();
16
+ }
17
+ }
18
+
19
+ const el = new MyElement();
20
+
21
+ el.dispatchEvent(new Event('click'));
22
+ });
23
+
24
+ it('should add listener to the shadow root if available', (done) => {
25
+ @element({
26
+ tagName: 'listener-2',
27
+ shadow: []
28
+ })
29
+ class MyElement extends HTMLElement {
30
+ @listen('click')
31
+ onClick(e: Event) {
32
+ assert.equal(e.type, 'click');
33
+
34
+ done();
35
+ }
36
+ }
37
+
38
+ const el = new MyElement();
39
+
40
+ el.shadowRoot!.dispatchEvent(new Event('click'));
41
+ });
42
+
43
+ it('should restrict argument to an event or an event subtype', (done) => {
44
+ class CustomEvent extends Event {
45
+ test = 'Hello World';
46
+
47
+ constructor() {
48
+ super('customevent');
49
+ }
50
+ }
51
+
52
+ @element({
53
+ tagName: 'listener-3'
54
+ })
55
+ class MyElement extends HTMLElement {
56
+ @listen('customevent')
57
+ onClick(e: CustomEvent) {
58
+ assert.equal(e.type, 'customevent');
59
+
60
+ done();
61
+ }
62
+ }
63
+
64
+ const el = new MyElement();
65
+
66
+ el.dispatchEvent(new CustomEvent());
67
+ });
68
+
69
+ it('should respect a provided selector function', (done) => {
70
+ @element({
71
+ tagName: 'listener-4',
72
+ shadow: []
73
+ })
74
+ class MyElement extends HTMLElement {
75
+ @listen('click', (host) => host)
76
+ onClick(e: Event) {
77
+ assert.equal(e.type, 'click');
78
+
79
+ done();
80
+ }
81
+ }
82
+
83
+ const el = new MyElement();
84
+
85
+ el.dispatchEvent(new Event('click'));
86
+ });
87
+ });
package/src/lib/listen.ts CHANGED
@@ -1,15 +1,12 @@
1
- import { ListenerRootSelector, metadataStore } from './metadata.js';
1
+ import { ListenerSelector, metadataStore } from './metadata.js';
2
2
 
3
- export function listen<This extends HTMLElement>(event: string, root?: ListenerRootSelector) {
4
- return function listenDecorator(
5
- value: (e: Event) => void,
6
- ctx: ClassMethodDecoratorContext<This>
7
- ) {
3
+ export function listen<This extends HTMLElement>(event: string, selector?: ListenerSelector) {
4
+ return function listenDecorator(value: (e: any) => void, ctx: ClassMethodDecoratorContext<This>) {
8
5
  const metadata = metadataStore.read(ctx.metadata);
9
6
 
10
7
  metadata.listeners.set(event, {
11
8
  cb: value,
12
- root: root ?? ((el: HTMLElement) => el.shadowRoot ?? el)
9
+ selector: selector ?? ((el: HTMLElement) => el.shadowRoot ?? el)
13
10
  });
14
11
  };
15
12
  }
@@ -6,11 +6,11 @@ export interface AttrDef {
6
6
  observe: boolean;
7
7
  }
8
8
 
9
- export type ListenerRootSelector = (el: HTMLElement) => HTMLElement | ShadowRoot;
9
+ export type ListenerSelector = (el: HTMLElement) => HTMLElement | ShadowRoot;
10
10
 
11
11
  export class ElementMetadata {
12
12
  attrs: AttrDef[] = [];
13
- listeners = new Map<string, { cb: (e: Event) => void; root: ListenerRootSelector }>();
13
+ listeners = new Map<string, { cb: (e: Event) => void; selector: ListenerSelector }>();
14
14
  onReady = new Set<Function>();
15
15
  }
16
16
 
@@ -5,30 +5,30 @@ import { template } from './template.js';
5
5
  // Run all tests with both shadow and light dom
6
6
  const TESTS = [
7
7
  function comments(el: HTMLElement, root: HTMLElement | ShadowRoot) {
8
- it(`should intialize template comments ${root instanceof ShadowRoot ? '(ShadowDOM)' : '(LightDOM)'}`, () => {
8
+ it(`should intialize bindable nodes ${root instanceof ShadowRoot ? '(ShadowDOM)' : '(LightDOM)'}`, () => {
9
9
  el.title = 'Hello World';
10
10
  el.ariaLabel = 'This is the label';
11
11
  el.ariaDescription = 'This is the description';
12
12
 
13
13
  root.innerHTML = /*html*/ `
14
- <!--#:title-->
14
+ <span #:bind="title"></span>
15
15
 
16
16
  <ul>
17
- <li><!--#:ariaLabel--></li>
18
- <li><!--#:ariaDescription--></li>
17
+ <li #:bind="ariaLabel"></li>
18
+ <li #:bind="ariaDescription"></li>
19
19
  </ul>
20
20
  `;
21
21
 
22
- const render = template();
22
+ const render = template().bind(el);
23
23
 
24
- render.call(el);
24
+ render();
25
25
 
26
26
  assert.equal(
27
27
  root.innerHTML
28
28
  .split('\n')
29
29
  .map((res) => res.trim())
30
30
  .join(''),
31
- 'Hello World<ul><li>This is the label</li><li>This is the description</li></ul>'
31
+ '<span #:bind="title">Hello World</span><ul><li #:bind="ariaLabel">This is the label</li><li #:bind="ariaDescription">This is the description</li></ul>'
32
32
  );
33
33
  });
34
34
  },
@@ -38,19 +38,49 @@ const TESTS = [
38
38
  el.ariaDescription = 'This is the description';
39
39
 
40
40
  root.innerHTML = /*html*/ `
41
- <ul aria-label="#:ariaLabel" aria-description="#:ariaDescription"></ul>
41
+ <ul #:aria-label="ariaLabel" #:aria-description="ariaDescription"></ul>
42
42
  `;
43
43
 
44
- const render = template();
44
+ const render = template().bind(el);
45
45
 
46
- render.call(el);
46
+ render();
47
47
 
48
48
  assert.equal(
49
49
  root.innerHTML
50
50
  .split('\n')
51
51
  .map((res) => res.trim())
52
52
  .join(''),
53
- '<ul aria-label="This is the label" aria-description="This is the description"></ul>'
53
+ '<ul #:aria-label="ariaLabel" #:aria-description="ariaDescription" aria-label="This is the label" aria-description="This is the description"></ul>'
54
+ );
55
+ });
56
+ },
57
+ function customGetter(el: HTMLElement, root: HTMLElement | ShadowRoot) {
58
+ it(`should use custom getter for values ${root instanceof ShadowRoot ? '(ShadowDOM)' : '(LightDOM)'}`, () => {
59
+ const data: Record<string, string> = {
60
+ title: 'Hello World',
61
+ ariaLabel: 'This is the label',
62
+ ariaDescription: 'This is the description'
63
+ };
64
+
65
+ root.innerHTML = /*html*/ `
66
+ <span #:bind="title"></span>
67
+
68
+ <ul>
69
+ <li #:bind="ariaLabel"></li>
70
+ <li #:bind="ariaDescription"></li>
71
+ </ul>
72
+ `;
73
+
74
+ const render = template({ value: (key) => data[key] }).bind(el);
75
+
76
+ render();
77
+
78
+ assert.equal(
79
+ root.innerHTML
80
+ .split('\n')
81
+ .map((res) => res.trim())
82
+ .join(''),
83
+ '<span #:bind="title">Hello World</span><ul><li #:bind="ariaLabel">This is the label</li><li #:bind="ariaDescription">This is the description</li></ul>'
54
84
  );
55
85
  });
56
86
  }
@@ -1,132 +1,115 @@
1
1
  const TOKEN_PREFIX = '#:';
2
2
 
3
- class NodeMap extends Map<Node, string> {}
3
+ type Updater = () => void;
4
+ class Updates extends Set<Updater> {}
5
+ type TemplateValueGetter = (key: string) => string;
4
6
 
5
- export interface TemplateOpts {}
6
-
7
- export interface RenderOpts {
8
- refresh?: boolean;
7
+ export interface TemplateOpts {
8
+ value?: TemplateValueGetter;
9
9
  }
10
10
 
11
- export function template(_templateOpts?: TemplateOpts) {
12
- // make sure we only initialize once
13
- let initialized = false;
11
+ export interface RenderOpts {}
14
12
 
13
+ export function template(templateOpts?: TemplateOpts) {
15
14
  // Track all nodes that can be updated and their associated property
16
- const nodes = new NodeMap();
17
-
18
- return function render<T extends HTMLElement>(this: T, renderOpts?: RenderOpts) {
19
- if (renderOpts?.refresh) {
20
- initialized = false;
21
- nodes.clear();
22
- }
23
-
24
- if (initialized) {
25
- return updateNodes(this, nodes);
15
+ let updates: Updates | null = null;
16
+
17
+ return function render<T extends HTMLElement>(this: T) {
18
+ if (!updates) {
19
+ updates = findUpdates(
20
+ this,
21
+ templateOpts?.value ?? ((key: string) => getTemplateValue(this, key))
22
+ );
23
+ } else {
24
+ for (let update of updates) {
25
+ update();
26
+ }
26
27
  }
27
-
28
- // find and track nodes
29
- initializeNodes(this, nodes);
30
-
31
- initialized = true;
32
28
  };
33
29
  }
34
30
 
35
- function initializeNodes(el: HTMLElement, nodes: NodeMap) {
36
- const iterator = document.createTreeWalker(
37
- el.shadowRoot || el,
38
- NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT
39
- );
31
+ function findUpdates(el: HTMLElement, getter: TemplateValueGetter): Updates {
32
+ const iterator = document.createTreeWalker(el.shadowRoot ?? el, NodeFilter.SHOW_ELEMENT);
33
+ const updates = new Updates();
40
34
 
41
35
  while (iterator.nextNode()) {
42
- const res = trackNode(el, iterator.currentNode, nodes);
36
+ const res = trackElement(iterator.currentNode, updates, getter);
43
37
 
44
38
  if (res !== null) {
45
39
  iterator.currentNode = res;
46
40
  }
47
41
  }
48
- }
49
-
50
- function updateNodes(el: HTMLElement, nodes: NodeMap) {
51
- for (let [node, prop] of nodes) {
52
- const value = Reflect.get(el, prop);
53
42
 
54
- const isAttribute = node.nodeType === Node.ATTRIBUTE_NODE;
55
-
56
- if (isAttribute && isBooleanAttributeNode(node as Attr)) {
57
- manageBooleanAttribute(el, node as Attr);
58
- } else if (value !== node.nodeValue) {
59
- node.nodeValue = value;
60
- }
61
- }
43
+ return updates;
62
44
  }
63
45
 
64
46
  /**
65
47
  * configures and tracks a given Node so that it can be updated in place later.
66
48
  */
67
- function trackNode(el: HTMLElement, node: Node, nodes: NodeMap): Node | null {
68
- switch (node.nodeType) {
69
- case Node.COMMENT_NODE: {
70
- const nodeValue = node.nodeValue?.trim();
49
+ function trackElement(node: Node, updates: Updates, getter: TemplateValueGetter): Node | null {
50
+ const element = node as Element;
71
51
 
72
- if (nodeValue?.startsWith(TOKEN_PREFIX)) {
73
- if (node.parentNode) {
74
- const propertyKey = nodeValue.replace(TOKEN_PREFIX, '');
75
- const textNode = document.createTextNode(Reflect.get(el, propertyKey));
52
+ for (let attr of element.attributes) {
53
+ const nodeValue = attr.value.trim();
54
+ const realAttributeName = attr.name.replace(TOKEN_PREFIX, '');
76
55
 
77
- node.parentNode.replaceChild(textNode, node);
56
+ let update: Updater | null = null;
78
57
 
79
- nodes.set(textNode, propertyKey);
58
+ if (attr.name.startsWith(`${TOKEN_PREFIX}bind`)) {
59
+ update = () => {
60
+ const value = getter(attr.value);
80
61
 
81
- return textNode;
62
+ if (element.textContent !== value) {
63
+ element.textContent = getter(attr.value);
82
64
  }
65
+ };
66
+ } else if (attr.name.startsWith(TOKEN_PREFIX)) {
67
+ const isBooleanAttr = nodeValue.startsWith('!');
68
+ const isPositive = nodeValue.startsWith('!!');
69
+ const propertyKey = nodeValue.replaceAll('!', '');
70
+
71
+ if (isBooleanAttr) {
72
+ update = () => {
73
+ let value = isPositive ? !!getter(propertyKey) : !getter(propertyKey);
74
+
75
+ if (value) {
76
+ element.setAttribute(realAttributeName, '');
77
+ } else {
78
+ element.removeAttribute(realAttributeName);
79
+ }
80
+ };
81
+ } else {
82
+ const realAttribute = document.createAttribute(realAttributeName);
83
+ element.setAttributeNode(realAttribute);
84
+
85
+ update = () => {
86
+ const value = getter(nodeValue);
87
+
88
+ if (realAttribute.value !== value) {
89
+ realAttribute.value = value;
90
+ }
91
+ };
83
92
  }
84
-
85
- break;
86
93
  }
87
94
 
88
- case Node.ELEMENT_NODE: {
89
- const element = node as Element;
90
-
91
- for (let attr of element.attributes) {
92
- const nodeValue = attr.value.trim();
93
-
94
- if (isBooleanAttributeNode(attr)) {
95
- manageBooleanAttribute(el, attr);
96
-
97
- nodes.set(attr, attr.value);
98
- } else if (nodeValue.startsWith(TOKEN_PREFIX)) {
99
- const propertyKey = nodeValue.replace(TOKEN_PREFIX, '');
95
+ if (update) {
96
+ updates.add(update);
100
97
 
101
- attr.value = Reflect.get(el, propertyKey);
102
-
103
- nodes.set(attr, propertyKey);
104
- }
105
- }
106
-
107
- break;
98
+ update();
108
99
  }
109
100
  }
110
101
 
111
102
  return null;
112
103
  }
113
104
 
114
- function isBooleanAttributeNode(attr: Attr) {
115
- return attr.name.startsWith(TOKEN_PREFIX);
116
- }
117
-
118
- function manageBooleanAttribute(el: HTMLElement, attr: Attr) {
119
- const realAttributeName = attr.name.replace(TOKEN_PREFIX, '');
105
+ export function getTemplateValue(obj: object, key: string) {
106
+ const parsed = key.split('.');
120
107
 
121
- if (attr.ownerElement) {
122
- let value = attr.value.startsWith('!')
123
- ? !Reflect.get(el, attr.value.replace('!', ''))
124
- : Reflect.get(el, attr.value);
108
+ let pointer: any = obj;
125
109
 
126
- if (value) {
127
- attr.ownerElement.setAttribute(realAttributeName, '');
128
- } else {
129
- attr.ownerElement.removeAttribute(realAttributeName);
130
- }
110
+ for (let part of parsed) {
111
+ pointer = pointer[part];
131
112
  }
113
+
114
+ return pointer;
132
115
  }
package/src/lib.ts CHANGED
@@ -3,5 +3,5 @@ export { attr } from './lib/attr.js';
3
3
  export { listen } from './lib/listen.js';
4
4
  export { element } from './lib/element.js';
5
5
  export { query } from './lib/query.js';
6
- export { template } from './lib/template.js';
6
+ export { template, getTemplateValue } from './lib/template.js';
7
7
  export { ready } from './lib/lifecycle.js';
@@ -28,7 +28,7 @@ export function element(opts) {
28
28
  }
29
29
  }
30
30
  }
31
- for (let [event, { cb, root }] of meta.listeners) {
31
+ for (let [event, { cb, selector: root }] of meta.listeners) {
32
32
  root(this).addEventListener(event, cb.bind(this));
33
33
  }
34
34
  for (let cb of meta.onReady) {
@@ -1 +1 @@
1
- {"version":3,"file":"element.js","sourceRoot":"","sources":["../../src/lib/element.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"element.js","sourceRoot":"","sources":["../../src/lib/element.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { ListenerRootSelector } from './metadata.js';
2
- export declare function listen<This extends HTMLElement>(event: string, root?: ListenerRootSelector): (value: (e: Event) => void, ctx: ClassMethodDecoratorContext<This>) => void;
1
+ import { ListenerSelector } from './metadata.js';
2
+ export declare function listen<This extends HTMLElement>(event: string, selector?: ListenerSelector): (value: (e: any) => void, ctx: ClassMethodDecoratorContext<This>) => void;
@@ -1,10 +1,10 @@
1
1
  import { metadataStore } from './metadata.js';
2
- export function listen(event, root) {
2
+ export function listen(event, selector) {
3
3
  return function listenDecorator(value, ctx) {
4
4
  const metadata = metadataStore.read(ctx.metadata);
5
5
  metadata.listeners.set(event, {
6
6
  cb: value,
7
- root: root ?? ((el) => el.shadowRoot ?? el)
7
+ selector: selector ?? ((el) => el.shadowRoot ?? el)
8
8
  });
9
9
  };
10
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"listen.js","sourceRoot":"","sources":["../../src/lib/listen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,aAAa,EAAE,MAAM,eAAe,CAAC;AAEpE,MAAM,UAAU,MAAM,CAA2B,KAAa,EAAE,IAA2B;IACzF,OAAO,SAAS,eAAe,CAC7B,KAAyB,EACzB,GAAsC;QAEtC,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAElD,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE;YAC5B,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,EAAe,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC;SACzD,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"listen.js","sourceRoot":"","sources":["../../src/lib/listen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,aAAa,EAAE,MAAM,eAAe,CAAC;AAEhE,MAAM,UAAU,MAAM,CAA2B,KAAa,EAAE,QAA2B;IACzF,OAAO,SAAS,eAAe,CAAC,KAAuB,EAAE,GAAsC;QAC7F,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAElD,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE;YAC5B,EAAE,EAAE,KAAK;YACT,QAAQ,EAAE,QAAQ,IAAI,CAAC,CAAC,EAAe,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC;SACjE,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,159 @@
1
+ import { __esDecorate, __runInitializers } from "tslib";
2
+ import { assert } from 'chai';
3
+ import { element } from './element.js';
4
+ import { listen } from './listen.js';
5
+ describe('@listen()', () => {
6
+ it('should add listener to an outer HTMLElement', (done) => {
7
+ let MyElement = (() => {
8
+ let _classDecorators = [element({
9
+ tagName: 'listener-1'
10
+ })];
11
+ let _classDescriptor;
12
+ let _classExtraInitializers = [];
13
+ let _classThis;
14
+ let _classSuper = HTMLElement;
15
+ let _instanceExtraInitializers = [];
16
+ let _onClick_decorators;
17
+ var MyElement = class extends _classSuper {
18
+ static { _classThis = this; }
19
+ static {
20
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
21
+ _onClick_decorators = [listen('click')];
22
+ __esDecorate(this, null, _onClick_decorators, { kind: "method", name: "onClick", static: false, private: false, access: { has: obj => "onClick" in obj, get: obj => obj.onClick }, metadata: _metadata }, null, _instanceExtraInitializers);
23
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
24
+ MyElement = _classThis = _classDescriptor.value;
25
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
26
+ __runInitializers(_classThis, _classExtraInitializers);
27
+ }
28
+ onClick(e) {
29
+ assert.equal(e.type, 'click');
30
+ done();
31
+ }
32
+ constructor() {
33
+ super(...arguments);
34
+ __runInitializers(this, _instanceExtraInitializers);
35
+ }
36
+ };
37
+ return MyElement = _classThis;
38
+ })();
39
+ const el = new MyElement();
40
+ el.dispatchEvent(new Event('click'));
41
+ });
42
+ it('should add listener to the shadow root if available', (done) => {
43
+ let MyElement = (() => {
44
+ let _classDecorators = [element({
45
+ tagName: 'listener-2',
46
+ shadow: []
47
+ })];
48
+ let _classDescriptor;
49
+ let _classExtraInitializers = [];
50
+ let _classThis;
51
+ let _classSuper = HTMLElement;
52
+ let _instanceExtraInitializers = [];
53
+ let _onClick_decorators;
54
+ var MyElement = class extends _classSuper {
55
+ static { _classThis = this; }
56
+ static {
57
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
58
+ _onClick_decorators = [listen('click')];
59
+ __esDecorate(this, null, _onClick_decorators, { kind: "method", name: "onClick", static: false, private: false, access: { has: obj => "onClick" in obj, get: obj => obj.onClick }, metadata: _metadata }, null, _instanceExtraInitializers);
60
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
61
+ MyElement = _classThis = _classDescriptor.value;
62
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
63
+ __runInitializers(_classThis, _classExtraInitializers);
64
+ }
65
+ onClick(e) {
66
+ assert.equal(e.type, 'click');
67
+ done();
68
+ }
69
+ constructor() {
70
+ super(...arguments);
71
+ __runInitializers(this, _instanceExtraInitializers);
72
+ }
73
+ };
74
+ return MyElement = _classThis;
75
+ })();
76
+ const el = new MyElement();
77
+ el.shadowRoot.dispatchEvent(new Event('click'));
78
+ });
79
+ it('should restrict argument to an event or an event subtype', (done) => {
80
+ class CustomEvent extends Event {
81
+ test = 'Hello World';
82
+ constructor() {
83
+ super('customevent');
84
+ }
85
+ }
86
+ let MyElement = (() => {
87
+ let _classDecorators = [element({
88
+ tagName: 'listener-3'
89
+ })];
90
+ let _classDescriptor;
91
+ let _classExtraInitializers = [];
92
+ let _classThis;
93
+ let _classSuper = HTMLElement;
94
+ let _instanceExtraInitializers = [];
95
+ let _onClick_decorators;
96
+ var MyElement = class extends _classSuper {
97
+ static { _classThis = this; }
98
+ static {
99
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
100
+ _onClick_decorators = [listen('customevent')];
101
+ __esDecorate(this, null, _onClick_decorators, { kind: "method", name: "onClick", static: false, private: false, access: { has: obj => "onClick" in obj, get: obj => obj.onClick }, metadata: _metadata }, null, _instanceExtraInitializers);
102
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
103
+ MyElement = _classThis = _classDescriptor.value;
104
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
105
+ __runInitializers(_classThis, _classExtraInitializers);
106
+ }
107
+ onClick(e) {
108
+ assert.equal(e.type, 'customevent');
109
+ done();
110
+ }
111
+ constructor() {
112
+ super(...arguments);
113
+ __runInitializers(this, _instanceExtraInitializers);
114
+ }
115
+ };
116
+ return MyElement = _classThis;
117
+ })();
118
+ const el = new MyElement();
119
+ el.dispatchEvent(new CustomEvent());
120
+ });
121
+ it('should respect a provided selector function', (done) => {
122
+ let MyElement = (() => {
123
+ let _classDecorators = [element({
124
+ tagName: 'listener-4',
125
+ shadow: []
126
+ })];
127
+ let _classDescriptor;
128
+ let _classExtraInitializers = [];
129
+ let _classThis;
130
+ let _classSuper = HTMLElement;
131
+ let _instanceExtraInitializers = [];
132
+ let _onClick_decorators;
133
+ var MyElement = class extends _classSuper {
134
+ static { _classThis = this; }
135
+ static {
136
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
137
+ _onClick_decorators = [listen('click', (host) => host)];
138
+ __esDecorate(this, null, _onClick_decorators, { kind: "method", name: "onClick", static: false, private: false, access: { has: obj => "onClick" in obj, get: obj => obj.onClick }, metadata: _metadata }, null, _instanceExtraInitializers);
139
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
140
+ MyElement = _classThis = _classDescriptor.value;
141
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
142
+ __runInitializers(_classThis, _classExtraInitializers);
143
+ }
144
+ onClick(e) {
145
+ assert.equal(e.type, 'click');
146
+ done();
147
+ }
148
+ constructor() {
149
+ super(...arguments);
150
+ __runInitializers(this, _instanceExtraInitializers);
151
+ }
152
+ };
153
+ return MyElement = _classThis;
154
+ })();
155
+ const el = new MyElement();
156
+ el.dispatchEvent(new Event('click'));
157
+ });
158
+ });
159
+ //# sourceMappingURL=listen.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listen.test.js","sourceRoot":"","sources":["../../src/lib/listen.test.ts"],"names":[],"mappings":"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"}
@@ -3,12 +3,12 @@ export interface AttrDef {
3
3
  attrName: string;
4
4
  observe: boolean;
5
5
  }
6
- export type ListenerRootSelector = (el: HTMLElement) => HTMLElement | ShadowRoot;
6
+ export type ListenerSelector = (el: HTMLElement) => HTMLElement | ShadowRoot;
7
7
  export declare class ElementMetadata {
8
8
  attrs: AttrDef[];
9
9
  listeners: Map<string, {
10
10
  cb: (e: Event) => void;
11
- root: ListenerRootSelector;
11
+ selector: ListenerSelector;
12
12
  }>;
13
13
  onReady: Set<Function>;
14
14
  }
@@ -1,6 +1,9 @@
1
+ type TemplateValueGetter = (key: string) => string;
1
2
  export interface TemplateOpts {
3
+ value?: TemplateValueGetter;
2
4
  }
3
5
  export interface RenderOpts {
4
- refresh?: boolean;
5
6
  }
6
- export declare function template(_templateOpts?: TemplateOpts): <T extends HTMLElement>(this: T, renderOpts?: RenderOpts) => void;
7
+ export declare function template(templateOpts?: TemplateOpts): <T extends HTMLElement>(this: T) => void;
8
+ export declare function getTemplateValue(obj: object, key: string): any;
9
+ export {};
@@ -1,91 +1,83 @@
1
1
  const TOKEN_PREFIX = '#:';
2
- class NodeMap extends Map {
2
+ class Updates extends Set {
3
3
  }
4
- export function template(_templateOpts) {
5
- let initialized = false;
6
- const nodes = new NodeMap();
7
- return function render(renderOpts) {
8
- if (renderOpts?.refresh) {
9
- initialized = false;
10
- nodes.clear();
4
+ export function template(templateOpts) {
5
+ let updates = null;
6
+ return function render() {
7
+ if (!updates) {
8
+ updates = findUpdates(this, templateOpts?.value ?? ((key) => getTemplateValue(this, key)));
11
9
  }
12
- if (initialized) {
13
- return updateNodes(this, nodes);
10
+ else {
11
+ for (let update of updates) {
12
+ update();
13
+ }
14
14
  }
15
- initializeNodes(this, nodes);
16
- initialized = true;
17
15
  };
18
16
  }
19
- function initializeNodes(el, nodes) {
20
- const iterator = document.createTreeWalker(el.shadowRoot || el, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT);
17
+ function findUpdates(el, getter) {
18
+ const iterator = document.createTreeWalker(el.shadowRoot ?? el, NodeFilter.SHOW_ELEMENT);
19
+ const updates = new Updates();
21
20
  while (iterator.nextNode()) {
22
- const res = trackNode(el, iterator.currentNode, nodes);
21
+ const res = trackElement(iterator.currentNode, updates, getter);
23
22
  if (res !== null) {
24
23
  iterator.currentNode = res;
25
24
  }
26
25
  }
26
+ return updates;
27
27
  }
28
- function updateNodes(el, nodes) {
29
- for (let [node, prop] of nodes) {
30
- const value = Reflect.get(el, prop);
31
- const isAttribute = node.nodeType === Node.ATTRIBUTE_NODE;
32
- if (isAttribute && isBooleanAttributeNode(node)) {
33
- manageBooleanAttribute(el, node);
34
- }
35
- else if (value !== node.nodeValue) {
36
- node.nodeValue = value;
37
- }
38
- }
39
- }
40
- function trackNode(el, node, nodes) {
41
- switch (node.nodeType) {
42
- case Node.COMMENT_NODE: {
43
- const nodeValue = node.nodeValue?.trim();
44
- if (nodeValue?.startsWith(TOKEN_PREFIX)) {
45
- if (node.parentNode) {
46
- const propertyKey = nodeValue.replace(TOKEN_PREFIX, '');
47
- const textNode = document.createTextNode(Reflect.get(el, propertyKey));
48
- node.parentNode.replaceChild(textNode, node);
49
- nodes.set(textNode, propertyKey);
50
- return textNode;
28
+ function trackElement(node, updates, getter) {
29
+ const element = node;
30
+ for (let attr of element.attributes) {
31
+ const nodeValue = attr.value.trim();
32
+ const realAttributeName = attr.name.replace(TOKEN_PREFIX, '');
33
+ let update = null;
34
+ if (attr.name.startsWith(`${TOKEN_PREFIX}bind`)) {
35
+ update = () => {
36
+ const value = getter(attr.value);
37
+ if (element.textContent !== value) {
38
+ element.textContent = getter(attr.value);
51
39
  }
52
- }
53
- break;
40
+ };
54
41
  }
55
- case Node.ELEMENT_NODE: {
56
- const element = node;
57
- for (let attr of element.attributes) {
58
- const nodeValue = attr.value.trim();
59
- if (isBooleanAttributeNode(attr)) {
60
- manageBooleanAttribute(el, attr);
61
- nodes.set(attr, attr.value);
62
- }
63
- else if (nodeValue.startsWith(TOKEN_PREFIX)) {
64
- const propertyKey = nodeValue.replace(TOKEN_PREFIX, '');
65
- attr.value = Reflect.get(el, propertyKey);
66
- nodes.set(attr, propertyKey);
67
- }
42
+ else if (attr.name.startsWith(TOKEN_PREFIX)) {
43
+ const isBooleanAttr = nodeValue.startsWith('!');
44
+ const isPositive = nodeValue.startsWith('!!');
45
+ const propertyKey = nodeValue.replaceAll('!', '');
46
+ if (isBooleanAttr) {
47
+ update = () => {
48
+ let value = isPositive ? !!getter(propertyKey) : !getter(propertyKey);
49
+ if (value) {
50
+ element.setAttribute(realAttributeName, '');
51
+ }
52
+ else {
53
+ element.removeAttribute(realAttributeName);
54
+ }
55
+ };
56
+ }
57
+ else {
58
+ const realAttribute = document.createAttribute(realAttributeName);
59
+ element.setAttributeNode(realAttribute);
60
+ update = () => {
61
+ const value = getter(nodeValue);
62
+ if (realAttribute.value !== value) {
63
+ realAttribute.value = value;
64
+ }
65
+ };
68
66
  }
69
- break;
67
+ }
68
+ if (update) {
69
+ updates.add(update);
70
+ update();
70
71
  }
71
72
  }
72
73
  return null;
73
74
  }
74
- function isBooleanAttributeNode(attr) {
75
- return attr.name.startsWith(TOKEN_PREFIX);
76
- }
77
- function manageBooleanAttribute(el, attr) {
78
- const realAttributeName = attr.name.replace(TOKEN_PREFIX, '');
79
- if (attr.ownerElement) {
80
- let value = attr.value.startsWith('!')
81
- ? !Reflect.get(el, attr.value.replace('!', ''))
82
- : Reflect.get(el, attr.value);
83
- if (value) {
84
- attr.ownerElement.setAttribute(realAttributeName, '');
85
- }
86
- else {
87
- attr.ownerElement.removeAttribute(realAttributeName);
88
- }
75
+ export function getTemplateValue(obj, key) {
76
+ const parsed = key.split('.');
77
+ let pointer = obj;
78
+ for (let part of parsed) {
79
+ pointer = pointer[part];
89
80
  }
81
+ return pointer;
90
82
  }
91
83
  //# sourceMappingURL=template.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/lib/template.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/lib/template.ts"],"names":[],"mappings":"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"}
@@ -2,24 +2,24 @@ import { assert } from 'chai';
2
2
  import { template } from './template.js';
3
3
  const TESTS = [
4
4
  function comments(el, root) {
5
- it(`should intialize template comments ${root instanceof ShadowRoot ? '(ShadowDOM)' : '(LightDOM)'}`, () => {
5
+ it(`should intialize bindable nodes ${root instanceof ShadowRoot ? '(ShadowDOM)' : '(LightDOM)'}`, () => {
6
6
  el.title = 'Hello World';
7
7
  el.ariaLabel = 'This is the label';
8
8
  el.ariaDescription = 'This is the description';
9
9
  root.innerHTML = `
10
- <!--#:title-->
10
+ <span #:bind="title"></span>
11
11
 
12
12
  <ul>
13
- <li><!--#:ariaLabel--></li>
14
- <li><!--#:ariaDescription--></li>
13
+ <li #:bind="ariaLabel"></li>
14
+ <li #:bind="ariaDescription"></li>
15
15
  </ul>
16
16
  `;
17
- const render = template();
18
- render.call(el);
17
+ const render = template().bind(el);
18
+ render();
19
19
  assert.equal(root.innerHTML
20
20
  .split('\n')
21
21
  .map((res) => res.trim())
22
- .join(''), 'Hello World<ul><li>This is the label</li><li>This is the description</li></ul>');
22
+ .join(''), '<span #:bind="title">Hello World</span><ul><li #:bind="ariaLabel">This is the label</li><li #:bind="ariaDescription">This is the description</li></ul>');
23
23
  });
24
24
  },
25
25
  function attributes(el, root) {
@@ -27,14 +27,37 @@ const TESTS = [
27
27
  el.ariaLabel = 'This is the label';
28
28
  el.ariaDescription = 'This is the description';
29
29
  root.innerHTML = `
30
- <ul aria-label="#:ariaLabel" aria-description="#:ariaDescription"></ul>
30
+ <ul #:aria-label="ariaLabel" #:aria-description="ariaDescription"></ul>
31
31
  `;
32
- const render = template();
33
- render.call(el);
32
+ const render = template().bind(el);
33
+ render();
34
34
  assert.equal(root.innerHTML
35
35
  .split('\n')
36
36
  .map((res) => res.trim())
37
- .join(''), '<ul aria-label="This is the label" aria-description="This is the description"></ul>');
37
+ .join(''), '<ul #:aria-label="ariaLabel" #:aria-description="ariaDescription" aria-label="This is the label" aria-description="This is the description"></ul>');
38
+ });
39
+ },
40
+ function customGetter(el, root) {
41
+ it(`should use custom getter for values ${root instanceof ShadowRoot ? '(ShadowDOM)' : '(LightDOM)'}`, () => {
42
+ const data = {
43
+ title: 'Hello World',
44
+ ariaLabel: 'This is the label',
45
+ ariaDescription: 'This is the description'
46
+ };
47
+ root.innerHTML = `
48
+ <span #:bind="title"></span>
49
+
50
+ <ul>
51
+ <li #:bind="ariaLabel"></li>
52
+ <li #:bind="ariaDescription"></li>
53
+ </ul>
54
+ `;
55
+ const render = template({ value: (key) => data[key] }).bind(el);
56
+ render();
57
+ assert.equal(root.innerHTML
58
+ .split('\n')
59
+ .map((res) => res.trim())
60
+ .join(''), '<span #:bind="title">Hello World</span><ul><li #:bind="ariaLabel">This is the label</li><li #:bind="ariaDescription">This is the description</li></ul>');
38
61
  });
39
62
  }
40
63
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"template.test.js","sourceRoot":"","sources":["../../src/lib/template.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,MAAM,KAAK,GAAG;IACZ,SAAS,QAAQ,CAAC,EAAe,EAAE,IAA8B;QAC/D,EAAE,CAAC,sCAAsC,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE;YACzG,EAAE,CAAC,KAAK,GAAG,aAAa,CAAC;YACzB,EAAE,CAAC,SAAS,GAAG,mBAAmB,CAAC;YACnC,EAAE,CAAC,eAAe,GAAG,yBAAyB,CAAC;YAE/C,IAAI,CAAC,SAAS,GAAY;;;;;;;OAOzB,CAAC;YAEF,MAAM,MAAM,GAAG,QAAQ,EAAE,CAAC;YAE1B,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEhB,MAAM,CAAC,KAAK,CACV,IAAI,CAAC,SAAS;iBACX,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;iBACxB,IAAI,CAAC,EAAE,CAAC,EACX,gFAAgF,CACjF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IACD,SAAS,UAAU,CAAC,EAAe,EAAE,IAA8B;QACjE,EAAE,CAAC,wCAAwC,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE;YAC3G,EAAE,CAAC,SAAS,GAAG,mBAAmB,CAAC;YACnC,EAAE,CAAC,eAAe,GAAG,yBAAyB,CAAC;YAE/C,IAAI,CAAC,SAAS,GAAY;;OAEzB,CAAC;YAEF,MAAM,MAAM,GAAG,QAAQ,EAAE,CAAC;YAE1B,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEhB,MAAM,CAAC,KAAK,CACV,IAAI,CAAC,SAAS;iBACX,KAAK,CAAC,IAAI,CAAC;iBACX,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;iBACxB,IAAI,CAAC,EAAE,CAAC,EACX,qFAAqF,CACtF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC;AAEF,KAAK,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;IACvB,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAEvB,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AAC1D,CAAC"}
1
+ {"version":3,"file":"template.test.js","sourceRoot":"","sources":["../../src/lib/template.test.ts"],"names":[],"mappings":"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"}
package/target/lib.d.ts CHANGED
@@ -3,5 +3,5 @@ export { attr } from './lib/attr.js';
3
3
  export { listen } from './lib/listen.js';
4
4
  export { element } from './lib/element.js';
5
5
  export { query } from './lib/query.js';
6
- export { template } from './lib/template.js';
6
+ export { template, getTemplateValue } from './lib/template.js';
7
7
  export { ready } from './lib/lifecycle.js';
package/target/lib.js CHANGED
@@ -3,6 +3,6 @@ export { attr } from './lib/attr.js';
3
3
  export { listen } from './lib/listen.js';
4
4
  export { element } from './lib/element.js';
5
5
  export { query } from './lib/query.js';
6
- export { template } from './lib/template.js';
6
+ export { template, getTemplateValue } from './lib/template.js';
7
7
  export { ready } from './lib/lifecycle.js';
8
8
  //# sourceMappingURL=lib.js.map
package/target/lib.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC"}