p-elements-core 1.2.32-rc5 → 1.2.32-rc7
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/.editorconfig +17 -17
- package/.gitlab-ci.yml +18 -18
- package/CHANGELOG.md +201 -201
- package/demo/sample.js +1 -1
- package/demo/screen.css +16 -16
- package/dist/p-elements-core-modern.js +1 -1
- package/dist/p-elements-core.js +1 -1
- package/docs/package-lock.json +6897 -6897
- package/docs/package.json +27 -27
- package/docs/src/404.md +8 -8
- package/docs/src/_data/demos/hello-world/hello-world.tsx +35 -35
- package/docs/src/_data/demos/hello-world/index.html +10 -10
- package/docs/src/_data/demos/hello-world/project.json +7 -7
- package/docs/src/_data/demos/timer/demo-timer.tsx +120 -120
- package/docs/src/_data/demos/timer/icons.tsx +62 -62
- package/docs/src/_data/demos/timer/index.html +12 -12
- package/docs/src/_data/demos/timer/project.json +8 -8
- package/docs/src/_data/global.js +13 -13
- package/docs/src/_data/helpers.js +19 -19
- package/docs/src/_includes/layouts/base.njk +30 -30
- package/docs/src/_includes/layouts/playground.njk +40 -40
- package/docs/src/_includes/partials/app-header.njk +8 -8
- package/docs/src/_includes/partials/head.njk +14 -14
- package/docs/src/_includes/partials/nav.njk +19 -19
- package/docs/src/_includes/partials/top-nav.njk +51 -51
- package/docs/src/documentation/custom-element.md +221 -221
- package/docs/src/documentation/decorators/bind.md +71 -71
- package/docs/src/documentation/decorators/custom-element-config.md +63 -63
- package/docs/src/documentation/decorators/property.md +83 -83
- package/docs/src/documentation/decorators/query.md +66 -66
- package/docs/src/documentation/decorators/render-property-on-set.md +60 -60
- package/docs/src/documentation/decorators.md +9 -9
- package/docs/src/documentation/reactive-properties.md +53 -53
- package/docs/src/index.d.ts +25 -25
- package/docs/src/index.md +3 -3
- package/docs/src/scripts/components/app-mode-switch/app-mode-switch.css +78 -78
- package/docs/src/scripts/components/app-mode-switch/app-mode-switch.tsx +166 -166
- package/docs/src/scripts/components/app-playground/app-playground.tsx +189 -189
- package/docs/tsconfig.json +22 -22
- package/package.json +2 -2
- package/readme.md +206 -206
- package/src/custom-element-controller.ts +31 -31
- package/src/custom-element.test.ts +906 -906
- package/src/custom-element.ts +9 -9
- package/src/decorators/bind.test.ts +163 -163
- package/src/decorators/bind.ts +46 -46
- package/src/decorators/custom-element-config.ts +17 -17
- package/src/decorators/property.test.ts +279 -279
- package/src/decorators/property.ts +1 -2
- package/src/decorators/query.test.ts +146 -146
- package/src/decorators/query.ts +12 -12
- package/src/decorators/render-property-on-set.ts +3 -3
- package/src/helpers/css.ts +71 -71
- package/src/maquette/cache.ts +35 -35
- package/src/maquette/dom.ts +115 -115
- package/src/maquette/h.ts +100 -100
- package/src/maquette/index.ts +12 -12
- package/src/maquette/interfaces.ts +536 -536
- package/src/maquette/jsx.ts +61 -61
- package/src/maquette/mapping.ts +56 -56
- package/src/maquette/projection.ts +666 -666
- package/src/maquette/projector.ts +200 -200
- package/src/sample/mixin/highlight.tsx +33 -33
package/src/custom-element.ts
CHANGED
|
@@ -241,8 +241,6 @@ export abstract class CustomElement extends HTMLElement {
|
|
|
241
241
|
this.#updateResolve = resolve;
|
|
242
242
|
});
|
|
243
243
|
}
|
|
244
|
-
// this.#projector.
|
|
245
|
-
// render(this.shadowRoot, this.render());
|
|
246
244
|
this.#projector?.renderNow();
|
|
247
245
|
|
|
248
246
|
// Call updated() lifecycle hook after DOM updates are complete
|
|
@@ -389,10 +387,13 @@ export abstract class CustomElement extends HTMLElement {
|
|
|
389
387
|
this.addStylesheetToRootNode(css, root);
|
|
390
388
|
}
|
|
391
389
|
|
|
392
|
-
protected createProjector(
|
|
390
|
+
protected async createProjector(
|
|
393
391
|
element: Element,
|
|
394
392
|
render: () => VNode,
|
|
395
393
|
): Promise<Projector> {
|
|
394
|
+
|
|
395
|
+
await new Promise((resolve) => requestAnimationFrame(resolve));
|
|
396
|
+
|
|
396
397
|
return new Promise<Projector>((resolve, reject) => {
|
|
397
398
|
let projector: Projector;
|
|
398
399
|
const mode = this.#projectorMode ? this.#projectorMode : "append";
|
|
@@ -406,7 +407,9 @@ export abstract class CustomElement extends HTMLElement {
|
|
|
406
407
|
});
|
|
407
408
|
projector[mode](element, render.bind(this));
|
|
408
409
|
this.#projector = projector;
|
|
409
|
-
|
|
410
|
+
requestAnimationFrame(() => {
|
|
411
|
+
projector.renderNow();
|
|
412
|
+
});
|
|
410
413
|
resolve(projector);
|
|
411
414
|
this.dispatchEvent(new CustomEvent("firstRender", {}));
|
|
412
415
|
});
|
|
@@ -571,7 +574,6 @@ export abstract class CustomElement extends HTMLElement {
|
|
|
571
574
|
if (this.#connected === false) {
|
|
572
575
|
return;
|
|
573
576
|
}
|
|
574
|
-
console.log("disconnectedCallback called");
|
|
575
577
|
this.#connected = false;
|
|
576
578
|
let i = 0;
|
|
577
579
|
const controllersLength = this.#controllers.length;
|
|
@@ -601,10 +603,8 @@ export abstract class CustomElement extends HTMLElement {
|
|
|
601
603
|
newValue: string | null,
|
|
602
604
|
): void {
|
|
603
605
|
// Skip if this attribute change came from a property setter (prevent infinite loop)
|
|
604
|
-
if (
|
|
605
|
-
|
|
606
|
-
}
|
|
607
|
-
if (newValue === oldValue) {
|
|
606
|
+
// Also skip if the value didn't actually change (some browsers may call this callback even if the value is the same)
|
|
607
|
+
if (isSettingAttribute(this) || newValue === oldValue) {
|
|
608
608
|
return;
|
|
609
609
|
}
|
|
610
610
|
const ctor = this.constructor as ComponentConstructor;
|
|
@@ -1,163 +1,163 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for @bind decorator
|
|
3
|
-
* Covers method binding to preserve 'this' context
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { describe, it, expect } from 'vitest';
|
|
7
|
-
import '../test-setup.js';
|
|
8
|
-
import { bind } from './bind.js';
|
|
9
|
-
import { CustomElement } from '../custom-element.js';
|
|
10
|
-
import { customElementConfig } from './custom-element-config.js';
|
|
11
|
-
import { generateUniqueTagName } from '../test-setup.js';
|
|
12
|
-
import { waitForRender } from '../test-utils.js';
|
|
13
|
-
|
|
14
|
-
describe('@bind decorator', () => {
|
|
15
|
-
it('should bind method to instance', async () => {
|
|
16
|
-
const tagName = generateUniqueTagName('bind-test');
|
|
17
|
-
|
|
18
|
-
@customElementConfig({ tagName })
|
|
19
|
-
class BindTest extends CustomElement {
|
|
20
|
-
static style = ':host { display: block; }';
|
|
21
|
-
value = 'bound';
|
|
22
|
-
|
|
23
|
-
@bind
|
|
24
|
-
getValue() {
|
|
25
|
-
return this.value;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
render() {
|
|
29
|
-
return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const el = document.createElement(tagName) as BindTest;
|
|
34
|
-
document.body.appendChild(el);
|
|
35
|
-
await waitForRender(el);
|
|
36
|
-
|
|
37
|
-
const method = el.getValue;
|
|
38
|
-
expect(method()).toBe('bound');
|
|
39
|
-
|
|
40
|
-
document.body.removeChild(el);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('should preserve this context when method is extracted', async () => {
|
|
44
|
-
const tagName = generateUniqueTagName('bind-test');
|
|
45
|
-
|
|
46
|
-
@customElementConfig({ tagName })
|
|
47
|
-
class BindTest extends CustomElement {
|
|
48
|
-
static style = ':host { display: block; }';
|
|
49
|
-
name = 'test-element';
|
|
50
|
-
|
|
51
|
-
@bind
|
|
52
|
-
getName() {
|
|
53
|
-
return this.name;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
render() {
|
|
57
|
-
return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const el = document.createElement(tagName) as BindTest;
|
|
62
|
-
document.body.appendChild(el);
|
|
63
|
-
await waitForRender(el);
|
|
64
|
-
|
|
65
|
-
const { getName } = el;
|
|
66
|
-
expect(getName()).toBe('test-element');
|
|
67
|
-
|
|
68
|
-
document.body.removeChild(el);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('should work with callbacks', async () => {
|
|
72
|
-
const tagName = generateUniqueTagName('bind-test');
|
|
73
|
-
let result: string;
|
|
74
|
-
|
|
75
|
-
@customElementConfig({ tagName })
|
|
76
|
-
class BindTest extends CustomElement {
|
|
77
|
-
static style = ':host { display: block; }';
|
|
78
|
-
message = 'callback test';
|
|
79
|
-
|
|
80
|
-
@bind
|
|
81
|
-
handleCallback() {
|
|
82
|
-
return this.message;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
render() {
|
|
86
|
-
return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const el = document.createElement(tagName) as BindTest;
|
|
91
|
-
document.body.appendChild(el);
|
|
92
|
-
await waitForRender(el);
|
|
93
|
-
|
|
94
|
-
const callback = el.handleCallback;
|
|
95
|
-
result = callback();
|
|
96
|
-
|
|
97
|
-
expect(result).toBe('callback test');
|
|
98
|
-
|
|
99
|
-
document.body.removeChild(el);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('should handle methods with arguments', async () => {
|
|
103
|
-
const tagName = generateUniqueTagName('bind-test');
|
|
104
|
-
|
|
105
|
-
@customElementConfig({ tagName })
|
|
106
|
-
class BindTest extends CustomElement {
|
|
107
|
-
static style = ':host { display: block; }';
|
|
108
|
-
|
|
109
|
-
prefixValue = 'Hello';
|
|
110
|
-
|
|
111
|
-
@bind
|
|
112
|
-
greet(name: string) {
|
|
113
|
-
return `${this.prefixValue}, ${name}!`;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
render() {
|
|
117
|
-
return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const el = document.createElement(tagName) as BindTest;
|
|
122
|
-
document.body.appendChild(el);
|
|
123
|
-
await waitForRender(el);
|
|
124
|
-
|
|
125
|
-
const extracted = el.greet;
|
|
126
|
-
expect(extracted('World')).toBe('Hello, World!');
|
|
127
|
-
|
|
128
|
-
document.body.removeChild(el);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it('should preserve bound method reference', async () => {
|
|
132
|
-
const tagName = generateUniqueTagName('bind-test');
|
|
133
|
-
|
|
134
|
-
@customElementConfig({ tagName })
|
|
135
|
-
class BindTest extends CustomElement {
|
|
136
|
-
static style = ':host { display: block; }';
|
|
137
|
-
|
|
138
|
-
valueNum = 42;
|
|
139
|
-
|
|
140
|
-
@bind
|
|
141
|
-
getValue() {
|
|
142
|
-
return this.valueNum;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
render() {
|
|
146
|
-
return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const el = document.createElement(tagName) as BindTest;
|
|
151
|
-
document.body.appendChild(el);
|
|
152
|
-
await waitForRender(el);
|
|
153
|
-
|
|
154
|
-
const bound1 = el.getValue;
|
|
155
|
-
const bound2 = el.getValue;
|
|
156
|
-
|
|
157
|
-
// Should return the same bound function
|
|
158
|
-
expect(bound1).toBe(bound2);
|
|
159
|
-
expect(bound1()).toBe(42);
|
|
160
|
-
|
|
161
|
-
document.body.removeChild(el);
|
|
162
|
-
});
|
|
163
|
-
});
|
|
1
|
+
/**
|
|
2
|
+
* Tests for @bind decorator
|
|
3
|
+
* Covers method binding to preserve 'this' context
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, it, expect } from 'vitest';
|
|
7
|
+
import '../test-setup.js';
|
|
8
|
+
import { bind } from './bind.js';
|
|
9
|
+
import { CustomElement } from '../custom-element.js';
|
|
10
|
+
import { customElementConfig } from './custom-element-config.js';
|
|
11
|
+
import { generateUniqueTagName } from '../test-setup.js';
|
|
12
|
+
import { waitForRender } from '../test-utils.js';
|
|
13
|
+
|
|
14
|
+
describe('@bind decorator', () => {
|
|
15
|
+
it('should bind method to instance', async () => {
|
|
16
|
+
const tagName = generateUniqueTagName('bind-test');
|
|
17
|
+
|
|
18
|
+
@customElementConfig({ tagName })
|
|
19
|
+
class BindTest extends CustomElement {
|
|
20
|
+
static style = ':host { display: block; }';
|
|
21
|
+
value = 'bound';
|
|
22
|
+
|
|
23
|
+
@bind
|
|
24
|
+
getValue() {
|
|
25
|
+
return this.value;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
render() {
|
|
29
|
+
return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const el = document.createElement(tagName) as BindTest;
|
|
34
|
+
document.body.appendChild(el);
|
|
35
|
+
await waitForRender(el);
|
|
36
|
+
|
|
37
|
+
const method = el.getValue;
|
|
38
|
+
expect(method()).toBe('bound');
|
|
39
|
+
|
|
40
|
+
document.body.removeChild(el);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should preserve this context when method is extracted', async () => {
|
|
44
|
+
const tagName = generateUniqueTagName('bind-test');
|
|
45
|
+
|
|
46
|
+
@customElementConfig({ tagName })
|
|
47
|
+
class BindTest extends CustomElement {
|
|
48
|
+
static style = ':host { display: block; }';
|
|
49
|
+
name = 'test-element';
|
|
50
|
+
|
|
51
|
+
@bind
|
|
52
|
+
getName() {
|
|
53
|
+
return this.name;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
render() {
|
|
57
|
+
return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const el = document.createElement(tagName) as BindTest;
|
|
62
|
+
document.body.appendChild(el);
|
|
63
|
+
await waitForRender(el);
|
|
64
|
+
|
|
65
|
+
const { getName } = el;
|
|
66
|
+
expect(getName()).toBe('test-element');
|
|
67
|
+
|
|
68
|
+
document.body.removeChild(el);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should work with callbacks', async () => {
|
|
72
|
+
const tagName = generateUniqueTagName('bind-test');
|
|
73
|
+
let result: string;
|
|
74
|
+
|
|
75
|
+
@customElementConfig({ tagName })
|
|
76
|
+
class BindTest extends CustomElement {
|
|
77
|
+
static style = ':host { display: block; }';
|
|
78
|
+
message = 'callback test';
|
|
79
|
+
|
|
80
|
+
@bind
|
|
81
|
+
handleCallback() {
|
|
82
|
+
return this.message;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
render() {
|
|
86
|
+
return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const el = document.createElement(tagName) as BindTest;
|
|
91
|
+
document.body.appendChild(el);
|
|
92
|
+
await waitForRender(el);
|
|
93
|
+
|
|
94
|
+
const callback = el.handleCallback;
|
|
95
|
+
result = callback();
|
|
96
|
+
|
|
97
|
+
expect(result).toBe('callback test');
|
|
98
|
+
|
|
99
|
+
document.body.removeChild(el);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should handle methods with arguments', async () => {
|
|
103
|
+
const tagName = generateUniqueTagName('bind-test');
|
|
104
|
+
|
|
105
|
+
@customElementConfig({ tagName })
|
|
106
|
+
class BindTest extends CustomElement {
|
|
107
|
+
static style = ':host { display: block; }';
|
|
108
|
+
|
|
109
|
+
prefixValue = 'Hello';
|
|
110
|
+
|
|
111
|
+
@bind
|
|
112
|
+
greet(name: string) {
|
|
113
|
+
return `${this.prefixValue}, ${name}!`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
render() {
|
|
117
|
+
return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const el = document.createElement(tagName) as BindTest;
|
|
122
|
+
document.body.appendChild(el);
|
|
123
|
+
await waitForRender(el);
|
|
124
|
+
|
|
125
|
+
const extracted = el.greet;
|
|
126
|
+
expect(extracted('World')).toBe('Hello, World!');
|
|
127
|
+
|
|
128
|
+
document.body.removeChild(el);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should preserve bound method reference', async () => {
|
|
132
|
+
const tagName = generateUniqueTagName('bind-test');
|
|
133
|
+
|
|
134
|
+
@customElementConfig({ tagName })
|
|
135
|
+
class BindTest extends CustomElement {
|
|
136
|
+
static style = ':host { display: block; }';
|
|
137
|
+
|
|
138
|
+
valueNum = 42;
|
|
139
|
+
|
|
140
|
+
@bind
|
|
141
|
+
getValue() {
|
|
142
|
+
return this.valueNum;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
render() {
|
|
146
|
+
return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const el = document.createElement(tagName) as BindTest;
|
|
151
|
+
document.body.appendChild(el);
|
|
152
|
+
await waitForRender(el);
|
|
153
|
+
|
|
154
|
+
const bound1 = el.getValue;
|
|
155
|
+
const bound2 = el.getValue;
|
|
156
|
+
|
|
157
|
+
// Should return the same bound function
|
|
158
|
+
expect(bound1).toBe(bound2);
|
|
159
|
+
expect(bound1()).toBe(42);
|
|
160
|
+
|
|
161
|
+
document.body.removeChild(el);
|
|
162
|
+
});
|
|
163
|
+
});
|
package/src/decorators/bind.ts
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
export const bind = (target, key, descriptor) => {
|
|
2
|
-
let fn = descriptor.value;
|
|
3
|
-
// console.warn("@Bind decorator is deprecated, use arrow function expression");
|
|
4
|
-
if (typeof fn !== "function") {
|
|
5
|
-
throw new Error(
|
|
6
|
-
`@Bind decorator can only be applied to methods not: ${typeof fn}`
|
|
7
|
-
);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
// In IE11 calling Object.defineProperty has a side-effect of evaluating the
|
|
11
|
-
// getter for the property which is being replaced. This causes infinite
|
|
12
|
-
// recursion and an "Out of stack space" error.
|
|
13
|
-
let definingProperty = false;
|
|
14
|
-
|
|
15
|
-
return {
|
|
16
|
-
configurable: true,
|
|
17
|
-
get() {
|
|
18
|
-
if (
|
|
19
|
-
definingProperty ||
|
|
20
|
-
this === target.prototype ||
|
|
21
|
-
this.hasOwnProperty(key) ||
|
|
22
|
-
typeof fn !== "function"
|
|
23
|
-
) {
|
|
24
|
-
return fn;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
let boundFn = fn.bind(this);
|
|
28
|
-
definingProperty = true;
|
|
29
|
-
Object.defineProperty(this, key, {
|
|
30
|
-
configurable: true,
|
|
31
|
-
get() {
|
|
32
|
-
return boundFn;
|
|
33
|
-
},
|
|
34
|
-
set(value) {
|
|
35
|
-
fn = value;
|
|
36
|
-
delete this[key];
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
definingProperty = false;
|
|
40
|
-
return boundFn;
|
|
41
|
-
},
|
|
42
|
-
set(value) {
|
|
43
|
-
fn = value;
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
|
-
};
|
|
1
|
+
export const bind = (target, key, descriptor) => {
|
|
2
|
+
let fn = descriptor.value;
|
|
3
|
+
// console.warn("@Bind decorator is deprecated, use arrow function expression");
|
|
4
|
+
if (typeof fn !== "function") {
|
|
5
|
+
throw new Error(
|
|
6
|
+
`@Bind decorator can only be applied to methods not: ${typeof fn}`
|
|
7
|
+
);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// In IE11 calling Object.defineProperty has a side-effect of evaluating the
|
|
11
|
+
// getter for the property which is being replaced. This causes infinite
|
|
12
|
+
// recursion and an "Out of stack space" error.
|
|
13
|
+
let definingProperty = false;
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
configurable: true,
|
|
17
|
+
get() {
|
|
18
|
+
if (
|
|
19
|
+
definingProperty ||
|
|
20
|
+
this === target.prototype ||
|
|
21
|
+
this.hasOwnProperty(key) ||
|
|
22
|
+
typeof fn !== "function"
|
|
23
|
+
) {
|
|
24
|
+
return fn;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let boundFn = fn.bind(this);
|
|
28
|
+
definingProperty = true;
|
|
29
|
+
Object.defineProperty(this, key, {
|
|
30
|
+
configurable: true,
|
|
31
|
+
get() {
|
|
32
|
+
return boundFn;
|
|
33
|
+
},
|
|
34
|
+
set(value) {
|
|
35
|
+
fn = value;
|
|
36
|
+
delete this[key];
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
definingProperty = false;
|
|
40
|
+
return boundFn;
|
|
41
|
+
},
|
|
42
|
+
set(value) {
|
|
43
|
+
fn = value;
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
};
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
export interface IElementConfig {
|
|
2
|
-
tagName: string;
|
|
3
|
-
options?: {
|
|
4
|
-
extends: string;
|
|
5
|
-
};
|
|
6
|
-
}
|
|
7
|
-
export const customElementConfig = (config: IElementConfig) => {
|
|
8
|
-
return (Element) => {
|
|
9
|
-
if (customElements.get(config.tagName)) {
|
|
10
|
-
console.warn(
|
|
11
|
-
`Custom element with tag name ${config.tagName} already exists.`
|
|
12
|
-
);
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
customElements.define(config.tagName, Element, config.options);
|
|
16
|
-
};
|
|
17
|
-
};
|
|
1
|
+
export interface IElementConfig {
|
|
2
|
+
tagName: string;
|
|
3
|
+
options?: {
|
|
4
|
+
extends: string;
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
export const customElementConfig = (config: IElementConfig) => {
|
|
8
|
+
return (Element) => {
|
|
9
|
+
if (customElements.get(config.tagName)) {
|
|
10
|
+
console.warn(
|
|
11
|
+
`Custom element with tag name ${config.tagName} already exists.`
|
|
12
|
+
);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
customElements.define(config.tagName, Element, config.options);
|
|
16
|
+
};
|
|
17
|
+
};
|