@webqit/oohtml 1.10.3 → 2.0.0
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/.gitignore +3 -3
- package/LICENSE +20 -20
- package/README.md +399 -396
- package/dist/context-api.js +2 -0
- package/dist/context-api.js.map +7 -0
- package/dist/html-imports.js +1 -2
- package/dist/html-imports.js.map +3 -3
- package/dist/html-modules.js +1 -2
- package/dist/html-modules.js.map +3 -3
- package/dist/main.js +26 -14
- package/dist/main.js.map +3 -3
- package/dist/namespaced-html.js +1 -2
- package/dist/namespaced-html.js.map +3 -3
- package/dist/scoped-js.js +27 -0
- package/dist/scoped-js.js.map +7 -0
- package/dist/state-api.js +1 -2
- package/dist/state-api.js.map +3 -3
- package/package.json +76 -76
- package/src/context-api/HTMLContext.js +158 -0
- package/src/context-api/HTMLContextManager.js +77 -0
- package/src/context-api/_ContextRequestEvent.js +26 -0
- package/src/context-api/index.js +53 -0
- package/src/{namespaced-html/browser-entry.js → context-api/targets.browser.js} +9 -9
- package/src/html-imports/_HTMLImportElement.js +216 -0
- package/src/html-imports/index.js +92 -557
- package/src/{browser-entry.js → html-imports/targets.browser.js} +10 -10
- package/src/html-modules/HTMLExportsManager.js +191 -0
- package/src/html-modules/_HTMLImportsContext.js +114 -0
- package/src/html-modules/index.js +133 -384
- package/src/{html-imports/browser-entry.js → html-modules/targets.browser.js} +9 -9
- package/src/index.js +34 -39
- package/src/namespaced-html/index.js +130 -144
- package/src/namespaced-html/targets.browser.js +10 -0
- package/src/scoped-js/index.js +382 -0
- package/src/scoped-js/targets.browser.js +10 -0
- package/src/state-api/index.js +55 -142
- package/src/state-api/targets.browser.js +10 -0
- package/src/{html-modules/browser-entry.js → targets.browser.js} +10 -10
- package/src/util.js +20 -180
- package/test/imports.test.js +194 -0
- package/test/index.js +119 -0
- package/test/modules.test.js +198 -0
- package/test/namespaced-html.test.js +50 -0
- package/test/scoped-js.js +57 -0
- package/test/state-api.test.js +34 -0
- package/test/test.html +69 -0
- package/dist/subscript.js +0 -15
- package/dist/subscript.js.map +0 -7
- package/src/state-api/browser-entry.js +0 -10
- package/src/subscript/Element.js +0 -103
- package/src/subscript/browser-entry.js +0 -10
- package/src/subscript/index.js +0 -70
- package/test/all.test.js +0 -0
|
@@ -1,384 +1,133 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
_internals(el, 'oohtml').set('parentTemplate', node);
|
|
135
|
-
if (eventsObject) {
|
|
136
|
-
eventsObject.addedTemplates[templateName] = el;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
// Recurse
|
|
140
|
-
discoverContents(el, el.content, _path, mutationType, fireEvents);
|
|
141
|
-
} else {
|
|
142
|
-
const manageExportItem = exportItem => {
|
|
143
|
-
var exportId = exportItem.getAttribute(_meta.get('attr.exportgroup')) || 'default';
|
|
144
|
-
if (mutationType === 'removed') {
|
|
145
|
-
if (_internals(node, 'oohtml', 'exports').has(exportId)) {
|
|
146
|
-
_remove(_internals(node, 'oohtml', 'exports').get(exportId), exportItem);
|
|
147
|
-
if (!_internals(node, 'oohtml', 'exports').has(exportId).length) {
|
|
148
|
-
_internals(node, 'oohtml', 'exports').delete(exportId);
|
|
149
|
-
}
|
|
150
|
-
if (eventsObject) {
|
|
151
|
-
if (!eventsObject.removedExports[exportId]) {
|
|
152
|
-
eventsObject.removedExports[exportId] = [];
|
|
153
|
-
}
|
|
154
|
-
eventsObject.removedExports[exportId].push(exportItem);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
} else if (mutationType === 'added') {
|
|
158
|
-
if (!_internals(node, 'oohtml', 'exports').has(exportId)) {
|
|
159
|
-
_internals(node, 'oohtml', 'exports').set(exportId, []);
|
|
160
|
-
}
|
|
161
|
-
_internals(node, 'oohtml', 'exports').get(exportId).push(exportItem);
|
|
162
|
-
if (eventsObject) {
|
|
163
|
-
if (!eventsObject.addedExports[exportId]) {
|
|
164
|
-
eventsObject.addedExports[exportId] = [];
|
|
165
|
-
}
|
|
166
|
-
eventsObject.addedExports[exportId].push(exportItem);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
if (el.matches(_meta.get('element.export'))) {
|
|
171
|
-
var exportId = el.getAttribute(_meta.get('attr.exportid')) || 'default';
|
|
172
|
-
_arrFrom(el.children).forEach(exportItem => {
|
|
173
|
-
exportItem.setAttribute(_meta.get('attr.exportgroup'), exportId);
|
|
174
|
-
manageExportItem(exportItem);
|
|
175
|
-
});
|
|
176
|
-
} else {
|
|
177
|
-
manageExportItem(el);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
// -----------------------
|
|
183
|
-
// Run...
|
|
184
|
-
node.modulemutationsType = mutationType;
|
|
185
|
-
const eventsObject = { addedTemplates: Object.create(null), removedTemplates: Object.create(null), addedExports: Object.create(null), removedExports: Object.create(null), };
|
|
186
|
-
_arrFrom(contentNode.children).forEach(el => manageComponent(el, eventsObject, mutationType, fireEvents));
|
|
187
|
-
if (fireEvents) {
|
|
188
|
-
fireDocumentTemplateEvent('templatemutation', eventsObject, path);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// -----------------------
|
|
192
|
-
// Handle content loading
|
|
193
|
-
if (mutationType === 'added' && !_internals(node, 'oohtml').get('onLiveMode')) {
|
|
194
|
-
_internals(node, 'oohtml').set('onLiveMode', true);
|
|
195
|
-
const honourSrc = () => {
|
|
196
|
-
if (node.content.children.length) return;
|
|
197
|
-
_internals(node, 'oohtml').delete('queryCallback');
|
|
198
|
-
return loadTemplateContent(node, path);
|
|
199
|
-
};
|
|
200
|
-
if (node.getAttribute('src')) {
|
|
201
|
-
if (node.getAttribute('loading') === 'lazy') {
|
|
202
|
-
_internals(node, 'oohtml').set('queryCallback', honourSrc);
|
|
203
|
-
} else {
|
|
204
|
-
loadingTemplates.push(honourSrc());
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
mutations.onAttrChange(node, mr => {
|
|
208
|
-
if (mr[0].target.getAttribute(mr[0].attributeName) === mr[0].oldValue) return;
|
|
209
|
-
if (node.getAttribute('loading') === 'lazy') {
|
|
210
|
-
_internals(node, 'oohtml').set('queryCallback', honourSrc);
|
|
211
|
-
} else if (mr[0].attributeName === 'loading') {
|
|
212
|
-
_internals(node, 'oohtml').delete('queryCallback');
|
|
213
|
-
} else {
|
|
214
|
-
honourSrc();
|
|
215
|
-
}
|
|
216
|
-
}, ['src', 'loading']);
|
|
217
|
-
|
|
218
|
-
// -----------------------
|
|
219
|
-
// Watch mutations
|
|
220
|
-
var mo = new window.MutationObserver(mutations => {
|
|
221
|
-
const eventsObject = { addedTemplates: Object.create(null), removedTemplates: Object.create(null), addedExports: Object.create(null), removedExports: Object.create(null), };
|
|
222
|
-
mutations.forEach(mutation => {
|
|
223
|
-
mutation.addedNodes.forEach(el => manageComponent(el, eventsObject, 'added', true));
|
|
224
|
-
mutation.removedNodes.forEach(el => manageComponent(el, eventsObject, 'removed', true));
|
|
225
|
-
});
|
|
226
|
-
fireDocumentTemplateEvent('templatemutation', eventsObject, path);
|
|
227
|
-
});
|
|
228
|
-
mo.observe(contentNode, {childList: true});
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
// ----------------------
|
|
234
|
-
// Define the global "templates" object
|
|
235
|
-
// ----------------------
|
|
236
|
-
|
|
237
|
-
if (_meta.get('api.templates') in document) {
|
|
238
|
-
throw new Error('document already has a "' + _meta.get('api.templates') + '" property!');
|
|
239
|
-
}
|
|
240
|
-
const loadingTemplates = [];
|
|
241
|
-
Object.defineProperty(document, _meta.get('api.templates'), {
|
|
242
|
-
get: function() {
|
|
243
|
-
return mapToObject(_internals(document, 'oohtml', 'templates'));
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
// ----------------------
|
|
248
|
-
// Define the "templates" and "exports" properties on HTMLTemplateElement.prototype
|
|
249
|
-
// ----------------------
|
|
250
|
-
|
|
251
|
-
if (_meta.get('api.templates') in TemplateElementClass.prototype) {
|
|
252
|
-
throw new Error('The "HTMLTemplateElement" class already has a "' + _meta.get('api.templates') + '" property!');
|
|
253
|
-
}
|
|
254
|
-
Object.defineProperty(TemplateElementClass.prototype, _meta.get('api.templates'), {
|
|
255
|
-
get: function() {
|
|
256
|
-
if (_internals(this, 'oohtml').has('queryCallback')) {
|
|
257
|
-
_internals(this, 'oohtml').get('queryCallback')();
|
|
258
|
-
}
|
|
259
|
-
return mapToObject(_internals(this, 'oohtml', 'templates'));
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
|
-
if (_meta.get('api.exports') in TemplateElementClass.prototype) {
|
|
263
|
-
throw new Error('The "HTMLTemplateElement" class already has a "' + _meta.get('api.exports') + '" property!');
|
|
264
|
-
}
|
|
265
|
-
Object.defineProperty(TemplateElementClass.prototype, _meta.get('api.exports'), {
|
|
266
|
-
get: function() {
|
|
267
|
-
if (_internals(this, 'oohtml').has('queryCallback')) {
|
|
268
|
-
_internals(this, 'oohtml').get('queryCallback')();
|
|
269
|
-
}
|
|
270
|
-
return mapToObject(_internals(this, 'oohtml', 'exports'));
|
|
271
|
-
}
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
const mapToObject = map => {
|
|
275
|
-
return Object.defineProperties({}, Array.from(map.keys()).reduce((desc, name) => {
|
|
276
|
-
desc[name] = {get: () => map.get(name)};
|
|
277
|
-
return desc;
|
|
278
|
-
}, {}));
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
const validateModuleName = name => {
|
|
282
|
-
var invalidCharacterMatch;
|
|
283
|
-
if (invalidCharacterMatch = name.match(/([^a-zA-Z0-9\_\-\@])/)) {
|
|
284
|
-
console.error(`Invalid character "${invalidCharacterMatch}" in the module name: ${name}.`);
|
|
285
|
-
return false;
|
|
286
|
-
}
|
|
287
|
-
return true;
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
const templatesQuery = query => {
|
|
291
|
-
var _module = document.createElement('template');
|
|
292
|
-
// -----------------
|
|
293
|
-
scopeQuery([document], query, function(host, prop) {
|
|
294
|
-
var collection = _internals(host, 'oohtml', 'templates');
|
|
295
|
-
if (arguments.length === 1) return collection;
|
|
296
|
-
if (prop.startsWith(':')) return _internals(host, 'oohtml', 'exports').get(prop.substr(1));
|
|
297
|
-
return collection.get(prop);
|
|
298
|
-
}).forEach($module => {
|
|
299
|
-
_internals($module, 'oohtml', 'templates').forEach((template, moduleId) => {
|
|
300
|
-
_internals(_module, 'oohtml', 'templates').set(moduleId, template);
|
|
301
|
-
});
|
|
302
|
-
_internals($module, 'oohtml', 'exports').forEach((exports, exportId) => {
|
|
303
|
-
if (!_internals(_module, 'oohtml', 'exports').has(exportId)) {
|
|
304
|
-
_internals(_module, 'oohtml', 'exports').set(exportId, []);
|
|
305
|
-
}
|
|
306
|
-
_internals(_module, 'oohtml', 'exports').get(exportId).push(...exports);
|
|
307
|
-
});
|
|
308
|
-
});
|
|
309
|
-
return _module;
|
|
310
|
-
};
|
|
311
|
-
|
|
312
|
-
_arrFrom(document.querySelectorAll(templateSelector)).forEach(async el => {
|
|
313
|
-
var name = el.getAttribute(_meta.get('attr.moduleid'));
|
|
314
|
-
if (!el.closest(_meta.get('element.import')) && validateModuleName(name)) {
|
|
315
|
-
_internals(document, 'oohtml', 'templates').set(name, el);
|
|
316
|
-
discoverContents(el, el.content, name, 'added', false);
|
|
317
|
-
}
|
|
318
|
-
});
|
|
319
|
-
mutations.onPresenceChange(templateSelector, async (els, presence) => {
|
|
320
|
-
const eventsObject = { addedTemplates: Object.create(null), removedTemplates: Object.create(null), addedExports: Object.create(null), removedExports: Object.create(null), };
|
|
321
|
-
els.forEach(el => {
|
|
322
|
-
var name = el.getAttribute(_meta.get('attr.moduleid'));
|
|
323
|
-
if (el.closest(_meta.get('element.import')) || !validateModuleName(name)) return;
|
|
324
|
-
if (presence) {
|
|
325
|
-
_internals(document, 'oohtml', 'templates').set(name, el);
|
|
326
|
-
discoverContents(el, el.content, name, 'added');
|
|
327
|
-
eventsObject.addedTemplates[name] = el;
|
|
328
|
-
} else {
|
|
329
|
-
if (_internals(document, 'oohtml', 'templates').get(name) === el) {
|
|
330
|
-
_internals(document, 'oohtml', 'templates').delete(name);
|
|
331
|
-
}
|
|
332
|
-
discoverContents(el, el.content, name, 'removed');
|
|
333
|
-
eventsObject.removedTemplates[name] = el;
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
fireDocumentTemplateEvent('templatemutation', eventsObject, '');
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
// ----------------------
|
|
340
|
-
// Capture import elements
|
|
341
|
-
// ----------------------
|
|
342
|
-
|
|
343
|
-
mutations.onPresent(_meta.get('element.import'), el => {
|
|
344
|
-
discoverContents(el, el, '', 'added', false);
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
// ----------------------
|
|
348
|
-
// Define the "template" property on Element.prototype
|
|
349
|
-
// ----------------------
|
|
350
|
-
|
|
351
|
-
if (_meta.get('api.moduleref') in window.Element.prototype) {
|
|
352
|
-
throw new Error('The "Element" class already has a "' + _meta.get('api.moduleref') + '" property!');
|
|
353
|
-
}
|
|
354
|
-
Object.defineProperty(window.Element.prototype, _meta.get('api.moduleref'), {
|
|
355
|
-
get: function() {
|
|
356
|
-
var templateId;
|
|
357
|
-
if (!_internals(this, 'oohtml').has('module')
|
|
358
|
-
&& (templateId = this.getAttribute(_meta.get('attr.moduleref')))) {
|
|
359
|
-
var _module = templatesQuery(templateId);
|
|
360
|
-
_internals(this, 'oohtml').set('module', _module)
|
|
361
|
-
}
|
|
362
|
-
return _internals(this, 'oohtml').get('module');
|
|
363
|
-
},
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
// ----------------------
|
|
367
|
-
// Hydrate
|
|
368
|
-
// ----------------------
|
|
369
|
-
|
|
370
|
-
//Object.defineProperty(document, 'templatesQuery', { value: templatesQuery });
|
|
371
|
-
var templatesReadyState = loadingTemplates.length ? 'loading' : 'indeterminate';
|
|
372
|
-
Object.defineProperty(document, 'templatesReadyState', { get: () => templatesReadyState });
|
|
373
|
-
WebQit.DOM.ready.call(WebQit, () => {
|
|
374
|
-
loadingTemplates.forEach(promise => {
|
|
375
|
-
promise && promise.catch(error => {
|
|
376
|
-
console.warn(error);
|
|
377
|
-
});
|
|
378
|
-
});
|
|
379
|
-
return Promise.all(loadingTemplates).then(() => {
|
|
380
|
-
templatesReadyState = 'complete';
|
|
381
|
-
document.dispatchEvent(new window.Event('templatesreadystatechange'));
|
|
382
|
-
});
|
|
383
|
-
});
|
|
384
|
-
}
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @imports
|
|
4
|
+
*/
|
|
5
|
+
import wqDom from '@webqit/dom';
|
|
6
|
+
import Observer from '@webqit/observer';
|
|
7
|
+
import _HTMLImportsContext from './_HTMLImportsContext.js';
|
|
8
|
+
import HTMLExportsManager from './HTMLExportsManager.js';
|
|
9
|
+
import { _ } from '../util.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Initializes HTML Modules.
|
|
13
|
+
*
|
|
14
|
+
* @param Object $params
|
|
15
|
+
*
|
|
16
|
+
* @return Void
|
|
17
|
+
*/
|
|
18
|
+
export default function init( $params = {} ) {
|
|
19
|
+
const window = this, dom = wqDom.call( window );
|
|
20
|
+
// -------
|
|
21
|
+
const params = dom.meta( 'oohtml' ).copyWithDefaults( $params, {
|
|
22
|
+
template: { attr: { exportid: 'exportid', inherits: 'inherits' }, api: { modules: 'modules', exportid: 'exportid' }, },
|
|
23
|
+
context: { attr: { importscontext: 'importscontext', contextname: 'contextname' }, api: { modules: 'modules' }, },
|
|
24
|
+
export: { attr: { exportid: 'exportid' }, },
|
|
25
|
+
staticsensitivity: true,
|
|
26
|
+
} );
|
|
27
|
+
params.window = window;
|
|
28
|
+
params.templateSelector = `template[${ window.CSS.escape( params.template.attr.exportid ) }]`;
|
|
29
|
+
params.ownerContextSelector = [ params.context.attr.contextname, params.context.attr.importscontext ].map( a => `[${ window.CSS.escape( a ) }]` ).join( ',' );
|
|
30
|
+
params.HTMLImportsContext = class extends _HTMLImportsContext {
|
|
31
|
+
static get params() { return params; }
|
|
32
|
+
}
|
|
33
|
+
// -------
|
|
34
|
+
exposeModulesObjects.call( this, params );
|
|
35
|
+
realtime.call( this, params );
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Returns the "exports" object associated with the given node.
|
|
40
|
+
*
|
|
41
|
+
* @param Element node
|
|
42
|
+
* @param Bool autoCreate
|
|
43
|
+
*
|
|
44
|
+
* @return Object
|
|
45
|
+
*/
|
|
46
|
+
export function getModulesObject( node, autoCreate = true ) {
|
|
47
|
+
if ( !_( node ).has( 'modules' ) && autoCreate ) {
|
|
48
|
+
const modulesObj = Object.create( null );
|
|
49
|
+
Observer.intercept( modulesObj, 'set', ( event, receiver, next ) => {
|
|
50
|
+
if ( !event.key.startsWith( '#' ) || event.value instanceof Set ) return next();
|
|
51
|
+
if ( !Array.isArray( event.value ) ) { event.value = [ event.value ]; }
|
|
52
|
+
event.value = new Set( event.value );
|
|
53
|
+
return next();
|
|
54
|
+
} );
|
|
55
|
+
_( node ).set( 'modules', modulesObj );
|
|
56
|
+
}
|
|
57
|
+
return _( node ).get( 'modules' );
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Exposes HTML Modules with native APIs.
|
|
62
|
+
*
|
|
63
|
+
* @param Object params
|
|
64
|
+
*
|
|
65
|
+
* @return Void
|
|
66
|
+
*/
|
|
67
|
+
function exposeModulesObjects( params ) {
|
|
68
|
+
const window = this;
|
|
69
|
+
// Assertions
|
|
70
|
+
if ( params.context.api.modules in window.document ) { throw new Error( `document already has a "${ params.context.api.modules }" property!` ); }
|
|
71
|
+
if ( params.template.api.modules in window.HTMLElement.prototype ) { throw new Error( `The "HTMLElement" class already has a "${ params.template.api.modules }" property!` ); }
|
|
72
|
+
if ( params.template.api.exportid in window.HTMLTemplateElement.prototype ) { throw new Error( `The "HTMLTemplateElement" class already has a "${ params.template.api.exportid }" property!` ); }
|
|
73
|
+
// Definitions
|
|
74
|
+
Object.defineProperty( window.document, params.context.api.modules, { get: function() {
|
|
75
|
+
return getModulesObject( window.document );
|
|
76
|
+
} } );
|
|
77
|
+
Object.defineProperty( window.HTMLElement.prototype, params.template.api.modules, { get: function() {
|
|
78
|
+
return getModulesObject( this );
|
|
79
|
+
} } );
|
|
80
|
+
Object.defineProperty( window.HTMLTemplateElement.prototype, params.template.api.exportid, { get: function() {
|
|
81
|
+
return this.isConnected ? HTMLExportsManager.instance( this, params ).exportId : this.getAttribute( params.template.attr.exportid );
|
|
82
|
+
} } );
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Performs realtime capture of elements and builds their contents graph.
|
|
87
|
+
*
|
|
88
|
+
* @param Object params
|
|
89
|
+
*
|
|
90
|
+
* @return Void
|
|
91
|
+
*/
|
|
92
|
+
function realtime( params ) {
|
|
93
|
+
const window = this, { dom } = window.wq;
|
|
94
|
+
// ------------
|
|
95
|
+
const attachImportsContext = host => {
|
|
96
|
+
const contextId = params.HTMLImportsContext.createId( host );
|
|
97
|
+
params.HTMLImportsContext.attachTo( host, contextId );
|
|
98
|
+
};
|
|
99
|
+
const detachImportsContext = ( host, force ) => {
|
|
100
|
+
const contextId = params.HTMLImportsContext.createId( host );
|
|
101
|
+
params.HTMLImportsContext.detachFrom( host, contextId, cx => {
|
|
102
|
+
return force || host.matches && !host.matches( params.ownerContextSelector ) && !Object.keys( cx.modules ).length;
|
|
103
|
+
} );
|
|
104
|
+
};
|
|
105
|
+
// ------------
|
|
106
|
+
dom.realtime( window.document ).observe( [ params.templateSelector, params.ownerContextSelector ], record => {
|
|
107
|
+
record.entrants.forEach( entry => {
|
|
108
|
+
if ( entry.matches( params.templateSelector ) ) {
|
|
109
|
+
Object.defineProperty( entry, 'scoped', { value: entry.hasAttribute( 'scoped' ) } );
|
|
110
|
+
const moduleExport = new HTMLExportsManager( entry, params );
|
|
111
|
+
moduleExport.ownerContext = entry.scoped ? record.target : window.document;
|
|
112
|
+
const ownerContextModulesObj = getModulesObject( moduleExport.ownerContext );
|
|
113
|
+
if ( moduleExport.exportId ) { Observer.set( ownerContextModulesObj, moduleExport.exportId, entry ); }
|
|
114
|
+
// The ownerContext's modulesObj - ownerContextModulesObj - has to be populated
|
|
115
|
+
// Before attaching a context instance to it, to give the just created context something to use for
|
|
116
|
+
// fullfiling reclaimed requests.
|
|
117
|
+
attachImportsContext( moduleExport.ownerContext );
|
|
118
|
+
} else {
|
|
119
|
+
attachImportsContext( entry );
|
|
120
|
+
}
|
|
121
|
+
} );
|
|
122
|
+
record.exits.forEach( entry => {
|
|
123
|
+
if ( entry.matches( params.templateSelector ) ) {
|
|
124
|
+
const moduleExport = HTMLExportsManager.instance( entry, params );
|
|
125
|
+
const ownerContextModulesObj = getModulesObject( moduleExport.ownerContext );
|
|
126
|
+
if ( moduleExport.exportId ) { Observer.deleteProperty( ownerContextModulesObj, moduleExport.exportId ); }
|
|
127
|
+
detachImportsContext( moduleExport.ownerContext );
|
|
128
|
+
} else {
|
|
129
|
+
detachImportsContext( entry, true );
|
|
130
|
+
}
|
|
131
|
+
} );
|
|
132
|
+
}, { subtree: true, timing: 'sync', staticSensitivity: params.staticsensitivity } );
|
|
133
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import init from './index.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @init
|
|
9
|
-
*/
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @imports
|
|
4
|
+
*/
|
|
5
|
+
import init from './index.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @init
|
|
9
|
+
*/
|
|
10
10
|
init.call( window );
|
package/src/index.js
CHANGED
|
@@ -1,39 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import Observer from '@webqit/observer';
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @init
|
|
15
|
-
*/
|
|
16
|
-
export default function init(configs = {}) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
* @exports
|
|
36
|
-
*/
|
|
37
|
-
export {
|
|
38
|
-
Observer,
|
|
39
|
-
}
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @imports
|
|
4
|
+
*/
|
|
5
|
+
import Observer from '@webqit/observer';
|
|
6
|
+
import StateAPI from './state-api/index.js';
|
|
7
|
+
import ContextAPI from './context-api/index.js';
|
|
8
|
+
import HTMLModules from './html-modules/index.js';
|
|
9
|
+
import HTMLImports from './html-imports/index.js';
|
|
10
|
+
import NamespacedHTML from './namespaced-html/index.js';
|
|
11
|
+
import ScopedJS from './scoped-js/index.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @init
|
|
15
|
+
*/
|
|
16
|
+
export default function init( configs = {} ) {
|
|
17
|
+
if ( !this.wq ) { this.wq = {}; }
|
|
18
|
+
if ( this.wq.oohtml ) return;
|
|
19
|
+
this.wq.Observer = Observer;
|
|
20
|
+
// --------------
|
|
21
|
+
StateAPI.call(this, ( configs.StateAPI || {} ) );
|
|
22
|
+
ContextAPI.call( this, ( configs.ContextAPI || {} ) );
|
|
23
|
+
HTMLModules.call( this, ( configs.HTMLModules || {} ) );
|
|
24
|
+
HTMLImports.call( this, ( configs.HTMLImports || {} ) );
|
|
25
|
+
NamespacedHTML.call(this, ( configs.NamespacedHTML || {} ) );
|
|
26
|
+
ScopedJS.call( this, ( configs.ScopedJS || {} ) );
|
|
27
|
+
// --------------
|
|
28
|
+
this.wq.oohtml = {};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @exports
|
|
33
|
+
*/
|
|
34
|
+
export { Observer }
|