diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/css/CSSStyleSheet.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/css/CSSStyleSheet.cpp')
-rw-r--r-- | Source/WebCore/css/CSSStyleSheet.cpp | 242 |
1 files changed, 122 insertions, 120 deletions
diff --git a/Source/WebCore/css/CSSStyleSheet.cpp b/Source/WebCore/css/CSSStyleSheet.cpp index d8229a44a..462b2f43b 100644 --- a/Source/WebCore/css/CSSStyleSheet.cpp +++ b/Source/WebCore/css/CSSStyleSheet.cpp @@ -21,42 +21,43 @@ #include "config.h" #include "CSSStyleSheet.h" -#include "CSSCharsetRule.h" #include "CSSFontFaceRule.h" #include "CSSImportRule.h" +#include "CSSKeyframesRule.h" #include "CSSParser.h" #include "CSSRuleList.h" #include "CSSStyleRule.h" #include "CachedCSSStyleSheet.h" #include "Document.h" -#include "DocumentStyleSheetCollection.h" #include "ExceptionCode.h" -#include "HTMLNames.h" +#include "ExtensionStyleSheets.h" +#include "HTMLLinkElement.h" #include "HTMLStyleElement.h" #include "MediaList.h" #include "Node.h" -#include "SVGNames.h" +#include "SVGStyleElement.h" #include "SecurityOrigin.h" +#include "ShadowRoot.h" #include "StyleResolver.h" #include "StyleRule.h" +#include "StyleScope.h" #include "StyleSheetContents.h" -#include "WebKitCSSKeyframesRule.h" #include <wtf/text/StringBuilder.h> namespace WebCore { -class StyleSheetCSSRuleList : public CSSRuleList { +class StyleSheetCSSRuleList final : public CSSRuleList { public: StyleSheetCSSRuleList(CSSStyleSheet* sheet) : m_styleSheet(sheet) { } private: - virtual void ref() { m_styleSheet->ref(); } - virtual void deref() { m_styleSheet->deref(); } - - virtual unsigned length() const { return m_styleSheet->length(); } - virtual CSSRule* item(unsigned index) const { return m_styleSheet->item(index); } - - virtual CSSStyleSheet* styleSheet() const { return m_styleSheet; } + void ref() final { m_styleSheet->ref(); } + void deref() final { m_styleSheet->deref(); } + + unsigned length() const final { return m_styleSheet->length(); } + CSSRule* item(unsigned index) const final { return m_styleSheet->item(index); } + + CSSStyleSheet* styleSheet() const final { return m_styleSheet; } CSSStyleSheet* m_styleSheet; }; @@ -67,49 +68,51 @@ static bool isAcceptableCSSStyleSheetParent(Node* parentNode) // Only these nodes can be parents of StyleSheets, and they need to call clearOwnerNode() when moved out of document. return !parentNode || parentNode->isDocumentNode() - || parentNode->hasTagName(HTMLNames::linkTag) - || isHTMLStyleElement(parentNode) -#if ENABLE(SVG) - || parentNode->hasTagName(SVGNames::styleTag) -#endif + || is<HTMLLinkElement>(*parentNode) + || is<HTMLStyleElement>(*parentNode) + || is<SVGStyleElement>(*parentNode) || parentNode->nodeType() == Node::PROCESSING_INSTRUCTION_NODE; } #endif -PassRef<CSSStyleSheet> CSSStyleSheet::create(PassRef<StyleSheetContents> sheet, CSSImportRule* ownerRule) -{ - return adoptRef(*new CSSStyleSheet(std::move(sheet), ownerRule)); +Ref<CSSStyleSheet> CSSStyleSheet::create(Ref<StyleSheetContents>&& sheet, CSSImportRule* ownerRule) +{ + return adoptRef(*new CSSStyleSheet(WTFMove(sheet), ownerRule)); } -PassRef<CSSStyleSheet> CSSStyleSheet::create(PassRef<StyleSheetContents> sheet, Node* ownerNode) -{ - return adoptRef(*new CSSStyleSheet(std::move(sheet), ownerNode, false)); +Ref<CSSStyleSheet> CSSStyleSheet::create(Ref<StyleSheetContents>&& sheet, Node& ownerNode, const std::optional<bool>& isCleanOrigin) +{ + return adoptRef(*new CSSStyleSheet(WTFMove(sheet), ownerNode, TextPosition(), false, isCleanOrigin)); } -PassRef<CSSStyleSheet> CSSStyleSheet::createInline(Node& ownerNode, const URL& baseURL, const String& encoding) +Ref<CSSStyleSheet> CSSStyleSheet::createInline(Ref<StyleSheetContents>&& sheet, Element& owner, const TextPosition& startPosition) { - CSSParserContext parserContext(ownerNode.document(), baseURL, encoding); - return adoptRef(*new CSSStyleSheet(StyleSheetContents::create(baseURL.string(), parserContext), &ownerNode, true)); + return adoptRef(*new CSSStyleSheet(WTFMove(sheet), owner, startPosition, true, true)); } -CSSStyleSheet::CSSStyleSheet(PassRef<StyleSheetContents> contents, CSSImportRule* ownerRule) - : m_contents(std::move(contents)) +CSSStyleSheet::CSSStyleSheet(Ref<StyleSheetContents>&& contents, CSSImportRule* ownerRule) + : m_contents(WTFMove(contents)) , m_isInlineStylesheet(false) , m_isDisabled(false) + , m_mutatedRules(false) , m_ownerNode(0) , m_ownerRule(ownerRule) + , m_startPosition() { m_contents->registerClient(this); } -CSSStyleSheet::CSSStyleSheet(PassRef<StyleSheetContents> contents, Node* ownerNode, bool isInlineStylesheet) - : m_contents(std::move(contents)) +CSSStyleSheet::CSSStyleSheet(Ref<StyleSheetContents>&& contents, Node& ownerNode, const TextPosition& startPosition, bool isInlineStylesheet, const std::optional<bool>& isOriginClean) + : m_contents(WTFMove(contents)) , m_isInlineStylesheet(isInlineStylesheet) , m_isDisabled(false) - , m_ownerNode(ownerNode) + , m_mutatedRules(false) + , m_isOriginClean(isOriginClean) + , m_ownerNode(&ownerNode) , m_ownerRule(0) + , m_startPosition(startPosition) { - ASSERT(isAcceptableCSSStyleSheetParent(ownerNode)); + ASSERT(isAcceptableCSSStyleSheetParent(&ownerNode)); m_contents->registerClient(this); } @@ -163,38 +166,36 @@ void CSSStyleSheet::didMutateRules(RuleMutationType mutationType, WhetherContent ASSERT(m_contents->isMutable()); ASSERT(m_contents->hasOneClient()); - Document* owner = ownerDocument(); - if (!owner) + auto* scope = styleScope(); + if (!scope) return; - if (mutationType == RuleInsertion && !contentsWereClonedForMutation && !owner->styleSheetCollection().activeStyleSheetsContains(this)) { + if (mutationType == RuleInsertion && !contentsWereClonedForMutation && !scope->activeStyleSheetsContains(this)) { if (insertedKeyframesRule) { - if (StyleResolver* resolver = owner->styleResolverIfExists()) - resolver->addKeyframeStyle(insertedKeyframesRule); + if (auto* resolver = scope->resolverIfExists()) + resolver->addKeyframeStyle(*insertedKeyframesRule); return; } - owner->scheduleOptimizedStyleSheetUpdate(); + scope->didChangeActiveStyleSheetCandidates(); return; } - owner->styleResolverChanged(DeferRecalcStyle); + scope->didChangeStyleSheetContents(); + + m_mutatedRules = true; } void CSSStyleSheet::didMutate() { - Document* owner = ownerDocument(); - if (!owner) + auto* scope = styleScope(); + if (!scope) return; - owner->styleResolverChanged(DeferRecalcStyle); + scope->didChangeStyleSheetContents(); } void CSSStyleSheet::clearOwnerNode() { - Document* owner = ownerDocument(); - m_ownerNode = 0; - if (!owner) - return; - owner->styleResolverChanged(DeferRecalcStyleIfNeeded); + m_ownerNode = nullptr; } void CSSStyleSheet::reattachChildRuleCSSOMWrappers() @@ -202,7 +203,7 @@ void CSSStyleSheet::reattachChildRuleCSSOMWrappers() for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) { if (!m_childRuleCSSOMWrappers[i]) continue; - m_childRuleCSSOMWrappers[i]->reattach(m_contents->ruleAt(i)); + m_childRuleCSSOMWrappers[i]->reattach(*m_contents->ruleAt(i)); } } @@ -212,19 +213,16 @@ void CSSStyleSheet::setDisabled(bool disabled) return; m_isDisabled = disabled; - didMutate(); + if (auto* scope = styleScope()) + scope->didChangeActiveStyleSheetCandidates(); } -void CSSStyleSheet::setMediaQueries(PassRefPtr<MediaQuerySet> mediaQueries) +void CSSStyleSheet::setMediaQueries(Ref<MediaQuerySet>&& mediaQueries) { - m_mediaQueries = mediaQueries; + m_mediaQueries = WTFMove(mediaQueries); if (m_mediaCSSOMWrapper && m_mediaQueries) m_mediaCSSOMWrapper->reattach(m_mediaQueries.get()); - -#if ENABLE(RESOLUTION_MEDIA_QUERY) - // Add warning message to inspector whenever dpi/dpcm values are used for "screen" media. reportMediaQueryWarningIfNeeded(ownerDocument(), m_mediaQueries.get()); -#endif } unsigned CSSStyleSheet::length() const @@ -243,98 +241,87 @@ CSSRule* CSSStyleSheet::item(unsigned index) ASSERT(m_childRuleCSSOMWrappers.size() == ruleCount); RefPtr<CSSRule>& cssRule = m_childRuleCSSOMWrappers[index]; - if (!cssRule) { - if (index == 0 && m_contents->hasCharsetRule()) { - ASSERT(!m_contents->ruleAt(0)); - cssRule = CSSCharsetRule::create(this, m_contents->encodingFromCharsetRule()); - } else - cssRule = m_contents->ruleAt(index)->createCSSOMWrapper(this); - } + if (!cssRule) + cssRule = m_contents->ruleAt(index)->createCSSOMWrapper(this); return cssRule.get(); } bool CSSStyleSheet::canAccessRules() const { - if (m_isInlineStylesheet) - return true; + if (m_isOriginClean) + return m_isOriginClean.value(); + URL baseURL = m_contents->baseURL(); if (baseURL.isEmpty()) return true; Document* document = ownerDocument(); if (!document) return true; - if (document->securityOrigin()->canRequest(baseURL)) - return true; - return false; + return document->securityOrigin().canRequest(baseURL); } -PassRefPtr<CSSRuleList> CSSStyleSheet::rules() +RefPtr<CSSRuleList> CSSStyleSheet::rules() { if (!canAccessRules()) - return 0; + return nullptr; // IE behavior. - RefPtr<StaticCSSRuleList> nonCharsetRules = StaticCSSRuleList::create(); + RefPtr<StaticCSSRuleList> ruleList = StaticCSSRuleList::create(); unsigned ruleCount = length(); - for (unsigned i = 0; i < ruleCount; ++i) { - CSSRule* rule = item(i); - if (rule->type() == CSSRule::CHARSET_RULE) - continue; - nonCharsetRules->rules().append(rule); - } - return nonCharsetRules.release(); + for (unsigned i = 0; i < ruleCount; ++i) + ruleList->rules().append(item(i)); + return ruleList; +} + +ExceptionOr<unsigned> CSSStyleSheet::deprecatedInsertRule(const String& ruleString) +{ + if (auto* document = ownerDocument()) + document->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, ASCIILiteral("Calling CSSStyleSheet.insertRule() with one argument is deprecated. Please pass the index argument as well: insertRule(x, 0).")); + + return insertRule(ruleString, 0); } -unsigned CSSStyleSheet::insertRule(const String& ruleString, unsigned index, ExceptionCode& ec) +ExceptionOr<unsigned> CSSStyleSheet::insertRule(const String& ruleString, unsigned index) { ASSERT(m_childRuleCSSOMWrappers.isEmpty() || m_childRuleCSSOMWrappers.size() == m_contents->ruleCount()); - ec = 0; - if (index > length()) { - ec = INDEX_SIZE_ERR; - return 0; - } - CSSParser p(m_contents.get().parserContext()); - RefPtr<StyleRuleBase> rule = p.parseRule(&m_contents.get(), ruleString); + if (index > length()) + return Exception { INDEX_SIZE_ERR }; + RefPtr<StyleRuleBase> rule = CSSParser::parseRule(m_contents.get().parserContext(), m_contents.ptr(), ruleString); - if (!rule) { - ec = SYNTAX_ERR; - return 0; - } + if (!rule) + return Exception { SYNTAX_ERR }; - RuleMutationScope mutationScope(this, RuleInsertion, rule->type() == StyleRuleBase::Keyframes ? static_cast<StyleRuleKeyframes*>(rule.get()) : 0); + RuleMutationScope mutationScope(this, RuleInsertion, is<StyleRuleKeyframes>(*rule) ? downcast<StyleRuleKeyframes>(rule.get()) : nullptr); - bool success = m_contents.get().wrapperInsertRule(rule, index); - if (!success) { - ec = HIERARCHY_REQUEST_ERR; - return 0; - } + bool success = m_contents.get().wrapperInsertRule(rule.releaseNonNull(), index); + if (!success) + return Exception { HIERARCHY_REQUEST_ERR }; if (!m_childRuleCSSOMWrappers.isEmpty()) m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>()); return index; } -void CSSStyleSheet::deleteRule(unsigned index, ExceptionCode& ec) +ExceptionOr<void> CSSStyleSheet::deleteRule(unsigned index) { ASSERT(m_childRuleCSSOMWrappers.isEmpty() || m_childRuleCSSOMWrappers.size() == m_contents->ruleCount()); - ec = 0; - if (index >= length()) { - ec = INDEX_SIZE_ERR; - return; - } + if (index >= length()) + return Exception { INDEX_SIZE_ERR }; RuleMutationScope mutationScope(this); m_contents->wrapperDeleteRule(index); if (!m_childRuleCSSOMWrappers.isEmpty()) { if (m_childRuleCSSOMWrappers[index]) - m_childRuleCSSOMWrappers[index]->setParentStyleSheet(0); + m_childRuleCSSOMWrappers[index]->setParentStyleSheet(nullptr); m_childRuleCSSOMWrappers.remove(index); } + + return { }; } -int CSSStyleSheet::addRule(const String& selector, const String& style, int index, ExceptionCode& ec) +ExceptionOr<int> CSSStyleSheet::addRule(const String& selector, const String& style, std::optional<unsigned> index) { StringBuilder text; text.append(selector); @@ -343,22 +330,18 @@ int CSSStyleSheet::addRule(const String& selector, const String& style, int inde if (!style.isEmpty()) text.append(' '); text.append('}'); - insertRule(text.toString(), index, ec); + auto insertRuleResult = insertRule(text.toString(), index.value_or(length())); + if (insertRuleResult.hasException()) + return insertRuleResult.releaseException(); // As per Microsoft documentation, always return -1. return -1; } -int CSSStyleSheet::addRule(const String& selector, const String& style, ExceptionCode& ec) -{ - return addRule(selector, style, length(), ec); -} - - -PassRefPtr<CSSRuleList> CSSStyleSheet::cssRules() +RefPtr<CSSRuleList> CSSStyleSheet::cssRules() { if (!canAccessRules()) - return 0; + return nullptr; if (!m_ruleListCSSOMWrapper) m_ruleListCSSOMWrapper = std::make_unique<StyleSheetCSSRuleList>(this); return m_ruleListCSSOMWrapper.get(); @@ -380,9 +363,9 @@ bool CSSStyleSheet::isLoading() const } MediaList* CSSStyleSheet::media() const -{ +{ if (!m_mediaQueries) - return 0; + return nullptr; if (!m_mediaCSSOMWrapper) m_mediaCSSOMWrapper = MediaList::create(m_mediaQueries.get(), const_cast<CSSStyleSheet*>(this)); @@ -391,15 +374,34 @@ MediaList* CSSStyleSheet::media() const CSSStyleSheet* CSSStyleSheet::parentStyleSheet() const { - return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0; + return m_ownerRule ? m_ownerRule->parentStyleSheet() : nullptr; } -Document* CSSStyleSheet::ownerDocument() const +CSSStyleSheet& CSSStyleSheet::rootStyleSheet() { - const CSSStyleSheet* root = this; + auto* root = this; while (root->parentStyleSheet()) root = root->parentStyleSheet(); - return root->ownerNode() ? &root->ownerNode()->document() : 0; + return *root; +} + +const CSSStyleSheet& CSSStyleSheet::rootStyleSheet() const +{ + return const_cast<CSSStyleSheet&>(*this).rootStyleSheet(); +} + +Document* CSSStyleSheet::ownerDocument() const +{ + auto& root = rootStyleSheet(); + return root.ownerNode() ? &root.ownerNode()->document() : nullptr; +} + +Style::Scope* CSSStyleSheet::styleScope() +{ + auto* ownerNode = rootStyleSheet().ownerNode(); + if (!ownerNode) + return nullptr; + return &Style::Scope::forNode(*ownerNode); } void CSSStyleSheet::clearChildRuleCSSOMWrappers() @@ -417,7 +419,7 @@ CSSStyleSheet::RuleMutationScope::RuleMutationScope(CSSStyleSheet* sheet, RuleMu } CSSStyleSheet::RuleMutationScope::RuleMutationScope(CSSRule* rule) - : m_styleSheet(rule ? rule->parentStyleSheet() : 0) + : m_styleSheet(rule ? rule->parentStyleSheet() : nullptr) , m_mutationType(OtherMutation) , m_contentsWereClonedForMutation(ContentsWereNotClonedForMutation) , m_insertedKeyframesRule(nullptr) |