ilha 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -169,21 +169,23 @@ function morphChildren(fromParent, toParent) {
169
169
  for (let i = 0; i < toNodes.length; i++) {
170
170
  const toNode = toNodes[i];
171
171
  let fromNode = fromParent.childNodes[i];
172
- if (fromKeyed !== null && toNode.nodeType === 1) {
173
- const key = toNode.getAttribute("data-key");
174
- if (key !== null) {
175
- const match = fromKeyed.get(key);
172
+ if (fromKeyed !== null) {
173
+ const toKey = toNode.nodeType === 1 ? toNode.getAttribute("data-key") : null;
174
+ if (toKey !== null) {
175
+ const match = fromKeyed.get(toKey);
176
176
  if (match) {
177
+ fromKeyed.delete(toKey);
177
178
  if (match !== fromNode) {
178
179
  fromParent.insertBefore(match, fromNode ?? null);
179
180
  fromNode = match;
180
181
  }
181
- } else if (fromNode instanceof Element) {
182
- const fromKey = fromNode.getAttribute("data-key");
183
- if (fromKey !== null && toKeys.has(fromKey)) {
184
- fromParent.insertBefore(toNode.cloneNode(true), fromNode);
185
- continue;
186
- }
182
+ }
183
+ }
184
+ if (fromNode instanceof Element) {
185
+ const fromKey = fromNode.getAttribute("data-key");
186
+ if (fromKey !== null && fromKey !== toKey && toKeys.has(fromKey)) {
187
+ fromParent.insertBefore(toNode.cloneNode(true), fromNode);
188
+ continue;
187
189
  }
188
190
  }
189
191
  }
@@ -210,6 +212,16 @@ function morphChildren(fromParent, toParent) {
210
212
  fromParent.replaceChild(toEl.cloneNode(true), fromEl);
211
213
  continue;
212
214
  }
215
+ if (fromEl.localName === "input") {
216
+ const hadChecked = fromEl.hasAttribute("checked");
217
+ const hadValue = fromEl.getAttribute("value");
218
+ syncAttributes(fromEl, toEl);
219
+ const hasChecked = toEl.hasAttribute("checked");
220
+ if (hasChecked !== hadChecked) fromEl.checked = hasChecked;
221
+ const newValue = toEl.getAttribute("value");
222
+ if (newValue !== hadValue) fromEl.value = newValue ?? "";
223
+ continue;
224
+ }
213
225
  syncAttributes(fromEl, toEl);
214
226
  if (fromEl.localName === "textarea") {
215
227
  const newText = toEl.textContent ?? "";
@@ -111,10 +111,23 @@ function pushJsxAttr(chunks, values, name, value) {
111
111
  values.push(value);
112
112
  chunks.push("\"");
113
113
  }
114
- function renderJsxElement(type, props, children) {
114
+ function escapeAttrValue(value) {
115
+ return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;");
116
+ }
117
+ function injectDataKey(out, key) {
118
+ const m = /^\s*<([a-zA-Z][a-zA-Z0-9:._-]*)/.exec(out.value);
119
+ if (!m) return out;
120
+ const openEnd = out.value.indexOf(">", m.index);
121
+ const openTag = out.value.slice(m.index, openEnd === -1 ? void 0 : openEnd);
122
+ if (/\sdata-key\s*=/.test(openTag)) return out;
123
+ const insertAt = m.index + m[0].length;
124
+ return raw(`${out.value.slice(0, insertAt)} data-key="${escapeAttrValue(key)}"${out.value.slice(insertAt)}`);
125
+ }
126
+ function renderJsxElement(type, props, children, slotKey) {
115
127
  const chunks = [`<${type}`];
116
128
  const values = [];
117
129
  if (props) for (const [name, value] of Object.entries(props)) pushJsxAttr(chunks, values, name, value);
130
+ if (slotKey !== void 0 && props?.["data-key"] == null) pushJsxAttr(chunks, values, "data-key", slotKey);
118
131
  chunks[chunks.length - 1] += ">";
119
132
  if (!VOID_ELEMENTS.has(type)) {
120
133
  for (const child of children) {
@@ -129,8 +142,8 @@ function jsx(type, props, maybeKey, ...restChildren) {
129
142
  const hasKeyArg = typeof maybeKey === "string" || typeof maybeKey === "number";
130
143
  const keyFromArg = hasKeyArg ? maybeKey : void 0;
131
144
  const normalizedChildren = normalizeJsxChildren(props, hasKeyArg || maybeKey === void 0 ? restChildren : [maybeKey, ...restChildren]);
145
+ const slotKey = extractJsxSlotKey(props, typeof keyFromArg === "string" || typeof keyFromArg === "number" ? keyFromArg : void 0);
132
146
  if (typeof type === "function") {
133
- const slotKey = extractJsxSlotKey(props, typeof keyFromArg === "string" || typeof keyFromArg === "number" ? keyFromArg : void 0);
134
147
  const componentProps = {
135
148
  ...props,
136
149
  ...normalizedChildren.length > 0 ? { children: normalizedChildren } : {}
@@ -141,13 +154,13 @@ function jsx(type, props, maybeKey, ...restChildren) {
141
154
  if (slotKey !== void 0) out.key = slotKey;
142
155
  return html`${out}`;
143
156
  }
144
- if (isRawHtml(out)) return out;
157
+ if (isRawHtml(out)) return slotKey !== void 0 ? injectDataKey(out, slotKey) : out;
145
158
  if (typeof out === "string" && isIsland(type)) return __ilhaJsxSlot(type, componentProps, slotKey);
146
159
  if (typeof out === "string") return html`${out}`;
147
160
  if (typeof out === "object" && out !== null && Object.getPrototypeOf(out) === Object.prototype && out[RENDER_PART] === true && typeof out.toString === "function") return raw(String(out));
148
161
  return html`${out}`;
149
162
  }
150
- return renderJsxElement(type, props, normalizedChildren);
163
+ return renderJsxElement(type, props, normalizedChildren, slotKey);
151
164
  }
152
165
  const jsxs = jsx;
153
166
  function Fragment(props, ...children) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ilha",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "A tiny, framework-free island architecture library",
5
5
  "keywords": [
6
6
  "framework-free",