single-file-core 1.5.78 → 1.5.80

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.
@@ -24,10 +24,11 @@
24
24
  import * as cssTree from "./../vendor/css-tree.js";
25
25
  import { computeMaxSpecificity } from "./css-specificity.js";
26
26
  import { parsePrelude } from "./css-scope-prelude-parser.js";
27
- import { sanitizeSelector } from "./css-selector-sanitizer.js";
27
+ import { sanitizeSelector, DYNAMIC_STATE_PSEUDO_CLASSES } from "./css-selector-sanitizer.js";
28
28
 
29
29
  const DEBUG = false;
30
30
 
31
+ const CANONICAL_PSEUDO_ELEMENT_NAMES = new Set(["after", "before", "first-letter", "first-line", "placeholder", "selection", "part", "marker"]);
31
32
  const CONDITIONAL_AT_RULE_NAMES = new Set(["media", "supports", "container"]);
32
33
  const RULE_TYPE = "Rule";
33
34
  const AT_RULE_TYPE = "Atrule";
@@ -287,13 +288,14 @@ function processSelectors(ruleData, processingContext, docContext) {
287
288
  for (let selector = ruleData.prelude.children.head, selectorIndex = 0; selector; selector = selector.next, selectorIndex++) {
288
289
  const {
289
290
  startsWithCombinator,
290
- hasPseudo,
291
+ hasCanonicalPseudoElement,
292
+ hasDynamicStatePseudoClass,
291
293
  scopeRelative
292
294
  } = analyzeSelector(selector.data);
293
295
  registerSelector(selector, ruleData, scopeRelative, processingContext, docContext);
294
296
  if (!startsWithCombinator || !ancestorsSelectors || !ancestorsSelectors.length) {
295
297
  const matchedElements = matchElements(selector, ancestorsSelectors, docContext);
296
- if (matchedElements.length && !hasPseudo) {
298
+ if (matchedElements.length && !(hasCanonicalPseudoElement || hasDynamicStatePseudoClass)) {
297
299
  updateMatchingSelectors(matchedElements, selector, docContext);
298
300
  } else if (!matchedElements.length) {
299
301
  removedSelectors.push(selector);
@@ -304,16 +306,20 @@ function processSelectors(ruleData, processingContext, docContext) {
304
306
  }
305
307
 
306
308
  function analyzeSelector(selector) {
307
- let hasPseudo = false;
309
+ let hasCanonicalPseudoElement = false;
310
+ let hasDynamicStatePseudoClass = false;
308
311
  let hasNestingOrScope = false;
309
312
  let startsWithCombinator = false;
310
313
  cssTree.walk(selector, {
311
314
  enter(node) {
312
315
  if (node.type === PSEUDO_ELEMENT_SELECTOR_TYPE) {
313
- hasPseudo = true;
316
+ hasCanonicalPseudoElement = true;
314
317
  } else if (node.type === PSEUDO_CLASS_SELECTOR_TYPE) {
315
- hasPseudo = true;
316
- if (node.name === SCOPE_NAME) {
318
+ if (CANONICAL_PSEUDO_ELEMENT_NAMES.has(node.name)) {
319
+ hasCanonicalPseudoElement = true;
320
+ } else if (DYNAMIC_STATE_PSEUDO_CLASSES.includes(node.name)) {
321
+ hasDynamicStatePseudoClass = true;
322
+ } else if (node.name === SCOPE_NAME) {
317
323
  hasNestingOrScope = true;
318
324
  }
319
325
  } else if (node.type === NESTING_SELECTOR_TYPE) {
@@ -324,7 +330,7 @@ function analyzeSelector(selector) {
324
330
  const firstChild = selector.children.head.data;
325
331
  startsWithCombinator = firstChild && firstChild.type === COMBINATOR_NAME;
326
332
  const scopeRelative = !startsWithCombinator && !hasNestingOrScope;
327
- return { hasPseudo, startsWithCombinator, scopeRelative };
333
+ return { hasCanonicalPseudoElement, hasDynamicStatePseudoClass, startsWithCombinator, scopeRelative };
328
334
  }
329
335
 
330
336
  function updateMatchingSelectors(matchedElements, selector, docContext) {
@@ -23,7 +23,7 @@
23
23
  */
24
24
 
25
25
  import * as cssTree from "./../vendor/css-tree.js";
26
- const UNMATCHABLE_PSEUDO_CLASSES = [
26
+ const DYNAMIC_STATE_PSEUDO_CLASSES = [
27
27
  "active-view-transition",
28
28
  "active-view-transition-type",
29
29
  "blank",
@@ -80,6 +80,7 @@ const UNMATCHABLE_PSEUDO_CLASSES = [
80
80
  ];
81
81
 
82
82
  export {
83
+ DYNAMIC_STATE_PSEUDO_CLASSES,
83
84
  sanitizeSelector,
84
85
  };
85
86
  /**
@@ -128,7 +129,7 @@ function normalizeSelectorNode(selector, ancestors) {
128
129
  selector.children.remove(current);
129
130
  } else if (childNode.type === "PseudoClassSelector") {
130
131
  const pseudoName = (childNode.name || "").toLowerCase();
131
- if (UNMATCHABLE_PSEUDO_CLASSES.includes(pseudoName)) {
132
+ if (DYNAMIC_STATE_PSEUDO_CLASSES.includes(pseudoName)) {
132
133
  selector.children.remove(current);
133
134
  }
134
135
  }
@@ -16951,8 +16951,12 @@ async function evalTemplate(template = "", options, content, doc, context = {})
16951
16951
  getter: () => {
16952
16952
  const pathname = url.pathname;
16953
16953
  const segments = pathname.split("/");
16954
- const lastSegment = segments[segments.length - 1] || segments[segments.length - 2] || "";
16955
- return decode(lastSegment);
16954
+ if (pathname.endsWith("/")) {
16955
+ return "";
16956
+ } else {
16957
+ const lastSegment = segments[segments.length - 1];
16958
+ return decode(lastSegment);
16959
+ }
16956
16960
  }, dontReplaceSlash: dontReplaceSlashIfUndefined
16957
16961
  },
16958
16962
  "bookmark-pathname": { getter: () => bookmarkFolder, dontReplaceSlash: dontReplaceSlashIfUndefined },
@@ -17050,7 +17054,7 @@ async function evalTemplate(template = "", options, content, doc, context = {})
17050
17054
  const utf8Array = base64ToBytes(value);
17051
17055
  return new TextDecoder("utf-8").decode(utf8Array);
17052
17056
  // eslint-disable-next-line no-unused-vars
17053
- } catch(error) {
17057
+ } catch (error) {
17054
17058
  return value;
17055
17059
  }
17056
17060
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "single-file-core",
3
- "version": "1.5.78",
3
+ "version": "1.5.80",
4
4
  "description": "SingleFile Core",
5
5
  "author": "Gildas Lormeau",
6
6
  "license": "AGPL-3.0-or-later",