@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/dev.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,36 +142,66 @@ 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
  if (!element) {
130
180
  throw new Error("The `element` passed to `render(..., element)` doesn't exist. Make sure `element` exists in the document.");
131
181
  }
132
182
  let disposer;
133
- solidJs.createRoot(dispose => {
134
- disposer = dispose;
135
- if (element === document) {
136
- const tree = code();
137
- effect(() => solidJs.flatten(tree), () => {});
138
- } else {
139
- const tree = code();
140
- insert(element, () => tree, element.firstChild ? null : undefined, init, options.insertOptions);
141
- }
142
- }, {
143
- id: options.renderId
144
- });
183
+ registerDelegatedRoot(element);
184
+ try {
185
+ solidJs.createRoot(dispose => {
186
+ disposer = dispose;
187
+ if (element === document) {
188
+ const tree = code();
189
+ effect(() => solidJs.flatten(tree), () => {});
190
+ } else {
191
+ const tree = code();
192
+ insert(element, () => tree, element.firstChild ? null : undefined, init, options.insertOptions);
193
+ }
194
+ }, {
195
+ id: options.renderId
196
+ });
197
+ } catch (err) {
198
+ if (disposer) disposer();
199
+ unregisterDelegatedRoot(element);
200
+ throw err;
201
+ }
145
202
  return () => {
146
203
  disposer();
204
+ unregisterDelegatedRoot(element);
147
205
  element.textContent = "";
148
206
  };
149
207
  }
@@ -159,20 +217,66 @@ function template(html, flag) {
159
217
  fn._html = flag === 2 ? html.replace(/^<[^>]+>/, "") : html;
160
218
  return fn;
161
219
  }
162
- function delegateEvents(eventNames, document = window.document) {
163
- const e = document[$$EVENTS] || (document[$$EVENTS] = new Set());
220
+ function delegateEvents(eventNames) {
164
221
  for (let i = 0, l = eventNames.length; i < l; i++) {
165
222
  const name = eventNames[i];
166
- if (!e.has(name)) {
167
- e.add(name);
168
- document.addEventListener(name, eventHandler);
223
+ if (!delegatedEvents.has(name)) {
224
+ delegatedEvents.add(name);
225
+ delegatedContainers.forEach((state, container) => attachDelegatedEvent(name, container, state));
169
226
  }
170
227
  }
171
228
  }
172
- function clearDelegatedEvents(document = window.document) {
173
- if (document[$$EVENTS]) {
174
- for (let name of document[$$EVENTS].keys()) document.removeEventListener(name, eventHandler);
175
- delete document[$$EVENTS];
229
+ function registerDelegatedRoot(root) {
230
+ const state = registerDelegatedContainer(root, root);
231
+ if (state) state.roots = (state.roots || 0) + 1;
232
+ }
233
+ function unregisterDelegatedRoot(root) {
234
+ const state = delegatedContainers.get(root);
235
+ if (state) state.roots > 1 ? state.roots-- : delete state.roots;
236
+ unregisterDelegatedContainer(root, root);
237
+ }
238
+ function registerDelegatedContainer(container, owner = container) {
239
+ if (!container || !owner) return;
240
+ let state = delegatedContainers.get(container);
241
+ if (!state) delegatedContainers.set(container, state = {
242
+ owners: new Map(),
243
+ handlers: new Map()
244
+ });
245
+ state.owners.set(owner, (state.owners.get(owner) || 0) + 1);
246
+ delegatedEvents.forEach(name => attachDelegatedEvent(name, container, state));
247
+ return state;
248
+ }
249
+ function unregisterDelegatedContainer(container, owner = container) {
250
+ const state = delegatedContainers.get(container);
251
+ if (!state) return;
252
+ const count = state.owners.get(owner);
253
+ if (count > 1) state.owners.set(owner, count - 1);else state.owners.delete(owner);
254
+ if (state.owners.size) return;
255
+ state.handlers.forEach((handler, name) => container.removeEventListener(name, handler));
256
+ delegatedContainers.delete(container);
257
+ }
258
+ function attachDelegatedEvent(name, container, state) {
259
+ if (state.handlers.has(name)) return;
260
+ const handler = e => eventHandler(e, container, state);
261
+ state.handlers.set(name, handler);
262
+ container.addEventListener(name, handler);
263
+ }
264
+ function getDelegatedRoot(node) {
265
+ while (node) {
266
+ if (delegatedContainers.get(node)?.roots) return node;
267
+ node = node._$host || node.parentNode || node.host;
268
+ }
269
+ }
270
+ function findOwner(target, state) {
271
+ let node = target;
272
+ let distance = 0;
273
+ while (node) {
274
+ if (state.owners.has(node)) return {
275
+ owner: node,
276
+ distance
277
+ };
278
+ distance++;
279
+ node = node._$host || node.parentNode || node.host;
176
280
  }
177
281
  }
178
282
  function setProperty(node, name, value) {
@@ -217,7 +321,7 @@ function className(node, value, prev) {
217
321
  node.classList.add(key);
218
322
  }
219
323
  }
220
- function addEventListener(node, name, handler, delegate) {
324
+ function addEvent(node, name, handler, delegate) {
221
325
  if (delegate) {
222
326
  if (Array.isArray(handler)) {
223
327
  node[`$$${name}`] = handler[0];
@@ -519,7 +623,17 @@ function runHydrationEvents() {
519
623
  const [el, e] = events[0];
520
624
  if (!completed.has(el)) return;
521
625
  events.shift();
522
- eventHandler(e);
626
+ let match;
627
+ for (const [container, state] of delegatedContainers) {
628
+ if (!state.handlers.has(e.type)) continue;
629
+ const entry = findOwner(e.target, state);
630
+ if (entry && (!match || entry.distance < match.distance)) match = {
631
+ container,
632
+ state,
633
+ distance: entry.distance
634
+ };
635
+ }
636
+ if (match) eventHandler(e, match.container, match.state);
523
637
  }
524
638
  if (solidJs.sharedConfig.done) {
525
639
  solidJs.sharedConfig.events = _$HY.events = null;
@@ -574,7 +688,7 @@ function assignProp(node, prop, value, prev, skipRef, nodeName) {
574
688
  node.removeEventListener(name, h);
575
689
  }
576
690
  if (delegate || value) {
577
- addEventListener(node, name, value, delegate);
691
+ addEvent(node, name, value, delegate);
578
692
  delegate && delegateEvents([name]);
579
693
  }
580
694
  } else if (hasNamespace && prop.slice(0, 5) === "prop:" || ChildProperties.has(prop) || DOMWithState[nodeName]?.[prop]) {
@@ -586,14 +700,18 @@ function assignProp(node, prop, value, prev, skipRef, nodeName) {
586
700
  }
587
701
  return value;
588
702
  }
589
- function eventHandler(e) {
703
+ function eventHandler(e, container, state) {
590
704
  if (solidJs.sharedConfig.registry && solidJs.sharedConfig.events) {
591
705
  if (solidJs.sharedConfig.events.find(([el, ev]) => ev === e)) return;
592
706
  }
707
+ if (e[$$EVENT_OWNER]) return;
708
+ const owner = state && (state.owners.size === 1 && state.owners.has(container) ? container : findOwner(e.target, state)?.owner);
709
+ if (state && !owner) return;
710
+ e[$$EVENT_OWNER] = owner || true;
593
711
  let node = e.target;
594
712
  const key = `$$${e.type}`;
595
713
  const oriTarget = e.target;
596
- const oriCurrentTarget = e.currentTarget;
714
+ const boundary = owner || container || e.currentTarget;
597
715
  const retarget = value => Object.defineProperty(e, "target", {
598
716
  configurable: true,
599
717
  value
@@ -609,29 +727,34 @@ function eventHandler(e) {
609
727
  return true;
610
728
  };
611
729
  const walkUpTree = () => {
612
- while (handleNode() && (node = node._$host || node.parentNode || node.host));
730
+ while (handleNode()) {
731
+ if (node === boundary || node.parentNode === boundary) break;
732
+ node = node._$host || node.parentNode || node.host;
733
+ }
613
734
  };
614
735
  Object.defineProperty(e, "currentTarget", {
615
736
  configurable: true,
616
737
  get() {
617
- return node || document;
738
+ return node || boundary || document;
618
739
  }
619
740
  });
620
741
  if (e.composedPath) {
621
742
  const path = e.composedPath();
622
- retarget(path[0]);
623
- for (let i = 0; i < path.length - 2; i++) {
624
- node = path[i];
625
- if (!handleNode()) break;
626
- if (node._$host) {
627
- node = node._$host;
628
- walkUpTree();
629
- break;
630
- }
631
- if (node.parentNode === oriCurrentTarget) {
632
- break;
743
+ if (path.length) {
744
+ retarget(path[0]);
745
+ for (let i = 0; i < path.length; i++) {
746
+ node = path[i];
747
+ if (!handleNode()) break;
748
+ if (node._$host) {
749
+ node = node._$host;
750
+ walkUpTree();
751
+ break;
752
+ }
753
+ if (node === boundary || node.parentNode === boundary) {
754
+ break;
755
+ }
633
756
  }
634
- }
757
+ } else walkUpTree();
635
758
  }
636
759
  else walkUpTree();
637
760
  retarget(oriTarget);
@@ -651,9 +774,14 @@ function insertExpression(parent, value, current, marker) {
651
774
  } else if (value.nodeType) {
652
775
  if (Array.isArray(current)) {
653
776
  cleanChildren(parent, current, multi ? marker : null, value);
654
- } else if (current === undefined || !parent.firstChild) {
777
+ } else if (current && current.nodeType) {
778
+ current.parentNode === parent ? parent.replaceChild(value, current) : parent.appendChild(value);
779
+ } else if (current && parent.firstChild) {
780
+ parent.replaceChild(value, parent.firstChild);
781
+ } else {
655
782
  parent.appendChild(value);
656
- } else parent.replaceChild(value, parent.firstChild);
783
+ }
784
+ if (marker) value[$$SLOT] = marker;
657
785
  } else if (Array.isArray(value)) {
658
786
  const currentArray = current && Array.isArray(current);
659
787
  if (value.length === 0) {
@@ -661,7 +789,7 @@ function insertExpression(parent, value, current, marker) {
661
789
  } else if (currentArray) {
662
790
  if (current.length === 0) {
663
791
  appendNodes(parent, value, marker);
664
- } else reconcileArrays(parent, current, value);
792
+ } else reconcileArrays(parent, current, value, marker);
665
793
  } else {
666
794
  current && cleanChildren(parent);
667
795
  appendNodes(parent, value);
@@ -686,7 +814,11 @@ function normalize(value, current, multi, doNotUnwrap) {
686
814
  return value;
687
815
  }
688
816
  function appendNodes(parent, array, marker = null) {
689
- for (let i = 0, len = array.length; i < len; i++) parent.insertBefore(array[i], marker);
817
+ for (let i = 0, len = array.length; i < len; i++) {
818
+ const n = array[i];
819
+ parent.insertBefore(n, marker);
820
+ if (marker) n[$$SLOT] = marker;
821
+ }
690
822
  }
691
823
  function cleanChildren(parent, current, marker, replacement) {
692
824
  if (marker === undefined) return parent.textContent = "";
@@ -695,11 +827,13 @@ function cleanChildren(parent, current, marker, replacement) {
695
827
  for (let i = current.length - 1; i >= 0; i--) {
696
828
  const el = current[i];
697
829
  if (replacement !== el) {
698
- const isParent = el.parentNode === parent;
699
- if (replacement && !inserted && !i) isParent ? parent.replaceChild(replacement, el) : parent.insertBefore(replacement, marker);else isParent && el.remove();
830
+ const tag = el[$$SLOT];
831
+ const owns = el.parentNode === parent && (!tag || tag === marker);
832
+ if (replacement && !inserted && !i) owns ? parent.replaceChild(replacement, el) : parent.insertBefore(replacement, marker);else if (owns) el.remove();
700
833
  } else inserted = true;
701
834
  }
702
835
  } else if (replacement) parent.insertBefore(replacement, marker);
836
+ if (replacement && marker) replacement[$$SLOT] = marker;
703
837
  }
704
838
  function gatherHydratable(element, root) {
705
839
  const templates = element.querySelectorAll(`*[_hk]`);
@@ -763,8 +897,8 @@ function Portal(props) {
763
897
  const treeMarker = document.createTextNode(""),
764
898
  startMarker = document.createTextNode(""),
765
899
  endMarker = document.createTextNode(""),
766
- mount = () => createElementProxy(props.mount || document.body, treeMarker);
767
- let content = solidJs.createMemo(() => [startMarker, props.children]);
900
+ mount = () => createElementProxy(props.mount || document.body, treeMarker),
901
+ content = solidJs.createMemo(() => [startMarker, props.children]);
768
902
  solidJs.createRenderEffect(() => [mount(), content()], ([m, c]) => {
769
903
  m.appendChild(endMarker);
770
904
  insert(m, c, endMarker);
@@ -777,6 +911,12 @@ function Portal(props) {
777
911
  }
778
912
  };
779
913
  });
914
+ solidJs.createEffect(mount, m => {
915
+ const ownerRoot = getDelegatedRoot(treeMarker);
916
+ if (!ownerRoot || ownerRoot.contains(m)) return;
917
+ registerDelegatedContainer(m, ownerRoot);
918
+ return () => unregisterDelegatedContainer(m, ownerRoot);
919
+ });
780
920
  return treeMarker;
781
921
  }
782
922
  function dynamic(source) {
@@ -893,11 +1033,10 @@ exports.RawTextElements = RawTextElements;
893
1033
  exports.RequestContext = RequestContext;
894
1034
  exports.SVGElements = SVGElements;
895
1035
  exports.VoidElements = VoidElements;
896
- exports.addEventListener = addEventListener;
1036
+ exports.addEvent = addEvent;
897
1037
  exports.applyRef = applyRef;
898
1038
  exports.assign = assign;
899
1039
  exports.className = className;
900
- exports.clearDelegatedEvents = clearDelegatedEvents;
901
1040
  exports.delegateEvents = delegateEvents;
902
1041
  exports.dynamic = dynamic;
903
1042
  exports.dynamicProperty = dynamicProperty;
@@ -905,6 +1044,7 @@ exports.effect = effect;
905
1044
  exports.escape = escape;
906
1045
  exports.generateHydrationScript = voidFn;
907
1046
  exports.getAssets = voidFn;
1047
+ exports.getDelegatedRoot = getDelegatedRoot;
908
1048
  exports.getFirstChild = getFirstChild;
909
1049
  exports.getHydrationKey = getHydrationKey;
910
1050
  exports.getNextElement = getNextElement;
@@ -919,6 +1059,8 @@ exports.isServer = isServer;
919
1059
  exports.memo = memo;
920
1060
  exports.mergeProps = mergeProps;
921
1061
  exports.ref = ref;
1062
+ exports.registerDelegatedContainer = registerDelegatedContainer;
1063
+ exports.registerDelegatedRoot = registerDelegatedRoot;
922
1064
  exports.render = render;
923
1065
  exports.renderToStream = renderToStream;
924
1066
  exports.renderToString = renderToString;
@@ -938,4 +1080,6 @@ exports.ssrHydrationKey = ssrHydrationKey;
938
1080
  exports.ssrStyle = ssrStyle;
939
1081
  exports.style = style;
940
1082
  exports.template = template;
1083
+ exports.unregisterDelegatedContainer = unregisterDelegatedContainer;
1084
+ exports.unregisterDelegatedRoot = unregisterDelegatedRoot;
941
1085
  exports.useAssets = voidFn;