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, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
      6  *
      7  * This library is free software; you can redistribute it and/or
      8  * modify it under the terms of the GNU Library General Public
      9  * License as published by the Free Software Foundation; either
     10  * version 2 of the License, or (at your option) any later version.
     11  *
     12  * This library is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  * Library General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU Library General Public License
     18  * along with this library; see the file COPYING.LIB.  If not, write to
     19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     20  * Boston, MA 02110-1301, USA.
     21  */
     22 
     23 #include "config.h"
     24 #include "HTMLScriptElement.h"
     25 
     26 #include "Attribute.h"
     27 #include "Document.h"
     28 #include "Event.h"
     29 #include "EventNames.h"
     30 #include "HTMLNames.h"
     31 #include "ScriptEventListener.h"
     32 #include "Settings.h"
     33 #include "Text.h"
     34 
     35 namespace WebCore {
     36 
     37 using namespace HTMLNames;
     38 
     39 inline HTMLScriptElement::HTMLScriptElement(const QualifiedName& tagName, Document* document, bool wasInsertedByParser, bool alreadyStarted)
     40     : HTMLElement(tagName, document)
     41     , ScriptElement(this, wasInsertedByParser, alreadyStarted)
     42 {
     43     ASSERT(hasTagName(scriptTag));
     44 }
     45 
     46 PassRefPtr<HTMLScriptElement> HTMLScriptElement::create(const QualifiedName& tagName, Document* document, bool wasInsertedByParser)
     47 {
     48     return adoptRef(new HTMLScriptElement(tagName, document, wasInsertedByParser, false));
     49 }
     50 
     51 bool HTMLScriptElement::isURLAttribute(Attribute* attr) const
     52 {
     53     return attr->name() == srcAttr;
     54 }
     55 
     56 void HTMLScriptElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
     57 {
     58     ScriptElement::childrenChanged();
     59     HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
     60 }
     61 
     62 void HTMLScriptElement::attributeChanged(Attribute* attr, bool preserveDecls)
     63 {
     64     if (attr->name() == asyncAttr)
     65         handleAsyncAttribute();
     66     HTMLElement::attributeChanged(attr, preserveDecls);
     67 }
     68 
     69 void HTMLScriptElement::parseMappedAttribute(Attribute* attr)
     70 {
     71     const QualifiedName& attrName = attr->name();
     72 
     73     if (attrName == srcAttr)
     74         handleSourceAttribute(attr->value());
     75     else if (attrName == onloadAttr)
     76         setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attr));
     77     else if (attrName == onbeforeloadAttr)
     78         setAttributeEventListener(eventNames().beforeloadEvent, createAttributeEventListener(this, attr));
     79     else if (attrName == onbeforeprocessAttr)
     80         setAttributeEventListener(eventNames().beforeprocessEvent, createAttributeEventListener(this, attr));
     81     else
     82         HTMLElement::parseMappedAttribute(attr);
     83 }
     84 
     85 static bool needsOldRequirejsQuirk(HTMLScriptElement* element)
     86 {
     87     if (element->fastGetAttribute(typeAttr) != "script/cache")
     88         return false;
     89 
     90     Document* document = element->document();
     91 
     92     const KURL& url = document->url();
     93     if (!equalIgnoringCase(url.host(), "www.zipcar.com"))
     94         return false;
     95 
     96     Settings* settings = document->settings();
     97     if (!settings)
     98         return false;
     99     if (!settings->needsSiteSpecificQuirks())
    100         return false;
    101 
    102     return true;
    103 }
    104 
    105 void HTMLScriptElement::insertedIntoDocument()
    106 {
    107     if (needsOldRequirejsQuirk(this)) {
    108         if (!asyncAttributeValue())
    109             handleAsyncAttribute(); // Clear forceAsync, so this script loads in parallel, but executes in order.
    110         setAttribute(typeAttr, "text/javascript");
    111     }
    112     HTMLElement::insertedIntoDocument();
    113     ScriptElement::insertedIntoDocument();
    114 }
    115 
    116 void HTMLScriptElement::removedFromDocument()
    117 {
    118     HTMLElement::removedFromDocument();
    119     ScriptElement::removedFromDocument();
    120 }
    121 
    122 void HTMLScriptElement::setText(const String &value)
    123 {
    124     ExceptionCode ec = 0;
    125     int numChildren = childNodeCount();
    126 
    127     if (numChildren == 1 && firstChild()->isTextNode()) {
    128         static_cast<Text*>(firstChild())->setData(value, ec);
    129         return;
    130     }
    131 
    132     if (numChildren > 0)
    133         removeChildren();
    134 
    135     appendChild(document()->createTextNode(value.impl()), ec);
    136 }
    137 
    138 void HTMLScriptElement::setAsync(bool async)
    139 {
    140     setBooleanAttribute(asyncAttr, async);
    141     handleAsyncAttribute();
    142 }
    143 
    144 bool HTMLScriptElement::async() const
    145 {
    146     return fastHasAttribute(asyncAttr) || forceAsync();
    147 }
    148 
    149 KURL HTMLScriptElement::src() const
    150 {
    151     return document()->completeURL(sourceAttributeValue());
    152 }
    153 
    154 void HTMLScriptElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
    155 {
    156     HTMLElement::addSubresourceAttributeURLs(urls);
    157 
    158     addSubresourceURL(urls, src());
    159 }
    160 
    161 String HTMLScriptElement::sourceAttributeValue() const
    162 {
    163     return getAttribute(srcAttr).string();
    164 }
    165 
    166 String HTMLScriptElement::charsetAttributeValue() const
    167 {
    168     return getAttribute(charsetAttr).string();
    169 }
    170 
    171 String HTMLScriptElement::typeAttributeValue() const
    172 {
    173     return getAttribute(typeAttr).string();
    174 }
    175 
    176 String HTMLScriptElement::languageAttributeValue() const
    177 {
    178     return getAttribute(languageAttr).string();
    179 }
    180 
    181 String HTMLScriptElement::forAttributeValue() const
    182 {
    183     return getAttribute(forAttr).string();
    184 }
    185 
    186 String HTMLScriptElement::eventAttributeValue() const
    187 {
    188     return getAttribute(eventAttr).string();
    189 }
    190 
    191 bool HTMLScriptElement::asyncAttributeValue() const
    192 {
    193     return fastHasAttribute(asyncAttr);
    194 }
    195 
    196 bool HTMLScriptElement::deferAttributeValue() const
    197 {
    198     return fastHasAttribute(deferAttr);
    199 }
    200 
    201 bool HTMLScriptElement::hasSourceAttribute() const
    202 {
    203     return fastHasAttribute(srcAttr);
    204 }
    205 
    206 void HTMLScriptElement::dispatchLoadEvent()
    207 {
    208     ASSERT(!haveFiredLoadEvent());
    209     setHaveFiredLoadEvent(true);
    210 
    211     dispatchEvent(Event::create(eventNames().loadEvent, false, false));
    212 }
    213 
    214 void HTMLScriptElement::dispatchErrorEvent()
    215 {
    216     dispatchEvent(Event::create(eventNames().errorEvent, true, false));
    217 }
    218 
    219 PassRefPtr<Element> HTMLScriptElement::cloneElementWithoutAttributesAndChildren() const
    220 {
    221     return adoptRef(new HTMLScriptElement(tagQName(), document(), false, alreadyStarted()));
    222 }
    223 
    224 }
    225