unsigned CSSGroupingRule::insertRule(const String& ruleString, unsigned index, ExceptionState& exceptionState) { ASSERT(m_childRuleCSSOMWrappers.size() == m_groupRule->childRules().size()); if (index > m_groupRule->childRules().size()) { exceptionState.throwDOMException(IndexSizeError, "the index " + String::number(index) + " must be less than or equal to the length of the rule list."); return 0; } CSSStyleSheet* styleSheet = parentStyleSheet(); CSSParserContext context(parserContext(), UseCounter::getFrom(styleSheet)); BisonCSSParser parser(context); RefPtrWillBeRawPtr<StyleRuleBase> newRule = parser.parseRule(styleSheet ? styleSheet->contents() : 0, ruleString); if (!newRule) { exceptionState.throwDOMException(SyntaxError, "the rule '" + ruleString + "' is invalid and cannot be parsed."); return 0; } if (newRule->isImportRule()) { // FIXME: an HierarchyRequestError should also be thrown for a @charset or a nested // @media rule. They are currently not getting parsed, resulting in a SyntaxError // to get raised above. exceptionState.throwDOMException(HierarchyRequestError, "'@import' rules cannot be inserted inside a group rule."); return 0; } CSSStyleSheet::RuleMutationScope mutationScope(this); m_groupRule->wrapperInsertRule(index, newRule); m_childRuleCSSOMWrappers.insert(index, RefPtrWillBeMember<CSSRule>(nullptr)); return index; }
ExceptionOr<unsigned> CSSGroupingRule::insertRule(const String& ruleString, unsigned index) { ASSERT(m_childRuleCSSOMWrappers.size() == m_groupRule->childRules().size()); if (index > m_groupRule->childRules().size()) { // INDEX_SIZE_ERR: Raised if the specified index is not a valid insertion point. return Exception { INDEX_SIZE_ERR }; } CSSParser parser(parserContext()); CSSStyleSheet* styleSheet = parentStyleSheet(); RefPtr<StyleRuleBase> newRule = parser.parseRule(styleSheet ? &styleSheet->contents() : nullptr, ruleString); if (!newRule) { // SYNTAX_ERR: Raised if the specified rule has a syntax error and is unparsable. return Exception { SYNTAX_ERR }; } if (newRule->isImportRule()) { // FIXME: an HIERARCHY_REQUEST_ERR should also be thrown for a @charset or a nested // @media rule. They are currently not getting parsed, resulting in a SYNTAX_ERR // to get raised above. // HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at the specified // index, e.g., if an @import rule is inserted after a standard rule set or other // at-rule. return Exception { HIERARCHY_REQUEST_ERR }; } CSSStyleSheet::RuleMutationScope mutationScope(this); m_groupRule->wrapperInsertRule(index, newRule.releaseNonNull()); m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>()); return index; }
unsigned CSSGroupingRule::insertRule(const String& ruleString, unsigned index, ExceptionState& exceptionState) { ASSERT(m_childRuleCSSOMWrappers.size() == m_groupRule->childRules().size()); if (index > m_groupRule->childRules().size()) { exceptionState.throwDOMException(IndexSizeError, "the index " + String::number(index) + " must be less than or equal to the length of the rule list."); return 0; } CSSStyleSheet* styleSheet = parentStyleSheet(); CSSParserContext context(parserContext(), UseCounter::getFrom(styleSheet)); BisonCSSParser parser(context); RefPtrWillBeRawPtr<StyleRuleBase> newRule = parser.parseRule(styleSheet ? styleSheet->contents() : 0, ruleString); if (!newRule) { exceptionState.throwDOMException(SyntaxError, "the rule '" + ruleString + "' is invalid and cannot be parsed."); return 0; } CSSStyleSheet::RuleMutationScope mutationScope(this); m_groupRule->wrapperInsertRule(index, newRule); m_childRuleCSSOMWrappers.insert(index, RefPtrWillBeMember<CSSRule>(nullptr)); return index; }
TEST_F(ApplyRulesetsTest, AddShadowV0BoundaryCrossingRuleToDocument) { document().view()->updateAllLifecyclePhases(); CSSStyleSheet* sheet = createSheet(".a /deep/ .b { color:red }"); ActiveStyleSheetVector newStyleSheets; newStyleSheets.append(std::make_pair(sheet, &sheet->contents()->ruleSet())); applyRuleSetChanges(styleEngine(), document(), ActiveStyleSheetVector(), newStyleSheets); EXPECT_EQ(SubtreeStyleChange, document().getStyleChangeType()); }
void ScopedStyleResolver::appendCSSStyleSheet(CSSStyleSheet& cssSheet, const MediaQueryEvaluator& medium) { unsigned index = m_authorStyleSheets.size(); m_authorStyleSheets.append(&cssSheet); StyleSheetContents* sheet = cssSheet.contents(); AddRuleFlags addRuleFlags = treeScope().document().securityOrigin()->canRequest(sheet->baseURL()) ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState; const RuleSet& ruleSet = sheet->ensureRuleSet(medium, addRuleFlags); addKeyframeRules(ruleSet); addFontFaceRules(ruleSet); addTreeBoundaryCrossingRules(ruleSet, &cssSheet, index); treeScope().document().styleResolver()->addMediaQueryResults(ruleSet.viewportDependentMediaQueryResults()); }
TEST_F(ApplyRulesetsTest, AddFontFaceRuleToDocument) { document().view()->updateAllLifecyclePhases(); CSSStyleSheet* sheet = createSheet("@font-face { font-family: ahum; src: url(ahum.ttf) }"); ActiveStyleSheetVector newStyleSheets; newStyleSheets.append(std::make_pair(sheet, &sheet->contents()->ruleSet())); applyRuleSetChanges(styleEngine(), document(), ActiveStyleSheetVector(), newStyleSheets); EXPECT_EQ(SubtreeStyleChange, document().getStyleChangeType()); }
void CSSKeyframesRule::insertRule(const String& ruleText) { ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size()); CSSStyleSheet* styleSheet = parentStyleSheet(); BisonCSSParser parser(parserContext(), UseCounter::getFrom(styleSheet)); RefPtr<StyleKeyframe> keyframe = parser.parseKeyframeRule(styleSheet ? styleSheet->contents() : 0, ruleText); if (!keyframe) return; CSSStyleSheet::RuleMutationScope mutationScope(this); m_keyframesRule->wrapperAppendKeyframe(keyframe); m_childRuleCSSOMWrappers.grow(length()); }
TEST_F(ApplyRulesetsTest, AddFontFaceRuleToShadowTree) { document().body()->setInnerHTML("<div id=host></div>", ASSERT_NO_EXCEPTION); Element* host = document().getElementById("host"); ASSERT_TRUE(host); ShadowRoot& shadowRoot = attachShadow(*host); document().view()->updateAllLifecyclePhases(); CSSStyleSheet* sheet = createSheet("@font-face { font-family: ahum; src: url(ahum.ttf) }"); ActiveStyleSheetVector newStyleSheets; newStyleSheets.append(std::make_pair(sheet, &sheet->contents()->ruleSet())); applyRuleSetChanges(styleEngine(), shadowRoot, ActiveStyleSheetVector(), newStyleSheets); EXPECT_FALSE(document().needsLayoutTreeUpdate()); }
TEST_F(ApplyRulesetsTest, AddShadowV0BoundaryCrossingRuleToShadowTree) { document().body()->setInnerHTML("<div id=host></div>", ASSERT_NO_EXCEPTION); Element* host = document().getElementById("host"); ASSERT_TRUE(host); ShadowRoot& shadowRoot = attachShadow(*host); document().view()->updateAllLifecyclePhases(); CSSStyleSheet* sheet = createSheet(".a /deep/ .b { color:red }"); ActiveStyleSheetVector newStyleSheets; newStyleSheets.append(std::make_pair(sheet, &sheet->contents()->ruleSet())); applyRuleSetChanges(styleEngine(), shadowRoot, ActiveStyleSheetVector(), newStyleSheets); EXPECT_FALSE(document().needsStyleRecalc()); EXPECT_EQ(SubtreeStyleChange, host->getStyleChangeType()); }
DISABLE_CFI_PERF StyleSheetContents* AbstractPropertySetCSSStyleDeclaration::contextStyleSheet() const { CSSStyleSheet* cssStyleSheet = parentStyleSheet(); return cssStyleSheet ? cssStyleSheet->contents() : nullptr; }
StyleSheetContents* AbstractPropertySetCSSStyleDeclaration::contextStyleSheet() const { CSSStyleSheet* cssStyleSheet = parentStyleSheet(); return cssStyleSheet ? cssStyleSheet->contents() : 0; }
const CSSParserContext& CSSRule::parserContext() const { CSSStyleSheet* styleSheet = parentStyleSheet(); return styleSheet ? styleSheet->contents()->parserContext() : strictCSSParserContext(); }