@solidjs/web 2.0.0-beta.13 → 2.0.0-beta.14

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/dist/web.cjs CHANGED
@@ -31,6 +31,7 @@ const DOMWithState = {
31
31
  }
32
32
  };
33
33
  const ChildProperties = /*#__PURE__*/new Set(["innerHTML", "textContent", "innerText", "children"]);
34
+ const $$SLOT = /*#__PURE__*/Symbol("slot");
34
35
  const DelegatedEvents = /*#__PURE__*/new Set(["beforeinput", "click", "dblclick", "contextmenu", "focusin", "focusout", "input", "keydown", "keyup", "mousedown", "mousemove", "mouseout", "mouseover", "mouseup", "pointerdown", "pointermove", "pointerout", "pointerover", "pointerup", "touchend", "touchmove", "touchstart"]);
35
36
  const SVGElements = /*#__PURE__*/new Set([
36
37
  "altGlyph", "altGlyphDef", "altGlyphItem", "animate", "animateColor", "animateMotion", "animateTransform", "circle", "clipPath", "color-profile", "cursor", "defs", "desc", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "font", "font-face", "font-face-format", "font-face-name", "font-face-src", "font-face-uri", "foreignObject", "g", "glyph", "glyphRef", "hkern", "image", "line", "linearGradient", "marker", "mask", "metadata", "missing-glyph", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect",
@@ -64,14 +65,18 @@ const effect = (fn, effectFn, options) => solidJs.createRenderEffect(fn, effectF
64
65
  } : transparentOptions);
65
66
  const memo = fn => solidJs.createMemo(() => fn(), syncOptions);
66
67
 
67
- function reconcileArrays(parentNode, a, b) {
68
+ function reconcileArrays(parentNode, a, b, marker) {
68
69
  let bLength = b.length,
69
70
  aEnd = a.length,
70
71
  bEnd = bLength,
71
72
  aStart = 0,
72
73
  bStart = 0,
73
- after = a[aEnd - 1].nextSibling,
74
- map = null;
74
+ tail = a[aEnd - 1],
75
+ tailTag = tail[$$SLOT],
76
+ after = tail.parentNode === parentNode && (!tailTag || tailTag === marker) ? tail.nextSibling : marker || null,
77
+ map = null,
78
+ anchor,
79
+ anchorTag;
75
80
  while (aStart < aEnd || bStart < bEnd) {
76
81
  if (a[aStart] === b[bStart]) {
77
82
  aStart++;
@@ -83,20 +88,43 @@ function reconcileArrays(parentNode, a, b) {
83
88
  bEnd--;
84
89
  }
85
90
  if (aEnd === aStart) {
86
- const node = bEnd < bLength ? bStart ? b[bStart - 1].nextSibling : b[bEnd - bStart] : after;
87
- while (bStart < bEnd) parentNode.insertBefore(b[bStart++], node);
91
+ let node;
92
+ if (bEnd < bLength) {
93
+ if (bStart) {
94
+ const prev = b[bStart - 1];
95
+ const prevTag = prev[$$SLOT];
96
+ node = prev.parentNode === parentNode && (!prevTag || prevTag === marker) ? prev.nextSibling : after;
97
+ } else node = b[bEnd - bStart];
98
+ } else node = after;
99
+ while (bStart < bEnd) {
100
+ const n = b[bStart++];
101
+ parentNode.insertBefore(n, node);
102
+ if (marker) n[$$SLOT] = marker;
103
+ }
88
104
  } else if (bEnd === bStart) {
89
105
  while (aStart < aEnd) {
90
- if (!map || !map.has(a[aStart])) a[aStart].remove();
91
- aStart++;
106
+ const n = a[aStart++];
107
+ if (!map || !map.has(n)) {
108
+ const tag = n[$$SLOT];
109
+ if (n.parentNode === parentNode && (!tag || tag === marker)) n.remove();
110
+ }
111
+ }
112
+ } else if ((anchor = a[aStart]) === b[bEnd - 1] && b[bStart] === a[aEnd - 1] && anchor.parentNode === parentNode && (!(anchorTag = anchor[$$SLOT]) || anchorTag === marker)) {
113
+ if (marker) {
114
+ do {
115
+ const n = a[--aEnd];
116
+ parentNode.insertBefore(n, anchor);
117
+ n[$$SLOT] = marker;
118
+ bStart++;
119
+ if (aStart >= aEnd - 1 || bStart >= bEnd) break;
120
+ } while (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]);
121
+ } else {
122
+ do {
123
+ parentNode.insertBefore(a[--aEnd], anchor);
124
+ bStart++;
125
+ if (aStart >= aEnd - 1 || bStart >= bEnd) break;
126
+ } while (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]);
92
127
  }
93
- } else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) {
94
- const anchor = a[aStart];
95
- do {
96
- parentNode.insertBefore(a[--aEnd], anchor);
97
- bStart++;
98
- if (aStart >= aEnd - 1 || bStart >= bEnd) break;
99
- } while (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]);
100
128
  } else {
101
129
  if (!map) {
102
130
  map = new Map();
@@ -114,33 +142,63 @@ function reconcileArrays(parentNode, a, b) {
114
142
  sequence++;
115
143
  }
116
144
  if (sequence > index - bStart) {
117
- const node = a[aStart];
118
- while (bStart < index) parentNode.insertBefore(b[bStart++], node);
119
- } else parentNode.replaceChild(b[bStart++], a[aStart++]);
145
+ const head = a[aStart];
146
+ const headTag = head[$$SLOT];
147
+ const node = head.parentNode === parentNode && (!headTag || headTag === marker) ? head : after;
148
+ while (bStart < index) {
149
+ const n = b[bStart++];
150
+ parentNode.insertBefore(n, node);
151
+ if (marker) n[$$SLOT] = marker;
152
+ }
153
+ } else {
154
+ const oldNode = a[aStart++];
155
+ const newNode = b[bStart++];
156
+ const oldTag = oldNode[$$SLOT];
157
+ if (oldNode.parentNode === parentNode && (!oldTag || oldTag === marker)) {
158
+ parentNode.replaceChild(newNode, oldNode);
159
+ } else {
160
+ parentNode.insertBefore(newNode, after);
161
+ }
162
+ if (marker) newNode[$$SLOT] = marker;
163
+ }
120
164
  } else aStart++;
121
- } else a[aStart++].remove();
165
+ } else {
166
+ const n = a[aStart++];
167
+ const nTag = n[$$SLOT];
168
+ if (n.parentNode === parentNode && (!nTag || nTag === marker)) n.remove();
169
+ }
122
170
  }
123
171
  }
124
172
  }
125
173
 
126
- const $$EVENTS = "_$DX_DELEGATE";
174
+ const $$EVENT_OWNER = "_$DX_EVENT_OWNER";
127
175
  const INNER_OWNED = {};
176
+ const delegatedEvents = new Set();
177
+ const delegatedContainers = new Map();
128
178
  function render$1(code, element, init, options = {}) {
129
179
  let disposer;
130
- solidJs.createRoot(dispose => {
131
- disposer = dispose;
132
- if (element === document) {
133
- const tree = code();
134
- effect(() => solidJs.flatten(tree), () => {});
135
- } else {
136
- const tree = code();
137
- insert(element, () => tree, element.firstChild ? null : undefined, init, options.insertOptions);
138
- }
139
- }, {
140
- id: options.renderId
141
- });
180
+ registerDelegatedRoot(element);
181
+ try {
182
+ solidJs.createRoot(dispose => {
183
+ disposer = dispose;
184
+ if (element === document) {
185
+ const tree = code();
186
+ effect(() => solidJs.flatten(tree), () => {});
187
+ } else {
188
+ const tree = code();
189
+ insert(element, () => tree, element.firstChild ? null : undefined, init, options.insertOptions);
190
+ }
191
+ }, {
192
+ id: options.renderId
193
+ });
194
+ } catch (err) {
195
+ if (disposer) disposer();
196
+ unregisterDelegatedRoot(element);
197
+ throw err;
198
+ }
142
199
  return () => {
143
200
  disposer();
201
+ unregisterDelegatedRoot(element);
144
202
  element.textContent = "";
145
203
  };
146
204
  }
@@ -154,20 +212,66 @@ function template(html, flag) {
154
212
  const fn = flag === 1 ? bypassGuard => document.importNode(node || (node = create(html, bypassGuard, flag)), true) : bypassGuard => (node || (node = create(html, bypassGuard, flag))).cloneNode(true);
155
213
  return fn;
156
214
  }
157
- function delegateEvents(eventNames, document = window.document) {
158
- const e = document[$$EVENTS] || (document[$$EVENTS] = new Set());
215
+ function delegateEvents(eventNames) {
159
216
  for (let i = 0, l = eventNames.length; i < l; i++) {
160
217
  const name = eventNames[i];
161
- if (!e.has(name)) {
162
- e.add(name);
163
- document.addEventListener(name, eventHandler);
218
+ if (!delegatedEvents.has(name)) {
219
+ delegatedEvents.add(name);
220
+ delegatedContainers.forEach((state, container) => attachDelegatedEvent(name, container, state));
164
221
  }
165
222
  }
166
223
  }
167
- function clearDelegatedEvents(document = window.document) {
168
- if (document[$$EVENTS]) {
169
- for (let name of document[$$EVENTS].keys()) document.removeEventListener(name, eventHandler);
170
- delete document[$$EVENTS];
224
+ function registerDelegatedRoot(root) {
225
+ const state = registerDelegatedContainer(root, root);
226
+ if (state) state.roots = (state.roots || 0) + 1;
227
+ }
228
+ function unregisterDelegatedRoot(root) {
229
+ const state = delegatedContainers.get(root);
230
+ if (state) state.roots > 1 ? state.roots-- : delete state.roots;
231
+ unregisterDelegatedContainer(root, root);
232
+ }
233
+ function registerDelegatedContainer(container, owner = container) {
234
+ if (!container || !owner) return;
235
+ let state = delegatedContainers.get(container);
236
+ if (!state) delegatedContainers.set(container, state = {
237
+ owners: new Map(),
238
+ handlers: new Map()
239
+ });
240
+ state.owners.set(owner, (state.owners.get(owner) || 0) + 1);
241
+ delegatedEvents.forEach(name => attachDelegatedEvent(name, container, state));
242
+ return state;
243
+ }
244
+ function unregisterDelegatedContainer(container, owner = container) {
245
+ const state = delegatedContainers.get(container);
246
+ if (!state) return;
247
+ const count = state.owners.get(owner);
248
+ if (count > 1) state.owners.set(owner, count - 1);else state.owners.delete(owner);
249
+ if (state.owners.size) return;
250
+ state.handlers.forEach((handler, name) => container.removeEventListener(name, handler));
251
+ delegatedContainers.delete(container);
252
+ }
253
+ function attachDelegatedEvent(name, container, state) {
254
+ if (state.handlers.has(name)) return;
255
+ const handler = e => eventHandler(e, container, state);
256
+ state.handlers.set(name, handler);
257
+ container.addEventListener(name, handler);
258
+ }
259
+ function getDelegatedRoot(node) {
260
+ while (node) {
261
+ if (delegatedContainers.get(node)?.roots) return node;
262
+ node = node._$host || node.parentNode || node.host;
263
+ }
264
+ }
265
+ function findOwner(target, state) {
266
+ let node = target;
267
+ let distance = 0;
268
+ while (node) {
269
+ if (state.owners.has(node)) return {
270
+ owner: node,
271
+ distance
272
+ };
273
+ distance++;
274
+ node = node._$host || node.parentNode || node.host;
171
275
  }
172
276
  }
173
277
  function setProperty(node, name, value) {
@@ -212,7 +316,7 @@ function className(node, value, prev) {
212
316
  node.classList.add(key);
213
317
  }
214
318
  }
215
- function addEventListener(node, name, handler, delegate) {
319
+ function addEvent(node, name, handler, delegate) {
216
320
  if (delegate) {
217
321
  if (Array.isArray(handler)) {
218
322
  node[`$$${name}`] = handler[0];
@@ -462,7 +566,17 @@ function runHydrationEvents() {
462
566
  const [el, e] = events[0];
463
567
  if (!completed.has(el)) return;
464
568
  events.shift();
465
- eventHandler(e);
569
+ let match;
570
+ for (const [container, state] of delegatedContainers) {
571
+ if (!state.handlers.has(e.type)) continue;
572
+ const entry = findOwner(e.target, state);
573
+ if (entry && (!match || entry.distance < match.distance)) match = {
574
+ container,
575
+ state,
576
+ distance: entry.distance
577
+ };
578
+ }
579
+ if (match) eventHandler(e, match.container, match.state);
466
580
  }
467
581
  if (solidJs.sharedConfig.done) {
468
582
  solidJs.sharedConfig.events = _$HY.events = null;
@@ -517,7 +631,7 @@ function assignProp(node, prop, value, prev, skipRef, nodeName) {
517
631
  node.removeEventListener(name, h);
518
632
  }
519
633
  if (delegate || value) {
520
- addEventListener(node, name, value, delegate);
634
+ addEvent(node, name, value, delegate);
521
635
  delegate && delegateEvents([name]);
522
636
  }
523
637
  } else if (hasNamespace && prop.slice(0, 5) === "prop:" || ChildProperties.has(prop) || DOMWithState[nodeName]?.[prop]) {
@@ -529,14 +643,18 @@ function assignProp(node, prop, value, prev, skipRef, nodeName) {
529
643
  }
530
644
  return value;
531
645
  }
532
- function eventHandler(e) {
646
+ function eventHandler(e, container, state) {
533
647
  if (solidJs.sharedConfig.registry && solidJs.sharedConfig.events) {
534
648
  if (solidJs.sharedConfig.events.find(([el, ev]) => ev === e)) return;
535
649
  }
650
+ if (e[$$EVENT_OWNER]) return;
651
+ const owner = state && (state.owners.size === 1 && state.owners.has(container) ? container : findOwner(e.target, state)?.owner);
652
+ if (state && !owner) return;
653
+ e[$$EVENT_OWNER] = owner || true;
536
654
  let node = e.target;
537
655
  const key = `$$${e.type}`;
538
656
  const oriTarget = e.target;
539
- const oriCurrentTarget = e.currentTarget;
657
+ const boundary = owner || container || e.currentTarget;
540
658
  const retarget = value => Object.defineProperty(e, "target", {
541
659
  configurable: true,
542
660
  value
@@ -552,29 +670,34 @@ function eventHandler(e) {
552
670
  return true;
553
671
  };
554
672
  const walkUpTree = () => {
555
- while (handleNode() && (node = node._$host || node.parentNode || node.host));
673
+ while (handleNode()) {
674
+ if (node === boundary || node.parentNode === boundary) break;
675
+ node = node._$host || node.parentNode || node.host;
676
+ }
556
677
  };
557
678
  Object.defineProperty(e, "currentTarget", {
558
679
  configurable: true,
559
680
  get() {
560
- return node || document;
681
+ return node || boundary || document;
561
682
  }
562
683
  });
563
684
  if (e.composedPath) {
564
685
  const path = e.composedPath();
565
- retarget(path[0]);
566
- for (let i = 0; i < path.length - 2; i++) {
567
- node = path[i];
568
- if (!handleNode()) break;
569
- if (node._$host) {
570
- node = node._$host;
571
- walkUpTree();
572
- break;
573
- }
574
- if (node.parentNode === oriCurrentTarget) {
575
- break;
686
+ if (path.length) {
687
+ retarget(path[0]);
688
+ for (let i = 0; i < path.length; i++) {
689
+ node = path[i];
690
+ if (!handleNode()) break;
691
+ if (node._$host) {
692
+ node = node._$host;
693
+ walkUpTree();
694
+ break;
695
+ }
696
+ if (node === boundary || node.parentNode === boundary) {
697
+ break;
698
+ }
576
699
  }
577
- }
700
+ } else walkUpTree();
578
701
  }
579
702
  else walkUpTree();
580
703
  retarget(oriTarget);
@@ -594,9 +717,14 @@ function insertExpression(parent, value, current, marker) {
594
717
  } else if (value.nodeType) {
595
718
  if (Array.isArray(current)) {
596
719
  cleanChildren(parent, current, multi ? marker : null, value);
597
- } else if (current === undefined || !parent.firstChild) {
720
+ } else if (current && current.nodeType) {
721
+ current.parentNode === parent ? parent.replaceChild(value, current) : parent.appendChild(value);
722
+ } else if (current && parent.firstChild) {
723
+ parent.replaceChild(value, parent.firstChild);
724
+ } else {
598
725
  parent.appendChild(value);
599
- } else parent.replaceChild(value, parent.firstChild);
726
+ }
727
+ if (marker) value[$$SLOT] = marker;
600
728
  } else if (Array.isArray(value)) {
601
729
  const currentArray = current && Array.isArray(current);
602
730
  if (value.length === 0) {
@@ -604,7 +732,7 @@ function insertExpression(parent, value, current, marker) {
604
732
  } else if (currentArray) {
605
733
  if (current.length === 0) {
606
734
  appendNodes(parent, value, marker);
607
- } else reconcileArrays(parent, current, value);
735
+ } else reconcileArrays(parent, current, value, marker);
608
736
  } else {
609
737
  current && cleanChildren(parent);
610
738
  appendNodes(parent, value);
@@ -629,7 +757,11 @@ function normalize(value, current, multi, doNotUnwrap) {
629
757
  return value;
630
758
  }
631
759
  function appendNodes(parent, array, marker = null) {
632
- for (let i = 0, len = array.length; i < len; i++) parent.insertBefore(array[i], marker);
760
+ for (let i = 0, len = array.length; i < len; i++) {
761
+ const n = array[i];
762
+ parent.insertBefore(n, marker);
763
+ if (marker) n[$$SLOT] = marker;
764
+ }
633
765
  }
634
766
  function cleanChildren(parent, current, marker, replacement) {
635
767
  if (marker === undefined) return parent.textContent = "";
@@ -638,11 +770,13 @@ function cleanChildren(parent, current, marker, replacement) {
638
770
  for (let i = current.length - 1; i >= 0; i--) {
639
771
  const el = current[i];
640
772
  if (replacement !== el) {
641
- const isParent = el.parentNode === parent;
642
- if (replacement && !inserted && !i) isParent ? parent.replaceChild(replacement, el) : parent.insertBefore(replacement, marker);else isParent && el.remove();
773
+ const tag = el[$$SLOT];
774
+ const owns = el.parentNode === parent && (!tag || tag === marker);
775
+ if (replacement && !inserted && !i) owns ? parent.replaceChild(replacement, el) : parent.insertBefore(replacement, marker);else if (owns) el.remove();
643
776
  } else inserted = true;
644
777
  }
645
778
  } else if (replacement) parent.insertBefore(replacement, marker);
779
+ if (replacement && marker) replacement[$$SLOT] = marker;
646
780
  }
647
781
  function gatherHydratable(element, root) {
648
782
  const templates = element.querySelectorAll(`*[_hk]`);
@@ -704,8 +838,8 @@ function Portal(props) {
704
838
  const treeMarker = document.createTextNode(""),
705
839
  startMarker = document.createTextNode(""),
706
840
  endMarker = document.createTextNode(""),
707
- mount = () => createElementProxy(props.mount || document.body, treeMarker);
708
- let content = solidJs.createMemo(() => [startMarker, props.children]);
841
+ mount = () => createElementProxy(props.mount || document.body, treeMarker),
842
+ content = solidJs.createMemo(() => [startMarker, props.children]);
709
843
  solidJs.createRenderEffect(() => [mount(), content()], ([m, c]) => {
710
844
  m.appendChild(endMarker);
711
845
  insert(m, c, endMarker);
@@ -718,6 +852,12 @@ function Portal(props) {
718
852
  }
719
853
  };
720
854
  });
855
+ solidJs.createEffect(mount, m => {
856
+ const ownerRoot = getDelegatedRoot(treeMarker);
857
+ if (!ownerRoot || ownerRoot.contains(m)) return;
858
+ registerDelegatedContainer(m, ownerRoot);
859
+ return () => unregisterDelegatedContainer(m, ownerRoot);
860
+ });
721
861
  return treeMarker;
722
862
  }
723
863
  function dynamic(source) {
@@ -831,11 +971,10 @@ exports.RawTextElements = RawTextElements;
831
971
  exports.RequestContext = RequestContext;
832
972
  exports.SVGElements = SVGElements;
833
973
  exports.VoidElements = VoidElements;
834
- exports.addEventListener = addEventListener;
974
+ exports.addEvent = addEvent;
835
975
  exports.applyRef = applyRef;
836
976
  exports.assign = assign;
837
977
  exports.className = className;
838
- exports.clearDelegatedEvents = clearDelegatedEvents;
839
978
  exports.delegateEvents = delegateEvents;
840
979
  exports.dynamic = dynamic;
841
980
  exports.dynamicProperty = dynamicProperty;
@@ -843,6 +982,7 @@ exports.effect = effect;
843
982
  exports.escape = escape;
844
983
  exports.generateHydrationScript = voidFn;
845
984
  exports.getAssets = voidFn;
985
+ exports.getDelegatedRoot = getDelegatedRoot;
846
986
  exports.getFirstChild = getFirstChild;
847
987
  exports.getHydrationKey = getHydrationKey;
848
988
  exports.getNextElement = getNextElement;
@@ -857,6 +997,8 @@ exports.isServer = isServer;
857
997
  exports.memo = memo;
858
998
  exports.mergeProps = mergeProps;
859
999
  exports.ref = ref;
1000
+ exports.registerDelegatedContainer = registerDelegatedContainer;
1001
+ exports.registerDelegatedRoot = registerDelegatedRoot;
860
1002
  exports.render = render;
861
1003
  exports.renderToStream = renderToStream;
862
1004
  exports.renderToString = renderToString;
@@ -876,4 +1018,6 @@ exports.ssrHydrationKey = ssrHydrationKey;
876
1018
  exports.ssrStyle = ssrStyle;
877
1019
  exports.style = style;
878
1020
  exports.template = template;
1021
+ exports.unregisterDelegatedContainer = unregisterDelegatedContainer;
1022
+ exports.unregisterDelegatedRoot = unregisterDelegatedRoot;
879
1023
  exports.useAssets = voidFn;