diff options
author | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-05-30 12:48:17 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-05-30 12:48:17 +0200 |
commit | 881da28418d380042aa95a97f0cbd42560a64f7c (patch) | |
tree | a794dff3274695e99c651902dde93d934ea7a5af /Source/WebCore/html/HTMLStyleElement.cpp | |
parent | 7e104c57a70fdf551bb3d22a5d637cdcbc69dbea (diff) | |
parent | 0fcedcd17cc00d3dd44c718b3cb36c1033319671 (diff) | |
download | qtwebkit-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.cpp | 200 |
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) |