summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/HTMLStyleElement.cpp
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-05-30 12:48:17 +0200
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-05-30 12:48:17 +0200
commit881da28418d380042aa95a97f0cbd42560a64f7c (patch)
treea794dff3274695e99c651902dde93d934ea7a5af /Source/WebCore/html/HTMLStyleElement.cpp
parent7e104c57a70fdf551bb3d22a5d637cdcbc69dbea (diff)
parent0fcedcd17cc00d3dd44c718b3cb36c1033319671 (diff)
downloadqtwebkit-881da28418d380042aa95a97f0cbd42560a64f7c.tar.gz
Merge 'wip/next' into dev
Change-Id: Iff9ee5e23bb326c4371ec8ed81d56f2f05d680e9
Diffstat (limited to 'Source/WebCore/html/HTMLStyleElement.cpp')
-rw-r--r--Source/WebCore/html/HTMLStyleElement.cpp200
1 files changed, 36 insertions, 164 deletions
diff --git a/Source/WebCore/html/HTMLStyleElement.cpp b/Source/WebCore/html/HTMLStyleElement.cpp
index e2d04841c..51c6f6ae2 100644
--- a/Source/WebCore/html/HTMLStyleElement.cpp
+++ b/Source/WebCore/html/HTMLStyleElement.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2010, 2013 Apple Inc. All rights reserved.
* (C) 2007 Rob Buis (buis@kde.org)
*
* This library is free software; you can redistribute it and/or
@@ -24,14 +24,12 @@
#include "config.h"
#include "HTMLStyleElement.h"
-#include "Attribute.h"
-#include "ContextFeatures.h"
#include "Document.h"
#include "Event.h"
#include "EventSender.h"
#include "HTMLNames.h"
#include "MediaList.h"
-#include "ScriptEventListener.h"
+#include "RuntimeEnabledFeatures.h"
#include "ScriptableDocumentParser.h"
#include "ShadowRoot.h"
#include "StyleSheetContents.h"
@@ -42,16 +40,15 @@ using namespace HTMLNames;
static StyleEventSender& styleLoadEventSender()
{
- DEFINE_STATIC_LOCAL(StyleEventSender, sharedLoadEventSender, (eventNames().loadEvent));
+ static NeverDestroyed<StyleEventSender> sharedLoadEventSender(eventNames().loadEvent);
return sharedLoadEventSender;
}
-inline HTMLStyleElement::HTMLStyleElement(const QualifiedName& tagName, Document* document, bool createdByParser)
+inline HTMLStyleElement::HTMLStyleElement(const QualifiedName& tagName, Document& document, bool createdByParser)
: HTMLElement(tagName, document)
- , StyleElement(document, createdByParser)
+ , m_styleSheetOwner(document, createdByParser)
, m_firedLoad(false)
, m_loadedSheet(false)
- , m_scopedStyleRegistrationState(NotRegistered)
{
ASSERT(hasTagName(styleTag));
}
@@ -60,185 +57,60 @@ HTMLStyleElement::~HTMLStyleElement()
{
// During tear-down, willRemove isn't called, so m_scopedStyleRegistrationState may still be RegisteredAsScoped or RegisteredInShadowRoot here.
// Therefore we can't ASSERT(m_scopedStyleRegistrationState == NotRegistered).
- StyleElement::clearDocumentData(document(), this);
+ m_styleSheetOwner.clearDocumentData(document(), *this);
- styleLoadEventSender().cancelEvent(this);
+ styleLoadEventSender().cancelEvent(*this);
}
-PassRefPtr<HTMLStyleElement> HTMLStyleElement::create(const QualifiedName& tagName, Document* document, bool createdByParser)
+Ref<HTMLStyleElement> HTMLStyleElement::create(const QualifiedName& tagName, Document& document, bool createdByParser)
{
- return adoptRef(new HTMLStyleElement(tagName, document, createdByParser));
+ return adoptRef(*new HTMLStyleElement(tagName, document, createdByParser));
}
void HTMLStyleElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- if (name == titleAttr && m_sheet)
- m_sheet->setTitle(value);
- else if (name == scopedAttr && ContextFeatures::styleScopedEnabled(document()))
- scopedAttributeChanged(!value.isNull());
- else if (name == mediaAttr && inDocument() && document()->renderer() && m_sheet) {
- m_sheet->setMediaQueries(MediaQuerySet::createAllowingDescriptionSyntax(value));
- document()->styleResolverChanged(RecalcStyleImmediately);
- } else
+ if (name == titleAttr && sheet())
+ sheet()->setTitle(value);
+ else if (name == mediaAttr) {
+ m_styleSheetOwner.setMedia(value);
+ if (sheet()) {
+ sheet()->setMediaQueries(MediaQuerySet::createAllowingDescriptionSyntax(value));
+ if (inDocument() && document().hasLivingRenderTree())
+ document().styleResolverChanged(RecalcStyleImmediately);
+ }
+ } else if (name == typeAttr)
+ m_styleSheetOwner.setContentType(value);
+ else
HTMLElement::parseAttribute(name, value);
}
-void HTMLStyleElement::scopedAttributeChanged(bool scoped)
-{
- ASSERT(ContextFeatures::styleScopedEnabled(document()));
-
- if (!inDocument())
- return;
-
- if (scoped) {
- // As any <style> in a shadow tree is treated as "scoped",
- // need to remove the <style> from its shadow root.
- if (m_scopedStyleRegistrationState == RegisteredInShadowRoot)
- unregisterWithScopingNode(containingShadowRoot());
-
- if (m_scopedStyleRegistrationState != RegisteredAsScoped)
- registerWithScopingNode(true);
- return;
- }
-
- // If the <style> was scoped, need to remove the <style> from the scoping
- // element, i.e. the parent node.
- if (m_scopedStyleRegistrationState == RegisteredAsScoped)
- unregisterWithScopingNode(parentNode());
-
- // As any <style> in a shadow tree is treated as "scoped",
- // need to add the <style> to its shadow root.
- if (isInShadowTree() && m_scopedStyleRegistrationState != RegisteredInShadowRoot)
- registerWithScopingNode(false);
-}
-
void HTMLStyleElement::finishParsingChildren()
{
- StyleElement::finishParsingChildren(this);
+ m_styleSheetOwner.finishParsingChildren(*this);
HTMLElement::finishParsingChildren();
}
-void HTMLStyleElement::registerWithScopingNode(bool scoped)
-{
- // Note: We cannot rely on the 'scoped' element already being present when this method is invoked.
- // Therefore we cannot rely on scoped()!
- ASSERT(m_scopedStyleRegistrationState == NotRegistered);
- ASSERT(inDocument());
- if (m_scopedStyleRegistrationState != NotRegistered)
- return;
-
- ContainerNode* scope = scoped ? parentNode() : containingShadowRoot();
- if (!scope)
- return;
- if (!scope->isElementNode() && !scope->isShadowRoot()) {
- // DocumentFragment nodes should never be inDocument,
- // <style> should not be a child of Document, PI or some such.
- ASSERT_NOT_REACHED();
- return;
- }
- scope->registerScopedHTMLStyleChild();
- if (scope->isShadowRoot())
- scope->shadowHost()->setNeedsStyleRecalc();
- else
- scope->setNeedsStyleRecalc();
- if (inDocument() && !document()->parsing() && document()->renderer())
- document()->styleResolverChanged(DeferRecalcStyle);
-
- m_scopedStyleRegistrationState = scoped ? RegisteredAsScoped : RegisteredInShadowRoot;
-}
-
-void HTMLStyleElement::unregisterWithScopingNode(ContainerNode* scope)
-{
- ASSERT(m_scopedStyleRegistrationState != NotRegistered || !ContextFeatures::styleScopedEnabled(document()));
- if (!isRegisteredAsScoped())
- return;
-
- ASSERT(scope);
- if (scope) {
- ASSERT(scope->hasScopedHTMLStyleChild());
- scope->unregisterScopedHTMLStyleChild();
- scope->setNeedsStyleRecalc();
- }
- if (inDocument() && !document()->parsing() && document()->renderer())
- document()->styleResolverChanged(DeferRecalcStyle);
-
- m_scopedStyleRegistrationState = NotRegistered;
-}
-
-Node::InsertionNotificationRequest HTMLStyleElement::insertedInto(ContainerNode* insertionPoint)
+Node::InsertionNotificationRequest HTMLStyleElement::insertedInto(ContainerNode& insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
- if (insertionPoint->inDocument()) {
- StyleElement::insertedIntoDocument(document(), this);
- if (m_scopedStyleRegistrationState == NotRegistered && (scoped() || isInShadowTree()))
- registerWithScopingNode(scoped());
- }
+ if (insertionPoint.inDocument())
+ m_styleSheetOwner.insertedIntoDocument(document(), *this);
return InsertionDone;
}
-void HTMLStyleElement::removedFrom(ContainerNode* insertionPoint)
+void HTMLStyleElement::removedFrom(ContainerNode& insertionPoint)
{
HTMLElement::removedFrom(insertionPoint);
- // In the current implementation, <style scoped> is only registered if the node is in the document.
- // That is, because willRemove() is also called if an ancestor is removed from the document.
- // Now, if we want to register <style scoped> even if it's not inDocument,
- // we'd need to find a way to discern whether that is the case, or whether <style scoped> itself is about to be removed.
- if (m_scopedStyleRegistrationState != NotRegistered) {
- ContainerNode* scope;
- if (m_scopedStyleRegistrationState == RegisteredInShadowRoot) {
- scope = containingShadowRoot();
- if (!scope)
- scope = insertionPoint->containingShadowRoot();
- } else
- scope = parentNode() ? parentNode() : insertionPoint;
- unregisterWithScopingNode(scope);
- }
-
- if (insertionPoint->inDocument())
- StyleElement::removedFromDocument(document(), this);
-}
-
-void HTMLStyleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
-{
- HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- StyleElement::childrenChanged(this);
-}
-
-const AtomicString& HTMLStyleElement::media() const
-{
- return getAttribute(mediaAttr);
-}
-
-const AtomicString& HTMLStyleElement::type() const
-{
- return getAttribute(typeAttr);
-}
-
-bool HTMLStyleElement::scoped() const
-{
- return fastHasAttribute(scopedAttr) && ContextFeatures::styleScopedEnabled(document());
+ if (insertionPoint.inDocument())
+ m_styleSheetOwner.removedFromDocument(document(), *this);
}
-void HTMLStyleElement::setScoped(bool scopedValue)
+void HTMLStyleElement::childrenChanged(const ChildChange& change)
{
- setBooleanAttribute(scopedAttr, scopedValue);
-}
-
-Element* HTMLStyleElement::scopingElement() const
-{
- if (!scoped())
- return 0;
-
- // FIXME: This probably needs to be refined for scoped stylesheets within shadow DOM.
- // As written, such a stylesheet could style the host element, as well as children of the host.
- // OTOH, this paves the way for a :bound-element implementation.
- ContainerNode* parentOrShadowHost = parentOrShadowHostNode();
- if (!parentOrShadowHost || !parentOrShadowHost->isElementNode())
- return 0;
-
- return toElement(parentOrShadowHost);
+ HTMLElement::childrenChanged(change);
+ m_styleSheetOwner.childrenChanged(*this);
}
void HTMLStyleElement::dispatchPendingLoadEvents()
@@ -260,24 +132,24 @@ void HTMLStyleElement::notifyLoadedSheetAndAllCriticalSubresources(bool errorOcc
if (m_firedLoad)
return;
m_loadedSheet = !errorOccurred;
- styleLoadEventSender().dispatchEventSoon(this);
+ styleLoadEventSender().dispatchEventSoon(*this);
m_firedLoad = true;
}
-void HTMLStyleElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+void HTMLStyleElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const
{
HTMLElement::addSubresourceAttributeURLs(urls);
if (CSSStyleSheet* styleSheet = const_cast<HTMLStyleElement*>(this)->sheet())
- styleSheet->contents()->addSubresourceStyleURLs(urls);
+ styleSheet->contents().addSubresourceStyleURLs(urls);
}
bool HTMLStyleElement::disabled() const
{
- if (!m_sheet)
+ if (!sheet())
return false;
- return m_sheet->disabled();
+ return sheet()->disabled();
}
void HTMLStyleElement::setDisabled(bool setDisabled)