@supersoniks/concorde 3.2.6 → 3.3.2
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/build-infos.json +1 -1
- package/concorde-core.bundle.js +249 -249
- package/concorde-core.es.js +2251 -1886
- package/dist/concorde-core.bundle.js +249 -249
- package/dist/concorde-core.es.js +2251 -1886
- package/docs/assets/{index-C0K6xugr.css → index-B669R8JF.css} +1 -1
- package/docs/assets/index-BTo6ly4d.js +4820 -0
- package/docs/index.html +2 -2
- package/docs/src/core/components/functional/fetch/fetch.md +6 -0
- package/docs/src/core/components/ui/menu/menu.md +46 -5
- package/docs/src/core/components/ui/modal/modal.md +0 -4
- package/docs/src/core/components/ui/toast/toast.md +166 -0
- package/docs/src/docs/_misc/ancestor-attribute.md +94 -0
- package/docs/src/docs/_misc/auto-subscribe.md +199 -0
- package/docs/src/docs/_misc/bind.md +362 -0
- package/docs/src/docs/_misc/on-assign.md +336 -0
- package/docs/src/docs/_misc/templates-demo.md +19 -0
- package/docs/src/docs/search/docs-search.json +550 -0
- package/docs/src/tsconfig-model.json +1 -1
- package/docs/src/tsconfig.json +28 -8
- package/package.json +8 -1
- package/src/core/components/functional/queue/queue.demo.ts +8 -11
- package/src/core/components/functional/sdui/sdui.ts +47 -22
- package/src/core/components/ui/form/input-autocomplete/input-autocomplete.ts +9 -1
- package/src/core/components/ui/tooltip/tooltip.ts +67 -2
- package/src/core/decorators/Subscriber.ts +5 -187
- package/src/core/decorators/subscriber/ancestorAttribute.ts +17 -0
- package/src/core/decorators/subscriber/autoFill.ts +28 -0
- package/src/core/decorators/subscriber/autoSubscribe.ts +54 -0
- package/src/core/decorators/subscriber/bind.ts +305 -0
- package/src/core/decorators/subscriber/common.ts +50 -0
- package/src/core/decorators/subscriber/onAssign.ts +318 -0
- package/src/core/mixins/Fetcher.ts +17 -8
- package/src/core/utils/HTML.ts +2 -0
- package/src/core/utils/PublisherProxy.ts +1 -1
- package/src/core/utils/api.ts +7 -0
- package/src/decorators.ts +9 -2
- package/src/docs/_misc/ancestor-attribute.md +94 -0
- package/src/docs/_misc/auto-subscribe.md +199 -0
- package/src/docs/_misc/bind.md +362 -0
- package/src/docs/_misc/on-assign.md +336 -0
- package/src/docs/_misc/templates-demo.md +19 -0
- package/src/docs/example/decorators-demo.ts +658 -0
- package/src/docs/navigation/navigation.ts +22 -3
- package/src/docs/search/docs-search.json +415 -0
- package/src/docs.ts +4 -0
- package/src/tsconfig-model.json +1 -1
- package/src/tsconfig.json +22 -2
- package/src/tsconfig.tsbuildinfo +1 -1
- package/vite.config.mts +0 -2
- package/docs/assets/index-Dgl1lJQo.js +0 -4861
- package/templates-test.html +0 -32
|
@@ -22,17 +22,14 @@ export class QueueDemo extends LitElement {
|
|
|
22
22
|
|
|
23
23
|
render() {
|
|
24
24
|
return html`
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
.noItems=${this.noItems}
|
|
34
|
-
></sonic-queue>
|
|
35
|
-
</div>
|
|
25
|
+
<sonic-queue
|
|
26
|
+
class="grid grid-cols-3 gap-3"
|
|
27
|
+
serviceurl="https://geo.api.gouv.fr/"
|
|
28
|
+
dataproviderexpression="communes?limit=$limit"
|
|
29
|
+
limit="30"
|
|
30
|
+
.items=${this.items}
|
|
31
|
+
.noItems=${this.noItems}
|
|
32
|
+
></sonic-queue>
|
|
36
33
|
`;
|
|
37
34
|
}
|
|
38
35
|
}
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
SDUINode,
|
|
6
6
|
SDUITransformDescription,
|
|
7
7
|
} from "@supersoniks/concorde/core/components/functional/sdui/types";
|
|
8
|
-
import {Fetcher, Subscriber} from "@supersoniks/concorde/mixins";
|
|
8
|
+
import { Fetcher, Subscriber } from "@supersoniks/concorde/mixins";
|
|
9
9
|
|
|
10
|
-
import {HTML, Objects} from "@supersoniks/concorde/utils";
|
|
11
|
-
import {LitElement, PropertyValues} from "lit";
|
|
12
|
-
import {customElement, property} from "lit/decorators.js";
|
|
10
|
+
import { HTML, Objects } from "@supersoniks/concorde/utils";
|
|
11
|
+
import { LitElement, PropertyValues } from "lit";
|
|
12
|
+
import { customElement, property } from "lit/decorators.js";
|
|
13
13
|
const tagName = "sonic-sdui"; // For Astro.build
|
|
14
14
|
/**
|
|
15
15
|
* ### sonic-sdui (Server Driven User Interface) est un fetcher chargant un JSON décrivant une interface utilisateur
|
|
@@ -75,7 +75,9 @@ export class SonicSDUI extends Fetcher(Subscriber(LitElement)) {
|
|
|
75
75
|
* Suppressiond du contenu du composant avant le génération de la nouvelle ui
|
|
76
76
|
*/
|
|
77
77
|
private removeChildren() {
|
|
78
|
-
while (
|
|
78
|
+
while (
|
|
79
|
+
[...this.children].filter((elt) => elt.nodeName != "SLOT").length > 0
|
|
80
|
+
) {
|
|
79
81
|
this.removeChild(this.children[0]);
|
|
80
82
|
}
|
|
81
83
|
}
|
|
@@ -118,9 +120,12 @@ export class SonicSDUI extends Fetcher(Subscriber(LitElement)) {
|
|
|
118
120
|
if (!this.sduiDescriptor) return;
|
|
119
121
|
let nodes = this.sduiDescriptor.nodes;
|
|
120
122
|
if (!nodes) nodes = [];
|
|
121
|
-
const messageProvider = {
|
|
123
|
+
const messageProvider = {
|
|
124
|
+
tagName: "sonic-toast-message-subscriber",
|
|
125
|
+
attributes: {},
|
|
126
|
+
};
|
|
122
127
|
if (this.messagesKey) {
|
|
123
|
-
messageProvider.attributes = {subDataProvider: this.messagesKey};
|
|
128
|
+
messageProvider.attributes = { subDataProvider: this.messagesKey };
|
|
124
129
|
}
|
|
125
130
|
nodes.push(messageProvider);
|
|
126
131
|
nodes.forEach((node) => this.appendChild(this.parseChild(node)));
|
|
@@ -130,7 +135,7 @@ export class SonicSDUI extends Fetcher(Subscriber(LitElement)) {
|
|
|
130
135
|
*/
|
|
131
136
|
private parseChild(node: SDUINode) {
|
|
132
137
|
const tagName = node.tagName || "div";
|
|
133
|
-
let {element, contentElement} = this.handleLibrary(node, tagName);
|
|
138
|
+
let { element, contentElement } = this.handleLibrary(node, tagName);
|
|
134
139
|
this.handleAttributes(node, element);
|
|
135
140
|
element = this.handleMarkup(node, element);
|
|
136
141
|
if (!contentElement) contentElement = element;
|
|
@@ -148,7 +153,8 @@ export class SonicSDUI extends Fetcher(Subscriber(LitElement)) {
|
|
|
148
153
|
*/
|
|
149
154
|
private handlePrefixSuffix(node: SDUINode, element: HTMLElement) {
|
|
150
155
|
const container = document.createElement("div");
|
|
151
|
-
container.innerHTML =
|
|
156
|
+
container.innerHTML =
|
|
157
|
+
(node.prefix || "") + element.outerHTML + (node.suffix || "");
|
|
152
158
|
container.style.display = "contents";
|
|
153
159
|
return container;
|
|
154
160
|
}
|
|
@@ -156,18 +162,26 @@ export class SonicSDUI extends Fetcher(Subscriber(LitElement)) {
|
|
|
156
162
|
* Création des enfants du noeud courant
|
|
157
163
|
* Si l'enfant à un attribut parentElementSelector, il est ajouté dans le noeud correspondant au sélecteur css associé et non pas dans l'élément directement.
|
|
158
164
|
*/
|
|
159
|
-
private handleChildNodes(
|
|
165
|
+
private handleChildNodes(
|
|
166
|
+
node: SDUINode,
|
|
167
|
+
contentElement: HTMLElement,
|
|
168
|
+
element: HTMLElement
|
|
169
|
+
) {
|
|
160
170
|
if (node.nodes) {
|
|
161
171
|
const children: Array<SDUINode> = node.nodes;
|
|
162
172
|
for (const child of children) {
|
|
163
173
|
const childElement = this.parseChild(child);
|
|
164
174
|
let nodeToAppendOn = contentElement;
|
|
165
175
|
if (child.parentElementSelector) {
|
|
166
|
-
nodeToAppendOn =
|
|
176
|
+
nodeToAppendOn =
|
|
177
|
+
element.querySelector(child.parentElementSelector) ||
|
|
178
|
+
contentElement;
|
|
167
179
|
}
|
|
168
|
-
if (nodeToAppendOn.shadowRoot)
|
|
180
|
+
if (nodeToAppendOn.shadowRoot)
|
|
181
|
+
nodeToAppendOn.shadowRoot.appendChild(childElement);
|
|
169
182
|
else if (nodeToAppendOn.tagName.toLocaleLowerCase() == "template") {
|
|
170
|
-
const template: HTMLTemplateElement =
|
|
183
|
+
const template: HTMLTemplateElement =
|
|
184
|
+
nodeToAppendOn as HTMLTemplateElement;
|
|
171
185
|
template.content.appendChild(childElement);
|
|
172
186
|
} else nodeToAppendOn.appendChild(childElement);
|
|
173
187
|
}
|
|
@@ -184,11 +198,15 @@ export class SonicSDUI extends Fetcher(Subscriber(LitElement)) {
|
|
|
184
198
|
let element: HTMLElement;
|
|
185
199
|
let contentElement: HTMLElement | undefined;
|
|
186
200
|
if (node.libraryKey && this.sduiDescriptor.library) {
|
|
187
|
-
element = this.parseChild(
|
|
188
|
-
|
|
189
|
-
|
|
201
|
+
element = this.parseChild(
|
|
202
|
+
this.sduiDescriptor.library[node.libraryKey] || { tagName: "div" }
|
|
203
|
+
);
|
|
204
|
+
const selector = (this.sduiDescriptor.library[node.libraryKey] || {})
|
|
205
|
+
.contentElementSelector;
|
|
206
|
+
if (selector)
|
|
207
|
+
contentElement = element.querySelector(selector) as HTMLElement;
|
|
190
208
|
} else element = document.createElement(tagName) as HTMLElement;
|
|
191
|
-
return {element, contentElement};
|
|
209
|
+
return { element, contentElement };
|
|
192
210
|
}
|
|
193
211
|
/**
|
|
194
212
|
* Remplissage des attributs html avec les attributs fournis dans le noeud
|
|
@@ -197,7 +215,9 @@ export class SonicSDUI extends Fetcher(Subscriber(LitElement)) {
|
|
|
197
215
|
const attributes = node.attributes;
|
|
198
216
|
for (const k in attributes) {
|
|
199
217
|
const attrData: object | string = attributes[k];
|
|
200
|
-
const attr: string = Objects.isObject(attrData)
|
|
218
|
+
const attr: string = Objects.isObject(attrData)
|
|
219
|
+
? JSON.stringify(attrData)
|
|
220
|
+
: attrData;
|
|
201
221
|
element.setAttribute(k, attr);
|
|
202
222
|
}
|
|
203
223
|
}
|
|
@@ -216,13 +236,18 @@ export class SonicSDUI extends Fetcher(Subscriber(LitElement)) {
|
|
|
216
236
|
/**
|
|
217
237
|
* si le noeud à une propriété innerHTML, on l'ajout ay innerHTML de l'élément html en cours de création
|
|
218
238
|
*/
|
|
219
|
-
private handleInnerHTML(
|
|
239
|
+
private handleInnerHTML(
|
|
240
|
+
node: SDUINode,
|
|
241
|
+
contentElement: HTMLElement | undefined
|
|
242
|
+
) {
|
|
220
243
|
if (!node.innerHTML) return;
|
|
221
244
|
if (node.innerHTML.indexOf("wording_") != -1) {
|
|
222
245
|
const wordingProvider = this.getAncestorAttributeValue("wordingProvider");
|
|
223
|
-
this.api
|
|
224
|
-
|
|
225
|
-
|
|
246
|
+
this.api
|
|
247
|
+
?.post(wordingProvider, { labels: [node.innerHTML.substring(8)] })
|
|
248
|
+
.then((value) => {
|
|
249
|
+
if (contentElement) contentElement.innerHTML += value;
|
|
250
|
+
});
|
|
226
251
|
} else if (contentElement) {
|
|
227
252
|
contentElement.innerHTML += node.innerHTML;
|
|
228
253
|
}
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
property,
|
|
5
5
|
queryAssignedNodes,
|
|
6
6
|
state,
|
|
7
|
+
query,
|
|
7
8
|
} from "lit/decorators.js";
|
|
8
9
|
import {
|
|
9
10
|
FormInput,
|
|
@@ -23,6 +24,7 @@ import { Input } from "@supersoniks/concorde/core/components/ui/form/input/input
|
|
|
23
24
|
import { customScroll } from "@supersoniks/concorde/core/components/ui/_css/scroll";
|
|
24
25
|
import { ResizeController } from "@lit-labs/observers/resize-controller.js";
|
|
25
26
|
import { traverseDotNotation } from "@supersoniks/concorde/core/utils/Objects";
|
|
27
|
+
import { Pop } from "../../pop/pop";
|
|
26
28
|
|
|
27
29
|
type ListItem = Record<string, string>;
|
|
28
30
|
|
|
@@ -82,6 +84,7 @@ export class InputAutocomplete extends TemplatesContainer(
|
|
|
82
84
|
slotInputPrefixNodes!: Array<Node>;
|
|
83
85
|
|
|
84
86
|
@state() hasInputPrefix = false;
|
|
87
|
+
@query("sonic-pop") popElement!: Pop;
|
|
85
88
|
_resizeController = new ResizeController(this, {});
|
|
86
89
|
|
|
87
90
|
@state() isPopVisible = false;
|
|
@@ -324,9 +327,13 @@ export class InputAutocomplete extends TemplatesContainer(
|
|
|
324
327
|
return this.searchPublisher?.get();
|
|
325
328
|
}
|
|
326
329
|
|
|
330
|
+
handleFocus(): void {
|
|
331
|
+
this.popElement.show();
|
|
332
|
+
}
|
|
333
|
+
|
|
327
334
|
render() {
|
|
328
335
|
return html`
|
|
329
|
-
<sonic-pop
|
|
336
|
+
<sonic-pop manual style="display:block;" @hide=${this.handleHide}>
|
|
330
337
|
<sonic-input
|
|
331
338
|
class="form-element"
|
|
332
339
|
dataProvider="${this.initSearchDataProvider + Math.random()}"
|
|
@@ -344,6 +351,7 @@ export class InputAutocomplete extends TemplatesContainer(
|
|
|
344
351
|
clearable
|
|
345
352
|
inlineContent
|
|
346
353
|
size=${this.size}
|
|
354
|
+
@focus=${this.handleFocus}
|
|
347
355
|
value=${ifDefined(this.getInputValue())}
|
|
348
356
|
>
|
|
349
357
|
<slot
|
|
@@ -36,9 +36,8 @@ export class Tooltip extends LitElement {
|
|
|
36
36
|
will-change: opacity, transform;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
/* désactive au focus-within cause persistance du tooltip au clic */
|
|
40
|
-
/* :host(:focus-within) .tooltip:before, */
|
|
41
39
|
:host(:focus-visible) .tooltip:before,
|
|
40
|
+
:host(.keyboard-focus) .tooltip:before,
|
|
42
41
|
.tooltip:hover:before {
|
|
43
42
|
opacity: 1;
|
|
44
43
|
scale: 1;
|
|
@@ -132,12 +131,78 @@ export class Tooltip extends LitElement {
|
|
|
132
131
|
@property({ type: Boolean }) disabled = false;
|
|
133
132
|
@property({ type: Boolean }) focusable = false;
|
|
134
133
|
|
|
134
|
+
private lastKeyWasTab = false;
|
|
135
|
+
private boundHandleKeyDown: (e: KeyboardEvent) => void;
|
|
136
|
+
private boundHandleMouseDown: () => void;
|
|
137
|
+
|
|
138
|
+
constructor() {
|
|
139
|
+
super();
|
|
140
|
+
this.boundHandleKeyDown = this.handleKeyDown.bind(this);
|
|
141
|
+
this.boundHandleMouseDown = this.handleMouseDown.bind(this);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private handleKeyDown = (e: KeyboardEvent) => {
|
|
145
|
+
// Détecter si Tab ou Shift+Tab a été pressé
|
|
146
|
+
if (e.key === "Tab") {
|
|
147
|
+
this.lastKeyWasTab = true;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
private handleMouseDown = () => {
|
|
152
|
+
// Réinitialiser le flag si la souris est utilisée
|
|
153
|
+
this.lastKeyWasTab = false;
|
|
154
|
+
// Retirer la classe si elle existe (au cas où)
|
|
155
|
+
this.classList.remove("keyboard-focus");
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
private handleFocusIn = () => {
|
|
159
|
+
// Ajouter la classe seulement si le focus est venu du clavier (Tab)
|
|
160
|
+
if (this.lastKeyWasTab) {
|
|
161
|
+
this.classList.add("keyboard-focus");
|
|
162
|
+
}
|
|
163
|
+
this.lastKeyWasTab = false;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
private handleFocusOut = () => {
|
|
167
|
+
this.classList.remove("keyboard-focus");
|
|
168
|
+
this.lastKeyWasTab = false;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
connectedCallback() {
|
|
172
|
+
super.connectedCallback();
|
|
173
|
+
this.addEventListener("focusin", this.handleFocusIn);
|
|
174
|
+
this.addEventListener("focusout", this.handleFocusOut);
|
|
175
|
+
// Écouter les événements au niveau du document avec capture pour détecter Tab
|
|
176
|
+
document.addEventListener("keydown", this.boundHandleKeyDown, true);
|
|
177
|
+
document.addEventListener("mousedown", this.boundHandleMouseDown, true);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
disconnectedCallback() {
|
|
181
|
+
super.disconnectedCallback();
|
|
182
|
+
this.removeEventListener("focusin", this.handleFocusIn);
|
|
183
|
+
this.removeEventListener("focusout", this.handleFocusOut);
|
|
184
|
+
document.removeEventListener("keydown", this.boundHandleKeyDown, true);
|
|
185
|
+
document.removeEventListener("mousedown", this.boundHandleMouseDown, true);
|
|
186
|
+
}
|
|
187
|
+
|
|
135
188
|
protected willUpdate(_changedProperties: PropertyValues): void {
|
|
136
189
|
if (_changedProperties.has("disabled")) {
|
|
137
190
|
const wasDisabledBefore = _changedProperties.get("disabled") === true;
|
|
138
191
|
if (this.disabled) {
|
|
139
192
|
this.setAttribute("tabindex", "-1");
|
|
193
|
+
this.classList.remove("keyboard-focus");
|
|
140
194
|
} else if (!this.disabled && wasDisabledBefore) {
|
|
195
|
+
if (this.focusable) {
|
|
196
|
+
this.setAttribute("tabindex", "0");
|
|
197
|
+
} else {
|
|
198
|
+
this.removeAttribute("tabindex");
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (_changedProperties.has("focusable")) {
|
|
203
|
+
if (this.focusable && !this.disabled) {
|
|
204
|
+
this.setAttribute("tabindex", "0");
|
|
205
|
+
} else if (!this.focusable && !this.disabled) {
|
|
141
206
|
this.removeAttribute("tabindex");
|
|
142
207
|
}
|
|
143
208
|
}
|
|
@@ -1,187 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
__onConnected__: (callback: (component: ConnectedComponent) => void) => void;
|
|
7
|
-
__onDisconnected__: (callback: (component: ConnectedComponent) => void) => void;
|
|
8
|
-
__connectedCallbackCalls__?: Set<(component: ConnectedComponent) => void>;
|
|
9
|
-
__disconnectedCallbackCalls__?: Set<(component: ConnectedComponent) => void>;
|
|
10
|
-
};
|
|
11
|
-
type Configuration = {
|
|
12
|
-
callbacks: Set<Callback>;
|
|
13
|
-
publisher: PublisherProxy;
|
|
14
|
-
onAssign: (value: unknown) => void;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
function onConnected(this: ConnectedComponent, callback: (component: ConnectedComponent) => void) {
|
|
18
|
-
if (!this.__connectedCallbackCalls__) this.__connectedCallbackCalls__ = new Set();
|
|
19
|
-
this.__connectedCallbackCalls__.add(callback);
|
|
20
|
-
}
|
|
21
|
-
function __onDisconnected__(this: ConnectedComponent, callback: (component: ConnectedComponent) => void) {
|
|
22
|
-
if (!this.__disconnectedCallbackCalls__) this.__disconnectedCallbackCalls__ = new Set();
|
|
23
|
-
this.__disconnectedCallbackCalls__.add(callback);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function setSubscribable(target: any) {
|
|
27
|
-
if (target.__is__setSubscribable__) return;
|
|
28
|
-
target.__is__setSubscribable__ = true;
|
|
29
|
-
|
|
30
|
-
target.__onConnected__ = onConnected;
|
|
31
|
-
target.__onDisconnected__ = __onDisconnected__;
|
|
32
|
-
// target.offConnected = onConnected;
|
|
33
|
-
// target.offDisconnected = __onDisconnected__;
|
|
34
|
-
|
|
35
|
-
const originalConnectedCallback = target.connectedCallback;
|
|
36
|
-
target.connectedCallback = function (this: any) {
|
|
37
|
-
originalConnectedCallback.call(this);
|
|
38
|
-
if (this.__connectedCallbackCalls__) {
|
|
39
|
-
this.__connectedCallbackCalls__.forEach((callback: (component: any) => void) => callback(this));
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
const originalDisconnectedCallback = target.disconnectedCallback;
|
|
43
|
-
target.disconnectedCallback = function (this: any) {
|
|
44
|
-
originalDisconnectedCallback.call(this);
|
|
45
|
-
if (this.__disconnectedCallbackCalls__) {
|
|
46
|
-
this.__disconnectedCallbackCalls__.forEach((callback: (component: any) => void) => callback(this));
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function bind(path: string) {
|
|
52
|
-
const split = path.split(".");
|
|
53
|
-
if (split.length == 0) {
|
|
54
|
-
return function () {
|
|
55
|
-
//Empty def function
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
const dataProvider: string = split.shift() || "";
|
|
59
|
-
let publisher = PublisherManager.get(dataProvider);
|
|
60
|
-
publisher = Objects.traverse(publisher, split);
|
|
61
|
-
return function (target: unknown, propertyKey: string) {
|
|
62
|
-
if (!target) return;
|
|
63
|
-
let onAssign: (value: unknown) => void;
|
|
64
|
-
setSubscribable(target);
|
|
65
|
-
|
|
66
|
-
(target as ConnectedComponent).__onConnected__((component) => {
|
|
67
|
-
onAssign = (value: unknown) => {
|
|
68
|
-
component[propertyKey] = value;
|
|
69
|
-
};
|
|
70
|
-
publisher.onAssign(onAssign);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
(target as ConnectedComponent).__onDisconnected__(() => {
|
|
74
|
-
publisher.offAssign(onAssign);
|
|
75
|
-
});
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function onAssign(...values: Array<string>) {
|
|
80
|
-
const onAssignValues: unknown[] = [];
|
|
81
|
-
const confs: Configuration[] = [];
|
|
82
|
-
for (let i = 0; i < values.length; i++) {
|
|
83
|
-
const value = values[i];
|
|
84
|
-
const split = value.split(".");
|
|
85
|
-
if (split.length == 0) {
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
const dataProvider: string = split.shift() || "";
|
|
89
|
-
|
|
90
|
-
let publisher = PublisherManager.get(dataProvider);
|
|
91
|
-
|
|
92
|
-
publisher = Objects.traverse(publisher, split);
|
|
93
|
-
const callbacks: Set<Callback> = new Set();
|
|
94
|
-
const onAssign = (value: unknown) => {
|
|
95
|
-
onAssignValues[i] = value;
|
|
96
|
-
if (onAssignValues.filter((v) => v !== null).length == values.length) callbacks.forEach((callback) => callback(...onAssignValues));
|
|
97
|
-
};
|
|
98
|
-
confs.push({publisher, onAssign, callbacks});
|
|
99
|
-
}
|
|
100
|
-
return function (target: unknown, _propertyKey: string, descriptor: PropertyDescriptor) {
|
|
101
|
-
setSubscribable(target);
|
|
102
|
-
let callback: Callback;
|
|
103
|
-
|
|
104
|
-
(target as ConnectedComponent).__onConnected__((component) => {
|
|
105
|
-
for (const conf of confs) {
|
|
106
|
-
callback = descriptor.value.bind(component);
|
|
107
|
-
conf.callbacks.add(callback);
|
|
108
|
-
conf.publisher.onAssign(conf.onAssign);
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
(target as ConnectedComponent).__onDisconnected__(() => {
|
|
113
|
-
for (const conf of confs) {
|
|
114
|
-
conf.callbacks.delete(callback);
|
|
115
|
-
conf.publisher.offAssign(conf.onAssign);
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function autoSubscribe() {
|
|
122
|
-
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
|
123
|
-
let renderId = 0;
|
|
124
|
-
|
|
125
|
-
const originalMethod = descriptor.value;
|
|
126
|
-
const originalDC = target.constructor.prototype.disconnectedCallback;
|
|
127
|
-
target.constructor.prototype.disconnectedCallback = function () {
|
|
128
|
-
originalDC.apply(this);
|
|
129
|
-
this.__removeAutoSubscribe__();
|
|
130
|
-
};
|
|
131
|
-
const originalConnectedCallback = target.connectedCallback;
|
|
132
|
-
target.connectedCallback = function (this: any) {
|
|
133
|
-
originalConnectedCallback?.call(this);
|
|
134
|
-
this[propertyKey]();
|
|
135
|
-
};
|
|
136
|
-
descriptor.value = function (...args: unknown[]) {
|
|
137
|
-
let publishers: Set<PublisherProxy> = new Set();
|
|
138
|
-
const onAssign = () => {
|
|
139
|
-
renderId++;
|
|
140
|
-
const id = renderId;
|
|
141
|
-
window.queueMicrotask(() => {
|
|
142
|
-
if (id !== renderId) return;
|
|
143
|
-
(this as any)[propertyKey]();
|
|
144
|
-
});
|
|
145
|
-
};
|
|
146
|
-
//on désabone les publishers du rendu précédant
|
|
147
|
-
publishers.forEach((publisher: PublisherProxy) => {
|
|
148
|
-
publisher.offAssign(onAssign);
|
|
149
|
-
});
|
|
150
|
-
//on collecte les publisher modifiés pour s'abonner pour la prochaine modification
|
|
151
|
-
PublisherManager.collectModifiedPublisher();
|
|
152
|
-
const result = originalMethod.apply(this, args);
|
|
153
|
-
publishers = PublisherManager.getModifiedPublishers() || new Set<PublisherProxy>();
|
|
154
|
-
publishers.forEach((publisher: PublisherProxy) => {
|
|
155
|
-
publisher.onAssign(onAssign, false);
|
|
156
|
-
});
|
|
157
|
-
(this as typeof target.constructor.prototype.disconnectedCallback).__removeAutoSubscribe__ = () => {
|
|
158
|
-
publishers.forEach((publisher: PublisherProxy) => {
|
|
159
|
-
publisher.offAssign(onAssign);
|
|
160
|
-
});
|
|
161
|
-
};
|
|
162
|
-
return result;
|
|
163
|
-
};
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
export function autoFill(values: string[]) {
|
|
167
|
-
return function (target: unknown) {
|
|
168
|
-
setSubscribable(target);
|
|
169
|
-
for (const value of values) {
|
|
170
|
-
const split = value.split(".");
|
|
171
|
-
if (split.length == 0) {
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
174
|
-
const dataProvider: string = split.shift() || "";
|
|
175
|
-
let publisher = PublisherManager.get(dataProvider);
|
|
176
|
-
publisher = Objects.traverse(publisher, split);
|
|
177
|
-
(target as ConnectedComponent).__onConnected__((component: unknown) => {
|
|
178
|
-
publisher.startTemplateFilling(component);
|
|
179
|
-
});
|
|
180
|
-
(target as ConnectedComponent).__onDisconnected__(() => {
|
|
181
|
-
(component: unknown) => {
|
|
182
|
-
publisher.stopTemplateFilling(component);
|
|
183
|
-
};
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
}
|
|
1
|
+
export { bind } from "./subscriber/bind";
|
|
2
|
+
export { onAssign } from "./subscriber/onAssign";
|
|
3
|
+
export { autoSubscribe } from "./subscriber/autoSubscribe";
|
|
4
|
+
export { autoFill } from "./subscriber/autoFill";
|
|
5
|
+
export { ancestorAttribute } from "./subscriber/ancestorAttribute";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import HTML from "../../utils/HTML";
|
|
2
|
+
import { ConnectedComponent, setSubscribable } from "./common";
|
|
3
|
+
|
|
4
|
+
export function ancestorAttribute(attributeName: string) {
|
|
5
|
+
return function (target: unknown, propertyKey: string) {
|
|
6
|
+
if (!target) return;
|
|
7
|
+
setSubscribable(target);
|
|
8
|
+
|
|
9
|
+
(target as ConnectedComponent).__onConnected__((component) => {
|
|
10
|
+
const value = HTML.getAncestorAttributeValue(
|
|
11
|
+
component as any,
|
|
12
|
+
attributeName
|
|
13
|
+
);
|
|
14
|
+
component[propertyKey] = value;
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Objects } from "@supersoniks/concorde/utils";
|
|
2
|
+
|
|
3
|
+
import { PublisherManager } from "../../utils/PublisherProxy";
|
|
4
|
+
import { ConnectedComponent, setSubscribable } from "./common";
|
|
5
|
+
|
|
6
|
+
export function autoFill(values: string[]) {
|
|
7
|
+
return function (target: unknown) {
|
|
8
|
+
setSubscribable(target);
|
|
9
|
+
for (const value of values) {
|
|
10
|
+
const split = value.split(".");
|
|
11
|
+
if (split.length === 0) {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
const dataProvider: string = split.shift() || "";
|
|
15
|
+
let publisher = PublisherManager.get(dataProvider);
|
|
16
|
+
publisher = Objects.traverse(publisher, split);
|
|
17
|
+
(target as ConnectedComponent).__onConnected__((component: unknown) => {
|
|
18
|
+
publisher.startTemplateFilling(component);
|
|
19
|
+
});
|
|
20
|
+
(target as ConnectedComponent).__onDisconnected__(() => {
|
|
21
|
+
(component: unknown) => {
|
|
22
|
+
publisher.stopTemplateFilling(component);
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { PublisherProxy, PublisherManager } from "../../utils/PublisherProxy";
|
|
2
|
+
|
|
3
|
+
export function autoSubscribe() {
|
|
4
|
+
return function (
|
|
5
|
+
target: any,
|
|
6
|
+
propertyKey: string,
|
|
7
|
+
descriptor: PropertyDescriptor
|
|
8
|
+
) {
|
|
9
|
+
let renderId = 0;
|
|
10
|
+
|
|
11
|
+
const originalMethod = descriptor.value;
|
|
12
|
+
const originalDisconnectedCallback =
|
|
13
|
+
target.constructor.prototype.disconnectedCallback;
|
|
14
|
+
target.constructor.prototype.disconnectedCallback = function () {
|
|
15
|
+
originalDisconnectedCallback?.apply(this);
|
|
16
|
+
this.__removeAutoSubscribe__();
|
|
17
|
+
};
|
|
18
|
+
const originalConnectedCallback = target.connectedCallback;
|
|
19
|
+
target.connectedCallback = function (this: any) {
|
|
20
|
+
originalConnectedCallback?.call(this);
|
|
21
|
+
this[propertyKey]();
|
|
22
|
+
};
|
|
23
|
+
descriptor.value = function (...args: unknown[]) {
|
|
24
|
+
let publishers: Set<PublisherProxy> = new Set();
|
|
25
|
+
const onAssign = () => {
|
|
26
|
+
renderId++;
|
|
27
|
+
const id = renderId;
|
|
28
|
+
window.queueMicrotask(() => {
|
|
29
|
+
if (id !== renderId) return;
|
|
30
|
+
(this as any)[propertyKey]();
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
publishers.forEach((publisher: PublisherProxy) => {
|
|
34
|
+
publisher.offAssign(onAssign);
|
|
35
|
+
});
|
|
36
|
+
PublisherManager.collectModifiedPublisher();
|
|
37
|
+
const result = originalMethod.apply(this, args);
|
|
38
|
+
publishers =
|
|
39
|
+
PublisherManager.getModifiedPublishers() || new Set<PublisherProxy>();
|
|
40
|
+
|
|
41
|
+
publishers.forEach((publisher: PublisherProxy) => {
|
|
42
|
+
publisher.onAssign(onAssign, false);
|
|
43
|
+
});
|
|
44
|
+
(
|
|
45
|
+
this as typeof target.constructor.prototype.disconnectedCallback
|
|
46
|
+
).__removeAutoSubscribe__ = () => {
|
|
47
|
+
publishers.forEach((publisher: PublisherProxy) => {
|
|
48
|
+
publisher.offAssign(onAssign);
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
}
|