From b42dfcfdf7b03a4faff93cfcff84ee3943494f3a Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Tue, 3 Mar 2026 15:41:47 +0900 Subject: [PATCH 1/2] Add CSSStyleDeclaration injection API for parsed rules --- README.mdown | 13 +++++++++++++ lib/CSSFontFaceRule.js | 13 ++++++------- lib/CSSKeyframeRule.js | 15 +++++++-------- lib/CSSNestedDeclarations.js | 17 ++++++++--------- lib/CSSOM.js | 8 +++++++- lib/CSSPageRule.js | 13 ++++++------- lib/CSSStyleRule.js | 13 ++++++------- lib/clone.js | 13 ++++++------- lib/cssstyleTryCatchBlock.js | 8 ++++++-- lib/index.js | 9 +++++++++ lib/styleDeclarationProvider.js | 28 ++++++++++++++++++++++++++++ 11 files changed, 102 insertions(+), 48 deletions(-) create mode 100644 lib/styleDeclarationProvider.js diff --git a/README.mdown b/README.mdown index 8684ece..aa8c5a6 100644 --- a/README.mdown +++ b/README.mdown @@ -33,6 +33,19 @@ To use it with Node.js or any other CommonJS loader: ➤ npm install @acemir/cssom +You can inject a custom declaration implementation for parsed rule styles: + +```js +const cssom = require("@acemir/cssom"); + +cssom.setup({ + CSSStyleDeclaration: YourCSSStyleDeclaration +}); + +// or globally: +cssom.setCSSStyleDeclaration(YourCSSStyleDeclaration); +``` + ## Don’t use it if... You parse CSS to mungle, minify or reformat code like this: diff --git a/lib/CSSFontFaceRule.js b/lib/CSSFontFaceRule.js index e1534d3..3ff27e3 100644 --- a/lib/CSSFontFaceRule.js +++ b/lib/CSSFontFaceRule.js @@ -1,14 +1,13 @@ //.CommonJS var CSSOM = { - CSSStyleDeclaration: require("./CSSStyleDeclaration").CSSStyleDeclaration, CSSRule: require("./CSSRule").CSSRule }; -// Use cssstyle if available -try { - CSSOM.CSSStyleDeclaration = require("cssstyle").CSSStyleDeclaration; -} catch (e) { - // ignore -} +var styleDeclarationProvider = require("./styleDeclarationProvider"); +Object.defineProperty(CSSOM, "CSSStyleDeclaration", { + enumerable: true, + configurable: true, + get: styleDeclarationProvider.getCSSStyleDeclaration +}); ///CommonJS diff --git a/lib/CSSKeyframeRule.js b/lib/CSSKeyframeRule.js index ebf628c..9322730 100644 --- a/lib/CSSKeyframeRule.js +++ b/lib/CSSKeyframeRule.js @@ -1,14 +1,13 @@ //.CommonJS var CSSOM = { - CSSRule: require("./CSSRule").CSSRule, - CSSStyleDeclaration: require('./CSSStyleDeclaration').CSSStyleDeclaration + CSSRule: require("./CSSRule").CSSRule }; -// Use cssstyle if available -try { - CSSOM.CSSStyleDeclaration = require("cssstyle").CSSStyleDeclaration; -} catch (e) { - // ignore -} +var styleDeclarationProvider = require("./styleDeclarationProvider"); +Object.defineProperty(CSSOM, "CSSStyleDeclaration", { + enumerable: true, + configurable: true, + get: styleDeclarationProvider.getCSSStyleDeclaration +}); ///CommonJS diff --git a/lib/CSSNestedDeclarations.js b/lib/CSSNestedDeclarations.js index 459f282..2c71740 100644 --- a/lib/CSSNestedDeclarations.js +++ b/lib/CSSNestedDeclarations.js @@ -1,14 +1,13 @@ //.CommonJS var CSSOM = { - CSSRule: require("./CSSRule").CSSRule, - CSSStyleDeclaration: require('./CSSStyleDeclaration').CSSStyleDeclaration + CSSRule: require("./CSSRule").CSSRule }; -// Use cssstyle if available -try { - CSSOM.CSSStyleDeclaration = require("cssstyle").CSSStyleDeclaration; -} catch (e) { - // ignore -} +var styleDeclarationProvider = require("./styleDeclarationProvider"); +Object.defineProperty(CSSOM, "CSSStyleDeclaration", { + enumerable: true, + configurable: true, + get: styleDeclarationProvider.getCSSStyleDeclaration +}); ///CommonJS @@ -53,4 +52,4 @@ Object.defineProperty(CSSOM.CSSNestedDeclarations.prototype, "cssText", { //.CommonJS exports.CSSNestedDeclarations = CSSOM.CSSNestedDeclarations; -///CommonJS \ No newline at end of file +///CommonJS diff --git a/lib/CSSOM.js b/lib/CSSOM.js index 08d47cb..02f384d 100644 --- a/lib/CSSOM.js +++ b/lib/CSSOM.js @@ -4,6 +4,7 @@ var CSSOM = { * * @param {Object} opts - Configuration options for the CSSOM instance * @param {Object} [opts.globalObject] - Optional global object to be assigned to CSSOM objects prototype + * @param {Function} [opts.CSSStyleDeclaration] - Optional constructor used for declaration blocks in parsed rules * @returns {Object} A new CSSOM instance with the applied configuration * @description * This method creates a new instance of CSSOM and optionally @@ -12,7 +13,13 @@ var CSSOM = { * using a factory function and assigns the globalObject to its prototype's __globalObject property. */ setup: function (opts) { + opts = opts || {}; var instance = Object.create(this); + if (opts.CSSStyleDeclaration) { + var styleDeclarationProvider = require("./styleDeclarationProvider"); + styleDeclarationProvider.setCSSStyleDeclaration(opts.CSSStyleDeclaration); + instance.CSSStyleDeclaration = opts.CSSStyleDeclaration; + } if (opts.globalObject) { if (instance.CSSStyleSheet) { var factoryCSSStyleSheet = createFunctionFactory(instance.CSSStyleSheet); @@ -55,4 +62,3 @@ function createFunctionFactory(fn) { //.CommonJS module.exports = CSSOM; ///CommonJS - diff --git a/lib/CSSPageRule.js b/lib/CSSPageRule.js index 1d75326..b54e43c 100644 --- a/lib/CSSPageRule.js +++ b/lib/CSSPageRule.js @@ -1,17 +1,16 @@ //.CommonJS var CSSOM = { - CSSStyleDeclaration: require("./CSSStyleDeclaration").CSSStyleDeclaration, CSSRule: require("./CSSRule").CSSRule, CSSRuleList: require("./CSSRuleList").CSSRuleList, CSSGroupingRule: require("./CSSGroupingRule").CSSGroupingRule, }; +var styleDeclarationProvider = require("./styleDeclarationProvider"); var regexPatterns = require("./regexPatterns").regexPatterns; -// Use cssstyle if available -try { - CSSOM.CSSStyleDeclaration = require("cssstyle").CSSStyleDeclaration; -} catch (e) { - // ignore -} +Object.defineProperty(CSSOM, "CSSStyleDeclaration", { + enumerable: true, + configurable: true, + get: styleDeclarationProvider.getCSSStyleDeclaration +}); ///CommonJS diff --git a/lib/CSSStyleRule.js b/lib/CSSStyleRule.js index a7c81d0..ddc83f1 100644 --- a/lib/CSSStyleRule.js +++ b/lib/CSSStyleRule.js @@ -1,17 +1,16 @@ //.CommonJS var CSSOM = { - CSSStyleDeclaration: require("./CSSStyleDeclaration").CSSStyleDeclaration, CSSRule: require("./CSSRule").CSSRule, CSSRuleList: require("./CSSRuleList").CSSRuleList, CSSGroupingRule: require("./CSSGroupingRule").CSSGroupingRule, }; +var styleDeclarationProvider = require("./styleDeclarationProvider"); var regexPatterns = require("./regexPatterns").regexPatterns; -// Use cssstyle if available -try { - CSSOM.CSSStyleDeclaration = require("cssstyle").CSSStyleDeclaration; -} catch (e) { - // ignore -} +Object.defineProperty(CSSOM, "CSSStyleDeclaration", { + enumerable: true, + configurable: true, + get: styleDeclarationProvider.getCSSStyleDeclaration +}); ///CommonJS diff --git a/lib/clone.js b/lib/clone.js index b9c262f..d7875cf 100644 --- a/lib/clone.js +++ b/lib/clone.js @@ -9,19 +9,18 @@ var CSSOM = { CSSMediaRule: require("./CSSMediaRule").CSSMediaRule, CSSContainerRule: require("./CSSContainerRule").CSSContainerRule, CSSSupportsRule: require("./CSSSupportsRule").CSSSupportsRule, - CSSStyleDeclaration: require("./CSSStyleDeclaration").CSSStyleDeclaration, CSSKeyframeRule: require('./CSSKeyframeRule').CSSKeyframeRule, CSSKeyframesRule: require('./CSSKeyframesRule').CSSKeyframesRule, CSSScopeRule: require('./CSSScopeRule').CSSScopeRule, CSSLayerBlockRule: require('./CSSLayerBlockRule').CSSLayerBlockRule, CSSLayerStatementRule: require('./CSSLayerStatementRule').CSSLayerStatementRule }; -// Use cssstyle if available -try { - CSSOM.CSSStyleDeclaration = require("cssstyle").CSSStyleDeclaration; -} catch (e) { - // ignore -} +var styleDeclarationProvider = require("./styleDeclarationProvider"); +Object.defineProperty(CSSOM, "CSSStyleDeclaration", { + enumerable: true, + configurable: true, + get: styleDeclarationProvider.getCSSStyleDeclaration +}); ///CommonJS diff --git a/lib/cssstyleTryCatchBlock.js b/lib/cssstyleTryCatchBlock.js index a97dab7..0be5e9c 100644 --- a/lib/cssstyleTryCatchBlock.js +++ b/lib/cssstyleTryCatchBlock.js @@ -1,5 +1,9 @@ +//.CommonJS +var styleDeclarationProvider = require("./styleDeclarationProvider"); + try { - CSSOM.CSSStyleDeclaration = require("cssstyle").CSSStyleDeclaration; + styleDeclarationProvider.setCSSStyleDeclaration(require("cssstyle").CSSStyleDeclaration); } catch (e) { // ignore -} \ No newline at end of file +} +///CommonJS diff --git a/lib/index.js b/lib/index.js index 6138e29..2423e99 100644 --- a/lib/index.js +++ b/lib/index.js @@ -6,6 +6,15 @@ require('./errorUtils'); require("./regexPatterns") exports.CSSStyleDeclaration = require('./CSSStyleDeclaration').CSSStyleDeclaration; +exports.getCSSStyleDeclaration = function() { + return require("./styleDeclarationProvider").getCSSStyleDeclaration(); +}; +exports.setCSSStyleDeclaration = function(CSSStyleDeclaration) { + return require("./styleDeclarationProvider").setCSSStyleDeclaration(CSSStyleDeclaration); +}; +exports.resetCSSStyleDeclaration = function() { + return require("./styleDeclarationProvider").resetCSSStyleDeclaration(); +}; require('./cssstyleTryCatchBlock'); diff --git a/lib/styleDeclarationProvider.js b/lib/styleDeclarationProvider.js new file mode 100644 index 0000000..ac53582 --- /dev/null +++ b/lib/styleDeclarationProvider.js @@ -0,0 +1,28 @@ +//.CommonJS +var currentCSSStyleDeclaration; +///CommonJS + +function getDefaultCSSStyleDeclaration() { + return require("./CSSStyleDeclaration").CSSStyleDeclaration; +} + +function getCSSStyleDeclaration() { + return currentCSSStyleDeclaration || getDefaultCSSStyleDeclaration(); +} + +function setCSSStyleDeclaration(CSSStyleDeclaration) { + if (typeof CSSStyleDeclaration !== "function") { + throw new TypeError("CSSStyleDeclaration must be a constructor function"); + } + currentCSSStyleDeclaration = CSSStyleDeclaration; +} + +function resetCSSStyleDeclaration() { + currentCSSStyleDeclaration = undefined; +} + +//.CommonJS +exports.getCSSStyleDeclaration = getCSSStyleDeclaration; +exports.setCSSStyleDeclaration = setCSSStyleDeclaration; +exports.resetCSSStyleDeclaration = resetCSSStyleDeclaration; +///CommonJS From e61c9413e5e17ec8768f02cbd90702e5cb694f1b Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Tue, 3 Mar 2026 15:57:21 +0900 Subject: [PATCH 2/2] Add changeset for CSSStyleDeclaration integration API --- .changeset/late-wolves-tickle.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .changeset/late-wolves-tickle.md diff --git a/.changeset/late-wolves-tickle.md b/.changeset/late-wolves-tickle.md new file mode 100644 index 0000000..f26b103 --- /dev/null +++ b/.changeset/late-wolves-tickle.md @@ -0,0 +1,13 @@ +--- +"@acemir/cssom": minor +--- + +Add an explicit CSSStyleDeclaration integration API. + +New APIs: +- `setup({ CSSStyleDeclaration })` +- `setCSSStyleDeclaration(CSSStyleDeclaration)` +- `getCSSStyleDeclaration()` +- `resetCSSStyleDeclaration()` + +Rule style declarations created during parsing/cloning now use the configured constructor consistently, avoiding module load-order issues when integrating with custom CSSStyleDeclaration implementations.