@rindo/core 4.25.3 → 4.26.0

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/cli/index.cjs +1 -1
  2. package/cli/index.js +1 -1
  3. package/cli/package.json +1 -1
  4. package/compiler/package.json +1 -1
  5. package/compiler/rindo.js +37 -13
  6. package/dev-server/client/index.js +1 -1
  7. package/dev-server/client/package.json +1 -1
  8. package/dev-server/connector.html +2 -2
  9. package/dev-server/index.js +1 -1
  10. package/dev-server/package.json +1 -1
  11. package/dev-server/server-process.js +2 -2
  12. package/internal/app-data/package.json +1 -1
  13. package/internal/client/index.js +405 -14
  14. package/internal/client/package.json +1 -1
  15. package/internal/client/patch-browser.js +1 -1
  16. package/internal/client/shadow-css.js +30 -6
  17. package/internal/hydrate/index.js +434 -15
  18. package/internal/hydrate/package.json +1 -1
  19. package/internal/hydrate/runner.d.ts +22 -5
  20. package/internal/hydrate/runner.js +29 -4
  21. package/internal/package.json +1 -1
  22. package/internal/rindo-public-compiler.d.ts +23 -6
  23. package/internal/testing/index.js +404 -23
  24. package/internal/testing/package.json +1 -1
  25. package/mock-doc/index.cjs +3 -3
  26. package/mock-doc/index.d.ts +5 -1
  27. package/mock-doc/index.js +3 -3
  28. package/mock-doc/package.json +1 -1
  29. package/package.json +1 -1
  30. package/screenshot/index.js +1 -1
  31. package/screenshot/package.json +1 -1
  32. package/screenshot/pixel-match.js +1 -1
  33. package/sys/node/index.js +1 -1
  34. package/sys/node/package.json +1 -1
  35. package/sys/node/worker.js +1 -1
  36. package/testing/index.js +1 -1
  37. package/testing/jest/jest-27-and-under/matchers/html.d.ts +2 -1
  38. package/testing/jest/jest-28/matchers/html.d.ts +2 -1
  39. package/testing/jest/jest-29/matchers/html.d.ts +2 -1
  40. package/testing/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*
2
- Rindo Hydrate Platform v4.25.3 | MIT Licensed | https://rindojs.web.app
2
+ Rindo Hydrate Platform v4.26.0 | MIT Licensed | https://rindojs.web.app
3
3
  */
4
4
  var __defProp = Object.defineProperty;
5
5
  var __export = (target, all) => {
@@ -64,6 +64,11 @@ function queryNonceMetaTagContent(doc2) {
64
64
  return (_c = (_b = (_a = doc2.head) == null ? void 0 : _a.querySelector('meta[name="csp-nonce"]')) == null ? void 0 : _b.getAttribute("content")) != null ? _c : void 0;
65
65
  }
66
66
 
67
+ // src/utils/regular-expression.ts
68
+ var escapeRegExpSpecialCharacters = (text) => {
69
+ return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
70
+ };
71
+
67
72
  // src/utils/result.ts
68
73
  var result_exports = {};
69
74
  __export(result_exports, {
@@ -878,7 +883,7 @@ var initializeClientHydrate = (hostElm, tagName, hostId, hostRef) => {
878
883
  delete hostElm["s-sc"];
879
884
  }
880
885
  }
881
- if (!plt.$orgLocNodes$) {
886
+ if (!plt.$orgLocNodes$ || !plt.$orgLocNodes$.size) {
882
887
  initializeDocumentHydrate(doc.body, plt.$orgLocNodes$ = /* @__PURE__ */ new Map());
883
888
  }
884
889
  hostElm[HYDRATE_ID] = hostId;
@@ -972,13 +977,25 @@ var initializeClientHydrate = (hostElm, tagName, hostId, hostRef) => {
972
977
  slot.$elm$.parentElement.classList.add(scopeId2 + "-s");
973
978
  });
974
979
  }
975
- if (BUILD6.shadowDom && shadowRoot) {
980
+ if (BUILD6.shadowDom && shadowRoot && !shadowRoot.childNodes.length) {
976
981
  let rnIdex = 0;
977
982
  const rnLen = shadowRootNodes.length;
978
- for (rnIdex; rnIdex < rnLen; rnIdex++) {
979
- shadowRoot.appendChild(shadowRootNodes[rnIdex]);
983
+ if (rnLen) {
984
+ for (rnIdex; rnIdex < rnLen; rnIdex++) {
985
+ shadowRoot.appendChild(shadowRootNodes[rnIdex]);
986
+ }
987
+ Array.from(hostElm.childNodes).forEach((node) => {
988
+ if (typeof node["s-sn"] !== "string") {
989
+ if (node.nodeType === 1 /* ElementNode */ && node.slot && node.hidden) {
990
+ node.removeAttribute("hidden");
991
+ } else if (node.nodeType === 8 /* CommentNode */ || node.nodeType === 3 /* TextNode */ && !node.wholeText.trim()) {
992
+ node.parentNode.removeChild(node);
993
+ }
994
+ }
995
+ });
980
996
  }
981
997
  }
998
+ plt.$orgLocNodes$.delete(hostElm["s-id"]);
982
999
  hostRef.$hostElement$ = hostElm;
983
1000
  endHydrate();
984
1001
  };
@@ -1089,7 +1106,7 @@ var clientHydrate = (parentVNode, childRenderNodes, slotNodes, shadowRootNodes,
1089
1106
  $text$: null
1090
1107
  });
1091
1108
  if (childNodeType === TEXT_NODE_ID) {
1092
- childVNode.$elm$ = node.nextSibling;
1109
+ childVNode.$elm$ = findCorrespondingNode(node, 3 /* TextNode */);
1093
1110
  if (childVNode.$elm$ && childVNode.$elm$.nodeType === 3 /* TextNode */) {
1094
1111
  childVNode.$text$ = childVNode.$elm$.textContent;
1095
1112
  childRenderNodes.push(childVNode);
@@ -1105,7 +1122,7 @@ var clientHydrate = (parentVNode, childRenderNodes, slotNodes, shadowRootNodes,
1105
1122
  }
1106
1123
  }
1107
1124
  } else if (childNodeType === COMMENT_NODE_ID) {
1108
- childVNode.$elm$ = node.nextSibling;
1125
+ childVNode.$elm$ = findCorrespondingNode(node, 8 /* CommentNode */);
1109
1126
  if (childVNode.$elm$ && childVNode.$elm$.nodeType === 8 /* CommentNode */) {
1110
1127
  childRenderNodes.push(childVNode);
1111
1128
  node.remove();
@@ -1139,6 +1156,10 @@ var clientHydrate = (parentVNode, childRenderNodes, slotNodes, shadowRootNodes,
1139
1156
  vnode.$elm$ = node;
1140
1157
  vnode.$index$ = "0";
1141
1158
  parentVNode.$children$ = [vnode];
1159
+ } else {
1160
+ if (node.nodeType === 3 /* TextNode */ && !node.wholeText.trim()) {
1161
+ node.remove();
1162
+ }
1142
1163
  }
1143
1164
  return parentVNode;
1144
1165
  };
@@ -1228,10 +1249,367 @@ var addSlottedNodes = (slottedNodes, slotNodeId, slotName, slotNode, hostId) =>
1228
1249
  slottedNode = slottedNode.nextSibling;
1229
1250
  }
1230
1251
  };
1252
+ var findCorrespondingNode = (node, type) => {
1253
+ let sibling = node;
1254
+ do {
1255
+ sibling = sibling.nextSibling;
1256
+ } while (sibling && (sibling.nodeType !== type || !sibling.nodeValue));
1257
+ return sibling;
1258
+ };
1231
1259
 
1232
1260
  // src/runtime/initialize-component.ts
1233
1261
  import { BUILD as BUILD17 } from "@rindo/core/internal/app-data";
1234
1262
 
1263
+ // src/utils/shadow-css.ts
1264
+ /**
1265
+ * @license
1266
+ * Copyright Google Inc. All Rights Reserved.
1267
+ *
1268
+ * Use of this source code is governed by an MIT-style license that can be
1269
+ * found in the LICENSE file at https://angular.io/license
1270
+ *
1271
+ * This file is a port of shadowCSS from `webcomponents.js` to TypeScript.
1272
+ * https://github.com/webcomponents/webcomponentsjs/blob/4efecd7e0e/src/ShadowCSS/ShadowCSS.js
1273
+ * https://github.com/angular/angular/blob/master/packages/compiler/src/shadow_css.ts
1274
+ */
1275
+ var safeSelector = (selector) => {
1276
+ const placeholders = [];
1277
+ let index = 0;
1278
+ selector = selector.replace(/(\[[^\]]*\])/g, (_, keep) => {
1279
+ const replaceBy = `__ph-${index}__`;
1280
+ placeholders.push(keep);
1281
+ index++;
1282
+ return replaceBy;
1283
+ });
1284
+ const content = selector.replace(/(:nth-[-\w]+)(\([^)]+\))/g, (_, pseudo, exp) => {
1285
+ const replaceBy = `__ph-${index}__`;
1286
+ placeholders.push(exp);
1287
+ index++;
1288
+ return pseudo + replaceBy;
1289
+ });
1290
+ const ss = {
1291
+ content,
1292
+ placeholders
1293
+ };
1294
+ return ss;
1295
+ };
1296
+ var restoreSafeSelector = (placeholders, content) => {
1297
+ return content.replace(/__ph-(\d+)__/g, (_, index) => placeholders[+index]);
1298
+ };
1299
+ var _polyfillHost = "-shadowcsshost";
1300
+ var _polyfillSlotted = "-shadowcssslotted";
1301
+ var _polyfillHostContext = "-shadowcsscontext";
1302
+ var _parenSuffix = ")(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))?([^,{]*)";
1303
+ var _cssColonHostRe = new RegExp("(" + _polyfillHost + _parenSuffix, "gim");
1304
+ var _cssColonHostContextRe = new RegExp("(" + _polyfillHostContext + _parenSuffix, "gim");
1305
+ var _cssColonSlottedRe = new RegExp("(" + _polyfillSlotted + _parenSuffix, "gim");
1306
+ var _polyfillHostNoCombinator = _polyfillHost + "-no-combinator";
1307
+ var _polyfillHostNoCombinatorRe = /-shadowcsshost-no-combinator([^\s]*)/;
1308
+ var _shadowDOMSelectorsRe = [/::shadow/g, /::content/g];
1309
+ var _selectorReSuffix = "([>\\s~+[.,{:][\\s\\S]*)?$";
1310
+ var _polyfillHostRe = /-shadowcsshost/gim;
1311
+ var createSupportsRuleRe = (selector) => new RegExp(`((?<!(^@supports(.*)))|(?<={.*))(${selector}\\b)`, "gim");
1312
+ var _colonSlottedRe = createSupportsRuleRe("::slotted");
1313
+ var _colonHostRe = createSupportsRuleRe(":host");
1314
+ var _colonHostContextRe = createSupportsRuleRe(":host-context");
1315
+ var _commentRe = /\/\*\s*[\s\S]*?\*\//g;
1316
+ var stripComments = (input) => {
1317
+ return input.replace(_commentRe, "");
1318
+ };
1319
+ var _commentWithHashRe = /\/\*\s*#\s*source(Mapping)?URL=[\s\S]+?\*\//g;
1320
+ var extractCommentsWithHash = (input) => {
1321
+ return input.match(_commentWithHashRe) || [];
1322
+ };
1323
+ var _ruleRe = /(\s*)([^;\{\}]+?)(\s*)((?:{%BLOCK%}?\s*;?)|(?:\s*;))/g;
1324
+ var _curlyRe = /([{}])/g;
1325
+ var _selectorPartsRe = /(^.*?[^\\])??((:+)(.*)|$)/;
1326
+ var OPEN_CURLY = "{";
1327
+ var CLOSE_CURLY = "}";
1328
+ var BLOCK_PLACEHOLDER = "%BLOCK%";
1329
+ var processRules = (input, ruleCallback) => {
1330
+ const inputWithEscapedBlocks = escapeBlocks(input);
1331
+ let nextBlockIndex = 0;
1332
+ return inputWithEscapedBlocks.escapedString.replace(_ruleRe, (...m) => {
1333
+ const selector = m[2];
1334
+ let content = "";
1335
+ let suffix = m[4];
1336
+ let contentPrefix = "";
1337
+ if (suffix && suffix.startsWith("{" + BLOCK_PLACEHOLDER)) {
1338
+ content = inputWithEscapedBlocks.blocks[nextBlockIndex++];
1339
+ suffix = suffix.substring(BLOCK_PLACEHOLDER.length + 1);
1340
+ contentPrefix = "{";
1341
+ }
1342
+ const cssRule = {
1343
+ selector,
1344
+ content
1345
+ };
1346
+ const rule = ruleCallback(cssRule);
1347
+ return `${m[1]}${rule.selector}${m[3]}${contentPrefix}${rule.content}${suffix}`;
1348
+ });
1349
+ };
1350
+ var escapeBlocks = (input) => {
1351
+ const inputParts = input.split(_curlyRe);
1352
+ const resultParts = [];
1353
+ const escapedBlocks = [];
1354
+ let bracketCount = 0;
1355
+ let currentBlockParts = [];
1356
+ for (let partIndex = 0; partIndex < inputParts.length; partIndex++) {
1357
+ const part = inputParts[partIndex];
1358
+ if (part === CLOSE_CURLY) {
1359
+ bracketCount--;
1360
+ }
1361
+ if (bracketCount > 0) {
1362
+ currentBlockParts.push(part);
1363
+ } else {
1364
+ if (currentBlockParts.length > 0) {
1365
+ escapedBlocks.push(currentBlockParts.join(""));
1366
+ resultParts.push(BLOCK_PLACEHOLDER);
1367
+ currentBlockParts = [];
1368
+ }
1369
+ resultParts.push(part);
1370
+ }
1371
+ if (part === OPEN_CURLY) {
1372
+ bracketCount++;
1373
+ }
1374
+ }
1375
+ if (currentBlockParts.length > 0) {
1376
+ escapedBlocks.push(currentBlockParts.join(""));
1377
+ resultParts.push(BLOCK_PLACEHOLDER);
1378
+ }
1379
+ const strEscapedBlocks = {
1380
+ escapedString: resultParts.join(""),
1381
+ blocks: escapedBlocks
1382
+ };
1383
+ return strEscapedBlocks;
1384
+ };
1385
+ var insertPolyfillHostInCssText = (cssText) => {
1386
+ cssText = cssText.replace(_colonHostContextRe, `$1${_polyfillHostContext}`).replace(_colonHostRe, `$1${_polyfillHost}`).replace(_colonSlottedRe, `$1${_polyfillSlotted}`);
1387
+ return cssText;
1388
+ };
1389
+ var convertColonRule = (cssText, regExp, partReplacer) => {
1390
+ return cssText.replace(regExp, (...m) => {
1391
+ if (m[2]) {
1392
+ const parts = m[2].split(",");
1393
+ const r = [];
1394
+ for (let i2 = 0; i2 < parts.length; i2++) {
1395
+ const p = parts[i2].trim();
1396
+ if (!p) break;
1397
+ r.push(partReplacer(_polyfillHostNoCombinator, p, m[3]));
1398
+ }
1399
+ return r.join(",");
1400
+ } else {
1401
+ return _polyfillHostNoCombinator + m[3];
1402
+ }
1403
+ });
1404
+ };
1405
+ var colonHostPartReplacer = (host, part, suffix) => {
1406
+ return host + part.replace(_polyfillHost, "") + suffix;
1407
+ };
1408
+ var convertColonHost = (cssText) => {
1409
+ return convertColonRule(cssText, _cssColonHostRe, colonHostPartReplacer);
1410
+ };
1411
+ var colonHostContextPartReplacer = (host, part, suffix) => {
1412
+ if (part.indexOf(_polyfillHost) > -1) {
1413
+ return colonHostPartReplacer(host, part, suffix);
1414
+ } else {
1415
+ return host + part + suffix + ", " + part + " " + host + suffix;
1416
+ }
1417
+ };
1418
+ var convertColonSlotted = (cssText, slotScopeId) => {
1419
+ const slotClass = "." + slotScopeId + " > ";
1420
+ const selectors = [];
1421
+ cssText = cssText.replace(_cssColonSlottedRe, (...m) => {
1422
+ if (m[2]) {
1423
+ const compound = m[2].trim();
1424
+ const suffix = m[3];
1425
+ const slottedSelector = slotClass + compound + suffix;
1426
+ let prefixSelector = "";
1427
+ for (let i2 = m[4] - 1; i2 >= 0; i2--) {
1428
+ const char = m[5][i2];
1429
+ if (char === "}" || char === ",") {
1430
+ break;
1431
+ }
1432
+ prefixSelector = char + prefixSelector;
1433
+ }
1434
+ const orgSelector = (prefixSelector + slottedSelector).trim();
1435
+ const addedSelector = `${prefixSelector.trimEnd()}${slottedSelector.trim()}`.trim();
1436
+ if (orgSelector !== addedSelector) {
1437
+ const updatedSelector = `${addedSelector}, ${orgSelector}`;
1438
+ selectors.push({
1439
+ orgSelector,
1440
+ updatedSelector
1441
+ });
1442
+ }
1443
+ return slottedSelector;
1444
+ } else {
1445
+ return _polyfillHostNoCombinator + m[3];
1446
+ }
1447
+ });
1448
+ return {
1449
+ selectors,
1450
+ cssText
1451
+ };
1452
+ };
1453
+ var convertColonHostContext = (cssText) => {
1454
+ return convertColonRule(cssText, _cssColonHostContextRe, colonHostContextPartReplacer);
1455
+ };
1456
+ var convertShadowDOMSelectors = (cssText) => {
1457
+ return _shadowDOMSelectorsRe.reduce((result, pattern) => result.replace(pattern, " "), cssText);
1458
+ };
1459
+ var makeScopeMatcher = (scopeSelector2) => {
1460
+ const lre = /\[/g;
1461
+ const rre = /\]/g;
1462
+ scopeSelector2 = scopeSelector2.replace(lre, "\\[").replace(rre, "\\]");
1463
+ return new RegExp("^(" + scopeSelector2 + ")" + _selectorReSuffix, "m");
1464
+ };
1465
+ var selectorNeedsScoping = (selector, scopeSelector2) => {
1466
+ const re = makeScopeMatcher(scopeSelector2);
1467
+ return !re.test(selector);
1468
+ };
1469
+ var injectScopingSelector = (selector, scopingSelector) => {
1470
+ return selector.replace(_selectorPartsRe, (_, before = "", _colonGroup, colon = "", after = "") => {
1471
+ return before + scopingSelector + colon + after;
1472
+ });
1473
+ };
1474
+ var applySimpleSelectorScope = (selector, scopeSelector2, hostSelector) => {
1475
+ _polyfillHostRe.lastIndex = 0;
1476
+ if (_polyfillHostRe.test(selector)) {
1477
+ const replaceBy = `.${hostSelector}`;
1478
+ return selector.replace(_polyfillHostNoCombinatorRe, (_, selector2) => injectScopingSelector(selector2, replaceBy)).replace(_polyfillHostRe, replaceBy + " ");
1479
+ }
1480
+ return scopeSelector2 + " " + selector;
1481
+ };
1482
+ var applyStrictSelectorScope = (selector, scopeSelector2, hostSelector) => {
1483
+ const isRe = /\[is=([^\]]*)\]/g;
1484
+ scopeSelector2 = scopeSelector2.replace(isRe, (_, ...parts) => parts[0]);
1485
+ const className = "." + scopeSelector2;
1486
+ const _scopeSelectorPart = (p) => {
1487
+ let scopedP = p.trim();
1488
+ if (!scopedP) {
1489
+ return "";
1490
+ }
1491
+ if (p.indexOf(_polyfillHostNoCombinator) > -1) {
1492
+ scopedP = applySimpleSelectorScope(p, scopeSelector2, hostSelector);
1493
+ } else {
1494
+ const t = p.replace(_polyfillHostRe, "");
1495
+ if (t.length > 0) {
1496
+ scopedP = injectScopingSelector(t, className);
1497
+ }
1498
+ }
1499
+ return scopedP;
1500
+ };
1501
+ const safeContent = safeSelector(selector);
1502
+ selector = safeContent.content;
1503
+ let scopedSelector = "";
1504
+ let startIndex = 0;
1505
+ let res;
1506
+ const sep = /( |>|\+|~(?!=))\s*/g;
1507
+ const hasHost = selector.indexOf(_polyfillHostNoCombinator) > -1;
1508
+ let shouldScope = !hasHost;
1509
+ while ((res = sep.exec(selector)) !== null) {
1510
+ const separator = res[1];
1511
+ const part2 = selector.slice(startIndex, res.index).trim();
1512
+ shouldScope = shouldScope || part2.indexOf(_polyfillHostNoCombinator) > -1;
1513
+ const scopedPart = shouldScope ? _scopeSelectorPart(part2) : part2;
1514
+ scopedSelector += `${scopedPart} ${separator} `;
1515
+ startIndex = sep.lastIndex;
1516
+ }
1517
+ const part = selector.substring(startIndex);
1518
+ shouldScope = shouldScope || part.indexOf(_polyfillHostNoCombinator) > -1;
1519
+ scopedSelector += shouldScope ? _scopeSelectorPart(part) : part;
1520
+ return restoreSafeSelector(safeContent.placeholders, scopedSelector);
1521
+ };
1522
+ var scopeSelector = (selector, scopeSelectorText, hostSelector, slotSelector) => {
1523
+ return selector.split(",").map((shallowPart) => {
1524
+ if (slotSelector && shallowPart.indexOf("." + slotSelector) > -1) {
1525
+ return shallowPart.trim();
1526
+ }
1527
+ if (selectorNeedsScoping(shallowPart, scopeSelectorText)) {
1528
+ return applyStrictSelectorScope(shallowPart, scopeSelectorText, hostSelector).trim();
1529
+ } else {
1530
+ return shallowPart.trim();
1531
+ }
1532
+ }).join(", ");
1533
+ };
1534
+ var scopeSelectors = (cssText, scopeSelectorText, hostSelector, slotSelector, commentOriginalSelector) => {
1535
+ return processRules(cssText, (rule) => {
1536
+ let selector = rule.selector;
1537
+ let content = rule.content;
1538
+ if (rule.selector[0] !== "@") {
1539
+ selector = scopeSelector(rule.selector, scopeSelectorText, hostSelector, slotSelector);
1540
+ } else if (rule.selector.startsWith("@media") || rule.selector.startsWith("@supports") || rule.selector.startsWith("@page") || rule.selector.startsWith("@document")) {
1541
+ content = scopeSelectors(rule.content, scopeSelectorText, hostSelector, slotSelector, commentOriginalSelector);
1542
+ }
1543
+ const cssRule = {
1544
+ selector: selector.replace(/\s{2,}/g, " ").trim(),
1545
+ content
1546
+ };
1547
+ return cssRule;
1548
+ });
1549
+ };
1550
+ var scopeCssText = (cssText, scopeId2, hostScopeId, slotScopeId, commentOriginalSelector) => {
1551
+ cssText = insertPolyfillHostInCssText(cssText);
1552
+ cssText = convertColonHost(cssText);
1553
+ cssText = convertColonHostContext(cssText);
1554
+ const slotted = convertColonSlotted(cssText, slotScopeId);
1555
+ cssText = slotted.cssText;
1556
+ cssText = convertShadowDOMSelectors(cssText);
1557
+ if (scopeId2) {
1558
+ cssText = scopeSelectors(cssText, scopeId2, hostScopeId, slotScopeId, commentOriginalSelector);
1559
+ }
1560
+ cssText = replaceShadowCssHost(cssText, hostScopeId);
1561
+ cssText = cssText.replace(/>\s*\*\s+([^{, ]+)/gm, " $1 ");
1562
+ return {
1563
+ cssText: cssText.trim(),
1564
+ // We need to replace the shadow CSS host string in each of these selectors since we created
1565
+ // them prior to the replacement happening in the components CSS text.
1566
+ slottedSelectors: slotted.selectors.map((ref) => ({
1567
+ orgSelector: replaceShadowCssHost(ref.orgSelector, hostScopeId),
1568
+ updatedSelector: replaceShadowCssHost(ref.updatedSelector, hostScopeId)
1569
+ }))
1570
+ };
1571
+ };
1572
+ var replaceShadowCssHost = (cssText, hostScopeId) => {
1573
+ return cssText.replace(/-shadowcsshost-no-combinator/g, `.${hostScopeId}`);
1574
+ };
1575
+ var scopeCss = (cssText, scopeId2, commentOriginalSelector) => {
1576
+ const hostScopeId = scopeId2 + "-h";
1577
+ const slotScopeId = scopeId2 + "-s";
1578
+ const commentsWithHash = extractCommentsWithHash(cssText);
1579
+ cssText = stripComments(cssText);
1580
+ const orgSelectors = [];
1581
+ if (commentOriginalSelector) {
1582
+ const processCommentedSelector = (rule) => {
1583
+ const placeholder = `/*!@___${orgSelectors.length}___*/`;
1584
+ const comment = `/*!@${rule.selector}*/`;
1585
+ orgSelectors.push({ placeholder, comment });
1586
+ rule.selector = placeholder + rule.selector;
1587
+ return rule;
1588
+ };
1589
+ cssText = processRules(cssText, (rule) => {
1590
+ if (rule.selector[0] !== "@") {
1591
+ return processCommentedSelector(rule);
1592
+ } else if (rule.selector.startsWith("@media") || rule.selector.startsWith("@supports") || rule.selector.startsWith("@page") || rule.selector.startsWith("@document")) {
1593
+ rule.content = processRules(rule.content, processCommentedSelector);
1594
+ return rule;
1595
+ }
1596
+ return rule;
1597
+ });
1598
+ }
1599
+ const scoped = scopeCssText(cssText, scopeId2, hostScopeId, slotScopeId, commentOriginalSelector);
1600
+ cssText = [scoped.cssText, ...commentsWithHash].join("\n");
1601
+ if (commentOriginalSelector) {
1602
+ orgSelectors.forEach(({ placeholder, comment }) => {
1603
+ cssText = cssText.replace(placeholder, comment);
1604
+ });
1605
+ }
1606
+ scoped.slottedSelectors.forEach((slottedSelector) => {
1607
+ const regex = new RegExp(escapeRegExpSpecialCharacters(slottedSelector.orgSelector), "g");
1608
+ cssText = cssText.replace(regex, slottedSelector.updatedSelector);
1609
+ });
1610
+ return cssText;
1611
+ };
1612
+
1235
1613
  // src/runtime/mode.ts
1236
1614
  var computeMode = (elm) => modeResolutionChain.map((h2) => h2(elm)).find((m) => !!m);
1237
1615
  var setMode = (handler) => modeResolutionChain.push(handler);
@@ -1337,7 +1715,7 @@ var addStyle = (styleContainerNode, cmpMeta, mode) => {
1337
1715
  if (nonce != null) {
1338
1716
  styleElm.setAttribute("nonce", nonce);
1339
1717
  }
1340
- if ((BUILD10.hydrateServerSide || BUILD10.hotModuleReplacement) && cmpMeta.$flags$ & 2 /* scopedCssEncapsulation */) {
1718
+ if ((BUILD10.hydrateServerSide || BUILD10.hotModuleReplacement) && (cmpMeta.$flags$ & 2 /* scopedCssEncapsulation */ || cmpMeta.$flags$ & 128 /* shadowNeedsScopedCss */)) {
1341
1719
  styleElm.setAttribute(HYDRATED_STYLE_ID, scopeId2);
1342
1720
  }
1343
1721
  if (!(cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */)) {
@@ -1365,7 +1743,7 @@ var addStyle = (styleContainerNode, cmpMeta, mode) => {
1365
1743
  styleContainerNode.append(styleElm);
1366
1744
  }
1367
1745
  }
1368
- if (cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */ && styleContainerNode.nodeName !== "HEAD") {
1746
+ if (cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) {
1369
1747
  styleContainerNode.insertBefore(styleElm, null);
1370
1748
  }
1371
1749
  }
@@ -1392,13 +1770,21 @@ var attachStyles = (hostRef) => {
1392
1770
  cmpMeta,
1393
1771
  hostRef.$modeName$
1394
1772
  );
1395
- if ((BUILD10.shadowDom || BUILD10.scoped) && BUILD10.cssAnnotations && flags & 10 /* needsScopedEncapsulation */ && flags & 2 /* scopedCssEncapsulation */) {
1773
+ if ((BUILD10.shadowDom || BUILD10.scoped) && BUILD10.cssAnnotations && (flags & 10 /* needsScopedEncapsulation */ && flags & 2 /* scopedCssEncapsulation */ || flags & 128 /* shadowNeedsScopedCss */)) {
1396
1774
  elm["s-sc"] = scopeId2;
1397
1775
  elm.classList.add(scopeId2 + "-h");
1398
1776
  }
1399
1777
  endAttachStyles();
1400
1778
  };
1401
1779
  var getScopeId = (cmp, mode) => "sc-" + (BUILD10.mode && mode && cmp.$flags$ & 32 /* hasMode */ ? cmp.$tagName$ + "-" + mode : cmp.$tagName$);
1780
+ var convertScopedToShadow = (css) => css.replace(/\/\*!@([^\/]+)\*\/[^\{]+\{/g, "$1{");
1781
+ var hydrateScopedToShadow = () => {
1782
+ const styles2 = doc.querySelectorAll(`[${HYDRATED_STYLE_ID}]`);
1783
+ let i2 = 0;
1784
+ for (; i2 < styles2.length; i2++) {
1785
+ registerStyle(styles2[i2].getAttribute(HYDRATED_STYLE_ID), convertScopedToShadow(styles2[i2].innerHTML), true);
1786
+ }
1787
+ };
1402
1788
 
1403
1789
  // src/runtime/vdom/vdom-render.ts
1404
1790
  import { BUILD as BUILD13 } from "@rindo/core/internal/app-data";
@@ -2039,7 +2425,7 @@ render() {
2039
2425
  if (BUILD13.scoped || BUILD13.shadowDom) {
2040
2426
  scopeId = hostElm["s-sc"];
2041
2427
  }
2042
- useNativeShadowDom = supportsShadow && (cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) !== 0;
2428
+ useNativeShadowDom = supportsShadow && !!(cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) && !(cmpMeta.$flags$ & 128 /* shadowNeedsScopedCss */);
2043
2429
  if (BUILD13.slotRelocation) {
2044
2430
  contentRef = hostElm["s-cr"];
2045
2431
  checkSlotFallbackVisibility = false;
@@ -2731,9 +3117,8 @@ var initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
2731
3117
  const scopeId2 = getScopeId(cmpMeta, hostRef.$modeName$);
2732
3118
  if (!styles.has(scopeId2)) {
2733
3119
  const endRegisterStyles = createTime("registerStyles", cmpMeta.$tagName$);
2734
- if (!BUILD17.hydrateServerSide && BUILD17.shadowDom && // TODO(RINDO-854): Remove code related to legacy shadowDomShim field
2735
- BUILD17.shadowDomShim && cmpMeta.$flags$ & 8 /* needsShadowDomShim */) {
2736
- style = await import("../client/shadow-css.js").then((m) => m.scopeCss(style, scopeId2));
3120
+ if (BUILD17.hydrateServerSide && BUILD17.shadowDom && cmpMeta.$flags$ & 128 /* shadowNeedsScopedCss */) {
3121
+ style = scopeCss(style, scopeId2, true);
2737
3122
  }
2738
3123
  registerStyle(scopeId2, style, !!(cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */));
2739
3124
  endRegisterStyles();
@@ -2904,6 +3289,9 @@ var proxyCustomElement = (Cstr, compactMeta) => {
2904
3289
  patchTextContent(Cstr.prototype);
2905
3290
  }
2906
3291
  }
3292
+ if (BUILD20.hydrateClientSide && BUILD20.shadowDom) {
3293
+ hydrateScopedToShadow();
3294
+ }
2907
3295
  const originalConnectedCallback = Cstr.prototype.connectedCallback;
2908
3296
  const originalDisconnectedCallback = Cstr.prototype.disconnectedCallback;
2909
3297
  Object.assign(Cstr.prototype, {
@@ -3024,6 +3412,9 @@ var bootstrapLazy = (lazyBundles, options = {}) => {
3024
3412
  if (BUILD21.hydrateClientSide) {
3025
3413
  plt.$flags$ |= 2 /* appLoaded */;
3026
3414
  }
3415
+ if (BUILD21.hydrateClientSide && BUILD21.shadowDom) {
3416
+ hydrateScopedToShadow();
3417
+ }
3027
3418
  let hasSlotRelocation = false;
3028
3419
  lazyBundles.map((lazyBundle) => {
3029
3420
  lazyBundle[1].map((compactMeta) => {
@@ -3412,7 +3803,7 @@ function proxyHostElement(elm, cstr) {
3412
3803
  if (typeof elm.forceUpdate !== "function") {
3413
3804
  elm.forceUpdate = forceUpdate2;
3414
3805
  }
3415
- if (!elm.shadowRoot && !!(cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */)) {
3806
+ if (!elm.shadowRoot && !!(cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) && !(cmpMeta.$flags$ & 128 /* shadowNeedsScopedCss */)) {
3416
3807
  if (BUILD23.shadowDelegatesFocus) {
3417
3808
  elm.attachShadow({
3418
3809
  mode: "open",
@@ -3554,6 +3945,15 @@ function hydrateApp(win2, opts, results, afterHydrate, resolve) {
3554
3945
  null
3555
3946
  );
3556
3947
  if (Cstr != null && Cstr.cmpMeta != null) {
3948
+ if (opts.serializeShadowRoot !== false && !!(Cstr.cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) && tagRequiresScoped(elm.tagName, opts.serializeShadowRoot)) {
3949
+ const cmpMeta = Cstr.cmpMeta;
3950
+ cmpMeta.$flags$ |= 128 /* shadowNeedsScopedCss */;
3951
+ Object.defineProperty(Cstr, "cmpMeta", {
3952
+ get: function() {
3953
+ return cmpMeta;
3954
+ }
3955
+ });
3956
+ }
3557
3957
  createdElements.add(elm);
3558
3958
  elm.connectedCallback = patchedConnectedCallback2;
3559
3959
  registerHost(elm, Cstr.cmpMeta);
@@ -3750,6 +4150,25 @@ ${indent}${ln}`;
3750
4150
  function waitingOnElementsMsg(waitingElements) {
3751
4151
  return Array.from(waitingElements).map(waitingOnElementMsg);
3752
4152
  }
4153
+ function tagRequiresScoped(tagName, opts) {
4154
+ if (typeof opts === "string") {
4155
+ return opts === "scoped";
4156
+ }
4157
+ if (typeof opts === "boolean") {
4158
+ return opts === true ? false : true;
4159
+ }
4160
+ if (typeof opts === "object") {
4161
+ tagName = tagName.toLowerCase();
4162
+ if (Array.isArray(opts["declarative-shadow-dom"]) && opts["declarative-shadow-dom"].includes(tagName)) {
4163
+ return false;
4164
+ } else if ((!Array.isArray(opts.scoped) || !opts.scoped.includes(tagName)) && opts.default === "declarative-shadow-dom") {
4165
+ return false;
4166
+ } else {
4167
+ return true;
4168
+ }
4169
+ }
4170
+ return false;
4171
+ }
3753
4172
 
3754
4173
  // src/hydrate/platform/index.ts
3755
4174
  import { BUILD as BUILD25, Env, NAMESPACE as NAMESPACE2 } from "@rindo/core/internal/app-data";
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rindo/core/internal/hydrate",
3
- "version": "4.25.3",
3
+ "version": "4.26.0",
4
4
  "description": "Rindo internal hydrate platform to be imported by the Rindo Compiler. Breaking changes can and will happen at any time.",
5
5
  "main": "./index.js",
6
6
  "private": true
@@ -138,12 +138,29 @@ export interface SerializeDocumentOptions extends HydrateDocumentOptions {
138
138
  */
139
139
  removeHtmlComments?: boolean;
140
140
  /**
141
- * If set to `true` the component will be rendered within a Declarative Shadow DOM.
142
- * If set to `false` Rindo will ignore the contents of the shadow root and render the
143
- * element as given in provided template.
144
- * @default true
141
+ * Configure how Rindo serializes the components shadow root.
142
+ * - If set to `declarative-shadow-dom` the component will be rendered within a Declarative Shadow DOM.
143
+ * - If set to `scoped` Rindo will render the contents of the shadow root as a `scoped: true` component
144
+ * and the shadow DOM will be created during client-side hydration.
145
+ * - Alternatively you can mix and match the two by providing an object with `declarative-shadow-dom` and `scoped` keys,
146
+ * the value arrays containing the tag names of the components that should be rendered in that mode.
147
+ *
148
+ * Examples:
149
+ * - `{ 'declarative-shadow-dom': ['my-component-1', 'another-component'], default: 'scoped' }`
150
+ * Render all components as `scoped` apart from `my-component-1` and `another-component`
151
+ * - `{ 'scoped': ['an-option-component'], default: 'declarative-shadow-dom' }`
152
+ * Render all components within `declarative-shadow-dom` apart from `an-option-component`
153
+ * - `'scoped'` Render all components as `scoped`
154
+ * - `false` disables shadow root serialization
155
+ *
156
+ * *NOTE* `true` has been deprecated in favor of `declarative-shadow-dom` and `scoped`
157
+ * @default 'declarative-shadow-dom'
145
158
  */
146
- serializeShadowRoot?: boolean;
159
+ serializeShadowRoot?: "declarative-shadow-dom" | "scoped" | {
160
+ "declarative-shadow-dom"?: string[];
161
+ scoped?: string[];
162
+ default: "declarative-shadow-dom" | "scoped";
163
+ } | boolean;
147
164
  /**
148
165
  * The `fullDocument` flag determines the format of the rendered output. Set it to true to
149
166
  * generate a complete HTML document, or false to render only the component.