mount-observer 0.1.14 → 0.1.16

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.
Files changed (40) hide show
  1. package/ElementMountExtension.js +5 -2
  2. package/ElementMountExtension.ts +7 -2
  3. package/MountObserver.js +3 -0
  4. package/MountObserver.ts +3 -0
  5. package/RegistryMountCoordinator.js +5 -5
  6. package/RegistryMountCoordinator.ts +8 -6
  7. package/{DefineCustomElementHandler.js → handlers/DefineCustomElement.js} +103 -99
  8. package/handlers/DefineCustomElement.ts +123 -0
  9. package/{EnhanceMountedElementHandler.js → handlers/EnhanceMountedElement.js} +109 -96
  10. package/handlers/EnhanceMountedElement.ts +126 -0
  11. package/handlers/Events.js +110 -0
  12. package/handlers/EvtRt.js +59 -0
  13. package/handlers/GenIds.js +37 -0
  14. package/handlers/GenIds.ts +45 -0
  15. package/handlers/HTMLInclude.js +393 -0
  16. package/handlers/HTMLInclude.ts +453 -0
  17. package/handlers/HoistTemplate.js +77 -0
  18. package/handlers/HoistTemplate.ts +89 -0
  19. package/handlers/MountObserver.js +941 -0
  20. package/handlers/MountObserverScript.js +78 -0
  21. package/handlers/MountObserverScript.ts +89 -0
  22. package/handlers/ScriptExport.js +83 -0
  23. package/handlers/ScriptExport.ts +97 -0
  24. package/handlers/SharedMutationObserver.js +78 -0
  25. package/handlers/arr.js +16 -0
  26. package/handlers/connectionMonitor.js +122 -0
  27. package/handlers/elementIntersection.js +73 -0
  28. package/handlers/emitEvents.js +187 -0
  29. package/handlers/getRegistryRoot.js +52 -0
  30. package/handlers/loadImports.js +129 -0
  31. package/handlers/mediaQuery.js +90 -0
  32. package/handlers/rootSizeObserver.js +131 -0
  33. package/handlers/upShadowSearch.js +70 -0
  34. package/handlers/withScopePerimeter.js +22 -0
  35. package/package.json +12 -2
  36. package/types/assign-gingerly/types.d.ts +244 -0
  37. package/types/be-a-beacon/types.d.ts +3 -0
  38. package/types/global.d.ts +29 -0
  39. package/types/id-generation/types.d.ts +26 -0
  40. package/types/mount-observer/types.d.ts +332 -0
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
24
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
50
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
51
+ if (ar || !(i in from)) {
52
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
53
+ ar[i] = from[i];
54
+ }
55
+ }
56
+ return to.concat(ar || Array.prototype.slice.call(from));
57
+ };
58
+ Object.defineProperty(exports, "__esModule", { value: true });
59
+ exports.emitMountedElementEvents = emitMountedElementEvents;
60
+ /**
61
+ * Emits events from a mounted element based on the mountedElemEmits configuration.
62
+ * This module is dynamically loaded only when mountedElemEmits is configured.
63
+ */
64
+ function emitMountedElementEvents(element, MountConfig, processedEventsForElement) {
65
+ return __awaiter(this, void 0, void 0, function () {
66
+ var configs, _i, configs_1, config;
67
+ return __generator(this, function (_a) {
68
+ switch (_a.label) {
69
+ case 0:
70
+ configs = Array.isArray(MountConfig.mountedElemEmits)
71
+ ? MountConfig.mountedElemEmits
72
+ : [MountConfig.mountedElemEmits];
73
+ _i = 0, configs_1 = configs;
74
+ _a.label = 1;
75
+ case 1:
76
+ if (!(_i < configs_1.length)) return [3 /*break*/, 4];
77
+ config = configs_1[_i];
78
+ return [4 /*yield*/, emitSingleEvent(element, MountConfig, config, processedEventsForElement)];
79
+ case 2:
80
+ _a.sent();
81
+ _a.label = 3;
82
+ case 3:
83
+ _i++;
84
+ return [3 /*break*/, 1];
85
+ case 4: return [2 /*return*/];
86
+ }
87
+ });
88
+ });
89
+ }
90
+ function emitSingleEvent(element, MountConfig, config, processedEventsForElement) {
91
+ return __awaiter(this, void 0, void 0, function () {
92
+ var eventId, processedEvents, EventCtor, processedArgs, event, options, assignGingerly, processedProps;
93
+ return __generator(this, function (_a) {
94
+ switch (_a.label) {
95
+ case 0:
96
+ // Check if this event should only fire once per element
97
+ if (config.oncePerMountedElement) {
98
+ eventId = getEventId(config);
99
+ processedEvents = processedEventsForElement.get(element);
100
+ if (!processedEvents) {
101
+ processedEvents = new Set();
102
+ processedEventsForElement.set(element, processedEvents);
103
+ }
104
+ if (processedEvents.has(eventId)) {
105
+ return [2 /*return*/]; // Already emitted for this element
106
+ }
107
+ processedEvents.add(eventId);
108
+ }
109
+ EventCtor = resolveEventConstructor(config.event);
110
+ processedArgs = config.args !== undefined
111
+ ? processMagicStrings(config.args, element, MountConfig)
112
+ : undefined;
113
+ if (processedArgs === undefined) {
114
+ event = new EventCtor();
115
+ }
116
+ else if (Array.isArray(processedArgs)) {
117
+ // For array args, ensure bubbles is set if second arg is an options object
118
+ if (processedArgs.length === 2 && typeof processedArgs[0] === 'string' && typeof processedArgs[1] === 'object' && processedArgs[1] !== null) {
119
+ options = __assign({ bubbles: true }, processedArgs[1]);
120
+ event = new EventCtor(processedArgs[0], options);
121
+ }
122
+ else {
123
+ event = new (EventCtor.bind.apply(EventCtor, __spreadArray([void 0], processedArgs, false)))();
124
+ }
125
+ }
126
+ else {
127
+ // Single arg - if it's a string (event name), add bubbles: true by default
128
+ if (typeof processedArgs === 'string') {
129
+ event = new EventCtor(processedArgs, { bubbles: true });
130
+ }
131
+ else {
132
+ event = new EventCtor(processedArgs);
133
+ }
134
+ }
135
+ if (!config.eventProps) return [3 /*break*/, 2];
136
+ return [4 /*yield*/, Promise.resolve().then(function () { return require('assign-gingerly/assignGingerly.js'); })];
137
+ case 1:
138
+ assignGingerly = (_a.sent()).assignGingerly;
139
+ processedProps = processMagicStrings(config.eventProps, element, MountConfig);
140
+ assignGingerly(event, processedProps);
141
+ _a.label = 2;
142
+ case 2:
143
+ // Dispatch the event from the mounted element
144
+ element.dispatchEvent(event);
145
+ return [2 /*return*/];
146
+ }
147
+ });
148
+ });
149
+ }
150
+ function resolveEventConstructor(event) {
151
+ if (typeof event === 'string') {
152
+ var EventCtor = globalThis[event];
153
+ if (!EventCtor || typeof EventCtor !== 'function') {
154
+ throw new Error("Event constructor \"".concat(event, "\" not found in globalThis"));
155
+ }
156
+ return EventCtor;
157
+ }
158
+ return event;
159
+ }
160
+ function getEventId(config) {
161
+ var eventName = typeof config.event === 'string' ? config.event : config.event.name;
162
+ var argsStr = JSON.stringify(config.args || '');
163
+ return "".concat(eventName, ":").concat(argsStr);
164
+ }
165
+ function processMagicStrings(value, element, MountConfig) {
166
+ if (typeof value === 'string') {
167
+ if (value === '{{mountedElement}}') {
168
+ return element;
169
+ }
170
+ if (value === '{{MountConfig}}') {
171
+ return MountConfig;
172
+ }
173
+ return value;
174
+ }
175
+ if (Array.isArray(value)) {
176
+ return value.map(function (item) { return processMagicStrings(item, element, MountConfig); });
177
+ }
178
+ if (value && typeof value === 'object') {
179
+ var processed = {};
180
+ for (var _i = 0, _a = Object.entries(value); _i < _a.length; _i++) {
181
+ var _b = _a[_i], key = _b[0], val = _b[1];
182
+ processed[key] = processMagicStrings(val, element, MountConfig);
183
+ }
184
+ return processed;
185
+ }
186
+ return value;
187
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRegistryRoot = getRegistryRoot;
4
+ /**
5
+ * Recursively traverses up the DOM tree to find the highest node
6
+ * that shares the same customElementRegistry as the passed in node.
7
+ * This is useful for scoped custom element registries where we want to observe within the correct scope.
8
+ *
9
+ * @param node - The starting node to check
10
+ * @returns The highest node with matching customElementRegistry, or null if node is invalid
11
+ */
12
+ function getRegistryRoot(node) {
13
+ if (!node) {
14
+ return null;
15
+ }
16
+ // Quick check: if root node has the same registry, return it immediately
17
+ var rn = node.getRootNode();
18
+ var customElementRegistry = node.customElementRegistry;
19
+ if (rn.customElementRegistry === customElementRegistry) {
20
+ return rn;
21
+ }
22
+ var startRegistry = node.customElementRegistry;
23
+ var currentNode = node;
24
+ var highestMatch = node;
25
+ while (currentNode) {
26
+ // Check if current node has matching customElementRegistry
27
+ if (currentNode.customElementRegistry === startRegistry) {
28
+ highestMatch = currentNode;
29
+ }
30
+ // Try to get parent element first
31
+ var parent_1 = currentNode.parentElement;
32
+ if (parent_1) {
33
+ currentNode = parent_1;
34
+ continue;
35
+ }
36
+ // If no parent element, check for rootNode (shadow root case)
37
+ var root = currentNode.getRootNode();
38
+ if (root && root !== currentNode) {
39
+ // If it's a shadow root (not document), return it
40
+ if (root !== document) {
41
+ return root;
42
+ }
43
+ // If it's the document, check if it has the same registry
44
+ if (root.customElementRegistry === startRegistry) {
45
+ return root;
46
+ }
47
+ }
48
+ // Reached the top
49
+ break;
50
+ }
51
+ return highestMatch;
52
+ }
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ // Dynamic import loading utilities
3
+ // Only loaded when MountConfig.import is specified
4
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
5
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6
+ return new (P || (P = Promise))(function (resolve, reject) {
7
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
8
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
9
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
10
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
11
+ });
12
+ };
13
+ var __generator = (this && this.__generator) || function (thisArg, body) {
14
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
15
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
16
+ function verb(n) { return function (v) { return step([n, v]); }; }
17
+ function step(op) {
18
+ if (f) throw new TypeError("Generator is already executing.");
19
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
20
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
21
+ if (y = 0, t) op = [op[0] & 2, t.value];
22
+ switch (op[0]) {
23
+ case 0: case 1: t = op; break;
24
+ case 4: _.label++; return { value: op[1], done: false };
25
+ case 5: _.label++; y = op[1]; op = [0]; continue;
26
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
27
+ default:
28
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
29
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
30
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
31
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
32
+ if (t[2]) _.ops.pop();
33
+ _.trys.pop(); continue;
34
+ }
35
+ op = body.call(thisArg, _);
36
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
37
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
38
+ }
39
+ };
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.loadImports = loadImports;
42
+ var arr_js_1 = require("./arr.js");
43
+ function loadImports(imports) {
44
+ return __awaiter(this, void 0, void 0, function () {
45
+ var importArray, promises;
46
+ return __generator(this, function (_a) {
47
+ importArray = (0, arr_js_1.arr)(imports);
48
+ promises = importArray.map(function (imp) { return loadSingleImport(imp); });
49
+ return [2 /*return*/, Promise.all(promises)];
50
+ });
51
+ });
52
+ }
53
+ function loadSingleImport(imp) {
54
+ return __awaiter(this, void 0, void 0, function () {
55
+ var url, type;
56
+ var _a;
57
+ return __generator(this, function (_b) {
58
+ type = 'js';
59
+ if (typeof imp === 'string') {
60
+ url = imp;
61
+ }
62
+ else if (Array.isArray(imp)) {
63
+ url = imp[0];
64
+ type = ((_a = imp[1]) === null || _a === void 0 ? void 0 : _a.type) || 'js';
65
+ }
66
+ else {
67
+ url = imp.url;
68
+ type = imp.type || 'js';
69
+ }
70
+ switch (type) {
71
+ case 'css':
72
+ return [2 /*return*/, loadCSS(url)];
73
+ case 'json':
74
+ return [2 /*return*/, loadJSON(url)];
75
+ case 'html':
76
+ return [2 /*return*/, loadHTML(url)];
77
+ default:
78
+ return [2 /*return*/, Promise.resolve("".concat(url)).then(function (s) { return require(s); })];
79
+ }
80
+ return [2 /*return*/];
81
+ });
82
+ });
83
+ }
84
+ function loadCSS(url) {
85
+ return __awaiter(this, void 0, void 0, function () {
86
+ var response, text, sheet;
87
+ return __generator(this, function (_a) {
88
+ switch (_a.label) {
89
+ case 0: return [4 /*yield*/, fetch(url)];
90
+ case 1:
91
+ response = _a.sent();
92
+ return [4 /*yield*/, response.text()];
93
+ case 2:
94
+ text = _a.sent();
95
+ sheet = new CSSStyleSheet();
96
+ return [4 /*yield*/, sheet.replace(text)];
97
+ case 3:
98
+ _a.sent();
99
+ return [2 /*return*/, sheet];
100
+ }
101
+ });
102
+ });
103
+ }
104
+ function loadJSON(url) {
105
+ return __awaiter(this, void 0, void 0, function () {
106
+ var response;
107
+ return __generator(this, function (_a) {
108
+ switch (_a.label) {
109
+ case 0: return [4 /*yield*/, fetch(url)];
110
+ case 1:
111
+ response = _a.sent();
112
+ return [2 /*return*/, response.json()];
113
+ }
114
+ });
115
+ });
116
+ }
117
+ function loadHTML(url) {
118
+ return __awaiter(this, void 0, void 0, function () {
119
+ var response;
120
+ return __generator(this, function (_a) {
121
+ switch (_a.label) {
122
+ case 0: return [4 /*yield*/, fetch(url)];
123
+ case 1:
124
+ response = _a.sent();
125
+ return [2 /*return*/, response.text()];
126
+ }
127
+ });
128
+ });
129
+ }
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setupMediaQuery = setupMediaQuery;
4
+ var Events_js_1 = require("./Events.js");
5
+ function setupMediaQuery(init, rootNodeRef, mountedElements, modules, observer, processNode) {
6
+ var withMediaMatching = init.withMediaMatching;
7
+ // Create or use MediaQueryList
8
+ var mediaQueryList;
9
+ if (typeof withMediaMatching === 'string') {
10
+ mediaQueryList = window.matchMedia(withMediaMatching);
11
+ }
12
+ else {
13
+ mediaQueryList = withMediaMatching;
14
+ }
15
+ // Track current state
16
+ var mediaMatches = mediaQueryList.matches;
17
+ // Set up change listener
18
+ var mediaChangeHandler = function (e) {
19
+ var previousMatches = mediaMatches;
20
+ mediaMatches = e.matches;
21
+ if (e.matches && !previousMatches) {
22
+ // Media query now matches - wake up and process elements
23
+ handleMediaMatch();
24
+ }
25
+ else if (!e.matches && previousMatches) {
26
+ // Media query no longer matches - dismount all elements
27
+ handleMediaUnmatch();
28
+ }
29
+ };
30
+ function handleMediaMatch() {
31
+ // Dispatch mediamatch event if requested
32
+ if (init.getPlayByPlay) {
33
+ observer.dispatchEvent(new Events_js_1.MediaMatchEvent(init));
34
+ }
35
+ // Process all elements in the observed node
36
+ var rootNode = rootNodeRef.deref();
37
+ if (rootNode) {
38
+ processNode(rootNode);
39
+ }
40
+ }
41
+ function handleMediaUnmatch() {
42
+ // Dispatch mediaunmatch event if requested
43
+ if (init.getPlayByPlay) {
44
+ observer.dispatchEvent(new Events_js_1.MediaUnmatchEvent(init));
45
+ }
46
+ // Dismount all currently mounted elements
47
+ var rootNode = rootNodeRef.deref();
48
+ if (!rootNode) {
49
+ return;
50
+ }
51
+ var context = {
52
+ modules: modules,
53
+ observer: observer,
54
+ rootNode: rootNode,
55
+ mountConfig: init
56
+ };
57
+ // Get all mounted elements from the WeakDual setWeak
58
+ var mountedElementsList = [];
59
+ for (var _i = 0, _a = mountedElements.setWeak; _i < _a.length; _i++) {
60
+ var ref = _a[_i];
61
+ var element = ref.deref();
62
+ if (element) {
63
+ mountedElementsList.push(element);
64
+ }
65
+ }
66
+ // Dismount each element
67
+ for (var _b = 0, mountedElementsList_1 = mountedElementsList; _b < mountedElementsList_1.length; _b++) {
68
+ var element = mountedElementsList_1[_b];
69
+ // Remove from both structures
70
+ mountedElements.weakSet.delete(element);
71
+ for (var _c = 0, _d = mountedElements.setWeak; _c < _d.length; _c++) {
72
+ var ref = _d[_c];
73
+ if (ref.deref() === element) {
74
+ mountedElements.setWeak.delete(ref);
75
+ break;
76
+ }
77
+ }
78
+ // Dispatch dismount event with reason
79
+ observer.dispatchEvent(new Events_js_1.DismountEvent(element, 'media-query-failed', init));
80
+ }
81
+ }
82
+ mediaQueryList.addEventListener('change', mediaChangeHandler);
83
+ return {
84
+ mediaQueryList: mediaQueryList,
85
+ mediaMatches: mediaMatches,
86
+ cleanup: function () {
87
+ mediaQueryList.removeEventListener('change', mediaChangeHandler);
88
+ }
89
+ };
90
+ }
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setupRootSizeObserver = setupRootSizeObserver;
4
+ var Events_js_1 = require("./Events.js");
5
+ function setupRootSizeObserver(init, rootNodeRef, mountedElements, modules, observer, processNode) {
6
+ var whereObservedRootSizeMatches = init.whereObservedRootSizeMatches;
7
+ if (!whereObservedRootSizeMatches) {
8
+ throw new Error('whereObservedRootSizeMatches is required');
9
+ }
10
+ var rootNode = rootNodeRef.deref();
11
+ if (!rootNode) {
12
+ throw new Error('Root node has been garbage collected');
13
+ }
14
+ // Get the element to observe
15
+ var rootElement = rootNode instanceof Element
16
+ ? rootNode
17
+ : rootNode.documentElement;
18
+ if (!rootElement) {
19
+ throw new Error('Could not determine root element for whereObservedRootSizeMatches');
20
+ }
21
+ // Parse the container query condition
22
+ // Container queries use the same syntax as media queries: (min-width: 700px)
23
+ var containerQuery = whereObservedRootSizeMatches;
24
+ // Check if condition currently matches
25
+ var conditionMatches = evaluateContainerQuery(rootElement, containerQuery);
26
+ // Set up ResizeObserver to watch for size changes
27
+ var resizeObserver = new ResizeObserver(function (entries) {
28
+ for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
29
+ var entry = entries_1[_i];
30
+ var previousMatches = conditionMatches;
31
+ conditionMatches = evaluateContainerQuery(entry.target, containerQuery);
32
+ if (conditionMatches && !previousMatches) {
33
+ // Condition now matches - process elements
34
+ handleConditionMatch();
35
+ }
36
+ else if (!conditionMatches && previousMatches) {
37
+ // Condition no longer matches - dismount all elements
38
+ handleConditionUnmatch();
39
+ }
40
+ }
41
+ });
42
+ function handleConditionMatch() {
43
+ // Process all elements in the observed node
44
+ var rootNode = rootNodeRef.deref();
45
+ if (rootNode) {
46
+ processNode(rootNode);
47
+ }
48
+ }
49
+ function handleConditionUnmatch() {
50
+ // Dismount all currently mounted elements
51
+ var rootNode = rootNodeRef.deref();
52
+ if (!rootNode) {
53
+ return;
54
+ }
55
+ var context = {
56
+ modules: modules,
57
+ observer: observer,
58
+ rootNode: rootNode,
59
+ mountConfig: init
60
+ };
61
+ // Get all mounted elements from the WeakDual setWeak
62
+ var mountedElementsList = [];
63
+ for (var _i = 0, _a = mountedElements.setWeak; _i < _a.length; _i++) {
64
+ var ref = _a[_i];
65
+ var element = ref.deref();
66
+ if (element) {
67
+ mountedElementsList.push(element);
68
+ }
69
+ }
70
+ // Dismount each element
71
+ for (var _b = 0, mountedElementsList_1 = mountedElementsList; _b < mountedElementsList_1.length; _b++) {
72
+ var element = mountedElementsList_1[_b];
73
+ // Remove from both structures
74
+ mountedElements.weakSet.delete(element);
75
+ for (var _c = 0, _d = mountedElements.setWeak; _c < _d.length; _c++) {
76
+ var ref = _d[_c];
77
+ if (ref.deref() === element) {
78
+ mountedElements.setWeak.delete(ref);
79
+ break;
80
+ }
81
+ }
82
+ // Dispatch dismount event with reason
83
+ observer.dispatchEvent(new Events_js_1.DismountEvent(element, 'root-size-failed', init));
84
+ }
85
+ }
86
+ // Start observing the root element
87
+ resizeObserver.observe(rootElement);
88
+ return {
89
+ conditionMatches: conditionMatches,
90
+ cleanup: function () {
91
+ resizeObserver.disconnect();
92
+ }
93
+ };
94
+ }
95
+ /**
96
+ * Evaluate a container query condition against an element
97
+ * Supports: min-width, max-width, min-height, max-height
98
+ */
99
+ function evaluateContainerQuery(element, query) {
100
+ // Parse container query: (min-width: 700px) or (max-height: 500px)
101
+ var match = query.match(/\(([^:]+):\s*([^)]+)\)/);
102
+ if (!match) {
103
+ console.warn("Invalid container query format: ".concat(query));
104
+ return false;
105
+ }
106
+ var property = match[1], valueStr = match[2];
107
+ var prop = property.trim();
108
+ var value = parseFloat(valueStr);
109
+ if (isNaN(value)) {
110
+ console.warn("Invalid container query value: ".concat(valueStr));
111
+ return false;
112
+ }
113
+ // Get element dimensions
114
+ var rect = element.getBoundingClientRect();
115
+ var width = rect.width;
116
+ var height = rect.height;
117
+ // Evaluate condition
118
+ switch (prop) {
119
+ case 'min-width':
120
+ return width >= value;
121
+ case 'max-width':
122
+ return width <= value;
123
+ case 'min-height':
124
+ return height >= value;
125
+ case 'max-height':
126
+ return height <= value;
127
+ default:
128
+ console.warn("Unsupported container query property: ".concat(prop));
129
+ return false;
130
+ }
131
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.upShadowSearch = upShadowSearch;
4
+ /**
5
+ * Searches for an element by ID, traversing up through shadow DOM boundaries.
6
+ *
7
+ * This function searches for an element with the specified ID starting from the reference
8
+ * element's root node and continuing up through shadow DOM boundaries until the element
9
+ * is found or the document root is reached.
10
+ *
11
+ * Registry-aware: Only searches in root nodes that share the same customElementRegistry
12
+ * as the reference element. This respects scoped custom element registry boundaries.
13
+ *
14
+ * Search order:
15
+ * 1. Check current root node using getElementById (if same registry)
16
+ * 2. If in shadow root, check host element's properties for the ID
17
+ * 3. Continue up to parent shadow root or document
18
+ * 4. Handle disconnected fragments via targetFragment property
19
+ *
20
+ * @param ref - The reference element to start searching from
21
+ * @param id - The ID of the element to find
22
+ * @returns The found element, or null if not found
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const template = document.querySelector('template[src="#myId"]');
27
+ * const source = upShadowSearch(template, 'myId');
28
+ * if (source) {
29
+ * const clone = source.cloneNode(true);
30
+ * }
31
+ * ```
32
+ */
33
+ function upShadowSearch(ref, id) {
34
+ var rn = ref.getRootNode();
35
+ while (rn) {
36
+ // Try getElementById on current root, but only if it shares the same registry
37
+ if ('getElementById' in rn && rn.customElementRegistry === ref.customElementRegistry) {
38
+ var test = rn.getElementById(id);
39
+ if (test)
40
+ return test;
41
+ }
42
+ // If in shadow root, check host element
43
+ if ('host' in rn && rn.host) {
44
+ // Check if host has a property with this ID
45
+ var hostProp = rn.host[id];
46
+ if (hostProp instanceof HTMLElement)
47
+ return hostProp;
48
+ // Move up to host's root
49
+ rn = rn.host.getRootNode();
50
+ }
51
+ else if (rn === document) {
52
+ // Reached document root without finding element
53
+ return null;
54
+ }
55
+ else if (!('isConnected' in rn) || !rn.isConnected) {
56
+ // Handle disconnected fragments
57
+ if (rn.targetFragment) {
58
+ rn = rn.targetFragment;
59
+ }
60
+ else {
61
+ rn = document;
62
+ }
63
+ }
64
+ else {
65
+ // No more parents to check
66
+ return null;
67
+ }
68
+ }
69
+ return null;
70
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withScopePerimeter = withScopePerimeter;
4
+ /**
5
+ * Check if an element is outside (not inside) any ancestor matching a selector.
6
+ * This implements "donut hole" scoping.
7
+ *
8
+ * @param rootNode - The root node to stop traversal at (not checked against selector)
9
+ * @param matchCandidate - The element to check
10
+ * @param outside - CSS selector for excluding ancestors
11
+ * @returns true if element is outside all matching ancestors, false otherwise
12
+ */
13
+ function withScopePerimeter(rootNode, matchCandidate, outside) {
14
+ var current = matchCandidate.parentElement;
15
+ while (current && current !== rootNode) {
16
+ if (current.matches(outside)) {
17
+ return false; // Found an excluding ancestor
18
+ }
19
+ current = current.parentElement;
20
+ }
21
+ return true; // No excluding ancestors found
22
+ }