single-file-core 1.5.50 → 1.5.52

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/core/index.js CHANGED
@@ -578,7 +578,6 @@ class Processor {
578
578
  styleElement.textContent = "img[src=\"data:,\"],source[src=\"data:,\"]{display:none!important}";
579
579
  this.doc.head.appendChild(styleElement);
580
580
  }
581
- this.doc.head.querySelectorAll("noscript").forEach(element => element.parentElement.appendChild(element));
582
581
  let size;
583
582
  if (this.options.displayStats) {
584
583
  size = util.getContentSize(this.doc.documentElement.outerHTML);
@@ -853,18 +852,22 @@ class Processor {
853
852
 
854
853
  removeDiscardedResources() {
855
854
  this.doc.querySelectorAll("." + util.SINGLE_FILE_UI_ELEMENT_CLASS).forEach(element => element.remove());
856
- const noscriptPlaceholders = new Map();
857
- this.doc.querySelectorAll("noscript").forEach(noscriptElement => {
858
- const placeholderElement = this.doc.createElement("div");
859
- placeholderElement.innerHTML = noscriptElement.dataset[util.NO_SCRIPT_PROPERTY_NAME];
860
- noscriptElement.replaceWith(placeholderElement);
861
- noscriptPlaceholders.set(placeholderElement, noscriptElement);
862
- });
855
+ if (this.options.removeNoScriptTags === false) {
856
+ const noscriptPlaceholders = new Map();
857
+ this.doc.querySelectorAll("noscript").forEach(noscriptElement => {
858
+ const placeholderElement = this.doc.createElement("div");
859
+ placeholderElement.innerHTML = noscriptElement.dataset[util.NO_SCRIPT_PROPERTY_NAME];
860
+ noscriptElement.replaceWith(placeholderElement);
861
+ noscriptPlaceholders.set(placeholderElement, noscriptElement);
862
+ });
863
+ noscriptPlaceholders.forEach((noscriptElement, placeholderElement) => {
864
+ noscriptElement.dataset[util.NO_SCRIPT_PROPERTY_NAME] = placeholderElement.innerHTML;
865
+ placeholderElement.replaceWith(noscriptElement);
866
+ });
867
+ } else {
868
+ this.doc.querySelectorAll("noscript").forEach(element => element.remove());
869
+ }
863
870
  this.doc.querySelectorAll("meta[http-equiv=refresh], meta[disabled-http-equiv]").forEach(element => element.remove());
864
- noscriptPlaceholders.forEach((noscriptElement, placeholderElement) => {
865
- noscriptElement.dataset[util.NO_SCRIPT_PROPERTY_NAME] = placeholderElement.innerHTML;
866
- placeholderElement.replaceWith(noscriptElement);
867
- });
868
871
  this.doc.querySelectorAll("meta[http-equiv=\"content-security-policy\"]").forEach(element => element.remove());
869
872
  const objectElements = this.doc.querySelectorAll("applet, object[data]:not([type=\"image/svg+xml\"]):not([type=\"image/svg-xml\"]):not([type=\"text/html\"]):not([data*=\".svg\"]):not([data*=\".pdf\"]), embed[src]:not([src*=\".svg\"]):not([src*=\".pdf\"])");
870
873
  this.stats.set("discarded", "objects", objectElements.length);
@@ -37,6 +37,7 @@ const NESTING_SELECTOR_TYPE = "NestingSelector";
37
37
  const PSEUDO_CLASS_SELECTOR_TYPE = "PseudoClassSelector";
38
38
  const DECLARATION_TYPE = "Declaration";
39
39
  const RAW_TYPE = "Raw";
40
+ const VALUE_TYPE = "Value";
40
41
  const PSEUDO_ELEMENT_SELECTOR_TYPE = "PseudoElementSelector";
41
42
  const LAYER_NAME = "layer";
42
43
  const SCOPE_NAME = "scope";
@@ -355,7 +356,6 @@ function updateMatchingSelectors(matchedElements, selector, docContext) {
355
356
 
356
357
  function processNestedRules(ruleData, stylesheets, processingContext, docContext) {
357
358
  expandRawCssRules(ruleData);
358
- removeDuplicateDeclarations(ruleData.block);
359
359
  const newProcessingContext = { ...processingContext, ancestorsSelectors: [...processingContext.ancestorsSelectors, ruleData.prelude] };
360
360
  minifyStylesheetRules(ruleData.block.children, stylesheets, newProcessingContext, docContext);
361
361
  }
@@ -421,14 +421,18 @@ function collectDeclarationItemsForElement(element, docContext) {
421
421
  const declarations = cssRule.block.children;
422
422
  for (let declaration = declarations.head; declaration; declaration = declaration.next) {
423
423
  const { type, value } = declaration.data;
424
- if (type === DECLARATION_TYPE && value && value.type !== RAW_TYPE) {
425
- allDeclarations.push({
426
- declaration,
427
- selector,
428
- effectiveSpecificity: computeEffectiveSpecificity(
429
- docContext.selectorData.get(selector), element, docContext),
430
- isInline: false
431
- });
424
+ if (type === DECLARATION_TYPE && value) {
425
+ const isRawValue = value.type === RAW_TYPE;
426
+ const isVendorValue = value.type === VALUE_TYPE && value.children.head && value.children.head.data.name && value.children.head.data.name.startsWith(VENDOR_PREFIX);
427
+ if (!isRawValue && !isVendorValue) {
428
+ allDeclarations.push({
429
+ declaration,
430
+ selector,
431
+ effectiveSpecificity: computeEffectiveSpecificity(
432
+ docContext.selectorData.get(selector), element, docContext),
433
+ isInline: false
434
+ });
435
+ }
432
436
  }
433
437
  }
434
438
  }
@@ -703,32 +707,6 @@ function removeUnmatchedSelectors(ruleData, removedSelectors, removedRules, cssR
703
707
  return false;
704
708
  }
705
709
 
706
- function removeDuplicateDeclarations(block) {
707
- const propertyMap = new Map();
708
- const removedDeclarations = [];
709
- for (let ruleChildNode = block.children.head; ruleChildNode; ruleChildNode = ruleChildNode.next) {
710
- if (ruleChildNode.data.type === DECLARATION_TYPE) {
711
- const property = ruleChildNode.data.property;
712
- const isImportant = ruleChildNode.data.important;
713
- if (propertyMap.has(property)) {
714
- const existing = propertyMap.get(property);
715
- if (existing.isImportant === isImportant) {
716
- removedDeclarations.push(existing.node);
717
- propertyMap.set(property, { node: ruleChildNode, isImportant });
718
- } else if (isImportant && !existing.isImportant) {
719
- removedDeclarations.push(existing.node);
720
- propertyMap.set(property, { node: ruleChildNode, isImportant });
721
- } else {
722
- removedDeclarations.push(ruleChildNode);
723
- }
724
- } else {
725
- propertyMap.set(property, { node: ruleChildNode, isImportant });
726
- }
727
- }
728
- }
729
- removedDeclarations.forEach(declaration => block.children.remove(declaration));
730
- }
731
-
732
710
  function removeLosingDeclarations(winningDeclarations, docContext) {
733
711
  const allDeclarations = new Map();
734
712
  const protectedDeclarations = new Set();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "single-file-core",
3
- "version": "1.5.50",
3
+ "version": "1.5.52",
4
4
  "description": "SingleFile Core",
5
5
  "author": "Gildas Lormeau",
6
6
  "license": "AGPL-3.0-or-later",