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; } 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; }
JSValue JSC_HOST_CALL jsCSSStyleSheetPrototypeFunctionAddRule(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UNUSED_PARAM(args); if (!thisValue.inherits(&JSCSSStyleSheet::s_info)) return throwError(exec, TypeError); JSCSSStyleSheet* castedThisObj = static_cast<JSCSSStyleSheet*>(asObject(thisValue)); CSSStyleSheet* imp = static_cast<CSSStyleSheet*>(castedThisObj->impl()); ExceptionCode ec = 0; const UString& selector = args.at(0).toString(exec); const UString& style = args.at(1).toString(exec); int argsCount = args.size(); if (argsCount < 3) { JSC::JSValue result = jsNumber(exec, imp->addRule(selector, style, ec)); setDOMException(exec, ec); return result; } unsigned index = args.at(2).toInt32(exec); JSC::JSValue result = jsNumber(exec, imp->addRule(selector, style, index, ec)); setDOMException(exec, ec); return result; }
void PageSerializer::retrieveResourcesForCSSDeclaration(CSSMutableStyleDeclaration* styleDeclaration) { if (!styleDeclaration) return; CSSStyleSheet* cssStyleSheet = styleDeclaration->parentStyleSheet(); ASSERT(cssStyleSheet); // The background-image and list-style-image (for ul or ol) are the CSS properties // that make use of images. We iterate to make sure we include any other // image properties there might be. unsigned propertyCount = styleDeclaration->propertyCount(); for (unsigned i = 0; i < propertyCount; ++i) { RefPtr<CSSValue> cssValue = styleDeclaration->propertyAt(i).value(); if (!cssValue->isImageValue()) continue; CSSImageValue* imageValue = static_cast<CSSImageValue*>(cssValue.get()); StyleImage* styleImage = imageValue->cachedOrPendingImage(); // Non cached-images are just place-holders and do not contain data. if (!styleImage || !styleImage->isCachedImage()) continue; CachedImage* image = static_cast<StyleCachedImage*>(styleImage)->cachedImage(); Document* document = cssStyleSheet->findDocument(); KURL url = document->completeURL(image->url()); addImageToResources(image, 0, url); } }
NS_IMETHODIMP inDOMUtils::GetRelativeRuleLine(nsIDOMCSSRule* aRule, uint32_t* _retval) { NS_ENSURE_ARG_POINTER(aRule); Rule* rule = aRule->GetCSSRule(); if (!rule) { return NS_ERROR_FAILURE; } uint32_t lineNumber = rule->GetLineNumber(); CSSStyleSheet* sheet = rule->GetStyleSheet(); if (sheet) { nsINode* owningNode = sheet->GetOwnerNode(); if (owningNode) { nsCOMPtr<nsIStyleSheetLinkingElement> link = do_QueryInterface(owningNode); if (link) { lineNumber -= link->GetLineNumber() - 1; } } } *_retval = lineNumber; return NS_OK; }
JSValue* jsCSSStyleSheetPrototypeFunctionAddRule(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args) { if (!thisValue->isObject(&JSCSSStyleSheet::s_info)) return throwError(exec, TypeError); JSCSSStyleSheet* castedThisObj = static_cast<JSCSSStyleSheet*>(thisValue); CSSStyleSheet* imp = static_cast<CSSStyleSheet*>(castedThisObj->impl()); ExceptionCode ec = 0; const UString& selector = args[0]->toString(exec); const UString& style = args[1]->toString(exec); int argsCount = args.size(); if (argsCount < 3) { KJS::JSValue* result = jsNumber(exec, imp->addRule(selector, style, ec)); setDOMException(exec, ec); return result; } unsigned index = args[2]->toInt32(exec); KJS::JSValue* result = jsNumber(exec, imp->addRule(selector, style, index, ec)); setDOMException(exec, ec); return result; }
void ProcessingInstruction::setCSSStyleSheet( const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource* sheet) { if (!isConnected()) { DCHECK(!m_sheet); return; } DCHECK(m_isCSS); CSSParserContext parserContext(document(), nullptr, baseURL, charset); StyleSheetContents* newSheet = StyleSheetContents::create(href, parserContext); CSSStyleSheet* cssSheet = CSSStyleSheet::create(newSheet, *this); cssSheet->setDisabled(m_alternate); cssSheet->setTitle(m_title); if (!m_alternate && !m_title.isEmpty()) document().styleEngine().setPreferredStylesheetSetNameIfNotSet( m_title, StyleEngine::DontUpdateActiveSheets); cssSheet->setMediaQueries(MediaQuerySet::create(m_media)); m_sheet = cssSheet; // We don't need the cross-origin security check here because we are // getting the sheet text in "strict" mode. This enforces a valid CSS MIME // type. parseStyleSheet(sheet->sheetText()); }
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; }
void PageSerializer::retrieveResourcesForCSSDeclaration(CSSStyleDeclaration* styleDeclaration) { if (!styleDeclaration) return; if (!styleDeclaration->stylesheet()->isCSSStyleSheet()) return; CSSStyleSheet* cssStyleSheet = static_cast<CSSStyleSheet*>(styleDeclaration->stylesheet()); // The background-image and list-style-image (for ul or ol) are the CSS properties // that make use of images. We iterate to make sure we include any other // image properties there might be. for (unsigned i = 0; i < styleDeclaration->length(); ++i) { // FIXME: It's kind of ridiculous to get the property name and then get // the value out of the name. Ideally we would get the value out of the // property ID, but CSSStyleDeclaration only gives access to property // names, not IDs. RefPtr<CSSValue> cssValue = styleDeclaration->getPropertyCSSValue(styleDeclaration->item(i)); if (!cssValue->isImageValue()) continue; CSSImageValue* imageValue = static_cast<CSSImageValue*>(cssValue.get()); StyleImage* styleImage = imageValue->cachedOrPendingImage(); // Non cached-images are just place-holders and do not contain data. if (!styleImage || !styleImage->isCachedImage()) continue; CachedImage* image = static_cast<StyleCachedImage*>(styleImage)->cachedImage(); KURL url = cssStyleSheet->document()->completeURL(image->url()); addImageToResources(image, url); } }
PassRefPtr<InspectorObject> InspectorStyleSheet::buildObjectForRule(CSSStyleRule* rule) { CSSStyleSheet* styleSheet = pageStyleSheet(); if (!styleSheet) return 0; RefPtr<InspectorObject> result = InspectorObject::create(); result->setString("selectorText", rule->selectorText()); result->setString("cssText", rule->cssText()); result->setNumber("sourceLine", rule->sourceLine()); result->setString("documentURL", m_documentURL); RefPtr<InspectorObject> parentStyleSheetValue = InspectorObject::create(); parentStyleSheetValue->setString("id", id()); parentStyleSheetValue->setString("href", styleSheet->href()); result->setObject("parentStyleSheet", parentStyleSheetValue.release()); result->setString("origin", m_origin); RefPtr<CSSRuleSourceData> sourceData; if (ensureParsedDataReady()) sourceData = ruleSourceDataFor(rule->style()); if (sourceData) { result->setNumber("selectorStartOffset", sourceData->selectorListRange.start); result->setNumber("selectorEndOffset", sourceData->selectorListRange.end); } result->setObject("style", buildObjectForStyle(rule->style())); if (canBind()) result->setString("id", fullRuleId(rule)); return result.release(); }
void HTMLLinkElement::SetDisabled(bool aDisabled) { CSSStyleSheet* ss = GetSheet(); if (ss) { ss->SetDisabled(aDisabled); } }
CSSStyleSheet::CSSStyleSheet(CSSRule* ownerRule, const String& href, const KURL& baseURL, const String& charset) : StyleSheet(ownerRule, href, baseURL) , m_charset(charset) , m_loadCompleted(false) , m_strictParsing(!ownerRule || ownerRule->useStrictParsing()) , m_hasSyntacticallyValidCSSHeader(true) { CSSStyleSheet* parentSheet = ownerRule ? ownerRule->parentStyleSheet() : 0; m_isUserStyleSheet = parentSheet ? parentSheet->isUserStyleSheet() : false; }
CSSStyleSheet::CSSStyleSheet(CSSRule *ownerRule, const String& href, const String& charset) : StyleSheet(ownerRule, href) , m_namespaces(0) , m_charset(charset) , m_loadCompleted(false) , m_strictParsing(!ownerRule || ownerRule->useStrictParsing()) { CSSStyleSheet* parentSheet = ownerRule ? ownerRule->parentStyleSheet() : 0; m_doc = parentSheet ? parentSheet->doc() : 0; }
CSSStyleSheet::CSSStyleSheet(StyleRuleImport* ownerRule, const String& href, const KURL& baseURL, const String& charset) : StyleSheet(href, baseURL) , m_ownerRule(ownerRule) , m_charset(charset) , m_loadCompleted(false) , m_cssParserMode((ownerRule && ownerRule->parentStyleSheet()) ? ownerRule->parentStyleSheet()->cssParserMode() : CSSStrictMode) , m_hasSyntacticallyValidCSSHeader(true) , m_didLoadErrorOccur(false) { CSSStyleSheet* parentSheet = ownerRule ? ownerRule->parentStyleSheet() : 0; m_isUserStyleSheet = parentSheet ? parentSheet->isUserStyleSheet() : false; }
void nsStyleLinkElement::UpdateStyleSheetScopedness(bool aIsNowScoped) { if (!mStyleSheet) { return; } if (mStyleSheet->IsServo()) { // XXXheycam ServoStyleSheets don't support <style scoped>. NS_ERROR("stylo: ServoStyleSheets don't support <style scoped>"); return; } CSSStyleSheet* sheet = mStyleSheet->AsGecko(); nsCOMPtr<nsIContent> thisContent; CallQueryInterface(this, getter_AddRefs(thisContent)); Element* oldScopeElement = sheet->GetScopeElement(); Element* newScopeElement = aIsNowScoped ? thisContent->GetParentElement() : nullptr; if (oldScopeElement == newScopeElement) { return; } nsIDocument* document = thisContent->GetOwnerDocument(); if (thisContent->IsInShadowTree()) { ShadowRoot* containingShadow = thisContent->GetContainingShadow(); containingShadow->RemoveSheet(mStyleSheet); sheet->SetScopeElement(newScopeElement); containingShadow->InsertSheet(mStyleSheet, thisContent); } else { document->BeginUpdate(UPDATE_STYLE); document->RemoveStyleSheet(mStyleSheet); sheet->SetScopeElement(newScopeElement); document->AddStyleSheet(mStyleSheet); document->EndUpdate(UPDATE_STYLE); } if (oldScopeElement) { UpdateIsElementInStyleScopeFlagOnSubtree(oldScopeElement); } if (newScopeElement) { newScopeElement->SetIsElementInStyleScopeFlagOnSubtree(true); } }
static v8::Handle<v8::Value> rulesAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { CSSStyleSheet* imp = V8CSSStyleSheet::toNative(info.Holder()); RefPtr<CSSRuleList> result = imp->rules(); v8::Handle<v8::Value> wrapper = result.get() ? v8::Handle<v8::Value>(DOMDataStore::getWrapper(result.get(), info.GetIsolate())) : v8Undefined(); if (wrapper.IsEmpty()) { wrapper = toV8(result.get(), info.Holder(), info.GetIsolate()); if (!wrapper.IsEmpty()) V8DOMWrapper::setNamedHiddenReference(info.Holder(), "rules", wrapper); } return wrapper; }
void ElementRuleCollector::appendCSSOMWrapperForRule(StyleRule* rule) { // FIXME: There should be no codepath that creates a CSSOMWrapper without a parent stylesheet or rule because // then that codepath can lead to the CSSStyleSheet contents not getting correctly copied when the rule is modified // through the wrapper (e.g. rule.selectorText="div"). Right now, the inspector uses the pointers for identity though, // so calling CSSStyleSheet->willMutateRules breaks the inspector. CSSStyleSheet* sheet = m_includeStyleSheet == IncludeStyleSheetInCSSOMWrapper ? findStyleSheet(m_context.element()->document().styleEngine(), rule) : 0; RefPtr<CSSRule> cssRule = rule->createCSSOMWrapper(sheet); if (sheet) sheet->registerExtraChildRuleCSSOMWrapper(cssRule); ensureRuleList()->rules().append(cssRule); }
static v8::Handle<v8::Value> rulesAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.CSSStyleSheet.rules._get"); CSSStyleSheet* imp = V8CSSStyleSheet::toNative(info.Holder()); RefPtr<CSSRuleList> result = imp->rules(); v8::Handle<v8::Value> wrapper = result.get() ? getDOMObjectMap().get(result.get()) : v8::Handle<v8::Value>(); if (wrapper.IsEmpty()) { wrapper = toV8(result.get()); if (!wrapper.IsEmpty()) V8DOMWrapper::setNamedHiddenReference(info.Holder(), "rules", wrapper); } return wrapper; }
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()); }
JSValue* jsCSSStyleSheetPrototypeFunctionRemoveRule(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args) { if (!thisValue->isObject(&JSCSSStyleSheet::s_info)) return throwError(exec, TypeError); JSCSSStyleSheet* castedThisObj = static_cast<JSCSSStyleSheet*>(thisValue); CSSStyleSheet* imp = static_cast<CSSStyleSheet*>(castedThisObj->impl()); ExceptionCode ec = 0; unsigned index = args[0]->toInt32(exec); imp->removeRule(index, ec); setDOMException(exec, ec); return jsUndefined(); }
void CSSStyleSheet::styleSheetChanged() { CSSStyleSheet* rootSheet = this; while (CSSStyleSheet* parent = rootSheet->parentStyleSheet()) rootSheet = parent; /* FIXME: We don't need to do everything updateStyleSelector does, * basically we just need to recreate the document's selector with the * already existing style sheets. */ if (Document* documentToUpdate = rootSheet->findDocument()) documentToUpdate->styleSelectorChanged(DeferRecalcStyle); }
static void filterEnabledNonemptyCSSStyleSheets(Vector<RefPtr<CSSStyleSheet> >& result, const Vector<RefPtr<StyleSheet> >& sheets) { for (unsigned i = 0; i < sheets.size(); ++i) { if (!sheets[i]->isCSSStyleSheet()) continue; if (sheets[i]->disabled()) continue; CSSStyleSheet* sheet = static_cast<CSSStyleSheet*>(sheets[i].get()); if (!sheet->length()) continue; result.append(sheet); } }
JSValue JSC_HOST_CALL jsCSSStyleSheetPrototypeFunctionRemoveRule(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UNUSED_PARAM(args); if (!thisValue.inherits(&JSCSSStyleSheet::s_info)) return throwError(exec, TypeError); JSCSSStyleSheet* castedThisObj = static_cast<JSCSSStyleSheet*>(asObject(thisValue)); CSSStyleSheet* imp = static_cast<CSSStyleSheet*>(castedThisObj->impl()); ExceptionCode ec = 0; unsigned index = args.at(0).toInt32(exec); imp->removeRule(index, ec); setDOMException(exec, ec); return jsUndefined(); }
static v8::Handle<v8::Value> removeRuleCallback(const v8::Arguments& args) { CSSStyleSheet* imp = V8CSSStyleSheet::toNative(args.Holder()); ExceptionCode ec = 0; { V8TRYCATCH(unsigned, index, toUInt32(MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined))); imp->removeRule(index, ec); if (UNLIKELY(ec)) goto fail; return v8Undefined(); } fail: return setDOMException(ec, args.GetIsolate()); }
void SVGFontFaceElement::removeFromMappedElementSheet() { CSSStyleSheet* mappedElementSheet = document()->mappedElementSheet(); if (!mappedElementSheet) return; for (unsigned i = 0; i < mappedElementSheet->length(); ++i) { if (mappedElementSheet->item(i) == m_fontFaceRule) { mappedElementSheet->remove(i); break; } } document()->styleSelectorChanged(DeferRecalcStyle); }
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()); }
static v8::Handle<v8::Value> insertRuleCallback(const v8::Arguments& args) { CSSStyleSheet* imp = V8CSSStyleSheet::toNative(args.Holder()); ExceptionCode ec = 0; { V8TRYCATCH_FOR_V8STRINGRESOURCE(V8StringResource<>, rule, MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined)); V8TRYCATCH(unsigned, index, toUInt32(MAYBE_MISSING_PARAMETER(args, 1, DefaultIsUndefined))); unsigned result = imp->insertRule(rule, index, ec); if (UNLIKELY(ec)) goto fail; return v8UnsignedInteger(result, args.GetIsolate()); } fail: return setDOMException(ec, args.GetIsolate()); }
static v8::Handle<v8::Value> removeRuleCallback(const v8::Arguments& args) { INC_STATS("DOM.CSSStyleSheet.removeRule"); CSSStyleSheet* imp = V8CSSStyleSheet::toNative(args.Holder()); ExceptionCode ec = 0; { EXCEPTION_BLOCK(unsigned, index, toUInt32(MAYBE_MISSING_PARAMETER(args, 0, MissingIsUndefined))); imp->removeRule(index, ec); if (UNLIKELY(ec)) goto fail; return v8::Handle<v8::Value>(); } fail: V8Proxy::setDOMException(ec); return v8::Handle<v8::Value>(); }
/* static */ void nsDOMCSSDeclaration::GetCSSParsingEnvironmentForRule(css::Rule* aRule, CSSParsingEnvironment& aCSSParseEnv) { CSSStyleSheet* sheet = aRule ? aRule->GetStyleSheet() : nullptr; if (!sheet) { aCSSParseEnv.mPrincipal = nullptr; return; } nsIDocument* document = sheet->GetOwningDocument(); aCSSParseEnv.mSheetURI = sheet->GetSheetURI(); aCSSParseEnv.mBaseURI = sheet->GetBaseURI(); aCSSParseEnv.mPrincipal = sheet->Principal(); aCSSParseEnv.mCSSLoader = document ? document->CSSLoader() : nullptr; }
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()); }