diff --git a/.changeset/three-bears-kick.md b/.changeset/three-bears-kick.md new file mode 100644 index 0000000..cea61b0 --- /dev/null +++ b/.changeset/three-bears-kick.md @@ -0,0 +1,5 @@ +--- +"rrweb-cssom": minor +--- + +add support for @starting-style diff --git a/lib/CSSRule.js b/lib/CSSRule.js index 0b5e25b..d40c2dd 100644 --- a/lib/CSSRule.js +++ b/lib/CSSRule.js @@ -30,6 +30,7 @@ CSSOM.CSSRule.DOCUMENT_RULE = 13; CSSOM.CSSRule.FONT_FEATURE_VALUES_RULE = 14; CSSOM.CSSRule.VIEWPORT_RULE = 15; CSSOM.CSSRule.REGION_STYLE_RULE = 16; +CSSOM.CSSRule.STARTING_STYLE_RULE = 1002; CSSOM.CSSRule.prototype = { diff --git a/lib/CSSStartingStyleRule.js b/lib/CSSStartingStyleRule.js new file mode 100644 index 0000000..e0087bc --- /dev/null +++ b/lib/CSSStartingStyleRule.js @@ -0,0 +1,37 @@ +//.CommonJS +var CSSOM = { + CSSRule: require("./CSSRule").CSSRule +}; +///CommonJS + + +/** + * @constructor + * @see http://www.w3.org/TR/shadow-dom/#host-at-rule + */ +CSSOM.CSSStartingStyleRule = function CSSStartingStyleRule() { + CSSOM.CSSRule.call(this); + this.cssRules = []; +}; + +CSSOM.CSSStartingStyleRule.prototype = new CSSOM.CSSRule(); +CSSOM.CSSStartingStyleRule.prototype.constructor = CSSOM.CSSStartingStyleRule; +CSSOM.CSSStartingStyleRule.prototype.type = 1002; +//FIXME +//CSSOM.CSSStartingStyleRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule; +//CSSOM.CSSStartingStyleRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule; + +Object.defineProperty(CSSOM.CSSStartingStyleRule.prototype, "cssText", { + get: function() { + var cssTexts = []; + for (var i=0, length=this.cssRules.length; i < length; i++) { + cssTexts.push(this.cssRules[i].cssText); + } + return "@starting-style {" + cssTexts.join("") + "}"; + } +}); + + +//.CommonJS +exports.CSSStartingStyleRule = CSSOM.CSSStartingStyleRule; +///CommonJS diff --git a/lib/index.js b/lib/index.js index 2098109..ec8d799 100644 --- a/lib/index.js +++ b/lib/index.js @@ -11,6 +11,7 @@ exports.CSSSupportsRule = require('./CSSSupportsRule').CSSSupportsRule; exports.CSSImportRule = require('./CSSImportRule').CSSImportRule; exports.CSSFontFaceRule = require('./CSSFontFaceRule').CSSFontFaceRule; exports.CSSHostRule = require('./CSSHostRule').CSSHostRule; +exports.CSSStartingStyleRule = require('./CSSStartingStyleRule').CSSStartingStyleRule; exports.StyleSheet = require('./StyleSheet').StyleSheet; exports.CSSStyleSheet = require('./CSSStyleSheet').CSSStyleSheet; exports.CSSKeyframesRule = require('./CSSKeyframesRule').CSSKeyframesRule; diff --git a/lib/parse.js b/lib/parse.js index 038ab01..8c5c022 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -51,7 +51,7 @@ CSSOM.parse = function parse(token) { var hasAncestors = false; var prevScope; - var name, priority="", styleRule, mediaRule, supportsRule, importRule, fontFaceRule, keyframesRule, documentRule, hostRule; + var name, priority="", styleRule, mediaRule, supportsRule, importRule, fontFaceRule, keyframesRule, documentRule, hostRule, startingStyleRule; var atKeyframesRegExp = /@(-(?:\w+-)+)?keyframes/g; @@ -171,6 +171,13 @@ CSSOM.parse = function parse(token) { hostRule.__starts = i; buffer = ""; break; + } else if (token.indexOf("@starting-style", i) === i) { + state = "startingStyleRule-begin"; + i += "startingStyle".length; + startingStyleRule = new CSSOM.CSSStartingStyleRule(); + startingStyleRule.__starts = i; + buffer = ""; + break; } else if (token.indexOf("@import", i) === i) { state = "importRule-begin"; i += "import".length; @@ -238,6 +245,16 @@ CSSOM.parse = function parse(token) { hostRule.parentStyleSheet = styleSheet; buffer = ""; state = "before-selector"; + } else if (state === "startingStyleRule-begin") { + if (parentRule) { + ancestorRules.push(parentRule); + } + + currentScope = parentRule = startingStyleRule; + startingStyleRule.parentStyleSheet = styleSheet; + buffer = ""; + state = "before-selector"; + } else if (state === "fontFaceRule-begin") { if (parentRule) { fontFaceRule.parentRule = parentRule; @@ -457,6 +474,7 @@ CSSOM.CSSConditionRule = require("./CSSConditionRule").CSSConditionRule; CSSOM.CSSSupportsRule = require("./CSSSupportsRule").CSSSupportsRule; CSSOM.CSSFontFaceRule = require("./CSSFontFaceRule").CSSFontFaceRule; CSSOM.CSSHostRule = require("./CSSHostRule").CSSHostRule; +CSSOM.CSSStartingStyleRule = require("./CSSStartingStyleRule").CSSStartingStyleRule; CSSOM.CSSStyleDeclaration = require('./CSSStyleDeclaration').CSSStyleDeclaration; CSSOM.CSSKeyframeRule = require('./CSSKeyframeRule').CSSKeyframeRule; CSSOM.CSSKeyframesRule = require('./CSSKeyframesRule').CSSKeyframesRule; diff --git a/spec/parse.spec.js b/spec/parse.spec.js index 32e509a..06ba800 100644 --- a/spec/parse.spec.js +++ b/spec/parse.spec.js @@ -972,6 +972,33 @@ var TESTS = [ return result; })() }, + { + input: "@starting-style { body { background: red; } }", + result: (function() { + var result = { + cssRules: [ + { + cssRules: { + 0: { + selectorText: "body", + style: { + 0: "background", + length: 1, + parentRule: "..", + background: "red" + } + } + }, + parentRule: null + } + ], + parentStyleSheet: null + }; + result.cssRules[0].parentStyleSheet = result.cssRules[0].cssRules[0].parentStyleSheet = result; + result.cssRules[0].cssRules[0].parentRule = result.cssRules[0]; + return result; + })() + }, { // Non-vendor prefixed @keyframes rule, from Twitter Bootstrap (progress-bars): input: '@keyframes progress-bar-stripes {\n from { background-position: 0 0; }\n to { background-position: 40px 0; }\n}', diff --git a/src/files.js b/src/files.js index 12563c2..a6bad45 100644 --- a/src/files.js +++ b/src/files.js @@ -10,6 +10,7 @@ exports.files = [ "CSSImportRule", "CSSFontFaceRule", "CSSHostRule", + "CSSStartingStyleRule", "StyleSheet", "CSSStyleSheet", "CSSKeyframesRule",