• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2001 Dirk Mueller (mueller@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 
HTMLScriptElement(const QualifiedName & tagName,Document * document,bool wasInsertedByParser,bool alreadyStarted)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 
create(const QualifiedName & tagName,Document * document,bool wasInsertedByParser)46 PassRefPtr<HTMLScriptElement> HTMLScriptElement::create(const QualifiedName& tagName, Document* document, bool wasInsertedByParser)
47 {
48     return adoptRef(new HTMLScriptElement(tagName, document, wasInsertedByParser, false));
49 }
50 
isURLAttribute(Attribute * attr) const51 bool HTMLScriptElement::isURLAttribute(Attribute* attr) const
52 {
53     return attr->name() == srcAttr;
54 }
55 
childrenChanged(bool changedByParser,Node * beforeChange,Node * afterChange,int childCountDelta)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 
attributeChanged(Attribute * attr,bool preserveDecls)62 void HTMLScriptElement::attributeChanged(Attribute* attr, bool preserveDecls)
63 {
64     if (attr->name() == asyncAttr)
65         handleAsyncAttribute();
66     HTMLElement::attributeChanged(attr, preserveDecls);
67 }
68 
parseMappedAttribute(Attribute * attr)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 
needsOldRequirejsQuirk(HTMLScriptElement * element)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 
insertedIntoDocument()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 
removedFromDocument()116 void HTMLScriptElement::removedFromDocument()
117 {
118     HTMLElement::removedFromDocument();
119     ScriptElement::removedFromDocument();
120 }
121 
setText(const String & value)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 
setAsync(bool async)138 void HTMLScriptElement::setAsync(bool async)
139 {
140     setBooleanAttribute(asyncAttr, async);
141     handleAsyncAttribute();
142 }
143 
async() const144 bool HTMLScriptElement::async() const
145 {
146     return fastHasAttribute(asyncAttr) || forceAsync();
147 }
148 
src() const149 KURL HTMLScriptElement::src() const
150 {
151     return document()->completeURL(sourceAttributeValue());
152 }
153 
addSubresourceAttributeURLs(ListHashSet<KURL> & urls) const154 void HTMLScriptElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
155 {
156     HTMLElement::addSubresourceAttributeURLs(urls);
157 
158     addSubresourceURL(urls, src());
159 }
160 
sourceAttributeValue() const161 String HTMLScriptElement::sourceAttributeValue() const
162 {
163     return getAttribute(srcAttr).string();
164 }
165 
charsetAttributeValue() const166 String HTMLScriptElement::charsetAttributeValue() const
167 {
168     return getAttribute(charsetAttr).string();
169 }
170 
typeAttributeValue() const171 String HTMLScriptElement::typeAttributeValue() const
172 {
173     return getAttribute(typeAttr).string();
174 }
175 
languageAttributeValue() const176 String HTMLScriptElement::languageAttributeValue() const
177 {
178     return getAttribute(languageAttr).string();
179 }
180 
forAttributeValue() const181 String HTMLScriptElement::forAttributeValue() const
182 {
183     return getAttribute(forAttr).string();
184 }
185 
eventAttributeValue() const186 String HTMLScriptElement::eventAttributeValue() const
187 {
188     return getAttribute(eventAttr).string();
189 }
190 
asyncAttributeValue() const191 bool HTMLScriptElement::asyncAttributeValue() const
192 {
193     return fastHasAttribute(asyncAttr);
194 }
195 
deferAttributeValue() const196 bool HTMLScriptElement::deferAttributeValue() const
197 {
198     return fastHasAttribute(deferAttr);
199 }
200 
hasSourceAttribute() const201 bool HTMLScriptElement::hasSourceAttribute() const
202 {
203     return fastHasAttribute(srcAttr);
204 }
205 
dispatchLoadEvent()206 void HTMLScriptElement::dispatchLoadEvent()
207 {
208     ASSERT(!haveFiredLoadEvent());
209     setHaveFiredLoadEvent(true);
210 
211     dispatchEvent(Event::create(eventNames().loadEvent, false, false));
212 }
213 
dispatchErrorEvent()214 void HTMLScriptElement::dispatchErrorEvent()
215 {
216     dispatchEvent(Event::create(eventNames().errorEvent, true, false));
217 }
218 
cloneElementWithoutAttributesAndChildren() const219 PassRefPtr<Element> HTMLScriptElement::cloneElementWithoutAttributesAndChildren() const
220 {
221     return adoptRef(new HTMLScriptElement(tagQName(), document(), false, alreadyStarted()));
222 }
223 
224 }
225