shadow-css.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. const _parenSuffix = ")(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))?([^,{]*)", _cssColonHostRe = new RegExp("(-shadowcsshost" + _parenSuffix, "gim"), _cssColonHostContextRe = new RegExp("(-shadowcsscontext" + _parenSuffix, "gim"), _cssColonSlottedRe = new RegExp("(-shadowcssslotted" + _parenSuffix, "gim"), _polyfillHostNoCombinatorRe = /-shadowcsshost-no-combinator([^\s]*)/, _shadowDOMSelectorsRe = [ /::shadow/g, /::content/g ], _polyfillHostRe = /-shadowcsshost/gim, _colonHostRe = /:host/gim, _colonSlottedRe = /::slotted/gim, _colonHostContextRe = /:host-context/gim, _commentRe = /\/\*\s*[\s\S]*?\*\//g, _commentWithHashRe = /\/\*\s*#\s*source(Mapping)?URL=[\s\S]+?\*\//g, _ruleRe = /(\s*)([^;\{\}]+?)(\s*)((?:{%BLOCK%}?\s*;?)|(?:\s*;))/g, _curlyRe = /([{}])/g, _selectorPartsRe = /(^.*?[^\\])??((:+)(.*)|$)/, processRules = (e, t) => {
  2. const o = escapeBlocks(e);
  3. let s = 0;
  4. return o.escapedString.replace(_ruleRe, ((...e) => {
  5. const c = e[2];
  6. let r = "", n = e[4], l = "";
  7. n && n.startsWith("{%BLOCK%") && (r = o.blocks[s++], n = n.substring("%BLOCK%".length + 1),
  8. l = "{");
  9. const a = t({
  10. selector: c,
  11. content: r
  12. });
  13. return `${e[1]}${a.selector}${e[3]}${l}${a.content}${n}`;
  14. }));
  15. }, escapeBlocks = e => {
  16. const t = e.split(_curlyRe), o = [], s = [];
  17. let c = 0, r = [];
  18. for (let e = 0; e < t.length; e++) {
  19. const n = t[e];
  20. "}" === n && c--, c > 0 ? r.push(n) : (r.length > 0 && (s.push(r.join("")), o.push("%BLOCK%"),
  21. r = []), o.push(n)), "{" === n && c++;
  22. }
  23. return r.length > 0 && (s.push(r.join("")), o.push("%BLOCK%")), {
  24. escapedString: o.join(""),
  25. blocks: s
  26. };
  27. }, convertColonRule = (e, t, o) => e.replace(t, ((...e) => {
  28. if (e[2]) {
  29. const t = e[2].split(","), s = [];
  30. for (let c = 0; c < t.length; c++) {
  31. const r = t[c].trim();
  32. if (!r) break;
  33. s.push(o("-shadowcsshost-no-combinator", r, e[3]));
  34. }
  35. return s.join(",");
  36. }
  37. return "-shadowcsshost-no-combinator" + e[3];
  38. })), colonHostPartReplacer = (e, t, o) => e + t.replace("-shadowcsshost", "") + o, colonHostContextPartReplacer = (e, t, o) => t.indexOf("-shadowcsshost") > -1 ? colonHostPartReplacer(e, t, o) : e + t + o + ", " + t + " " + e + o, injectScopingSelector = (e, t) => e.replace(_selectorPartsRe, ((e, o = "", s, c = "", r = "") => o + t + c + r)), scopeSelectors = (e, t, o, s, c) => processRules(e, (e => {
  39. let c = e.selector, r = e.content;
  40. return "@" !== e.selector[0] ? c = ((e, t, o, s) => e.split(",").map((e => s && e.indexOf("." + s) > -1 ? e.trim() : ((e, t) => !(e => (e = e.replace(/\[/g, "\\[").replace(/\]/g, "\\]"),
  41. new RegExp("^(" + e + ")([>\\s~+[.,{:][\\s\\S]*)?$", "m")))(t).test(e))(e, t) ? ((e, t, o) => {
  42. const s = "." + (t = t.replace(/\[is=([^\]]*)\]/g, ((e, ...t) => t[0]))), c = e => {
  43. let c = e.trim();
  44. if (!c) return "";
  45. if (e.indexOf("-shadowcsshost-no-combinator") > -1) c = ((e, t, o) => {
  46. if (_polyfillHostRe.lastIndex = 0, _polyfillHostRe.test(e)) {
  47. const t = `.${o}`;
  48. return e.replace(_polyfillHostNoCombinatorRe, ((e, o) => injectScopingSelector(o, t))).replace(_polyfillHostRe, t + " ");
  49. }
  50. return t + " " + e;
  51. })(e, t, o); else {
  52. const t = e.replace(_polyfillHostRe, "");
  53. t.length > 0 && (c = injectScopingSelector(t, s));
  54. }
  55. return c;
  56. }, r = (e => {
  57. const t = [];
  58. let o = 0;
  59. return {
  60. content: (e = e.replace(/(\[[^\]]*\])/g, ((e, s) => {
  61. const c = `__ph-${o}__`;
  62. return t.push(s), o++, c;
  63. }))).replace(/(:nth-[-\w]+)(\([^)]+\))/g, ((e, s, c) => {
  64. const r = `__ph-${o}__`;
  65. return t.push(c), o++, s + r;
  66. })),
  67. placeholders: t
  68. };
  69. })(e);
  70. let n, l = "", a = 0;
  71. const i = /( |>|\+|~(?!=))\s*/g;
  72. let p = !((e = r.content).indexOf("-shadowcsshost-no-combinator") > -1);
  73. for (;null !== (n = i.exec(e)); ) {
  74. const t = n[1], o = e.slice(a, n.index).trim();
  75. p = p || o.indexOf("-shadowcsshost-no-combinator") > -1, l += `${p ? c(o) : o} ${t} `,
  76. a = i.lastIndex;
  77. }
  78. const h = e.substring(a);
  79. return p = p || h.indexOf("-shadowcsshost-no-combinator") > -1, l += p ? c(h) : h,
  80. u = r.placeholders, l.replace(/__ph-(\d+)__/g, ((e, t) => u[+t]));
  81. var u;
  82. })(e, t, o).trim() : e.trim())).join(", "))(e.selector, t, o, s) : (e.selector.startsWith("@media") || e.selector.startsWith("@supports") || e.selector.startsWith("@page") || e.selector.startsWith("@document")) && (r = scopeSelectors(e.content, t, o, s)),
  83. {
  84. selector: c.replace(/\s{2,}/g, " ").trim(),
  85. content: r
  86. };
  87. })), scopeCss = (e, t, o) => {
  88. const s = t + "-h", c = t + "-s", r = e.match(_commentWithHashRe) || [];
  89. e = e.replace(_commentRe, "");
  90. const n = [];
  91. if (o) {
  92. const t = e => {
  93. const t = `/*!@___${n.length}___*/`, o = `/*!@${e.selector}*/`;
  94. return n.push({
  95. placeholder: t,
  96. comment: o
  97. }), e.selector = t + e.selector, e;
  98. };
  99. e = processRules(e, (e => "@" !== e.selector[0] ? t(e) : e.selector.startsWith("@media") || e.selector.startsWith("@supports") || e.selector.startsWith("@page") || e.selector.startsWith("@document") ? (e.content = processRules(e.content, t),
  100. e) : e));
  101. }
  102. const l = ((e, t, o, s, c) => {
  103. const r = ((e, t) => {
  104. const o = "." + t + " > ", s = [];
  105. return e = e.replace(_cssColonSlottedRe, ((...e) => {
  106. if (e[2]) {
  107. const t = e[2].trim(), c = e[3], r = o + t + c;
  108. let n = "";
  109. for (let t = e[4] - 1; t >= 0; t--) {
  110. const o = e[5][t];
  111. if ("}" === o || "," === o) break;
  112. n = o + n;
  113. }
  114. const l = n + r, a = `${n.trimRight()}${r.trim()}`;
  115. if (l.trim() !== a.trim()) {
  116. const e = `${a}, ${l}`;
  117. s.push({
  118. orgSelector: l,
  119. updatedSelector: e
  120. });
  121. }
  122. return r;
  123. }
  124. return "-shadowcsshost-no-combinator" + e[3];
  125. })), {
  126. selectors: s,
  127. cssText: e
  128. };
  129. })(e = (e => convertColonRule(e, _cssColonHostContextRe, colonHostContextPartReplacer))(e = (e => convertColonRule(e, _cssColonHostRe, colonHostPartReplacer))(e = e.replace(_colonHostContextRe, "-shadowcsscontext").replace(_colonHostRe, "-shadowcsshost").replace(_colonSlottedRe, "-shadowcssslotted"))), s);
  130. return e = (e => _shadowDOMSelectorsRe.reduce(((e, t) => e.replace(t, " ")), e))(e = r.cssText),
  131. t && (e = scopeSelectors(e, t, o, s)), {
  132. cssText: (e = (e = e.replace(/-shadowcsshost-no-combinator/g, `.${o}`)).replace(/>\s*\*\s+([^{, ]+)/gm, " $1 ")).trim(),
  133. slottedSelectors: r.selectors
  134. };
  135. })(e, t, s, c);
  136. return e = [ l.cssText, ...r ].join("\n"), o && n.forEach((({placeholder: t, comment: o}) => {
  137. e = e.replace(t, o);
  138. })), l.slottedSelectors.forEach((t => {
  139. e = e.replace(t.orgSelector, t.updatedSelector);
  140. })), e;
  141. };
  142. export { scopeCss };