marko 6.1.20 → 6.1.22

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/debug/dom.js CHANGED
@@ -718,8 +718,8 @@ function init(runtimeId = "M") {
718
718
  }
719
719
  };
720
720
  const serializeContext = ((data, registryId) => typeof data === "number" ? registryId ? registeredValues[registryId](getScope(data)) : getScope(data) : applyScopes(data));
721
- const createVisitBranches = (branchScopesStack = [], branchStarts = [], orphanBranches = [], curBranchScopes) => {
722
- return (branchId, branch, endedBranches, accessor, singleNode, parent = visit.parentNode, startVisit = visit, i = orphanBranches.length) => {
721
+ const createVisitBranches = (branchScopesStack = [], branchStarts = [], orphanBranches = [], deferredOwners = [], curBranchScopes) => {
722
+ return (branchId, branch, endedBranches, accessor, singleNode, parent = visit.parentNode, startVisit = visit, i = orphanBranches.length, j = deferredOwners.length) => {
723
723
  if (visitType !== "[") {
724
724
  visitScope[nextToken()] = visitType === ")" || visitType === "}" ? parent : visit;
725
725
  accessor = "BranchScopes:" + lastToken;
@@ -746,6 +746,10 @@ function init(runtimeId = "M") {
746
746
  branch["#EndNode"] = visit.previousSibling === startVisit ? startVisit : parent.insertBefore(new Text(), visit);
747
747
  }
748
748
  while (i && orphanBranches[--i]["#Id"] > branchId) setParentBranch(orphanBranches.pop(), branch);
749
+ while (j && deferredOwners[--j]["#Id"] > branchId) {
750
+ const owner = deferredOwners.pop();
751
+ if (owner["#ClosestBranch"] !== owner) owner["#ClosestBranch"] = branch;
752
+ }
749
753
  nextToken();
750
754
  }
751
755
  if (endedBranches) {
@@ -758,7 +762,7 @@ function init(runtimeId = "M") {
758
762
  curBranchScopes = void 0;
759
763
  }
760
764
  branchStarts.push(visit);
761
- }
765
+ } else deferredOwners.push(visitScope);
762
766
  };
763
767
  };
764
768
  const nextToken = () => lastToken = visitText.slice(lastTokenIndex, (lastTokenIndex = visitText.indexOf(" ", lastTokenIndex) + 1 || visitText.length + 1) - 1);
@@ -1350,7 +1354,12 @@ function _await_promise(nodeAccessor, params) {
1350
1354
  c() {
1351
1355
  if (--awaitCounter.i) return 1;
1352
1356
  if (tryBranch === scope[branchAccessor]) {
1353
- if (scope[nodeAccessor].parentNode) scope[nodeAccessor].replaceWith(scope[branchAccessor]["#StartNode"].parentNode);
1357
+ const anchor = scope[nodeAccessor];
1358
+ if (anchor.parentNode) {
1359
+ const detachedParent = scope[branchAccessor]["#StartNode"].parentNode;
1360
+ if (detachedParent === anchor.parentNode) anchor.remove();
1361
+ else anchor.replaceWith(detachedParent);
1362
+ }
1354
1363
  } else dismissPlaceholder(tryBranch);
1355
1364
  queueEffect(tryBranch, runPendingEffects);
1356
1365
  }
@@ -716,8 +716,8 @@ function init(runtimeId = "M") {
716
716
  }
717
717
  };
718
718
  const serializeContext = ((data, registryId) => typeof data === "number" ? registryId ? registeredValues[registryId](getScope(data)) : getScope(data) : applyScopes(data));
719
- const createVisitBranches = (branchScopesStack = [], branchStarts = [], orphanBranches = [], curBranchScopes) => {
720
- return (branchId, branch, endedBranches, accessor, singleNode, parent = visit.parentNode, startVisit = visit, i = orphanBranches.length) => {
719
+ const createVisitBranches = (branchScopesStack = [], branchStarts = [], orphanBranches = [], deferredOwners = [], curBranchScopes) => {
720
+ return (branchId, branch, endedBranches, accessor, singleNode, parent = visit.parentNode, startVisit = visit, i = orphanBranches.length, j = deferredOwners.length) => {
721
721
  if (visitType !== "[") {
722
722
  visitScope[nextToken()] = visitType === ")" || visitType === "}" ? parent : visit;
723
723
  accessor = "BranchScopes:" + lastToken;
@@ -744,6 +744,10 @@ function init(runtimeId = "M") {
744
744
  branch["#EndNode"] = visit.previousSibling === startVisit ? startVisit : parent.insertBefore(new Text(), visit);
745
745
  }
746
746
  while (i && orphanBranches[--i]["#Id"] > branchId) setParentBranch(orphanBranches.pop(), branch);
747
+ while (j && deferredOwners[--j]["#Id"] > branchId) {
748
+ const owner = deferredOwners.pop();
749
+ if (owner["#ClosestBranch"] !== owner) owner["#ClosestBranch"] = branch;
750
+ }
747
751
  nextToken();
748
752
  }
749
753
  if (endedBranches) {
@@ -756,7 +760,7 @@ function init(runtimeId = "M") {
756
760
  curBranchScopes = void 0;
757
761
  }
758
762
  branchStarts.push(visit);
759
- }
763
+ } else deferredOwners.push(visitScope);
760
764
  };
761
765
  };
762
766
  const nextToken = () => lastToken = visitText.slice(lastTokenIndex, (lastTokenIndex = visitText.indexOf(" ", lastTokenIndex) + 1 || visitText.length + 1) - 1);
@@ -1348,7 +1352,12 @@ function _await_promise(nodeAccessor, params) {
1348
1352
  c() {
1349
1353
  if (--awaitCounter.i) return 1;
1350
1354
  if (tryBranch === scope[branchAccessor]) {
1351
- if (scope[nodeAccessor].parentNode) scope[nodeAccessor].replaceWith(scope[branchAccessor]["#StartNode"].parentNode);
1355
+ const anchor = scope[nodeAccessor];
1356
+ if (anchor.parentNode) {
1357
+ const detachedParent = scope[branchAccessor]["#StartNode"].parentNode;
1358
+ if (detachedParent === anchor.parentNode) anchor.remove();
1359
+ else anchor.replaceWith(detachedParent);
1360
+ }
1352
1361
  } else dismissPlaceholder(tryBranch);
1353
1362
  queueEffect(tryBranch, runPendingEffects);
1354
1363
  }
@@ -2526,6 +2526,15 @@ function _attr_nonce() {
2526
2526
  function _attr(name, value) {
2527
2527
  return isVoid(value) ? "" : nonVoidAttr(name, value);
2528
2528
  }
2529
+ function _attr_and(name, value, attr) {
2530
+ return value ? attr : _attr(name, value);
2531
+ }
2532
+ function _attr_or(name, value, attr) {
2533
+ return value ? _attr(name, value) : attr;
2534
+ }
2535
+ function _attr_nullish(name, value, attr) {
2536
+ return value == null ? attr : _attr(name, value);
2537
+ }
2529
2538
  function _attrs(data, nodeAccessor, scopeId, tagName) {
2530
2539
  let result = "";
2531
2540
  let skip = /[\s/>"'=]/;
@@ -3153,6 +3162,7 @@ function NOOP() {}
3153
3162
  exports.$global = $global;
3154
3163
  exports._assert_hoist = _assert_hoist;
3155
3164
  exports._attr = _attr;
3165
+ exports._attr_and = _attr_and;
3156
3166
  exports._attr_class = _attr_class;
3157
3167
  exports._attr_content = _attr_content;
3158
3168
  exports._attr_details_open = _attr_details_or_dialog_open;
@@ -3161,7 +3171,9 @@ exports._attr_input_checked = _attr_input_checked;
3161
3171
  exports._attr_input_checkedValue = _attr_input_checkedValue;
3162
3172
  exports._attr_input_value = _attr_input_value;
3163
3173
  exports._attr_nonce = _attr_nonce;
3174
+ exports._attr_nullish = _attr_nullish;
3164
3175
  exports._attr_option_value = _attr_option_value;
3176
+ exports._attr_or = _attr_or;
3165
3177
  exports._attr_select_value = _attr_select_value;
3166
3178
  exports._attr_style = _attr_style;
3167
3179
  exports._attr_textarea_value = _attr_textarea_value;
@@ -2524,6 +2524,15 @@ function _attr_nonce() {
2524
2524
  function _attr(name, value) {
2525
2525
  return isVoid(value) ? "" : nonVoidAttr(name, value);
2526
2526
  }
2527
+ function _attr_and(name, value, attr) {
2528
+ return value ? attr : _attr(name, value);
2529
+ }
2530
+ function _attr_or(name, value, attr) {
2531
+ return value ? _attr(name, value) : attr;
2532
+ }
2533
+ function _attr_nullish(name, value, attr) {
2534
+ return value == null ? attr : _attr(name, value);
2535
+ }
2527
2536
  function _attrs(data, nodeAccessor, scopeId, tagName) {
2528
2537
  let result = "";
2529
2538
  let skip = /[\s/>"'=]/;
@@ -3148,4 +3157,4 @@ const compat = {
3148
3157
  };
3149
3158
  function NOOP() {}
3150
3159
  //#endregion
3151
- export { $global, _assert_hoist, _attr, _attr_class, _attr_content, _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open as _attr_dialog_open, _attr_input_checked, _attr_input_checkedValue, _attr_input_value, _attr_nonce, _attr_option_value, _attr_select_value, _attr_style, _attr_textarea_value, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, _await, _content, _content_resume, _dynamic_tag, _el, _el_read_error, _el_resume, _escape, _escape_comment, _escape_script, _escape_style, _existing_scope, _flush_head, _for_in, _for_of, _for_to, _for_until, _hoist, _hoist_read_error, _html, _id, _if, _peek_scope_id, _resume, _resume_branch, writeScope as _scope, _scope_id, _scope_reason, _scope_with_id, _script, _sep, _serialize_guard, _serialize_if, _set_serialize_reason, _subscribe, _template, _to_text, _trailers, _try, _unescaped, _var, attrTag, attrTags, compat, forIn, forInBy, forOf, forOfBy, forStepBy, forTo, forUntil, withLoadAssets, withPageAssets };
3160
+ export { $global, _assert_hoist, _attr, _attr_and, _attr_class, _attr_content, _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open as _attr_dialog_open, _attr_input_checked, _attr_input_checkedValue, _attr_input_value, _attr_nonce, _attr_nullish, _attr_option_value, _attr_or, _attr_select_value, _attr_style, _attr_textarea_value, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, _await, _content, _content_resume, _dynamic_tag, _el, _el_read_error, _el_resume, _escape, _escape_comment, _escape_script, _escape_style, _existing_scope, _flush_head, _for_in, _for_of, _for_to, _for_until, _hoist, _hoist_read_error, _html, _id, _if, _peek_scope_id, _resume, _resume_branch, writeScope as _scope, _scope_id, _scope_reason, _scope_with_id, _script, _sep, _serialize_guard, _serialize_if, _set_serialize_reason, _subscribe, _template, _to_text, _trailers, _try, _unescaped, _var, attrTag, attrTags, compat, forIn, forInBy, forOf, forOfBy, forStepBy, forTo, forUntil, withLoadAssets, withPageAssets };
package/dist/dom.js CHANGED
@@ -457,20 +457,24 @@ function init(runtimeId = "M") {
457
457
  let partial = partials[i];
458
458
  typeof partial == "number" ? scopeId += partial : (scopeId ? initScope(Object.assign(scopeLookup[scopeId] ||= (partial.L = scopeId, partial), partial)) : Object.assign(initGlobal(), partial), scopeId++);
459
459
  }
460
- }, serializeContext = ((data, registryId) => typeof data == "number" ? registryId ? registeredValues[registryId](getScope(data)) : getScope(data) : applyScopes(data)), createVisitBranches = (branchScopesStack = [], branchStarts = [], orphanBranches = [], curBranchScopes) => (branchId, branch, endedBranches, accessor, singleNode, parent = visit.parentNode, startVisit = visit, i = orphanBranches.length) => {
460
+ }, serializeContext = ((data, registryId) => typeof data == "number" ? registryId ? registeredValues[registryId](getScope(data)) : getScope(data) : applyScopes(data)), createVisitBranches = (branchScopesStack = [], branchStarts = [], orphanBranches = [], deferredOwners = [], curBranchScopes) => (branchId, branch, endedBranches, accessor, singleNode, parent = visit.parentNode, startVisit = visit, i = orphanBranches.length, j = deferredOwners.length) => {
461
461
  for (visitType !== "[" && (visitScope[nextToken()] = visitType === ")" || visitType === "}" ? parent : visit, accessor = "A" + lastToken, singleNode = visitType !== "]" && visitType !== ")", nextToken()); branchId = +lastToken;) {
462
462
  if ((endedBranches ||= []).push(branch = getScope(branchId)), setParentBranch(branch, branch.F), (branch.O = render.p?.[branchId]) && (branch.O.m = render.m), singleNode) {
463
463
  for (; startVisit.previousSibling && ~visits.indexOf(startVisit = startVisit.previousSibling););
464
464
  branch.K = branch.S = startVisit, visitType === "'" && (branch.a = startVisit);
465
465
  } else curBranchScopes = push(curBranchScopes, branch), accessor && (visitScope[accessor] = curBranchScopes, curBranchScopes = branchScopesStack.pop()), startVisit = branchStarts.pop(), parent !== startVisit.parentNode && parent.prepend(startVisit), branch.S = startVisit, branch.K = visit.previousSibling === startVisit ? startVisit : parent.insertBefore(new Text(), visit);
466
466
  for (; i && orphanBranches[--i].L > branchId;) setParentBranch(orphanBranches.pop(), branch);
467
+ for (; j && deferredOwners[--j].L > branchId;) {
468
+ let owner = deferredOwners.pop();
469
+ owner.F !== owner && (owner.F = branch);
470
+ }
467
471
  nextToken();
468
472
  }
469
473
  if (endedBranches) {
470
474
  for (let ended of endedBranches) orphanBranches.push(ended);
471
475
  singleNode && (visitScope[accessor] = endedBranches.length > 1 ? endedBranches.reverse() : endedBranches[0]);
472
476
  }
473
- visitType === "[" && (endedBranches || (branchScopesStack.push(curBranchScopes), curBranchScopes = void 0), branchStarts.push(visit));
477
+ visitType === "[" ? (endedBranches || (branchScopesStack.push(curBranchScopes), curBranchScopes = void 0), branchStarts.push(visit)) : deferredOwners.push(visitScope);
474
478
  }, nextToken = () => lastToken = visitText.slice(lastTokenIndex, (lastTokenIndex = visitText.indexOf(" ", lastTokenIndex) + 1 || visitText.length + 1) - 1), processResumes = (resumes = [], effects) => {
475
479
  let i = 0;
476
480
  for (; i < resumes.length; i++) {
@@ -883,7 +887,14 @@ function _await_promise(nodeAccessor, params) {
883
887
  i: 0,
884
888
  c() {
885
889
  if (--awaitCounter.i) return 1;
886
- tryBranch === scope[branchAccessor] ? scope[nodeAccessor].parentNode && scope[nodeAccessor].replaceWith(scope[branchAccessor].S.parentNode) : dismissPlaceholder(tryBranch), queueEffect(tryBranch, runPendingEffects);
890
+ if (tryBranch === scope[branchAccessor]) {
891
+ let anchor = scope[nodeAccessor];
892
+ if (anchor.parentNode) {
893
+ let detachedParent = scope[branchAccessor].S.parentNode;
894
+ detachedParent === anchor.parentNode ? anchor.remove() : anchor.replaceWith(detachedParent);
895
+ }
896
+ } else dismissPlaceholder(tryBranch);
897
+ queueEffect(tryBranch, runPendingEffects);
887
898
  }
888
899
  }), scope[promiseAccessor] || (awaitBranch && (awaitBranch.W ||= []), awaitCounter.i++ || requestAnimationFrame(() => awaitCounter.i && runEffects(prepareEffects(() => queueRender(scope, () => {
889
900
  awaitBranch.V || (awaitBranch.S.parentNode.insertBefore(scope[nodeAccessor], awaitBranch.S), tempDetachBranch(tryBranch));
package/dist/dom.mjs CHANGED
@@ -456,20 +456,24 @@ function init(runtimeId = "M") {
456
456
  let partial = partials[i];
457
457
  typeof partial == "number" ? scopeId += partial : (scopeId ? initScope(Object.assign(scopeLookup[scopeId] ||= (partial.L = scopeId, partial), partial)) : Object.assign(initGlobal(), partial), scopeId++);
458
458
  }
459
- }, serializeContext = ((data, registryId) => typeof data == "number" ? registryId ? registeredValues[registryId](getScope(data)) : getScope(data) : applyScopes(data)), createVisitBranches = (branchScopesStack = [], branchStarts = [], orphanBranches = [], curBranchScopes) => (branchId, branch, endedBranches, accessor, singleNode, parent = visit.parentNode, startVisit = visit, i = orphanBranches.length) => {
459
+ }, serializeContext = ((data, registryId) => typeof data == "number" ? registryId ? registeredValues[registryId](getScope(data)) : getScope(data) : applyScopes(data)), createVisitBranches = (branchScopesStack = [], branchStarts = [], orphanBranches = [], deferredOwners = [], curBranchScopes) => (branchId, branch, endedBranches, accessor, singleNode, parent = visit.parentNode, startVisit = visit, i = orphanBranches.length, j = deferredOwners.length) => {
460
460
  for (visitType !== "[" && (visitScope[nextToken()] = visitType === ")" || visitType === "}" ? parent : visit, accessor = "A" + lastToken, singleNode = visitType !== "]" && visitType !== ")", nextToken()); branchId = +lastToken;) {
461
461
  if ((endedBranches ||= []).push(branch = getScope(branchId)), setParentBranch(branch, branch.F), (branch.O = render.p?.[branchId]) && (branch.O.m = render.m), singleNode) {
462
462
  for (; startVisit.previousSibling && ~visits.indexOf(startVisit = startVisit.previousSibling););
463
463
  branch.K = branch.S = startVisit, visitType === "'" && (branch.a = startVisit);
464
464
  } else curBranchScopes = push(curBranchScopes, branch), accessor && (visitScope[accessor] = curBranchScopes, curBranchScopes = branchScopesStack.pop()), startVisit = branchStarts.pop(), parent !== startVisit.parentNode && parent.prepend(startVisit), branch.S = startVisit, branch.K = visit.previousSibling === startVisit ? startVisit : parent.insertBefore(new Text(), visit);
465
465
  for (; i && orphanBranches[--i].L > branchId;) setParentBranch(orphanBranches.pop(), branch);
466
+ for (; j && deferredOwners[--j].L > branchId;) {
467
+ let owner = deferredOwners.pop();
468
+ owner.F !== owner && (owner.F = branch);
469
+ }
466
470
  nextToken();
467
471
  }
468
472
  if (endedBranches) {
469
473
  for (let ended of endedBranches) orphanBranches.push(ended);
470
474
  singleNode && (visitScope[accessor] = endedBranches.length > 1 ? endedBranches.reverse() : endedBranches[0]);
471
475
  }
472
- visitType === "[" && (endedBranches || (branchScopesStack.push(curBranchScopes), curBranchScopes = void 0), branchStarts.push(visit));
476
+ visitType === "[" ? (endedBranches || (branchScopesStack.push(curBranchScopes), curBranchScopes = void 0), branchStarts.push(visit)) : deferredOwners.push(visitScope);
473
477
  }, nextToken = () => lastToken = visitText.slice(lastTokenIndex, (lastTokenIndex = visitText.indexOf(" ", lastTokenIndex) + 1 || visitText.length + 1) - 1), processResumes = (resumes = [], effects) => {
474
478
  let i = 0;
475
479
  for (; i < resumes.length; i++) {
@@ -882,7 +886,14 @@ function _await_promise(nodeAccessor, params) {
882
886
  i: 0,
883
887
  c() {
884
888
  if (--awaitCounter.i) return 1;
885
- tryBranch === scope[branchAccessor] ? scope[nodeAccessor].parentNode && scope[nodeAccessor].replaceWith(scope[branchAccessor].S.parentNode) : dismissPlaceholder(tryBranch), queueEffect(tryBranch, runPendingEffects);
889
+ if (tryBranch === scope[branchAccessor]) {
890
+ let anchor = scope[nodeAccessor];
891
+ if (anchor.parentNode) {
892
+ let detachedParent = scope[branchAccessor].S.parentNode;
893
+ detachedParent === anchor.parentNode ? anchor.remove() : anchor.replaceWith(detachedParent);
894
+ }
895
+ } else dismissPlaceholder(tryBranch);
896
+ queueEffect(tryBranch, runPendingEffects);
886
897
  }
887
898
  }), scope[promiseAccessor] || (awaitBranch && (awaitBranch.W ||= []), awaitCounter.i++ || requestAnimationFrame(() => awaitCounter.i && runEffects(prepareEffects(() => queueRender(scope, () => {
888
899
  awaitBranch.V || (awaitBranch.S.parentNode.insertBefore(scope[nodeAccessor], awaitBranch.S), tempDetachBranch(tryBranch));
@@ -10,6 +10,9 @@ export declare function _attr_input_checkedValue(scopeId: number, nodeAccessor:
10
10
  export declare function _attr_details_or_dialog_open(scopeId: number, nodeAccessor: Accessor, open: unknown, openChange: unknown, serializeType?: 1): "" | " open";
11
11
  export declare function _attr_nonce(): string;
12
12
  export declare function _attr(name: string, value: unknown): string;
13
+ export declare function _attr_and(name: string, value: unknown, attr: string): string;
14
+ export declare function _attr_or(name: string, value: unknown, attr: string): string;
15
+ export declare function _attr_nullish(name: string, value: unknown, attr: string): string;
13
16
  export declare function _attrs(data: Record<string, unknown>, nodeAccessor: Accessor, scopeId: number, tagName: string): string;
14
17
  export declare function _attrs_content(data: Record<string, unknown>, nodeAccessor: Accessor, scopeId: number, tagName: string, serializeReason?: 1 | 0): void;
15
18
  export declare function _attrs_partial(data: Record<string, unknown>, skip: Record<string, 1>, nodeAccessor: Accessor, scopeId: number, tagName: string): string;
package/dist/html.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { attrTag, attrTags } from "./common/attr-tag";
2
2
  export { _assert_hoist, _el_read_error, _hoist_read_error, } from "./common/errors";
3
3
  export { _flush_head, withLoadAssets, withPageAssets } from "./html/assets";
4
- export { _attr, _attr_class, _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open as _attr_dialog_open, _attr_input_checked, _attr_input_checkedValue, _attr_input_value, _attr_nonce, _attr_option_value, _attr_select_value, _attr_style, _attr_textarea_value, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, } from "./html/attrs";
4
+ export { _attr, _attr_and, _attr_class, _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open as _attr_dialog_open, _attr_input_checked, _attr_input_checkedValue, _attr_input_value, _attr_nonce, _attr_nullish, _attr_option_value, _attr_or, _attr_select_value, _attr_style, _attr_textarea_value, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, } from "./html/attrs";
5
5
  export { compat } from "./html/compat";
6
6
  export { _escape, _escape_comment, _escape_script, _escape_style, _to_text, _unescaped, } from "./html/content";
7
7
  export { _content, _content_resume, _dynamic_tag } from "./html/dynamic-tag";
package/dist/html.js CHANGED
@@ -1647,6 +1647,15 @@ function _attr_nonce() {
1647
1647
  function _attr(name, value) {
1648
1648
  return isVoid(value) ? "" : nonVoidAttr(name, value);
1649
1649
  }
1650
+ function _attr_and(name, value, attr) {
1651
+ return value ? attr : _attr(name, value);
1652
+ }
1653
+ function _attr_or(name, value, attr) {
1654
+ return value ? _attr(name, value) : attr;
1655
+ }
1656
+ function _attr_nullish(name, value, attr) {
1657
+ return value == null ? attr : _attr(name, value);
1658
+ }
1650
1659
  function _attrs(data, nodeAccessor, scopeId, tagName) {
1651
1660
  let result = "", skip = /[\s/>"'=]/, events;
1652
1661
  switch (tagName) {
@@ -1970,7 +1979,7 @@ function toObjectExpression(options) {
1970
1979
  //#endregion
1971
1980
  //#region src/html/compat.ts
1972
1981
  function NOOP() {}
1973
- exports.$global = $global, exports._assert_hoist = _assert_hoist, exports._attr = _attr, exports._attr_class = _attr_class, exports._attr_content = _attr_content, exports._attr_details_open = _attr_details_or_dialog_open, exports._attr_dialog_open = _attr_details_or_dialog_open, exports._attr_input_checked = _attr_input_checked, exports._attr_input_checkedValue = _attr_input_checkedValue, exports._attr_input_value = _attr_input_value, exports._attr_nonce = _attr_nonce, exports._attr_option_value = _attr_option_value, exports._attr_select_value = _attr_select_value, exports._attr_style = _attr_style, exports._attr_textarea_value = _attr_textarea_value, exports._attrs = _attrs, exports._attrs_content = _attrs_content, exports._attrs_partial = _attrs_partial, exports._attrs_partial_content = _attrs_partial_content, exports._await = _await, exports._content = _content, exports._content_resume = _content_resume, Object.defineProperty(exports, "_dynamic_tag", {
1982
+ exports.$global = $global, exports._assert_hoist = _assert_hoist, exports._attr = _attr, exports._attr_and = _attr_and, exports._attr_class = _attr_class, exports._attr_content = _attr_content, exports._attr_details_open = _attr_details_or_dialog_open, exports._attr_dialog_open = _attr_details_or_dialog_open, exports._attr_input_checked = _attr_input_checked, exports._attr_input_checkedValue = _attr_input_checkedValue, exports._attr_input_value = _attr_input_value, exports._attr_nonce = _attr_nonce, exports._attr_nullish = _attr_nullish, exports._attr_option_value = _attr_option_value, exports._attr_or = _attr_or, exports._attr_select_value = _attr_select_value, exports._attr_style = _attr_style, exports._attr_textarea_value = _attr_textarea_value, exports._attrs = _attrs, exports._attrs_content = _attrs_content, exports._attrs_partial = _attrs_partial, exports._attrs_partial_content = _attrs_partial_content, exports._await = _await, exports._content = _content, exports._content_resume = _content_resume, Object.defineProperty(exports, "_dynamic_tag", {
1974
1983
  enumerable: !0,
1975
1984
  get: function() {
1976
1985
  return _dynamic_tag;
package/dist/html.mjs CHANGED
@@ -1646,6 +1646,15 @@ function _attr_nonce() {
1646
1646
  function _attr(name, value) {
1647
1647
  return isVoid(value) ? "" : nonVoidAttr(name, value);
1648
1648
  }
1649
+ function _attr_and(name, value, attr) {
1650
+ return value ? attr : _attr(name, value);
1651
+ }
1652
+ function _attr_or(name, value, attr) {
1653
+ return value ? _attr(name, value) : attr;
1654
+ }
1655
+ function _attr_nullish(name, value, attr) {
1656
+ return value == null ? attr : _attr(name, value);
1657
+ }
1649
1658
  function _attrs(data, nodeAccessor, scopeId, tagName) {
1650
1659
  let result = "", skip = /[\s/>"'=]/, events;
1651
1660
  switch (tagName) {
@@ -1970,4 +1979,4 @@ function toObjectExpression(options) {
1970
1979
  //#region src/html/compat.ts
1971
1980
  function NOOP() {}
1972
1981
  //#endregion
1973
- export { $global, _assert_hoist, _attr, _attr_class, _attr_content, _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open as _attr_dialog_open, _attr_input_checked, _attr_input_checkedValue, _attr_input_value, _attr_nonce, _attr_option_value, _attr_select_value, _attr_style, _attr_textarea_value, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, _await, _content, _content_resume, _dynamic_tag, _el, _el_read_error, _el_resume, _escape, _escape_comment, _escape_script, _escape_style, _existing_scope, _flush_head, _for_in, _for_of, _for_to, _for_until, _hoist, _hoist_read_error, _html, _id, _if, _peek_scope_id, _resume, _resume_branch, writeScope as _scope, _scope_id, _scope_reason, _scope_with_id, _script, _sep, _serialize_guard, _serialize_if, _set_serialize_reason, _subscribe, _template, _to_text, _trailers, _try, _unescaped, _var, attrTag, attrTags, compat, forIn, forInBy, forOf, forOfBy, forStepBy, forTo, forUntil, withLoadAssets, withPageAssets };
1982
+ export { $global, _assert_hoist, _attr, _attr_and, _attr_class, _attr_content, _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open as _attr_dialog_open, _attr_input_checked, _attr_input_checkedValue, _attr_input_value, _attr_nonce, _attr_nullish, _attr_option_value, _attr_or, _attr_select_value, _attr_style, _attr_textarea_value, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, _await, _content, _content_resume, _dynamic_tag, _el, _el_read_error, _el_resume, _escape, _escape_comment, _escape_script, _escape_style, _existing_scope, _flush_head, _for_in, _for_of, _for_to, _for_until, _hoist, _hoist_read_error, _html, _id, _if, _peek_scope_id, _resume, _resume_branch, writeScope as _scope, _scope_id, _scope_reason, _scope_with_id, _script, _sep, _serialize_guard, _serialize_if, _set_serialize_reason, _subscribe, _template, _to_text, _trailers, _try, _unescaped, _var, attrTag, attrTags, compat, forIn, forInBy, forOf, forOfBy, forStepBy, forTo, forUntil, withLoadAssets, withPageAssets };
@@ -4459,13 +4459,19 @@ var native_tag_default = {
4459
4459
  case "style": {
4460
4460
  const helper = `_attr_${name}`;
4461
4461
  if (confident) write`${getHTMLRuntime()[helper](computed)}`;
4462
- else write`${callRuntime(helper, value)}`;
4462
+ else write`${factorAttrConditional(buildAttrExpression(value, (branch) => {
4463
+ const { confident, computed } = evaluate(branch);
4464
+ return confident ? getHTMLRuntime()[helper](computed) : void 0;
4465
+ }, (branch) => buildStringAttrAnd(helper, branch) || name === "class" && buildClassAttrExpression(branch) || callRuntime(helper, branch)))}`;
4463
4466
  break;
4464
4467
  }
4465
4468
  default:
4466
4469
  if (confident) write`${getHTMLRuntime()._attr(name, computed)}`;
4467
4470
  else if (isEventHandler(name)) addHTMLEffectCall(tagSection, valueReferences);
4468
- else write`${callRuntime("_attr", _marko_compiler.types.stringLiteral(name), value)}`;
4471
+ else write`${factorAttrConditional(buildAttrExpression(value, (branch) => {
4472
+ const { confident, computed } = evaluate(branch);
4473
+ return confident ? getHTMLRuntime()._attr(name, computed) : void 0;
4474
+ }, (branch) => buildLogicalAttr(name, branch) || callRuntime("_attr", _marko_compiler.types.stringLiteral(name), branch)))}`;
4469
4475
  break;
4470
4476
  }
4471
4477
  }
@@ -4796,6 +4802,84 @@ function getTextOnlyEscapeHelper(tagName) {
4796
4802
  default: return "_escape";
4797
4803
  }
4798
4804
  }
4805
+ function buildAttrExpression(value, serialize, dynamic) {
4806
+ if (value.type === "ConditionalExpression") return _marko_compiler.types.conditionalExpression(value.test, buildAttrExpression(value.consequent, serialize, dynamic), buildAttrExpression(value.alternate, serialize, dynamic));
4807
+ const serialized = serialize(value);
4808
+ return serialized === void 0 ? dynamic(value) : _marko_compiler.types.stringLiteral(serialized);
4809
+ }
4810
+ function factorAttrConditional(value) {
4811
+ if (value.type !== "ConditionalExpression") return value;
4812
+ const consequent = factorAttrConditional(value.consequent);
4813
+ const alternate = factorAttrConditional(value.alternate);
4814
+ if (consequent.type === "StringLiteral" && alternate.type === "StringLiteral") {
4815
+ const a = consequent.value;
4816
+ const b = alternate.value;
4817
+ const end = commonAttrPrefixEnd([a, b]);
4818
+ if (end) return normalizeStringExpression([a.slice(0, end), _marko_compiler.types.conditionalExpression(value.test, _marko_compiler.types.stringLiteral(a.slice(end)), _marko_compiler.types.stringLiteral(b.slice(end)))]);
4819
+ }
4820
+ return _marko_compiler.types.conditionalExpression(value.test, consequent, alternate);
4821
+ }
4822
+ function commonAttrPrefixEnd(strings) {
4823
+ let prefix = strings[0];
4824
+ for (let i = 1; i < strings.length && prefix; i++) {
4825
+ const s = strings[i];
4826
+ const len = Math.min(prefix.length, s.length);
4827
+ let j = 0;
4828
+ while (j < len && prefix[j] === s[j]) j++;
4829
+ prefix = prefix.slice(0, j);
4830
+ }
4831
+ return prefix.lastIndexOf("=") + 1;
4832
+ }
4833
+ function buildLogicalAttr(name, value) {
4834
+ if (value.type !== "LogicalExpression") return;
4835
+ const { confident, computed } = evaluate(value.right);
4836
+ if (!confident) return;
4837
+ const attr = getHTMLRuntime()._attr(name, computed);
4838
+ return callRuntime(value.operator === "&&" ? "_attr_and" : value.operator === "||" ? "_attr_or" : "_attr_nullish", _marko_compiler.types.stringLiteral(name), value.left, _marko_compiler.types.stringLiteral(attr));
4839
+ }
4840
+ function buildStringAttrAnd(helper, value) {
4841
+ if (value.type === "LogicalExpression" && value.operator === "&&") {
4842
+ const { confident, computed } = evaluate(value.right);
4843
+ if (confident) return _marko_compiler.types.conditionalExpression(value.left, _marko_compiler.types.stringLiteral(getHTMLRuntime()[helper](computed)), _marko_compiler.types.stringLiteral(""));
4844
+ }
4845
+ }
4846
+ const MAX_PRECOMPUTED_CLASS_TOGGLES = 4;
4847
+ function buildClassAttrExpression(value) {
4848
+ if (value.type !== "ObjectExpression" && value.type !== "ArrayExpression") return;
4849
+ const meta = {
4850
+ staticItems: void 0,
4851
+ dynamicItems: void 0,
4852
+ dynamicValues: void 0
4853
+ };
4854
+ trackDelimitedAttrValue(value, meta);
4855
+ if (meta.dynamicItems || !meta.staticItems || !meta.dynamicValues) return;
4856
+ const base = toDelimitedString(meta.staticItems, " ", stringifyClassObject);
4857
+ if (!base) return;
4858
+ const { _attr_class } = getHTMLRuntime();
4859
+ const keys = Object.keys(meta.dynamicValues);
4860
+ if (keys.length === 1) {
4861
+ const [key] = keys;
4862
+ return _marko_compiler.types.conditionalExpression(meta.dynamicValues[key], _marko_compiler.types.stringLiteral(_attr_class(base + " " + key)), _marko_compiler.types.stringLiteral(_attr_class(base)));
4863
+ }
4864
+ if (keys.length <= MAX_PRECOMPUTED_CLASS_TOGGLES) {
4865
+ const combos = [];
4866
+ for (let mask = 0; mask < 1 << keys.length; mask++) {
4867
+ let classes = base;
4868
+ for (let i = 0; i < keys.length; i++) if (mask & 1 << i) classes += " " + keys[i];
4869
+ combos.push(_attr_class(classes));
4870
+ }
4871
+ const end = commonAttrPrefixEnd(combos);
4872
+ const table = generateUidIdentifier("class");
4873
+ (0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.markoScriptlet([_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(table, _marko_compiler.types.arrayExpression(combos.map((combo) => _marko_compiler.types.stringLiteral(combo.slice(end)))))])], true));
4874
+ let index = _marko_compiler.types.conditionalExpression(meta.dynamicValues[keys[0]], _marko_compiler.types.numericLiteral(1), _marko_compiler.types.numericLiteral(0));
4875
+ for (let i = 1; i < keys.length; i++) index = _marko_compiler.types.binaryExpression("+", index, _marko_compiler.types.conditionalExpression(meta.dynamicValues[keys[i]], _marko_compiler.types.numericLiteral(1 << i), _marko_compiler.types.numericLiteral(0)));
4876
+ const lookup = _marko_compiler.types.memberExpression(_marko_compiler.types.cloneNode(table), index, true);
4877
+ return normalizeStringExpression([combos[0].slice(0, end), lookup]);
4878
+ }
4879
+ let classes = _marko_compiler.types.stringLiteral(base);
4880
+ for (const key of keys) classes = _marko_compiler.types.binaryExpression("+", classes, _marko_compiler.types.conditionalExpression(meta.dynamicValues[key], _marko_compiler.types.stringLiteral(" " + key), _marko_compiler.types.stringLiteral("")));
4881
+ return callRuntime("_attr_class", classes);
4882
+ }
4799
4883
  function trackDelimitedAttrValue(expr, meta) {
4800
4884
  switch (expr.type) {
4801
4885
  case "ObjectExpression":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "6.1.20",
3
+ "version": "6.1.22",
4
4
  "description": "Optimized runtime for Marko templates.",
5
5
  "keywords": [
6
6
  "api",