p-elements-core 1.2.32-rc8 → 1.2.32
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/index.html +10 -2
- package/package.json +1 -1
- 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 +3 -8
- 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/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 +205 -205
- package/src/sample/mixin/highlight.tsx +33 -33
- package/src/sample/sample.tsx +98 -0
|
@@ -1,146 +1,146 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for @query decorator
|
|
3
|
-
* Covers Shadow DOM and Light DOM queries
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { describe, it, expect } from 'vitest';
|
|
7
|
-
import '../test-setup.js';
|
|
8
|
-
import { query } from './query.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('@query decorator', () => {
|
|
15
|
-
it('should query element in shadow DOM by default', async () => {
|
|
16
|
-
const tagName = generateUniqueTagName('query-shadow');
|
|
17
|
-
|
|
18
|
-
@customElementConfig({ tagName })
|
|
19
|
-
class QueryTest extends CustomElement {
|
|
20
|
-
static style = ':host { display: block; }';
|
|
21
|
-
@query('.test-target')
|
|
22
|
-
target: HTMLElement;
|
|
23
|
-
|
|
24
|
-
render() {
|
|
25
|
-
return {
|
|
26
|
-
vnodeSelector: 'div',
|
|
27
|
-
properties: {},
|
|
28
|
-
children: [
|
|
29
|
-
{
|
|
30
|
-
vnodeSelector: 'span',
|
|
31
|
-
properties: { class: 'test-target' },
|
|
32
|
-
text: 'Found me!',
|
|
33
|
-
domNode: null as any,
|
|
34
|
-
children: []
|
|
35
|
-
},
|
|
36
|
-
],
|
|
37
|
-
text: undefined,
|
|
38
|
-
domNode: null
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const el = document.createElement(tagName) as QueryTest;
|
|
44
|
-
document.body.appendChild(el);
|
|
45
|
-
await waitForRender(el);
|
|
46
|
-
|
|
47
|
-
expect(el.target).toBeDefined();
|
|
48
|
-
expect(el.target.tagName).toBe('SPAN');
|
|
49
|
-
expect(el.target.classList.contains('test-target')).toBe(true);
|
|
50
|
-
|
|
51
|
-
document.body.removeChild(el);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('should query element in light DOM when useShadowRoot is false', async () => {
|
|
55
|
-
const tagName = generateUniqueTagName('query-light');
|
|
56
|
-
|
|
57
|
-
@customElementConfig({ tagName })
|
|
58
|
-
class QueryTest extends CustomElement {
|
|
59
|
-
static style = ':host { display: block; }';
|
|
60
|
-
@query('.light-target', false)
|
|
61
|
-
target: HTMLElement;
|
|
62
|
-
|
|
63
|
-
render() {
|
|
64
|
-
return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const el = document.createElement(tagName) as QueryTest;
|
|
69
|
-
const lightChild = document.createElement('div');
|
|
70
|
-
lightChild.className = 'light-target';
|
|
71
|
-
lightChild.textContent = 'Light DOM';
|
|
72
|
-
el.appendChild(lightChild);
|
|
73
|
-
|
|
74
|
-
document.body.appendChild(el);
|
|
75
|
-
await waitForRender(el);
|
|
76
|
-
|
|
77
|
-
expect(el.target).toBeDefined();
|
|
78
|
-
expect(el.target.className).toBe('light-target');
|
|
79
|
-
|
|
80
|
-
document.body.removeChild(el);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('should return null when element not found', async () => {
|
|
84
|
-
const tagName = generateUniqueTagName('query-missing');
|
|
85
|
-
|
|
86
|
-
@customElementConfig({ tagName })
|
|
87
|
-
class QueryTest extends CustomElement {
|
|
88
|
-
static style = ':host { display: block; }';
|
|
89
|
-
@query('.does-not-exist')
|
|
90
|
-
target: HTMLElement;
|
|
91
|
-
|
|
92
|
-
render() {
|
|
93
|
-
return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const el = document.createElement(tagName) as QueryTest;
|
|
98
|
-
document.body.appendChild(el);
|
|
99
|
-
await waitForRender(el);
|
|
100
|
-
|
|
101
|
-
expect(el.target).toBeNull();
|
|
102
|
-
|
|
103
|
-
document.body.removeChild(el);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('should update query result when DOM changes', async () => {
|
|
107
|
-
const tagName = generateUniqueTagName('query-dynamic');
|
|
108
|
-
let showElement = false;
|
|
109
|
-
|
|
110
|
-
@customElementConfig({ tagName })
|
|
111
|
-
class QueryTest extends CustomElement {
|
|
112
|
-
static style = ':host { display: block; }';
|
|
113
|
-
@query('.dynamic')
|
|
114
|
-
target: HTMLElement;
|
|
115
|
-
|
|
116
|
-
render() {
|
|
117
|
-
const children = showElement
|
|
118
|
-
? [{ vnodeSelector: 'span', properties: { class: 'dynamic' }, text: 'Dynamic', domNode: null as any, children: [] }]
|
|
119
|
-
: [];
|
|
120
|
-
|
|
121
|
-
return {
|
|
122
|
-
vnodeSelector: 'div',
|
|
123
|
-
properties: {},
|
|
124
|
-
children,
|
|
125
|
-
text: undefined,
|
|
126
|
-
domNode: null
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const el = document.createElement(tagName) as QueryTest;
|
|
132
|
-
document.body.appendChild(el);
|
|
133
|
-
await waitForRender(el);
|
|
134
|
-
|
|
135
|
-
expect(el.target).toBeNull();
|
|
136
|
-
|
|
137
|
-
showElement = true;
|
|
138
|
-
el.renderNow();
|
|
139
|
-
await waitForRender(el);
|
|
140
|
-
|
|
141
|
-
expect(el.target).toBeDefined();
|
|
142
|
-
expect(el.target.tagName).toBe('SPAN');
|
|
143
|
-
|
|
144
|
-
document.body.removeChild(el);
|
|
145
|
-
});
|
|
146
|
-
});
|
|
1
|
+
/**
|
|
2
|
+
* Tests for @query decorator
|
|
3
|
+
* Covers Shadow DOM and Light DOM queries
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, it, expect } from 'vitest';
|
|
7
|
+
import '../test-setup.js';
|
|
8
|
+
import { query } from './query.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('@query decorator', () => {
|
|
15
|
+
it('should query element in shadow DOM by default', async () => {
|
|
16
|
+
const tagName = generateUniqueTagName('query-shadow');
|
|
17
|
+
|
|
18
|
+
@customElementConfig({ tagName })
|
|
19
|
+
class QueryTest extends CustomElement {
|
|
20
|
+
static style = ':host { display: block; }';
|
|
21
|
+
@query('.test-target')
|
|
22
|
+
target: HTMLElement;
|
|
23
|
+
|
|
24
|
+
render() {
|
|
25
|
+
return {
|
|
26
|
+
vnodeSelector: 'div',
|
|
27
|
+
properties: {},
|
|
28
|
+
children: [
|
|
29
|
+
{
|
|
30
|
+
vnodeSelector: 'span',
|
|
31
|
+
properties: { class: 'test-target' },
|
|
32
|
+
text: 'Found me!',
|
|
33
|
+
domNode: null as any,
|
|
34
|
+
children: []
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
text: undefined,
|
|
38
|
+
domNode: null
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const el = document.createElement(tagName) as QueryTest;
|
|
44
|
+
document.body.appendChild(el);
|
|
45
|
+
await waitForRender(el);
|
|
46
|
+
|
|
47
|
+
expect(el.target).toBeDefined();
|
|
48
|
+
expect(el.target.tagName).toBe('SPAN');
|
|
49
|
+
expect(el.target.classList.contains('test-target')).toBe(true);
|
|
50
|
+
|
|
51
|
+
document.body.removeChild(el);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should query element in light DOM when useShadowRoot is false', async () => {
|
|
55
|
+
const tagName = generateUniqueTagName('query-light');
|
|
56
|
+
|
|
57
|
+
@customElementConfig({ tagName })
|
|
58
|
+
class QueryTest extends CustomElement {
|
|
59
|
+
static style = ':host { display: block; }';
|
|
60
|
+
@query('.light-target', false)
|
|
61
|
+
target: HTMLElement;
|
|
62
|
+
|
|
63
|
+
render() {
|
|
64
|
+
return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const el = document.createElement(tagName) as QueryTest;
|
|
69
|
+
const lightChild = document.createElement('div');
|
|
70
|
+
lightChild.className = 'light-target';
|
|
71
|
+
lightChild.textContent = 'Light DOM';
|
|
72
|
+
el.appendChild(lightChild);
|
|
73
|
+
|
|
74
|
+
document.body.appendChild(el);
|
|
75
|
+
await waitForRender(el);
|
|
76
|
+
|
|
77
|
+
expect(el.target).toBeDefined();
|
|
78
|
+
expect(el.target.className).toBe('light-target');
|
|
79
|
+
|
|
80
|
+
document.body.removeChild(el);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should return null when element not found', async () => {
|
|
84
|
+
const tagName = generateUniqueTagName('query-missing');
|
|
85
|
+
|
|
86
|
+
@customElementConfig({ tagName })
|
|
87
|
+
class QueryTest extends CustomElement {
|
|
88
|
+
static style = ':host { display: block; }';
|
|
89
|
+
@query('.does-not-exist')
|
|
90
|
+
target: HTMLElement;
|
|
91
|
+
|
|
92
|
+
render() {
|
|
93
|
+
return { vnodeSelector: 'div', properties: {}, children: [], text: undefined, domNode: null };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const el = document.createElement(tagName) as QueryTest;
|
|
98
|
+
document.body.appendChild(el);
|
|
99
|
+
await waitForRender(el);
|
|
100
|
+
|
|
101
|
+
expect(el.target).toBeNull();
|
|
102
|
+
|
|
103
|
+
document.body.removeChild(el);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should update query result when DOM changes', async () => {
|
|
107
|
+
const tagName = generateUniqueTagName('query-dynamic');
|
|
108
|
+
let showElement = false;
|
|
109
|
+
|
|
110
|
+
@customElementConfig({ tagName })
|
|
111
|
+
class QueryTest extends CustomElement {
|
|
112
|
+
static style = ':host { display: block; }';
|
|
113
|
+
@query('.dynamic')
|
|
114
|
+
target: HTMLElement;
|
|
115
|
+
|
|
116
|
+
render() {
|
|
117
|
+
const children = showElement
|
|
118
|
+
? [{ vnodeSelector: 'span', properties: { class: 'dynamic' }, text: 'Dynamic', domNode: null as any, children: [] }]
|
|
119
|
+
: [];
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
vnodeSelector: 'div',
|
|
123
|
+
properties: {},
|
|
124
|
+
children,
|
|
125
|
+
text: undefined,
|
|
126
|
+
domNode: null
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const el = document.createElement(tagName) as QueryTest;
|
|
132
|
+
document.body.appendChild(el);
|
|
133
|
+
await waitForRender(el);
|
|
134
|
+
|
|
135
|
+
expect(el.target).toBeNull();
|
|
136
|
+
|
|
137
|
+
showElement = true;
|
|
138
|
+
el.renderNow();
|
|
139
|
+
await waitForRender(el);
|
|
140
|
+
|
|
141
|
+
expect(el.target).toBeDefined();
|
|
142
|
+
expect(el.target.tagName).toBe('SPAN');
|
|
143
|
+
|
|
144
|
+
document.body.removeChild(el);
|
|
145
|
+
});
|
|
146
|
+
});
|
package/src/decorators/query.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
export const query = (selector: string, useShadowRoot = true) => {
|
|
2
|
-
return function(target: Object, propertyKey: string) {
|
|
3
|
-
Object.defineProperty(target, propertyKey, {
|
|
4
|
-
get: function() {
|
|
5
|
-
if (useShadowRoot) {
|
|
6
|
-
return this.shadowRoot.querySelector(selector);
|
|
7
|
-
}
|
|
8
|
-
return this.querySelector(selector);
|
|
9
|
-
},
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
};
|
|
1
|
+
export const query = (selector: string, useShadowRoot = true) => {
|
|
2
|
+
return function(target: Object, propertyKey: string) {
|
|
3
|
+
Object.defineProperty(target, propertyKey, {
|
|
4
|
+
get: function() {
|
|
5
|
+
if (useShadowRoot) {
|
|
6
|
+
return this.shadowRoot.querySelector(selector);
|
|
7
|
+
}
|
|
8
|
+
return this.querySelector(selector);
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {property} from "./property";
|
|
2
|
-
const propertDecorator = property({});
|
|
3
|
-
export const propertyRenderOnSet = propertDecorator;
|
|
1
|
+
import {property} from "./property";
|
|
2
|
+
const propertDecorator = property({});
|
|
3
|
+
export const propertyRenderOnSet = propertDecorator;
|
package/src/helpers/css.ts
CHANGED
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
import { CustomStyleElement } from "../custom-style-element";
|
|
2
|
-
|
|
3
|
-
const VAR_ASSIGN =
|
|
4
|
-
/(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};{])+)|\{([^}]*)\}(?:(?=[;\s}])|$))/gi;
|
|
5
|
-
|
|
6
|
-
export const cssApplyVars = new Map<string, string[]>();
|
|
7
|
-
|
|
8
|
-
function getMixinValues(valueMixin: string): { key: string; value: string }[] {
|
|
9
|
-
return valueMixin
|
|
10
|
-
?.split(";")
|
|
11
|
-
.map((mixin: string) => {
|
|
12
|
-
const [key, value] = mixin.split(":", 2);
|
|
13
|
-
return { key: key.trim(), value: value ? value.trim() : "" };
|
|
14
|
-
})
|
|
15
|
-
.filter(
|
|
16
|
-
(mixin: any) =>
|
|
17
|
-
mixin.key && mixin.key !== "" && mixin.value !== ""
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function cssApplyToCssVars(style: string): string {
|
|
22
|
-
let nrOfReplacements = 0;
|
|
23
|
-
const cssText = style.replace(
|
|
24
|
-
VAR_ASSIGN,
|
|
25
|
-
(matchText, propertyName, valueProperty, valueMixin) => {
|
|
26
|
-
if (valueMixin) {
|
|
27
|
-
nrOfReplacements++;
|
|
28
|
-
const values = getMixinValues(valueMixin);
|
|
29
|
-
let replaceText = "";
|
|
30
|
-
const props: string[] = [];
|
|
31
|
-
values.forEach((mixin: any) => {
|
|
32
|
-
props.push(mixin.key);
|
|
33
|
-
replaceText +=
|
|
34
|
-
`${propertyName}_-_${mixin.key}: ${mixin.value};` + "\n";
|
|
35
|
-
});
|
|
36
|
-
cssApplyVars.set(propertyName, props);
|
|
37
|
-
return matchText.replace(
|
|
38
|
-
propertyName,
|
|
39
|
-
`${replaceText}
|
|
40
|
-
${propertyName}`
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
return matchText;
|
|
44
|
-
}
|
|
45
|
-
);
|
|
46
|
-
return nrOfReplacements > 0 ? cssText : null;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function replaceApplyToCssVars(cssText: string) : string {
|
|
50
|
-
const allVars = (
|
|
51
|
-
customElements.get("custom-style") as typeof CustomStyleElement
|
|
52
|
-
).cssApplyVars;
|
|
53
|
-
|
|
54
|
-
let style = cssText;
|
|
55
|
-
const MIXIN_MATCH = /(?:^|\W+)@apply\s*\(?([^);\n]*)\)?/gi;
|
|
56
|
-
let m;
|
|
57
|
-
while ((m = MIXIN_MATCH.exec(style))) {
|
|
58
|
-
let matchText = m[0];
|
|
59
|
-
let mixinName = m[1];
|
|
60
|
-
if (allVars.has(mixinName)) {
|
|
61
|
-
const searchText = "@apply" + matchText.split("@apply", 2)[1];
|
|
62
|
-
const replaceText = allVars
|
|
63
|
-
.get(mixinName)
|
|
64
|
-
.map((prop: string) => `;${prop}: var(${mixinName}_-_${prop});`)
|
|
65
|
-
.join("");
|
|
66
|
-
|
|
67
|
-
style = style.replace(searchText, replaceText);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return style;
|
|
71
|
-
}
|
|
1
|
+
import { CustomStyleElement } from "../custom-style-element";
|
|
2
|
+
|
|
3
|
+
const VAR_ASSIGN =
|
|
4
|
+
/(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};{])+)|\{([^}]*)\}(?:(?=[;\s}])|$))/gi;
|
|
5
|
+
|
|
6
|
+
export const cssApplyVars = new Map<string, string[]>();
|
|
7
|
+
|
|
8
|
+
function getMixinValues(valueMixin: string): { key: string; value: string }[] {
|
|
9
|
+
return valueMixin
|
|
10
|
+
?.split(";")
|
|
11
|
+
.map((mixin: string) => {
|
|
12
|
+
const [key, value] = mixin.split(":", 2);
|
|
13
|
+
return { key: key.trim(), value: value ? value.trim() : "" };
|
|
14
|
+
})
|
|
15
|
+
.filter(
|
|
16
|
+
(mixin: any) =>
|
|
17
|
+
mixin.key && mixin.key !== "" && mixin.value !== ""
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function cssApplyToCssVars(style: string): string {
|
|
22
|
+
let nrOfReplacements = 0;
|
|
23
|
+
const cssText = style.replace(
|
|
24
|
+
VAR_ASSIGN,
|
|
25
|
+
(matchText, propertyName, valueProperty, valueMixin) => {
|
|
26
|
+
if (valueMixin) {
|
|
27
|
+
nrOfReplacements++;
|
|
28
|
+
const values = getMixinValues(valueMixin);
|
|
29
|
+
let replaceText = "";
|
|
30
|
+
const props: string[] = [];
|
|
31
|
+
values.forEach((mixin: any) => {
|
|
32
|
+
props.push(mixin.key);
|
|
33
|
+
replaceText +=
|
|
34
|
+
`${propertyName}_-_${mixin.key}: ${mixin.value};` + "\n";
|
|
35
|
+
});
|
|
36
|
+
cssApplyVars.set(propertyName, props);
|
|
37
|
+
return matchText.replace(
|
|
38
|
+
propertyName,
|
|
39
|
+
`${replaceText}
|
|
40
|
+
${propertyName}`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return matchText;
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
return nrOfReplacements > 0 ? cssText : null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function replaceApplyToCssVars(cssText: string) : string {
|
|
50
|
+
const allVars = (
|
|
51
|
+
customElements.get("custom-style") as typeof CustomStyleElement
|
|
52
|
+
).cssApplyVars;
|
|
53
|
+
|
|
54
|
+
let style = cssText;
|
|
55
|
+
const MIXIN_MATCH = /(?:^|\W+)@apply\s*\(?([^);\n]*)\)?/gi;
|
|
56
|
+
let m;
|
|
57
|
+
while ((m = MIXIN_MATCH.exec(style))) {
|
|
58
|
+
let matchText = m[0];
|
|
59
|
+
let mixinName = m[1];
|
|
60
|
+
if (allVars.has(mixinName)) {
|
|
61
|
+
const searchText = "@apply" + matchText.split("@apply", 2)[1];
|
|
62
|
+
const replaceText = allVars
|
|
63
|
+
.get(mixinName)
|
|
64
|
+
.map((prop: string) => `;${prop}: var(${mixinName}_-_${prop});`)
|
|
65
|
+
.join("");
|
|
66
|
+
|
|
67
|
+
style = style.replace(searchText, replaceText);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return style;
|
|
71
|
+
}
|
package/src/maquette/cache.ts
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import { CalculationCache } from "./interfaces";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Creates a [[CalculationCache]] object, useful for caching [[VNode]] trees.
|
|
5
|
-
* In practice, caching of [[VNode]] trees is not needed, because achieving 60 frames per second is almost never a problem.
|
|
6
|
-
* For more information, see [[CalculationCache]].
|
|
7
|
-
*
|
|
8
|
-
* @param <Result> The type of the value that is cached.
|
|
9
|
-
*/
|
|
10
|
-
export let createCache = <Result,>(): CalculationCache<Result> => {
|
|
11
|
-
let cachedInputs: unknown[] | undefined;
|
|
12
|
-
let cachedOutcome: Result | undefined;
|
|
13
|
-
|
|
14
|
-
return {
|
|
15
|
-
invalidate: () => {
|
|
16
|
-
cachedOutcome = undefined;
|
|
17
|
-
cachedInputs = undefined;
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
result: (inputs: unknown[], calculation: () => Result) => {
|
|
21
|
-
if (cachedInputs) {
|
|
22
|
-
for (let i = 0; i < inputs.length; i++) {
|
|
23
|
-
if (cachedInputs[i] !== inputs[i]) {
|
|
24
|
-
cachedOutcome = undefined;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
if (!cachedOutcome) {
|
|
29
|
-
cachedOutcome = calculation();
|
|
30
|
-
cachedInputs = inputs;
|
|
31
|
-
}
|
|
32
|
-
return cachedOutcome;
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
};
|
|
1
|
+
import { CalculationCache } from "./interfaces";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates a [[CalculationCache]] object, useful for caching [[VNode]] trees.
|
|
5
|
+
* In practice, caching of [[VNode]] trees is not needed, because achieving 60 frames per second is almost never a problem.
|
|
6
|
+
* For more information, see [[CalculationCache]].
|
|
7
|
+
*
|
|
8
|
+
* @param <Result> The type of the value that is cached.
|
|
9
|
+
*/
|
|
10
|
+
export let createCache = <Result,>(): CalculationCache<Result> => {
|
|
11
|
+
let cachedInputs: unknown[] | undefined;
|
|
12
|
+
let cachedOutcome: Result | undefined;
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
invalidate: () => {
|
|
16
|
+
cachedOutcome = undefined;
|
|
17
|
+
cachedInputs = undefined;
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
result: (inputs: unknown[], calculation: () => Result) => {
|
|
21
|
+
if (cachedInputs) {
|
|
22
|
+
for (let i = 0; i < inputs.length; i++) {
|
|
23
|
+
if (cachedInputs[i] !== inputs[i]) {
|
|
24
|
+
cachedOutcome = undefined;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (!cachedOutcome) {
|
|
29
|
+
cachedOutcome = calculation();
|
|
30
|
+
cachedInputs = inputs;
|
|
31
|
+
}
|
|
32
|
+
return cachedOutcome;
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
};
|