@acemir/cssom 0.9.29 → 0.9.30
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/build/CSSOM.js +249 -37
- package/lib/CSSMediaRule.js +1 -0
- package/lib/CSSPropertyRule.js +122 -0
- package/lib/CSSStyleRule.js +4 -2
- package/lib/CSSStyleSheet.js +5 -0
- package/lib/index.js +1 -0
- package/lib/parse.js +124 -35
- package/package.json +4 -3
package/build/CSSOM.js
CHANGED
|
@@ -716,6 +716,122 @@ Object.defineProperty(CSSOM.CSSCounterStyleRule.prototype, "parse", {
|
|
|
716
716
|
|
|
717
717
|
|
|
718
718
|
|
|
719
|
+
/**
|
|
720
|
+
* @constructor
|
|
721
|
+
* @see https://drafts.css-houdini.org/css-properties-values-api/#the-css-property-rule-interface
|
|
722
|
+
*/
|
|
723
|
+
CSSOM.CSSPropertyRule = function CSSPropertyRule() {
|
|
724
|
+
CSSOM.CSSRule.call(this);
|
|
725
|
+
this.__name = "";
|
|
726
|
+
this.__syntax = "";
|
|
727
|
+
this.__inherits = false;
|
|
728
|
+
this.__initialValue = null;
|
|
729
|
+
};
|
|
730
|
+
|
|
731
|
+
CSSOM.CSSPropertyRule.prototype = Object.create(CSSOM.CSSRule.prototype);
|
|
732
|
+
CSSOM.CSSPropertyRule.prototype.constructor = CSSOM.CSSPropertyRule;
|
|
733
|
+
|
|
734
|
+
Object.setPrototypeOf(CSSOM.CSSPropertyRule, CSSOM.CSSRule);
|
|
735
|
+
|
|
736
|
+
Object.defineProperty(CSSOM.CSSPropertyRule.prototype, "type", {
|
|
737
|
+
value: 0,
|
|
738
|
+
writable: false
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
Object.defineProperty(CSSOM.CSSPropertyRule.prototype, "cssText", {
|
|
742
|
+
get: function() {
|
|
743
|
+
var text = "@property " + this.name + " {";
|
|
744
|
+
if (this.syntax !== "") {
|
|
745
|
+
text += " syntax: \"" + this.syntax.replace(/\\/g, '\\\\').replace(/"/g, '\\"') + "\";";
|
|
746
|
+
}
|
|
747
|
+
text += " inherits: " + (this.inherits ? "true" : "false") + ";";
|
|
748
|
+
if (this.initialValue !== null) {
|
|
749
|
+
text += " initial-value: " + this.initialValue + ";";
|
|
750
|
+
}
|
|
751
|
+
text += " }";
|
|
752
|
+
return text;
|
|
753
|
+
}
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
Object.defineProperty(CSSOM.CSSPropertyRule.prototype, "name", {
|
|
757
|
+
get: function() {
|
|
758
|
+
return this.__name;
|
|
759
|
+
}
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
Object.defineProperty(CSSOM.CSSPropertyRule.prototype, "syntax", {
|
|
763
|
+
get: function() {
|
|
764
|
+
return this.__syntax;
|
|
765
|
+
}
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
Object.defineProperty(CSSOM.CSSPropertyRule.prototype, "inherits", {
|
|
769
|
+
get: function() {
|
|
770
|
+
return this.__inherits;
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
Object.defineProperty(CSSOM.CSSPropertyRule.prototype, "initialValue", {
|
|
775
|
+
get: function() {
|
|
776
|
+
return this.__initialValue;
|
|
777
|
+
}
|
|
778
|
+
});
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* NON-STANDARD
|
|
782
|
+
* Rule text parser.
|
|
783
|
+
* @param {string} cssText
|
|
784
|
+
* @returns {boolean} True if the rule is valid and was parsed successfully
|
|
785
|
+
*/
|
|
786
|
+
Object.defineProperty(CSSOM.CSSPropertyRule.prototype, "parse", {
|
|
787
|
+
value: function(cssText) {
|
|
788
|
+
// Extract the name from "@property <name> { ... }"
|
|
789
|
+
var match = cssText.match(/@property\s+(--[^\s{]+)\s*\{([^]*)\}/);
|
|
790
|
+
if (!match) {
|
|
791
|
+
return false;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
this.__name = match[1];
|
|
795
|
+
var bodyText = match[2];
|
|
796
|
+
|
|
797
|
+
// Parse syntax descriptor (REQUIRED)
|
|
798
|
+
var syntaxMatch = bodyText.match(/syntax\s*:\s*(['"])([^]*?)\1\s*;/);
|
|
799
|
+
if (!syntaxMatch) {
|
|
800
|
+
return false; // syntax is required
|
|
801
|
+
}
|
|
802
|
+
this.__syntax = syntaxMatch[2];
|
|
803
|
+
|
|
804
|
+
// Syntax cannot be empty
|
|
805
|
+
if (this.__syntax === "") {
|
|
806
|
+
return false;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
// Parse inherits descriptor (REQUIRED)
|
|
810
|
+
var inheritsMatch = bodyText.match(/inherits\s*:\s*(true|false)\s*;/);
|
|
811
|
+
if (!inheritsMatch) {
|
|
812
|
+
return false; // inherits is required
|
|
813
|
+
}
|
|
814
|
+
this.__inherits = inheritsMatch[1] === "true";
|
|
815
|
+
|
|
816
|
+
// Parse initial-value descriptor (OPTIONAL, but required if syntax is not "*")
|
|
817
|
+
var initialValueMatch = bodyText.match(/initial-value\s*:\s*([^;]+);/);
|
|
818
|
+
if (initialValueMatch) {
|
|
819
|
+
this.__initialValue = initialValueMatch[1].trim();
|
|
820
|
+
} else {
|
|
821
|
+
// If syntax is not "*", initial-value is required
|
|
822
|
+
if (this.__syntax !== "*") {
|
|
823
|
+
return false;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
return true; // Successfully parsed
|
|
828
|
+
}
|
|
829
|
+
});
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
|
|
719
835
|
/**
|
|
720
836
|
* @constructor
|
|
721
837
|
* @see https://www.w3.org/TR/css-conditional-3/#the-cssconditionrule-interface
|
|
@@ -781,7 +897,8 @@ Object.defineProperty(CSSOM.CSSStyleRule.prototype, "selectorText", {
|
|
|
781
897
|
|
|
782
898
|
this.__selectorText = trimmedValue;
|
|
783
899
|
}
|
|
784
|
-
}
|
|
900
|
+
},
|
|
901
|
+
configurable: true
|
|
785
902
|
});
|
|
786
903
|
|
|
787
904
|
Object.defineProperty(CSSOM.CSSStyleRule.prototype, "style", {
|
|
@@ -794,7 +911,8 @@ Object.defineProperty(CSSOM.CSSStyleRule.prototype, "style", {
|
|
|
794
911
|
} else {
|
|
795
912
|
this.__style = value;
|
|
796
913
|
}
|
|
797
|
-
}
|
|
914
|
+
},
|
|
915
|
+
configurable: true
|
|
798
916
|
});
|
|
799
917
|
|
|
800
918
|
Object.defineProperty(CSSOM.CSSStyleRule.prototype, "cssText", {
|
|
@@ -934,6 +1052,7 @@ Object.defineProperties(CSSOM.CSSMediaRule.prototype, {
|
|
|
934
1052
|
this.__media = value;
|
|
935
1053
|
}
|
|
936
1054
|
},
|
|
1055
|
+
configurable: true,
|
|
937
1056
|
enumerable: true
|
|
938
1057
|
},
|
|
939
1058
|
"conditionText": {
|
|
@@ -1728,6 +1847,11 @@ CSSOM.CSSStyleSheet.prototype.insertRule = function(rule, index) {
|
|
|
1728
1847
|
|
|
1729
1848
|
// Validate rule ordering based on CSS specification
|
|
1730
1849
|
if (cssRule.constructor.name === 'CSSImportRule') {
|
|
1850
|
+
if (this.__constructed === true) {
|
|
1851
|
+
errorUtils.throwError(this, 'DOMException',
|
|
1852
|
+
"Failed to execute 'insertRule' on '" + this.constructor.name + "': Can't insert @import rules into a constructed stylesheet.",
|
|
1853
|
+
'SyntaxError');
|
|
1854
|
+
}
|
|
1731
1855
|
// @import rules cannot be inserted after @layer rules that already exist
|
|
1732
1856
|
// They can only be inserted at the beginning or after other @import rules
|
|
1733
1857
|
var firstLayerIndex = findFirstNonConstructorIndex(this.cssRules, ['CSSImportRule']);
|
|
@@ -3023,6 +3147,7 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
3023
3147
|
"containerBlock": true,
|
|
3024
3148
|
"conditionBlock": true,
|
|
3025
3149
|
"counterStyleBlock": true,
|
|
3150
|
+
"propertyBlock": true,
|
|
3026
3151
|
'documentRule-begin': true,
|
|
3027
3152
|
"scopeBlock": true,
|
|
3028
3153
|
"layerBlock": true,
|
|
@@ -3054,6 +3179,10 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
3054
3179
|
if (ownerNodeMedia) {
|
|
3055
3180
|
styleSheet.media.mediaText = ownerNodeMedia;
|
|
3056
3181
|
}
|
|
3182
|
+
var ownerNodeTitle = opts.ownerNode.title || (opts.ownerNode.getAttribute && opts.ownerNode.getAttribute("title"));
|
|
3183
|
+
if (ownerNodeTitle) {
|
|
3184
|
+
styleSheet.__title = ownerNodeTitle;
|
|
3185
|
+
}
|
|
3057
3186
|
}
|
|
3058
3187
|
|
|
3059
3188
|
if (opts && opts.ownerRule) {
|
|
@@ -3069,7 +3198,7 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
3069
3198
|
var ancestorRules = [];
|
|
3070
3199
|
var prevScope;
|
|
3071
3200
|
|
|
3072
|
-
var name, priority = "", styleRule, mediaRule, containerRule, counterStyleRule, supportsRule, importRule, fontFaceRule, keyframesRule, documentRule, hostRule, startingStyleRule, scopeRule, pageRule, layerBlockRule, layerStatementRule, nestedSelectorRule, namespaceRule;
|
|
3201
|
+
var name, priority = "", styleRule, mediaRule, containerRule, counterStyleRule, propertyRule, supportsRule, importRule, fontFaceRule, keyframesRule, documentRule, hostRule, startingStyleRule, scopeRule, pageRule, layerBlockRule, layerStatementRule, nestedSelectorRule, namespaceRule;
|
|
3073
3202
|
|
|
3074
3203
|
// Track defined namespace prefixes for validation
|
|
3075
3204
|
var definedNamespacePrefixes = {};
|
|
@@ -3384,6 +3513,44 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
3384
3513
|
return invalidNestingPattern.test(selector);
|
|
3385
3514
|
};
|
|
3386
3515
|
|
|
3516
|
+
/**
|
|
3517
|
+
* Checks if an at-rule can be nested based on parent chain validation.
|
|
3518
|
+
* Used for at-rules like `@counter-style`, `@property` and `@font-face` rules that can only be nested inside
|
|
3519
|
+
* `CSSScopeRule` or `CSSConditionRule` without `CSSStyleRule` in parent chain.
|
|
3520
|
+
* @returns {boolean} `true` if nesting is allowed, `false` otherwise
|
|
3521
|
+
*/
|
|
3522
|
+
function canAtRuleBeNested() {
|
|
3523
|
+
if (currentScope === topScope) {
|
|
3524
|
+
return true; // Top-level is always allowed
|
|
3525
|
+
}
|
|
3526
|
+
|
|
3527
|
+
var hasStyleRuleInChain = false;
|
|
3528
|
+
var hasValidParent = false;
|
|
3529
|
+
|
|
3530
|
+
// Check currentScope
|
|
3531
|
+
if (currentScope.constructor.name === 'CSSStyleRule') {
|
|
3532
|
+
hasStyleRuleInChain = true;
|
|
3533
|
+
} else if (currentScope instanceof CSSOM.CSSScopeRule || currentScope instanceof CSSOM.CSSConditionRule) {
|
|
3534
|
+
hasValidParent = true;
|
|
3535
|
+
}
|
|
3536
|
+
|
|
3537
|
+
// Check ancestorRules for CSSStyleRule
|
|
3538
|
+
if (!hasStyleRuleInChain) {
|
|
3539
|
+
for (var j = 0; j < ancestorRules.length; j++) {
|
|
3540
|
+
if (ancestorRules[j].constructor.name === 'CSSStyleRule') {
|
|
3541
|
+
hasStyleRuleInChain = true;
|
|
3542
|
+
break;
|
|
3543
|
+
}
|
|
3544
|
+
if (ancestorRules[j] instanceof CSSOM.CSSScopeRule || ancestorRules[j] instanceof CSSOM.CSSConditionRule) {
|
|
3545
|
+
hasValidParent = true;
|
|
3546
|
+
}
|
|
3547
|
+
}
|
|
3548
|
+
}
|
|
3549
|
+
|
|
3550
|
+
// Allow nesting if we have a valid parent and no style rule in the chain
|
|
3551
|
+
return hasValidParent && !hasStyleRuleInChain;
|
|
3552
|
+
}
|
|
3553
|
+
|
|
3387
3554
|
function validateAtRule(atRuleKey, validCallback, cannotBeNested) {
|
|
3388
3555
|
var isValid = false;
|
|
3389
3556
|
var sourceRuleRegExp = atRuleKey === "@import" ? forwardImportRuleValidationRegExp : forwardRuleValidationRegExp;
|
|
@@ -4565,13 +4732,28 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
4565
4732
|
buffer = "";
|
|
4566
4733
|
break;
|
|
4567
4734
|
} else if (token.indexOf("@counter-style", i) === i) {
|
|
4735
|
+
buffer = "";
|
|
4736
|
+
// @counter-style can be nested only inside CSSScopeRule or CSSConditionRule
|
|
4737
|
+
// and only if there's no CSSStyleRule in the parent chain
|
|
4738
|
+
var cannotBeNested = !canAtRuleBeNested();
|
|
4568
4739
|
validateAtRule("@counter-style", function () {
|
|
4569
4740
|
state = "counterStyleBlock"
|
|
4570
4741
|
counterStyleRule = new CSSOM.CSSCounterStyleRule();
|
|
4571
4742
|
counterStyleRule.__starts = i;
|
|
4572
4743
|
i += "counter-style".length;
|
|
4573
|
-
},
|
|
4744
|
+
}, cannotBeNested);
|
|
4745
|
+
break;
|
|
4746
|
+
} else if (token.indexOf("@property", i) === i) {
|
|
4574
4747
|
buffer = "";
|
|
4748
|
+
// @property can be nested only inside CSSScopeRule or CSSConditionRule
|
|
4749
|
+
// and only if there's no CSSStyleRule in the parent chain
|
|
4750
|
+
var cannotBeNested = !canAtRuleBeNested();
|
|
4751
|
+
validateAtRule("@property", function () {
|
|
4752
|
+
state = "propertyBlock"
|
|
4753
|
+
propertyRule = new CSSOM.CSSPropertyRule();
|
|
4754
|
+
propertyRule.__starts = i;
|
|
4755
|
+
i += "property".length;
|
|
4756
|
+
}, cannotBeNested);
|
|
4575
4757
|
break;
|
|
4576
4758
|
} else if (token.indexOf("@scope", i) === i) {
|
|
4577
4759
|
validateAtRule("@scope", function () {
|
|
@@ -4647,36 +4829,7 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
4647
4829
|
buffer = "";
|
|
4648
4830
|
// @font-face can be nested only inside CSSScopeRule or CSSConditionRule
|
|
4649
4831
|
// and only if there's no CSSStyleRule in the parent chain
|
|
4650
|
-
var cannotBeNested =
|
|
4651
|
-
if (currentScope !== topScope) {
|
|
4652
|
-
var hasStyleRuleInChain = false;
|
|
4653
|
-
var hasValidParent = false;
|
|
4654
|
-
|
|
4655
|
-
// Check currentScope
|
|
4656
|
-
if (currentScope.constructor.name === 'CSSStyleRule') {
|
|
4657
|
-
hasStyleRuleInChain = true;
|
|
4658
|
-
} else if (currentScope instanceof CSSOM.CSSScopeRule || currentScope instanceof CSSOM.CSSConditionRule) {
|
|
4659
|
-
hasValidParent = true;
|
|
4660
|
-
}
|
|
4661
|
-
|
|
4662
|
-
// Check ancestorRules for CSSStyleRule
|
|
4663
|
-
if (!hasStyleRuleInChain) {
|
|
4664
|
-
for (var j = 0; j < ancestorRules.length; j++) {
|
|
4665
|
-
if (ancestorRules[j].constructor.name === 'CSSStyleRule') {
|
|
4666
|
-
hasStyleRuleInChain = true;
|
|
4667
|
-
break;
|
|
4668
|
-
}
|
|
4669
|
-
if (ancestorRules[j] instanceof CSSOM.CSSScopeRule || ancestorRules[j] instanceof CSSOM.CSSConditionRule) {
|
|
4670
|
-
hasValidParent = true;
|
|
4671
|
-
}
|
|
4672
|
-
}
|
|
4673
|
-
}
|
|
4674
|
-
|
|
4675
|
-
// Allow nesting if we have a valid parent and no style rule in the chain
|
|
4676
|
-
if (hasValidParent && !hasStyleRuleInChain) {
|
|
4677
|
-
cannotBeNested = false;
|
|
4678
|
-
}
|
|
4679
|
-
}
|
|
4832
|
+
var cannotBeNested = !canAtRuleBeNested();
|
|
4680
4833
|
validateAtRule("@font-face", function () {
|
|
4681
4834
|
state = "fontFaceRule-begin";
|
|
4682
4835
|
i += "font-face".length;
|
|
@@ -4793,8 +4946,25 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
4793
4946
|
|
|
4794
4947
|
if (isValidCounterStyleName) {
|
|
4795
4948
|
counterStyleRule.name = counterStyleName;
|
|
4796
|
-
|
|
4949
|
+
if (parentRule) {
|
|
4950
|
+
counterStyleRule.__parentRule = parentRule;
|
|
4951
|
+
}
|
|
4797
4952
|
counterStyleRule.__parentStyleSheet = styleSheet;
|
|
4953
|
+
styleRule = counterStyleRule;
|
|
4954
|
+
}
|
|
4955
|
+
buffer = "";
|
|
4956
|
+
} else if (state === "propertyBlock") {
|
|
4957
|
+
var propertyName = buffer.trim().replace(/\n/g, "");
|
|
4958
|
+
// Validate: name must start with -- (custom property)
|
|
4959
|
+
var isValidPropertyName = propertyName.indexOf("--") === 0;
|
|
4960
|
+
|
|
4961
|
+
if (isValidPropertyName) {
|
|
4962
|
+
propertyRule.__name = propertyName;
|
|
4963
|
+
if (parentRule) {
|
|
4964
|
+
propertyRule.__parentRule = parentRule;
|
|
4965
|
+
}
|
|
4966
|
+
propertyRule.__parentStyleSheet = styleSheet;
|
|
4967
|
+
styleRule = propertyRule;
|
|
4798
4968
|
}
|
|
4799
4969
|
buffer = "";
|
|
4800
4970
|
} else if (state === "conditionBlock") {
|
|
@@ -5082,6 +5252,7 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
5082
5252
|
if (opts && opts.globalObject && opts.globalObject.CSSStyleSheet) {
|
|
5083
5253
|
importRule.__styleSheet = new opts.globalObject.CSSStyleSheet();
|
|
5084
5254
|
}
|
|
5255
|
+
importRule.styleSheet.__constructed = false;
|
|
5085
5256
|
importRule.__parentStyleSheet = importRule.styleSheet.__parentStyleSheet = styleSheet;
|
|
5086
5257
|
importRule.parse(buffer + character);
|
|
5087
5258
|
topScope.cssRules.push(importRule);
|
|
@@ -5163,11 +5334,50 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
5163
5334
|
if (state === "counterStyleBlock") {
|
|
5164
5335
|
// FIXME : Implement missing properties on CSSCounterStyleRule interface and update parse method
|
|
5165
5336
|
// For now it's just assigning entire rule text
|
|
5166
|
-
|
|
5337
|
+
if (counterStyleRule.name) {
|
|
5338
|
+
// Only process if name was set (valid)
|
|
5339
|
+
counterStyleRule.parse("@counter-style " + counterStyleRule.name + " { " + buffer + " }");
|
|
5340
|
+
counterStyleRule.__ends = i + 1;
|
|
5341
|
+
// Add to parent's cssRules
|
|
5342
|
+
if (counterStyleRule.__parentRule) {
|
|
5343
|
+
counterStyleRule.__parentRule.cssRules.push(counterStyleRule);
|
|
5344
|
+
} else {
|
|
5345
|
+
topScope.cssRules.push(counterStyleRule);
|
|
5346
|
+
}
|
|
5347
|
+
}
|
|
5348
|
+
// Restore currentScope to parent after closing this rule
|
|
5349
|
+
if (counterStyleRule.__parentRule) {
|
|
5350
|
+
currentScope = counterStyleRule.__parentRule;
|
|
5351
|
+
}
|
|
5352
|
+
styleRule = null;
|
|
5167
5353
|
buffer = "";
|
|
5168
5354
|
state = "before-selector";
|
|
5355
|
+
break;
|
|
5356
|
+
}
|
|
5357
|
+
if (state === "propertyBlock") {
|
|
5358
|
+
// Only process if name was set (valid)
|
|
5359
|
+
if (propertyRule.__name) {
|
|
5360
|
+
var parseSuccess = propertyRule.parse("@property " + propertyRule.__name + " { " + buffer + " }");
|
|
5361
|
+
// Only add the rule if parse was successful (syntax, inherits, and initial-value validation passed)
|
|
5362
|
+
if (parseSuccess) {
|
|
5363
|
+
propertyRule.__ends = i + 1;
|
|
5364
|
+
// Add to parent's cssRules
|
|
5365
|
+
if (propertyRule.__parentRule) {
|
|
5366
|
+
propertyRule.__parentRule.cssRules.push(propertyRule);
|
|
5367
|
+
} else {
|
|
5368
|
+
topScope.cssRules.push(propertyRule);
|
|
5369
|
+
}
|
|
5370
|
+
}
|
|
5371
|
+
}
|
|
5372
|
+
// Restore currentScope to parent after closing this rule
|
|
5373
|
+
if (propertyRule.__parentRule) {
|
|
5374
|
+
currentScope = propertyRule.__parentRule;
|
|
5375
|
+
}
|
|
5376
|
+
styleRule = null;
|
|
5377
|
+
buffer = "";
|
|
5378
|
+
state = "before-selector";
|
|
5379
|
+
break;
|
|
5169
5380
|
}
|
|
5170
|
-
|
|
5171
5381
|
switch (state) {
|
|
5172
5382
|
case "value":
|
|
5173
5383
|
styleRule.style.setProperty(name, buffer.trim(), priority, parseError);
|
|
@@ -5292,6 +5502,8 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
5292
5502
|
currentScope.cssRules.push(prevScope);
|
|
5293
5503
|
}
|
|
5294
5504
|
nestedSelectorRule = currentScope;
|
|
5505
|
+
// Stop here to preserve context for sibling selectors
|
|
5506
|
+
break;
|
|
5295
5507
|
} else {
|
|
5296
5508
|
// Top-level CSSStyleRule with nested grouping rule
|
|
5297
5509
|
prevScope = currentScope;
|
package/lib/CSSMediaRule.js
CHANGED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
//.CommonJS
|
|
2
|
+
var CSSOM = {
|
|
3
|
+
CSSRule: require("./CSSRule").CSSRule
|
|
4
|
+
};
|
|
5
|
+
///CommonJS
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @constructor
|
|
10
|
+
* @see https://drafts.css-houdini.org/css-properties-values-api/#the-css-property-rule-interface
|
|
11
|
+
*/
|
|
12
|
+
CSSOM.CSSPropertyRule = function CSSPropertyRule() {
|
|
13
|
+
CSSOM.CSSRule.call(this);
|
|
14
|
+
this.__name = "";
|
|
15
|
+
this.__syntax = "";
|
|
16
|
+
this.__inherits = false;
|
|
17
|
+
this.__initialValue = null;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
CSSOM.CSSPropertyRule.prototype = Object.create(CSSOM.CSSRule.prototype);
|
|
21
|
+
CSSOM.CSSPropertyRule.prototype.constructor = CSSOM.CSSPropertyRule;
|
|
22
|
+
|
|
23
|
+
Object.setPrototypeOf(CSSOM.CSSPropertyRule, CSSOM.CSSRule);
|
|
24
|
+
|
|
25
|
+
Object.defineProperty(CSSOM.CSSPropertyRule.prototype, "type", {
|
|
26
|
+
value: 0,
|
|
27
|
+
writable: false
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
Object.defineProperty(CSSOM.CSSPropertyRule.prototype, "cssText", {
|
|
31
|
+
get: function() {
|
|
32
|
+
var text = "@property " + this.name + " {";
|
|
33
|
+
if (this.syntax !== "") {
|
|
34
|
+
text += " syntax: \"" + this.syntax.replace(/\\/g, '\\\\').replace(/"/g, '\\"') + "\";";
|
|
35
|
+
}
|
|
36
|
+
text += " inherits: " + (this.inherits ? "true" : "false") + ";";
|
|
37
|
+
if (this.initialValue !== null) {
|
|
38
|
+
text += " initial-value: " + this.initialValue + ";";
|
|
39
|
+
}
|
|
40
|
+
text += " }";
|
|
41
|
+
return text;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
Object.defineProperty(CSSOM.CSSPropertyRule.prototype, "name", {
|
|
46
|
+
get: function() {
|
|
47
|
+
return this.__name;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
Object.defineProperty(CSSOM.CSSPropertyRule.prototype, "syntax", {
|
|
52
|
+
get: function() {
|
|
53
|
+
return this.__syntax;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
Object.defineProperty(CSSOM.CSSPropertyRule.prototype, "inherits", {
|
|
58
|
+
get: function() {
|
|
59
|
+
return this.__inherits;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
Object.defineProperty(CSSOM.CSSPropertyRule.prototype, "initialValue", {
|
|
64
|
+
get: function() {
|
|
65
|
+
return this.__initialValue;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* NON-STANDARD
|
|
71
|
+
* Rule text parser.
|
|
72
|
+
* @param {string} cssText
|
|
73
|
+
* @returns {boolean} True if the rule is valid and was parsed successfully
|
|
74
|
+
*/
|
|
75
|
+
Object.defineProperty(CSSOM.CSSPropertyRule.prototype, "parse", {
|
|
76
|
+
value: function(cssText) {
|
|
77
|
+
// Extract the name from "@property <name> { ... }"
|
|
78
|
+
var match = cssText.match(/@property\s+(--[^\s{]+)\s*\{([^]*)\}/);
|
|
79
|
+
if (!match) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
this.__name = match[1];
|
|
84
|
+
var bodyText = match[2];
|
|
85
|
+
|
|
86
|
+
// Parse syntax descriptor (REQUIRED)
|
|
87
|
+
var syntaxMatch = bodyText.match(/syntax\s*:\s*(['"])([^]*?)\1\s*;/);
|
|
88
|
+
if (!syntaxMatch) {
|
|
89
|
+
return false; // syntax is required
|
|
90
|
+
}
|
|
91
|
+
this.__syntax = syntaxMatch[2];
|
|
92
|
+
|
|
93
|
+
// Syntax cannot be empty
|
|
94
|
+
if (this.__syntax === "") {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Parse inherits descriptor (REQUIRED)
|
|
99
|
+
var inheritsMatch = bodyText.match(/inherits\s*:\s*(true|false)\s*;/);
|
|
100
|
+
if (!inheritsMatch) {
|
|
101
|
+
return false; // inherits is required
|
|
102
|
+
}
|
|
103
|
+
this.__inherits = inheritsMatch[1] === "true";
|
|
104
|
+
|
|
105
|
+
// Parse initial-value descriptor (OPTIONAL, but required if syntax is not "*")
|
|
106
|
+
var initialValueMatch = bodyText.match(/initial-value\s*:\s*([^;]+);/);
|
|
107
|
+
if (initialValueMatch) {
|
|
108
|
+
this.__initialValue = initialValueMatch[1].trim();
|
|
109
|
+
} else {
|
|
110
|
+
// If syntax is not "*", initial-value is required
|
|
111
|
+
if (this.__syntax !== "*") {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return true; // Successfully parsed
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
//.CommonJS
|
|
121
|
+
exports.CSSPropertyRule = CSSOM.CSSPropertyRule;
|
|
122
|
+
///CommonJS
|
package/lib/CSSStyleRule.js
CHANGED
|
@@ -55,7 +55,8 @@ Object.defineProperty(CSSOM.CSSStyleRule.prototype, "selectorText", {
|
|
|
55
55
|
|
|
56
56
|
this.__selectorText = trimmedValue;
|
|
57
57
|
}
|
|
58
|
-
}
|
|
58
|
+
},
|
|
59
|
+
configurable: true
|
|
59
60
|
});
|
|
60
61
|
|
|
61
62
|
Object.defineProperty(CSSOM.CSSStyleRule.prototype, "style", {
|
|
@@ -68,7 +69,8 @@ Object.defineProperty(CSSOM.CSSStyleRule.prototype, "style", {
|
|
|
68
69
|
} else {
|
|
69
70
|
this.__style = value;
|
|
70
71
|
}
|
|
71
|
-
}
|
|
72
|
+
},
|
|
73
|
+
configurable: true
|
|
72
74
|
});
|
|
73
75
|
|
|
74
76
|
Object.defineProperty(CSSOM.CSSStyleRule.prototype, "cssText", {
|
package/lib/CSSStyleSheet.js
CHANGED
|
@@ -123,6 +123,11 @@ CSSOM.CSSStyleSheet.prototype.insertRule = function(rule, index) {
|
|
|
123
123
|
|
|
124
124
|
// Validate rule ordering based on CSS specification
|
|
125
125
|
if (cssRule.constructor.name === 'CSSImportRule') {
|
|
126
|
+
if (this.__constructed === true) {
|
|
127
|
+
errorUtils.throwError(this, 'DOMException',
|
|
128
|
+
"Failed to execute 'insertRule' on '" + this.constructor.name + "': Can't insert @import rules into a constructed stylesheet.",
|
|
129
|
+
'SyntaxError');
|
|
130
|
+
}
|
|
126
131
|
// @import rules cannot be inserted after @layer rules that already exist
|
|
127
132
|
// They can only be inserted at the beginning or after other @import rules
|
|
128
133
|
var firstLayerIndex = findFirstNonConstructorIndex(this.cssRules, ['CSSImportRule']);
|
package/lib/index.js
CHANGED
|
@@ -13,6 +13,7 @@ exports.CSSRuleList = require('./CSSRuleList').CSSRuleList;
|
|
|
13
13
|
exports.CSSNestedDeclarations = require('./CSSNestedDeclarations').CSSNestedDeclarations;
|
|
14
14
|
exports.CSSGroupingRule = require('./CSSGroupingRule').CSSGroupingRule;
|
|
15
15
|
exports.CSSCounterStyleRule = require('./CSSCounterStyleRule').CSSCounterStyleRule;
|
|
16
|
+
exports.CSSPropertyRule = require('./CSSPropertyRule').CSSPropertyRule;
|
|
16
17
|
exports.CSSConditionRule = require('./CSSConditionRule').CSSConditionRule;
|
|
17
18
|
exports.CSSStyleRule = require('./CSSStyleRule').CSSStyleRule;
|
|
18
19
|
exports.MediaList = require('./MediaList').MediaList;
|
package/lib/parse.js
CHANGED
|
@@ -52,6 +52,7 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
52
52
|
"containerBlock": true,
|
|
53
53
|
"conditionBlock": true,
|
|
54
54
|
"counterStyleBlock": true,
|
|
55
|
+
"propertyBlock": true,
|
|
55
56
|
'documentRule-begin': true,
|
|
56
57
|
"scopeBlock": true,
|
|
57
58
|
"layerBlock": true,
|
|
@@ -83,6 +84,10 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
83
84
|
if (ownerNodeMedia) {
|
|
84
85
|
styleSheet.media.mediaText = ownerNodeMedia;
|
|
85
86
|
}
|
|
87
|
+
var ownerNodeTitle = opts.ownerNode.title || (opts.ownerNode.getAttribute && opts.ownerNode.getAttribute("title"));
|
|
88
|
+
if (ownerNodeTitle) {
|
|
89
|
+
styleSheet.__title = ownerNodeTitle;
|
|
90
|
+
}
|
|
86
91
|
}
|
|
87
92
|
|
|
88
93
|
if (opts && opts.ownerRule) {
|
|
@@ -98,7 +103,7 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
98
103
|
var ancestorRules = [];
|
|
99
104
|
var prevScope;
|
|
100
105
|
|
|
101
|
-
var name, priority = "", styleRule, mediaRule, containerRule, counterStyleRule, supportsRule, importRule, fontFaceRule, keyframesRule, documentRule, hostRule, startingStyleRule, scopeRule, pageRule, layerBlockRule, layerStatementRule, nestedSelectorRule, namespaceRule;
|
|
106
|
+
var name, priority = "", styleRule, mediaRule, containerRule, counterStyleRule, propertyRule, supportsRule, importRule, fontFaceRule, keyframesRule, documentRule, hostRule, startingStyleRule, scopeRule, pageRule, layerBlockRule, layerStatementRule, nestedSelectorRule, namespaceRule;
|
|
102
107
|
|
|
103
108
|
// Track defined namespace prefixes for validation
|
|
104
109
|
var definedNamespacePrefixes = {};
|
|
@@ -413,6 +418,44 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
413
418
|
return invalidNestingPattern.test(selector);
|
|
414
419
|
};
|
|
415
420
|
|
|
421
|
+
/**
|
|
422
|
+
* Checks if an at-rule can be nested based on parent chain validation.
|
|
423
|
+
* Used for at-rules like `@counter-style`, `@property` and `@font-face` rules that can only be nested inside
|
|
424
|
+
* `CSSScopeRule` or `CSSConditionRule` without `CSSStyleRule` in parent chain.
|
|
425
|
+
* @returns {boolean} `true` if nesting is allowed, `false` otherwise
|
|
426
|
+
*/
|
|
427
|
+
function canAtRuleBeNested() {
|
|
428
|
+
if (currentScope === topScope) {
|
|
429
|
+
return true; // Top-level is always allowed
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
var hasStyleRuleInChain = false;
|
|
433
|
+
var hasValidParent = false;
|
|
434
|
+
|
|
435
|
+
// Check currentScope
|
|
436
|
+
if (currentScope.constructor.name === 'CSSStyleRule') {
|
|
437
|
+
hasStyleRuleInChain = true;
|
|
438
|
+
} else if (currentScope instanceof CSSOM.CSSScopeRule || currentScope instanceof CSSOM.CSSConditionRule) {
|
|
439
|
+
hasValidParent = true;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// Check ancestorRules for CSSStyleRule
|
|
443
|
+
if (!hasStyleRuleInChain) {
|
|
444
|
+
for (var j = 0; j < ancestorRules.length; j++) {
|
|
445
|
+
if (ancestorRules[j].constructor.name === 'CSSStyleRule') {
|
|
446
|
+
hasStyleRuleInChain = true;
|
|
447
|
+
break;
|
|
448
|
+
}
|
|
449
|
+
if (ancestorRules[j] instanceof CSSOM.CSSScopeRule || ancestorRules[j] instanceof CSSOM.CSSConditionRule) {
|
|
450
|
+
hasValidParent = true;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// Allow nesting if we have a valid parent and no style rule in the chain
|
|
456
|
+
return hasValidParent && !hasStyleRuleInChain;
|
|
457
|
+
}
|
|
458
|
+
|
|
416
459
|
function validateAtRule(atRuleKey, validCallback, cannotBeNested) {
|
|
417
460
|
var isValid = false;
|
|
418
461
|
var sourceRuleRegExp = atRuleKey === "@import" ? forwardImportRuleValidationRegExp : forwardRuleValidationRegExp;
|
|
@@ -1594,13 +1637,28 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
1594
1637
|
buffer = "";
|
|
1595
1638
|
break;
|
|
1596
1639
|
} else if (token.indexOf("@counter-style", i) === i) {
|
|
1640
|
+
buffer = "";
|
|
1641
|
+
// @counter-style can be nested only inside CSSScopeRule or CSSConditionRule
|
|
1642
|
+
// and only if there's no CSSStyleRule in the parent chain
|
|
1643
|
+
var cannotBeNested = !canAtRuleBeNested();
|
|
1597
1644
|
validateAtRule("@counter-style", function () {
|
|
1598
1645
|
state = "counterStyleBlock"
|
|
1599
1646
|
counterStyleRule = new CSSOM.CSSCounterStyleRule();
|
|
1600
1647
|
counterStyleRule.__starts = i;
|
|
1601
1648
|
i += "counter-style".length;
|
|
1602
|
-
},
|
|
1649
|
+
}, cannotBeNested);
|
|
1650
|
+
break;
|
|
1651
|
+
} else if (token.indexOf("@property", i) === i) {
|
|
1603
1652
|
buffer = "";
|
|
1653
|
+
// @property can be nested only inside CSSScopeRule or CSSConditionRule
|
|
1654
|
+
// and only if there's no CSSStyleRule in the parent chain
|
|
1655
|
+
var cannotBeNested = !canAtRuleBeNested();
|
|
1656
|
+
validateAtRule("@property", function () {
|
|
1657
|
+
state = "propertyBlock"
|
|
1658
|
+
propertyRule = new CSSOM.CSSPropertyRule();
|
|
1659
|
+
propertyRule.__starts = i;
|
|
1660
|
+
i += "property".length;
|
|
1661
|
+
}, cannotBeNested);
|
|
1604
1662
|
break;
|
|
1605
1663
|
} else if (token.indexOf("@scope", i) === i) {
|
|
1606
1664
|
validateAtRule("@scope", function () {
|
|
@@ -1676,36 +1734,7 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
1676
1734
|
buffer = "";
|
|
1677
1735
|
// @font-face can be nested only inside CSSScopeRule or CSSConditionRule
|
|
1678
1736
|
// and only if there's no CSSStyleRule in the parent chain
|
|
1679
|
-
var cannotBeNested =
|
|
1680
|
-
if (currentScope !== topScope) {
|
|
1681
|
-
var hasStyleRuleInChain = false;
|
|
1682
|
-
var hasValidParent = false;
|
|
1683
|
-
|
|
1684
|
-
// Check currentScope
|
|
1685
|
-
if (currentScope.constructor.name === 'CSSStyleRule') {
|
|
1686
|
-
hasStyleRuleInChain = true;
|
|
1687
|
-
} else if (currentScope instanceof CSSOM.CSSScopeRule || currentScope instanceof CSSOM.CSSConditionRule) {
|
|
1688
|
-
hasValidParent = true;
|
|
1689
|
-
}
|
|
1690
|
-
|
|
1691
|
-
// Check ancestorRules for CSSStyleRule
|
|
1692
|
-
if (!hasStyleRuleInChain) {
|
|
1693
|
-
for (var j = 0; j < ancestorRules.length; j++) {
|
|
1694
|
-
if (ancestorRules[j].constructor.name === 'CSSStyleRule') {
|
|
1695
|
-
hasStyleRuleInChain = true;
|
|
1696
|
-
break;
|
|
1697
|
-
}
|
|
1698
|
-
if (ancestorRules[j] instanceof CSSOM.CSSScopeRule || ancestorRules[j] instanceof CSSOM.CSSConditionRule) {
|
|
1699
|
-
hasValidParent = true;
|
|
1700
|
-
}
|
|
1701
|
-
}
|
|
1702
|
-
}
|
|
1703
|
-
|
|
1704
|
-
// Allow nesting if we have a valid parent and no style rule in the chain
|
|
1705
|
-
if (hasValidParent && !hasStyleRuleInChain) {
|
|
1706
|
-
cannotBeNested = false;
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1737
|
+
var cannotBeNested = !canAtRuleBeNested();
|
|
1709
1738
|
validateAtRule("@font-face", function () {
|
|
1710
1739
|
state = "fontFaceRule-begin";
|
|
1711
1740
|
i += "font-face".length;
|
|
@@ -1822,8 +1851,25 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
1822
1851
|
|
|
1823
1852
|
if (isValidCounterStyleName) {
|
|
1824
1853
|
counterStyleRule.name = counterStyleName;
|
|
1825
|
-
|
|
1854
|
+
if (parentRule) {
|
|
1855
|
+
counterStyleRule.__parentRule = parentRule;
|
|
1856
|
+
}
|
|
1826
1857
|
counterStyleRule.__parentStyleSheet = styleSheet;
|
|
1858
|
+
styleRule = counterStyleRule;
|
|
1859
|
+
}
|
|
1860
|
+
buffer = "";
|
|
1861
|
+
} else if (state === "propertyBlock") {
|
|
1862
|
+
var propertyName = buffer.trim().replace(/\n/g, "");
|
|
1863
|
+
// Validate: name must start with -- (custom property)
|
|
1864
|
+
var isValidPropertyName = propertyName.indexOf("--") === 0;
|
|
1865
|
+
|
|
1866
|
+
if (isValidPropertyName) {
|
|
1867
|
+
propertyRule.__name = propertyName;
|
|
1868
|
+
if (parentRule) {
|
|
1869
|
+
propertyRule.__parentRule = parentRule;
|
|
1870
|
+
}
|
|
1871
|
+
propertyRule.__parentStyleSheet = styleSheet;
|
|
1872
|
+
styleRule = propertyRule;
|
|
1827
1873
|
}
|
|
1828
1874
|
buffer = "";
|
|
1829
1875
|
} else if (state === "conditionBlock") {
|
|
@@ -2111,6 +2157,7 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
2111
2157
|
if (opts && opts.globalObject && opts.globalObject.CSSStyleSheet) {
|
|
2112
2158
|
importRule.__styleSheet = new opts.globalObject.CSSStyleSheet();
|
|
2113
2159
|
}
|
|
2160
|
+
importRule.styleSheet.__constructed = false;
|
|
2114
2161
|
importRule.__parentStyleSheet = importRule.styleSheet.__parentStyleSheet = styleSheet;
|
|
2115
2162
|
importRule.parse(buffer + character);
|
|
2116
2163
|
topScope.cssRules.push(importRule);
|
|
@@ -2192,11 +2239,50 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
2192
2239
|
if (state === "counterStyleBlock") {
|
|
2193
2240
|
// FIXME : Implement missing properties on CSSCounterStyleRule interface and update parse method
|
|
2194
2241
|
// For now it's just assigning entire rule text
|
|
2195
|
-
|
|
2242
|
+
if (counterStyleRule.name) {
|
|
2243
|
+
// Only process if name was set (valid)
|
|
2244
|
+
counterStyleRule.parse("@counter-style " + counterStyleRule.name + " { " + buffer + " }");
|
|
2245
|
+
counterStyleRule.__ends = i + 1;
|
|
2246
|
+
// Add to parent's cssRules
|
|
2247
|
+
if (counterStyleRule.__parentRule) {
|
|
2248
|
+
counterStyleRule.__parentRule.cssRules.push(counterStyleRule);
|
|
2249
|
+
} else {
|
|
2250
|
+
topScope.cssRules.push(counterStyleRule);
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
// Restore currentScope to parent after closing this rule
|
|
2254
|
+
if (counterStyleRule.__parentRule) {
|
|
2255
|
+
currentScope = counterStyleRule.__parentRule;
|
|
2256
|
+
}
|
|
2257
|
+
styleRule = null;
|
|
2196
2258
|
buffer = "";
|
|
2197
2259
|
state = "before-selector";
|
|
2260
|
+
break;
|
|
2261
|
+
}
|
|
2262
|
+
if (state === "propertyBlock") {
|
|
2263
|
+
// Only process if name was set (valid)
|
|
2264
|
+
if (propertyRule.__name) {
|
|
2265
|
+
var parseSuccess = propertyRule.parse("@property " + propertyRule.__name + " { " + buffer + " }");
|
|
2266
|
+
// Only add the rule if parse was successful (syntax, inherits, and initial-value validation passed)
|
|
2267
|
+
if (parseSuccess) {
|
|
2268
|
+
propertyRule.__ends = i + 1;
|
|
2269
|
+
// Add to parent's cssRules
|
|
2270
|
+
if (propertyRule.__parentRule) {
|
|
2271
|
+
propertyRule.__parentRule.cssRules.push(propertyRule);
|
|
2272
|
+
} else {
|
|
2273
|
+
topScope.cssRules.push(propertyRule);
|
|
2274
|
+
}
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
// Restore currentScope to parent after closing this rule
|
|
2278
|
+
if (propertyRule.__parentRule) {
|
|
2279
|
+
currentScope = propertyRule.__parentRule;
|
|
2280
|
+
}
|
|
2281
|
+
styleRule = null;
|
|
2282
|
+
buffer = "";
|
|
2283
|
+
state = "before-selector";
|
|
2284
|
+
break;
|
|
2198
2285
|
}
|
|
2199
|
-
|
|
2200
2286
|
switch (state) {
|
|
2201
2287
|
case "value":
|
|
2202
2288
|
styleRule.style.setProperty(name, buffer.trim(), priority, parseError);
|
|
@@ -2321,6 +2407,8 @@ CSSOM.parse = function parse(token, opts, errorHandler) {
|
|
|
2321
2407
|
currentScope.cssRules.push(prevScope);
|
|
2322
2408
|
}
|
|
2323
2409
|
nestedSelectorRule = currentScope;
|
|
2410
|
+
// Stop here to preserve context for sibling selectors
|
|
2411
|
+
break;
|
|
2324
2412
|
} else {
|
|
2325
2413
|
// Top-level CSSStyleRule with nested grouping rule
|
|
2326
2414
|
prevScope = currentScope;
|
|
@@ -2484,6 +2572,7 @@ CSSOM.CSSNamespaceRule = require("./CSSNamespaceRule").CSSNamespaceRule;
|
|
|
2484
2572
|
CSSOM.CSSGroupingRule = require("./CSSGroupingRule").CSSGroupingRule;
|
|
2485
2573
|
CSSOM.CSSMediaRule = require("./CSSMediaRule").CSSMediaRule;
|
|
2486
2574
|
CSSOM.CSSCounterStyleRule = require("./CSSCounterStyleRule").CSSCounterStyleRule;
|
|
2575
|
+
CSSOM.CSSPropertyRule = require("./CSSPropertyRule").CSSPropertyRule;
|
|
2487
2576
|
CSSOM.CSSContainerRule = require("./CSSContainerRule").CSSContainerRule;
|
|
2488
2577
|
CSSOM.CSSConditionRule = require("./CSSConditionRule").CSSConditionRule;
|
|
2489
2578
|
CSSOM.CSSSupportsRule = require("./CSSSupportsRule").CSSSupportsRule;
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"parser",
|
|
8
8
|
"styleSheet"
|
|
9
9
|
],
|
|
10
|
-
"version": "0.9.
|
|
10
|
+
"version": "0.9.30",
|
|
11
11
|
"author": "Nikita Vasilyev <me@elv1s.ru>",
|
|
12
12
|
"contributors": [
|
|
13
13
|
"Acemir Sousa Mendes <acemirsm@gmail.com>"
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"release": "npm run build && changeset publish"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@changesets/changelog-github": "^0.5.
|
|
28
|
-
"@changesets/cli": "^2.
|
|
27
|
+
"@changesets/changelog-github": "^0.5.2",
|
|
28
|
+
"@changesets/cli": "^2.29.8",
|
|
29
|
+
"@changesets/get-release-plan": "^4.0.14"
|
|
29
30
|
}
|
|
30
31
|
}
|