Home | History | Annotate | Download | only in html
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      4  *           (C) 2001 Dirk Mueller (mueller (at) kde.org)
      5  * Copyright (C) 2003, 2010 Apple Inc. All rights reserved.
      6  *           (C) 2007 Rob Buis (buis (at) kde.org)
      7  *
      8  * This library is free software; you can redistribute it and/or
      9  * modify it under the terms of the GNU Library General Public
     10  * License as published by the Free Software Foundation; either
     11  * version 2 of the License, or (at your option) any later version.
     12  *
     13  * This library is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16  * Library General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU Library General Public License
     19  * along with this library; see the file COPYING.LIB.  If not, write to
     20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     21  * Boston, MA 02110-1301, USA.
     22  */
     23 
     24 #include "config.h"
     25 #include "core/html/HTMLStyleElement.h"
     26 
     27 #include "core/HTMLNames.h"
     28 #include "core/css/MediaList.h"
     29 #include "core/css/StyleSheetContents.h"
     30 #include "core/dom/ContextFeatures.h"
     31 #include "core/dom/Document.h"
     32 #include "core/events/Event.h"
     33 #include "core/events/EventSender.h"
     34 #include "core/dom/StyleEngine.h"
     35 #include "core/dom/shadow/ShadowRoot.h"
     36 
     37 namespace WebCore {
     38 
     39 using namespace HTMLNames;
     40 
     41 static StyleEventSender& styleLoadEventSender()
     42 {
     43     DEFINE_STATIC_LOCAL(StyleEventSender, sharedLoadEventSender, (EventTypeNames::load));
     44     return sharedLoadEventSender;
     45 }
     46 
     47 inline HTMLStyleElement::HTMLStyleElement(Document& document, bool createdByParser)
     48     : HTMLElement(styleTag, document)
     49     , StyleElement(&document, createdByParser)
     50     , m_firedLoad(false)
     51     , m_loadedSheet(false)
     52 {
     53     ScriptWrappable::init(this);
     54 }
     55 
     56 HTMLStyleElement::~HTMLStyleElement()
     57 {
     58 #if !ENABLE(OILPAN)
     59     StyleElement::clearDocumentData(document(), this);
     60 #endif
     61 
     62     styleLoadEventSender().cancelEvent(this);
     63 }
     64 
     65 PassRefPtrWillBeRawPtr<HTMLStyleElement> HTMLStyleElement::create(Document& document, bool createdByParser)
     66 {
     67     return adoptRefWillBeNoop(new HTMLStyleElement(document, createdByParser));
     68 }
     69 
     70 void HTMLStyleElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
     71 {
     72     if (name == titleAttr && m_sheet) {
     73         m_sheet->setTitle(value);
     74     } else if (name == mediaAttr && inDocument() && document().isActive() && m_sheet) {
     75         m_sheet->setMediaQueries(MediaQuerySet::create(value));
     76         document().modifiedStyleSheet(m_sheet.get());
     77     } else {
     78         HTMLElement::parseAttribute(name, value);
     79     }
     80 }
     81 
     82 void HTMLStyleElement::finishParsingChildren()
     83 {
     84     StyleElement::finishParsingChildren(this);
     85     HTMLElement::finishParsingChildren();
     86 }
     87 
     88 Node::InsertionNotificationRequest HTMLStyleElement::insertedInto(ContainerNode* insertionPoint)
     89 {
     90     HTMLElement::insertedInto(insertionPoint);
     91     if (insertionPoint->inDocument() && isInShadowTree()) {
     92         if (ShadowRoot* scope = containingShadowRoot())
     93             scope->registerScopedHTMLStyleChild();
     94     }
     95     return InsertionShouldCallDidNotifySubtreeInsertions;
     96 }
     97 
     98 void HTMLStyleElement::removedFrom(ContainerNode* insertionPoint)
     99 {
    100     HTMLElement::removedFrom(insertionPoint);
    101 
    102     if (!insertionPoint->inDocument())
    103         return;
    104 
    105     ShadowRoot* scopingNode = containingShadowRoot();
    106     if (!scopingNode)
    107         scopingNode = insertionPoint->containingShadowRoot();
    108 
    109     if (scopingNode)
    110         scopingNode->unregisterScopedHTMLStyleChild();
    111 
    112     TreeScope* containingScope = containingShadowRoot();
    113     StyleElement::removedFromDocument(document(), this, scopingNode, containingScope ? *containingScope : insertionPoint->treeScope());
    114 }
    115 
    116 void HTMLStyleElement::didNotifySubtreeInsertionsToDocument()
    117 {
    118     StyleElement::processStyleSheet(document(), this);
    119 }
    120 
    121 void HTMLStyleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
    122 {
    123     HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
    124     StyleElement::childrenChanged(this);
    125 }
    126 
    127 const AtomicString& HTMLStyleElement::media() const
    128 {
    129     return getAttribute(mediaAttr);
    130 }
    131 
    132 const AtomicString& HTMLStyleElement::type() const
    133 {
    134     return getAttribute(typeAttr);
    135 }
    136 
    137 ContainerNode* HTMLStyleElement::scopingNode()
    138 {
    139     if (!inDocument())
    140         return 0;
    141 
    142     if (isInShadowTree())
    143         return containingShadowRoot();
    144 
    145     return &document();
    146 }
    147 
    148 void HTMLStyleElement::dispatchPendingLoadEvents()
    149 {
    150     styleLoadEventSender().dispatchPendingEvents();
    151 }
    152 
    153 void HTMLStyleElement::dispatchPendingEvent(StyleEventSender* eventSender)
    154 {
    155     ASSERT_UNUSED(eventSender, eventSender == &styleLoadEventSender());
    156     dispatchEvent(Event::create(m_loadedSheet ? EventTypeNames::load : EventTypeNames::error));
    157 }
    158 
    159 void HTMLStyleElement::notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred)
    160 {
    161     if (m_firedLoad)
    162         return;
    163     m_loadedSheet = !errorOccurred;
    164     styleLoadEventSender().dispatchEventSoon(this);
    165     m_firedLoad = true;
    166 }
    167 
    168 bool HTMLStyleElement::disabled() const
    169 {
    170     if (!m_sheet)
    171         return false;
    172 
    173     return m_sheet->disabled();
    174 }
    175 
    176 void HTMLStyleElement::setDisabled(bool setDisabled)
    177 {
    178     if (CSSStyleSheet* styleSheet = sheet())
    179         styleSheet->setDisabled(setDisabled);
    180 }
    181 
    182 void HTMLStyleElement::trace(Visitor* visitor)
    183 {
    184     StyleElement::trace(visitor);
    185     HTMLElement::trace(visitor);
    186 }
    187 
    188 }
    189