| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
| 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserv
ed. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserv
ed. |
| 6 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> | 6 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| 11 * version 2 of the License, or (at your option) any later version. | 11 * version 2 of the License, or (at your option) any later version. |
| 12 * | 12 * |
| 13 * This library is distributed in the hope that it will be useful, | 13 * This library is distributed in the hope that it will be useful, |
| 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 16 * Library General Public License for more details. | 16 * Library General Public License for more details. |
| 17 * | 17 * |
| 18 * You should have received a copy of the GNU Library General Public License | 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 | 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, | 20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 21 * Boston, MA 02110-1301, USA. | 21 * Boston, MA 02110-1301, USA. |
| 22 */ | 22 */ |
| 23 | 23 |
| 24 #include "config.h" | 24 #include "config.h" |
| 25 #include "core/dom/ScriptElement.h" | 25 #include "core/dom/ScriptLoader.h" |
| 26 | 26 |
| 27 #include "HTMLNames.h" | 27 #include "HTMLNames.h" |
| 28 #include "SVGNames.h" | 28 #include "SVGNames.h" |
| 29 #include "bindings/v8/ScriptController.h" | 29 #include "bindings/v8/ScriptController.h" |
| 30 #include "bindings/v8/ScriptSourceCode.h" | 30 #include "bindings/v8/ScriptSourceCode.h" |
| 31 #include "core/dom/Document.h" | 31 #include "core/dom/Document.h" |
| 32 #include "core/dom/Event.h" | 32 #include "core/dom/Event.h" |
| 33 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" | 33 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" |
| 34 #include "core/dom/ScriptLoaderClient.h" |
| 34 #include "core/dom/ScriptRunner.h" | 35 #include "core/dom/ScriptRunner.h" |
| 35 #include "core/dom/ScriptableDocumentParser.h" | 36 #include "core/dom/ScriptableDocumentParser.h" |
| 36 #include "core/dom/Text.h" | 37 #include "core/dom/Text.h" |
| 37 #include "core/html/HTMLScriptElement.h" | 38 #include "core/html/HTMLScriptElement.h" |
| 38 #include "core/html/parser/HTMLParserIdioms.h" | 39 #include "core/html/parser/HTMLParserIdioms.h" |
| 39 #include "core/loader/cache/CachedResourceLoader.h" | 40 #include "core/loader/cache/CachedResourceLoader.h" |
| 40 #include "core/loader/cache/CachedResourceRequest.h" | 41 #include "core/loader/cache/CachedResourceRequest.h" |
| 41 #include "core/loader/cache/CachedScript.h" | 42 #include "core/loader/cache/CachedScript.h" |
| 42 #include "core/page/ContentSecurityPolicy.h" | 43 #include "core/page/ContentSecurityPolicy.h" |
| 43 #include "core/page/Frame.h" | 44 #include "core/page/Frame.h" |
| 44 #include "core/platform/MIMETypeRegistry.h" | 45 #include "core/platform/MIMETypeRegistry.h" |
| 45 #include "core/svg/SVGScriptElement.h" | 46 #include "core/svg/SVGScriptElement.h" |
| 46 #include "weborigin/SecurityOrigin.h" | 47 #include "weborigin/SecurityOrigin.h" |
| 47 #include "wtf/StdLibExtras.h" | 48 #include "wtf/StdLibExtras.h" |
| 48 #include "wtf/text/StringBuilder.h" | 49 #include "wtf/text/StringBuilder.h" |
| 49 #include "wtf/text/StringHash.h" | 50 #include "wtf/text/StringHash.h" |
| 50 #include "wtf/text/TextPosition.h" | 51 #include "wtf/text/TextPosition.h" |
| 51 | 52 |
| 52 namespace WebCore { | 53 namespace WebCore { |
| 53 | 54 |
| 54 ScriptElement::ScriptElement(Element* element, bool parserInserted, bool already
Started) | 55 ScriptLoader::ScriptLoader(Element* element, bool parserInserted, bool alreadySt
arted) |
| 55 : m_element(element) | 56 : m_element(element) |
| 56 , m_cachedScript(0) | 57 , m_cachedScript(0) |
| 57 , m_startLineNumber(WTF::OrdinalNumber::beforeFirst()) | 58 , m_startLineNumber(WTF::OrdinalNumber::beforeFirst()) |
| 58 , m_parserInserted(parserInserted) | 59 , m_parserInserted(parserInserted) |
| 59 , m_isExternalScript(false) | 60 , m_isExternalScript(false) |
| 60 , m_alreadyStarted(alreadyStarted) | 61 , m_alreadyStarted(alreadyStarted) |
| 61 , m_haveFiredLoad(false) | 62 , m_haveFiredLoad(false) |
| 62 , m_willBeParserExecuted(false) | 63 , m_willBeParserExecuted(false) |
| 63 , m_readyToBeParserExecuted(false) | 64 , m_readyToBeParserExecuted(false) |
| 64 , m_willExecuteWhenDocumentFinishedParsing(false) | 65 , m_willExecuteWhenDocumentFinishedParsing(false) |
| 65 , m_forceAsync(!parserInserted) | 66 , m_forceAsync(!parserInserted) |
| 66 , m_willExecuteInOrder(false) | 67 , m_willExecuteInOrder(false) |
| 67 { | 68 { |
| 68 ASSERT(m_element); | 69 ASSERT(m_element); |
| 69 if (parserInserted && element->document()->scriptableDocumentParser() && !el
ement->document()->isInDocumentWrite()) | 70 if (parserInserted && element->document()->scriptableDocumentParser() && !el
ement->document()->isInDocumentWrite()) |
| 70 m_startLineNumber = element->document()->scriptableDocumentParser()->lin
eNumber(); | 71 m_startLineNumber = element->document()->scriptableDocumentParser()->lin
eNumber(); |
| 71 } | 72 } |
| 72 | 73 |
| 73 ScriptElement::~ScriptElement() | 74 ScriptLoader::~ScriptLoader() |
| 74 { | 75 { |
| 75 stopLoadRequest(); | 76 stopLoadRequest(); |
| 76 } | 77 } |
| 77 | 78 |
| 78 void ScriptElement::insertedInto(ContainerNode* insertionPoint) | 79 void ScriptLoader::insertedInto(ContainerNode* insertionPoint) |
| 79 { | 80 { |
| 80 if (insertionPoint->inDocument() && !m_parserInserted) | 81 if (insertionPoint->inDocument() && !m_parserInserted) |
| 81 prepareScript(); // FIXME: Provide a real starting line number here. | 82 prepareScript(); // FIXME: Provide a real starting line number here. |
| 82 } | 83 } |
| 83 | 84 |
| 84 void ScriptElement::childrenChanged() | 85 void ScriptLoader::childrenChanged() |
| 85 { | 86 { |
| 86 if (!m_parserInserted && m_element->inDocument()) | 87 if (!m_parserInserted && m_element->inDocument()) |
| 87 prepareScript(); // FIXME: Provide a real starting line number here. | 88 prepareScript(); // FIXME: Provide a real starting line number here. |
| 88 } | 89 } |
| 89 | 90 |
| 90 void ScriptElement::handleSourceAttribute(const String& sourceUrl) | 91 void ScriptLoader::handleSourceAttribute(const String& sourceUrl) |
| 91 { | 92 { |
| 92 if (ignoresLoadRequest() || sourceUrl.isEmpty()) | 93 if (ignoresLoadRequest() || sourceUrl.isEmpty()) |
| 93 return; | 94 return; |
| 94 | 95 |
| 95 prepareScript(); // FIXME: Provide a real starting line number here. | 96 prepareScript(); // FIXME: Provide a real starting line number here. |
| 96 } | 97 } |
| 97 | 98 |
| 98 void ScriptElement::handleAsyncAttribute() | 99 void ScriptLoader::handleAsyncAttribute() |
| 99 { | 100 { |
| 100 m_forceAsync = false; | 101 m_forceAsync = false; |
| 101 } | 102 } |
| 102 | 103 |
| 103 // Helper function | 104 // Helper function |
| 104 static bool isLegacySupportedJavaScriptLanguage(const String& language) | 105 static bool isLegacySupportedJavaScriptLanguage(const String& language) |
| 105 { | 106 { |
| 106 // Mozilla 1.8 accepts javascript1.0 - javascript1.7, but WinIE 7 accepts on
ly javascript1.1 - javascript1.3. | 107 // Mozilla 1.8 accepts javascript1.0 - javascript1.7, but WinIE 7 accepts on
ly javascript1.1 - javascript1.3. |
| 107 // Mozilla 1.8 and WinIE 7 both accept javascript and livescript. | 108 // Mozilla 1.8 and WinIE 7 both accept javascript and livescript. |
| 108 // WinIE 7 accepts ecmascript and jscript, but Mozilla 1.8 doesn't. | 109 // WinIE 7 accepts ecmascript and jscript, but Mozilla 1.8 doesn't. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 124 languages.add("javascript1.6"); | 125 languages.add("javascript1.6"); |
| 125 languages.add("javascript1.7"); | 126 languages.add("javascript1.7"); |
| 126 languages.add("livescript"); | 127 languages.add("livescript"); |
| 127 languages.add("ecmascript"); | 128 languages.add("ecmascript"); |
| 128 languages.add("jscript"); | 129 languages.add("jscript"); |
| 129 } | 130 } |
| 130 | 131 |
| 131 return languages.contains(language); | 132 return languages.contains(language); |
| 132 } | 133 } |
| 133 | 134 |
| 134 void ScriptElement::dispatchErrorEvent() | 135 void ScriptLoader::dispatchErrorEvent() |
| 135 { | 136 { |
| 136 m_element->dispatchEvent(Event::create(eventNames().errorEvent, false, false
)); | 137 m_element->dispatchEvent(Event::create(eventNames().errorEvent, false, false
)); |
| 137 } | 138 } |
| 138 | 139 |
| 139 void ScriptElement::dispatchLoadEvent() | 140 void ScriptLoader::dispatchLoadEvent() |
| 140 { | 141 { |
| 141 ASSERT(!haveFiredLoadEvent()); | 142 ASSERT(!haveFiredLoadEvent()); |
| 142 if (ScriptElementClient* client = this->client()) | 143 if (ScriptLoaderClient* client = this->client()) |
| 143 client->dispatchLoadEvent(); | 144 client->dispatchLoadEvent(); |
| 144 setHaveFiredLoadEvent(true); | 145 setHaveFiredLoadEvent(true); |
| 145 } | 146 } |
| 146 | 147 |
| 147 bool ScriptElement::isScriptTypeSupported(LegacyTypeSupport supportLegacyTypes)
const | 148 bool ScriptLoader::isScriptTypeSupported(LegacyTypeSupport supportLegacyTypes) c
onst |
| 148 { | 149 { |
| 149 // FIXME: isLegacySupportedJavaScriptLanguage() is not valid HTML5. It is us
ed here to maintain backwards compatibility with existing layout tests. The spec
ific violations are: | 150 // FIXME: isLegacySupportedJavaScriptLanguage() is not valid HTML5. It is us
ed here to maintain backwards compatibility with existing layout tests. The spec
ific violations are: |
| 150 // - Allowing type=javascript. type= should only support MIME types, such as
text/javascript. | 151 // - Allowing type=javascript. type= should only support MIME types, such as
text/javascript. |
| 151 // - Allowing a different set of languages for language= and type=. language
= supports Javascript 1.1 and 1.4-1.6, but type= does not. | 152 // - Allowing a different set of languages for language= and type=. language
= supports Javascript 1.1 and 1.4-1.6, but type= does not. |
| 152 | 153 |
| 153 String type = client()->typeAttributeValue(); | 154 String type = client()->typeAttributeValue(); |
| 154 String language = client()->languageAttributeValue(); | 155 String language = client()->languageAttributeValue(); |
| 155 if (type.isEmpty() && language.isEmpty()) | 156 if (type.isEmpty() && language.isEmpty()) |
| 156 return true; // Assume text/javascript. | 157 return true; // Assume text/javascript. |
| 157 if (type.isEmpty()) { | 158 if (type.isEmpty()) { |
| 158 type = "text/" + language.lower(); | 159 type = "text/" + language.lower(); |
| 159 if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type) || isLegacySup
portedJavaScriptLanguage(language)) | 160 if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type) || isLegacySup
portedJavaScriptLanguage(language)) |
| 160 return true; | 161 return true; |
| 161 } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSp
ace().lower()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLeg
acySupportedJavaScriptLanguage(type))) | 162 } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSp
ace().lower()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLeg
acySupportedJavaScriptLanguage(type))) { |
| 162 return true; | 163 return true; |
| 164 } |
| 165 |
| 163 return false; | 166 return false; |
| 164 } | 167 } |
| 165 | 168 |
| 166 // http://dev.w3.org/html5/spec/Overview.html#prepare-a-script | 169 // http://dev.w3.org/html5/spec/Overview.html#prepare-a-script |
| 167 bool ScriptElement::prepareScript(const TextPosition& scriptStartPosition, Legac
yTypeSupport supportLegacyTypes) | 170 bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy
TypeSupport supportLegacyTypes) |
| 168 { | 171 { |
| 169 if (m_alreadyStarted) | 172 if (m_alreadyStarted) |
| 170 return false; | 173 return false; |
| 171 | 174 |
| 172 ScriptElementClient* client = this->client(); | 175 ScriptLoaderClient* client = this->client(); |
| 173 | 176 |
| 174 bool wasParserInserted; | 177 bool wasParserInserted; |
| 175 if (m_parserInserted) { | 178 if (m_parserInserted) { |
| 176 wasParserInserted = true; | 179 wasParserInserted = true; |
| 177 m_parserInserted = false; | 180 m_parserInserted = false; |
| 178 } else | 181 } else { |
| 179 wasParserInserted = false; | 182 wasParserInserted = false; |
| 183 } |
| 180 | 184 |
| 181 if (wasParserInserted && !client->asyncAttributeValue()) | 185 if (wasParserInserted && !client->asyncAttributeValue()) |
| 182 m_forceAsync = true; | 186 m_forceAsync = true; |
| 183 | 187 |
| 184 // FIXME: HTML5 spec says we should check that all children are either comme
nts or empty text nodes. | 188 // FIXME: HTML5 spec says we should check that all children are either comme
nts or empty text nodes. |
| 185 if (!client->hasSourceAttribute() && !m_element->firstChild()) | 189 if (!client->hasSourceAttribute() && !m_element->firstChild()) |
| 186 return false; | 190 return false; |
| 187 | 191 |
| 188 if (!m_element->inDocument()) | 192 if (!m_element->inDocument()) |
| 189 return false; | 193 return false; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 211 return false; | 215 return false; |
| 212 | 216 |
| 213 if (!isScriptForEventSupported()) | 217 if (!isScriptForEventSupported()) |
| 214 return false; | 218 return false; |
| 215 | 219 |
| 216 if (!client->charsetAttributeValue().isEmpty()) | 220 if (!client->charsetAttributeValue().isEmpty()) |
| 217 m_characterEncoding = client->charsetAttributeValue(); | 221 m_characterEncoding = client->charsetAttributeValue(); |
| 218 else | 222 else |
| 219 m_characterEncoding = document->charset(); | 223 m_characterEncoding = document->charset(); |
| 220 | 224 |
| 221 if (client->hasSourceAttribute()) | 225 if (client->hasSourceAttribute()) { |
| 222 if (!requestScript(client->sourceAttributeValue())) | 226 if (!requestScript(client->sourceAttributeValue())) |
| 223 return false; | 227 return false; |
| 228 } |
| 224 | 229 |
| 225 if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parse
rInserted && !client->asyncAttributeValue()) { | 230 if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parse
rInserted && !client->asyncAttributeValue()) { |
| 226 m_willExecuteWhenDocumentFinishedParsing = true; | 231 m_willExecuteWhenDocumentFinishedParsing = true; |
| 227 m_willBeParserExecuted = true; | 232 m_willBeParserExecuted = true; |
| 228 } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyn
cAttributeValue()) | 233 } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyn
cAttributeValue()) { |
| 229 m_willBeParserExecuted = true; | 234 m_willBeParserExecuted = true; |
| 230 else if (!client->hasSourceAttribute() && m_parserInserted && !document->hav
eStylesheetsAndImportsLoaded()) { | 235 } else if (!client->hasSourceAttribute() && m_parserInserted && !document->h
aveStylesheetsAndImportsLoaded()) { |
| 231 m_willBeParserExecuted = true; | 236 m_willBeParserExecuted = true; |
| 232 m_readyToBeParserExecuted = true; | 237 m_readyToBeParserExecuted = true; |
| 233 } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() &&
!m_forceAsync) { | 238 } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() &&
!m_forceAsync) { |
| 234 m_willExecuteInOrder = true; | 239 m_willExecuteInOrder = true; |
| 235 document->scriptRunner()->queueScriptForExecution(this, m_cachedScript,
ScriptRunner::IN_ORDER_EXECUTION); | 240 document->scriptRunner()->queueScriptForExecution(this, m_cachedScript,
ScriptRunner::IN_ORDER_EXECUTION); |
| 236 m_cachedScript->addClient(this); | 241 m_cachedScript->addClient(this); |
| 237 } else if (client->hasSourceAttribute()) { | 242 } else if (client->hasSourceAttribute()) { |
| 238 document->scriptRunner()->queueScriptForExecution(this, m_cachedScript,
ScriptRunner::ASYNC_EXECUTION); | 243 document->scriptRunner()->queueScriptForExecution(this, m_cachedScript,
ScriptRunner::ASYNC_EXECUTION); |
| 239 m_cachedScript->addClient(this); | 244 m_cachedScript->addClient(this); |
| 240 } else { | 245 } else { |
| 241 // Reset line numbering for nested writes. | 246 // Reset line numbering for nested writes. |
| 242 TextPosition position = document->isInDocumentWrite() ? TextPosition() :
scriptStartPosition; | 247 TextPosition position = document->isInDocumentWrite() ? TextPosition() :
scriptStartPosition; |
| 243 KURL scriptURL = (!document->isInDocumentWrite() && m_parserInserted) ?
document->url() : KURL(); | 248 KURL scriptURL = (!document->isInDocumentWrite() && m_parserInserted) ?
document->url() : KURL(); |
| 244 executeScript(ScriptSourceCode(scriptContent(), scriptURL, position)); | 249 executeScript(ScriptSourceCode(scriptContent(), scriptURL, position)); |
| 245 } | 250 } |
| 246 | 251 |
| 247 return true; | 252 return true; |
| 248 } | 253 } |
| 249 | 254 |
| 250 bool ScriptElement::requestScript(const String& sourceUrl) | 255 bool ScriptLoader::requestScript(const String& sourceUrl) |
| 251 { | 256 { |
| 252 ASSERT(m_element); | 257 ASSERT(m_element); |
| 253 | 258 |
| 254 RefPtr<Document> originalDocument = m_element->document(); | 259 RefPtr<Document> originalDocument = m_element->document(); |
| 255 if (!m_element->dispatchBeforeLoadEvent(sourceUrl)) | 260 if (!m_element->dispatchBeforeLoadEvent(sourceUrl)) |
| 256 return false; | 261 return false; |
| 257 if (!m_element->inDocument() || m_element->document() != originalDocument) | 262 if (!m_element->inDocument() || m_element->document() != originalDocument) |
| 258 return false; | 263 return false; |
| 259 | 264 |
| 260 ASSERT(!m_cachedScript); | 265 ASSERT(!m_cachedScript); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 277 } | 282 } |
| 278 | 283 |
| 279 if (m_cachedScript) { | 284 if (m_cachedScript) { |
| 280 return true; | 285 return true; |
| 281 } | 286 } |
| 282 | 287 |
| 283 dispatchErrorEvent(); | 288 dispatchErrorEvent(); |
| 284 return false; | 289 return false; |
| 285 } | 290 } |
| 286 | 291 |
| 287 bool isHTMLScriptElement(Element* element) | 292 bool isHTMLScriptLoader(Element* element) |
| 288 { | 293 { |
| 289 return element->hasTagName(HTMLNames::scriptTag); | 294 return element->hasTagName(HTMLNames::scriptTag); |
| 290 } | 295 } |
| 291 | 296 |
| 292 bool isSVGScriptElement(Element* element) | 297 bool isSVGScriptLoader(Element* element) |
| 293 { | 298 { |
| 294 return element->hasTagName(SVGNames::scriptTag); | 299 return element->hasTagName(SVGNames::scriptTag); |
| 295 } | 300 } |
| 296 | 301 |
| 297 void ScriptElement::executeScript(const ScriptSourceCode& sourceCode) | 302 void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode) |
| 298 { | 303 { |
| 299 ASSERT(m_alreadyStarted); | 304 ASSERT(m_alreadyStarted); |
| 300 | 305 |
| 301 if (sourceCode.isEmpty()) | 306 if (sourceCode.isEmpty()) |
| 302 return; | 307 return; |
| 303 | 308 |
| 304 RefPtr<Document> document = m_element->document(); | 309 RefPtr<Document> document = m_element->document(); |
| 305 Frame* frame = document->frame(); | 310 Frame* frame = document->frame(); |
| 306 | 311 |
| 307 bool shouldBypassMainWorldContentSecurityPolicy = (frame && frame->script()-
>shouldBypassMainWorldContentSecurityPolicy()) || document->contentSecurityPolic
y()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)); | 312 bool shouldBypassMainWorldContentSecurityPolicy = (frame && frame->script()-
>shouldBypassMainWorldContentSecurityPolicy()) || document->contentSecurityPolic
y()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)); |
| 308 | 313 |
| 309 if (!m_isExternalScript && (!shouldBypassMainWorldContentSecurityPolicy && !
document->contentSecurityPolicy()->allowInlineScript(document->url(), m_startLin
eNumber))) | 314 if (!m_isExternalScript && (!shouldBypassMainWorldContentSecurityPolicy && !
document->contentSecurityPolicy()->allowInlineScript(document->url(), m_startLin
eNumber))) |
| 310 return; | 315 return; |
| 311 | 316 |
| 312 if (m_isExternalScript && m_cachedScript && !m_cachedScript->mimeTypeAllowed
ByNosniff()) { | 317 if (m_isExternalScript && m_cachedScript && !m_cachedScript->mimeTypeAllowed
ByNosniff()) { |
| 313 document->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "R
efused to execute script from '" + m_cachedScript->url().elidedString() + "' bec
ause its MIME type ('" + m_cachedScript->mimeType() + "') is not executable, and
strict MIME type checking is enabled."); | 318 document->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "R
efused to execute script from '" + m_cachedScript->url().elidedString() + "' bec
ause its MIME type ('" + m_cachedScript->mimeType() + "') is not executable, and
strict MIME type checking is enabled."); |
| 314 return; | 319 return; |
| 315 } | 320 } |
| 316 | 321 |
| 317 if (frame) { | 322 if (frame) { |
| 318 { | 323 IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncre
menter(m_isExternalScript ? document.get() : 0); |
| 319 IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountI
ncrementer(m_isExternalScript ? document.get() : 0); | |
| 320 | 324 |
| 321 if (isHTMLScriptElement(m_element)) | 325 if (isHTMLScriptLoader(m_element)) |
| 322 document->pushCurrentScript(toHTMLScriptElement(m_element)); | 326 document->pushCurrentScript(toHTMLScriptElement(m_element)); |
| 323 | 327 |
| 324 // Create a script from the script element node, using the script | 328 // Create a script from the script element node, using the script |
| 325 // block's source and the script block's type. | 329 // block's source and the script block's type. |
| 326 // Note: This is where the script is compiled and actually executed. | 330 // Note: This is where the script is compiled and actually executed. |
| 327 frame->script()->executeScriptInMainWorld(sourceCode); | 331 frame->script()->executeScriptInMainWorld(sourceCode); |
| 328 | 332 |
| 329 if (isHTMLScriptElement(m_element)) { | 333 if (isHTMLScriptLoader(m_element)) { |
| 330 ASSERT(document->currentScript() == m_element); | 334 ASSERT(document->currentScript() == m_element); |
| 331 document->popCurrentScript(); | 335 document->popCurrentScript(); |
| 332 } | |
| 333 } | 336 } |
| 334 } | 337 } |
| 335 } | 338 } |
| 336 | 339 |
| 337 void ScriptElement::stopLoadRequest() | 340 void ScriptLoader::stopLoadRequest() |
| 338 { | 341 { |
| 339 if (m_cachedScript) { | 342 if (m_cachedScript) { |
| 340 if (!m_willBeParserExecuted) | 343 if (!m_willBeParserExecuted) |
| 341 m_cachedScript->removeClient(this); | 344 m_cachedScript->removeClient(this); |
| 342 m_cachedScript = 0; | 345 m_cachedScript = 0; |
| 343 } | 346 } |
| 344 } | 347 } |
| 345 | 348 |
| 346 void ScriptElement::execute(CachedScript* cachedScript) | 349 void ScriptLoader::execute(CachedScript* cachedScript) |
| 347 { | 350 { |
| 348 ASSERT(!m_willBeParserExecuted); | 351 ASSERT(!m_willBeParserExecuted); |
| 349 ASSERT(cachedScript); | 352 ASSERT(cachedScript); |
| 350 if (cachedScript->errorOccurred()) | 353 if (cachedScript->errorOccurred()) { |
| 351 dispatchErrorEvent(); | 354 dispatchErrorEvent(); |
| 352 else if (!cachedScript->wasCanceled()) { | 355 } else if (!cachedScript->wasCanceled()) { |
| 353 executeScript(ScriptSourceCode(cachedScript)); | 356 executeScript(ScriptSourceCode(cachedScript)); |
| 354 dispatchLoadEvent(); | 357 dispatchLoadEvent(); |
| 355 } | 358 } |
| 356 cachedScript->removeClient(this); | 359 cachedScript->removeClient(this); |
| 357 } | 360 } |
| 358 | 361 |
| 359 void ScriptElement::notifyFinished(CachedResource* resource) | 362 void ScriptLoader::notifyFinished(CachedResource* resource) |
| 360 { | 363 { |
| 361 ASSERT(!m_willBeParserExecuted); | 364 ASSERT(!m_willBeParserExecuted); |
| 362 | 365 |
| 363 // CachedResource possibly invokes this notifyFinished() more than | 366 // CachedResource possibly invokes this notifyFinished() more than |
| 364 // once because ScriptElement doesn't unsubscribe itself from | 367 // once because ScriptLoader doesn't unsubscribe itself from |
| 365 // CachedResource here and does it in execute() instead. | 368 // CachedResource here and does it in execute() instead. |
| 366 // We use m_cachedScript to check if this function is already called. | 369 // We use m_cachedScript to check if this function is already called. |
| 367 ASSERT_UNUSED(resource, resource == m_cachedScript); | 370 ASSERT_UNUSED(resource, resource == m_cachedScript); |
| 368 if (!m_cachedScript) | 371 if (!m_cachedScript) |
| 369 return; | 372 return; |
| 370 if (!m_element->document()->cachedResourceLoader()->canAccess(m_cachedScript
.get())) { | 373 if (!m_element->document()->cachedResourceLoader()->canAccess(m_cachedScript
.get())) { |
| 371 dispatchErrorEvent(); | 374 dispatchErrorEvent(); |
| 372 return; | 375 return; |
| 373 } | 376 } |
| 374 | 377 |
| 375 if (m_willExecuteInOrder) | 378 if (m_willExecuteInOrder) |
| 376 m_element->document()->scriptRunner()->notifyScriptReady(this, ScriptRun
ner::IN_ORDER_EXECUTION); | 379 m_element->document()->scriptRunner()->notifyScriptReady(this, ScriptRun
ner::IN_ORDER_EXECUTION); |
| 377 else | 380 else |
| 378 m_element->document()->scriptRunner()->notifyScriptReady(this, ScriptRun
ner::ASYNC_EXECUTION); | 381 m_element->document()->scriptRunner()->notifyScriptReady(this, ScriptRun
ner::ASYNC_EXECUTION); |
| 379 | 382 |
| 380 m_cachedScript = 0; | 383 m_cachedScript = 0; |
| 381 } | 384 } |
| 382 | 385 |
| 383 bool ScriptElement::ignoresLoadRequest() const | 386 bool ScriptLoader::ignoresLoadRequest() const |
| 384 { | 387 { |
| 385 return m_alreadyStarted || m_isExternalScript || m_parserInserted || !elemen
t() || !element()->inDocument(); | 388 return m_alreadyStarted || m_isExternalScript || m_parserInserted || !elemen
t() || !element()->inDocument(); |
| 386 } | 389 } |
| 387 | 390 |
| 388 bool ScriptElement::isScriptForEventSupported() const | 391 bool ScriptLoader::isScriptForEventSupported() const |
| 389 { | 392 { |
| 390 String eventAttribute = client()->eventAttributeValue(); | 393 String eventAttribute = client()->eventAttributeValue(); |
| 391 String forAttribute = client()->forAttributeValue(); | 394 String forAttribute = client()->forAttributeValue(); |
| 392 if (!eventAttribute.isEmpty() && !forAttribute.isEmpty()) { | 395 if (!eventAttribute.isEmpty() && !forAttribute.isEmpty()) { |
| 393 forAttribute = forAttribute.stripWhiteSpace(); | 396 forAttribute = forAttribute.stripWhiteSpace(); |
| 394 if (!equalIgnoringCase(forAttribute, "window")) | 397 if (!equalIgnoringCase(forAttribute, "window")) |
| 395 return false; | 398 return false; |
| 396 | 399 |
| 397 eventAttribute = eventAttribute.stripWhiteSpace(); | 400 eventAttribute = eventAttribute.stripWhiteSpace(); |
| 398 if (!equalIgnoringCase(eventAttribute, "onload") && !equalIgnoringCase(e
ventAttribute, "onload()")) | 401 if (!equalIgnoringCase(eventAttribute, "onload") && !equalIgnoringCase(e
ventAttribute, "onload()")) |
| 399 return false; | 402 return false; |
| 400 } | 403 } |
| 401 return true; | 404 return true; |
| 402 } | 405 } |
| 403 | 406 |
| 404 String ScriptElement::scriptContent() const | 407 String ScriptLoader::scriptContent() const |
| 405 { | 408 { |
| 406 return m_element->textFromChildren(); | 409 return m_element->textFromChildren(); |
| 407 } | 410 } |
| 408 | 411 |
| 409 ScriptElementClient* ScriptElement::client() const | 412 ScriptLoaderClient* ScriptLoader::client() const |
| 410 { | 413 { |
| 411 if (isHTMLScriptElement(m_element)) | 414 if (isHTMLScriptLoader(m_element)) |
| 412 return toHTMLScriptElement(m_element); | 415 return toHTMLScriptElement(m_element); |
| 413 | 416 |
| 414 if (isSVGScriptElement(m_element)) | 417 if (isSVGScriptLoader(m_element)) |
| 415 return toSVGScriptElement(m_element); | 418 return toSVGScriptElement(m_element); |
| 416 | 419 |
| 417 ASSERT_NOT_REACHED(); | 420 ASSERT_NOT_REACHED(); |
| 418 return 0; | 421 return 0; |
| 419 } | 422 } |
| 420 | 423 |
| 421 ScriptElement* toScriptElementIfPossible(Element* element) | 424 ScriptLoader* toScriptLoaderIfPossible(Element* element) |
| 422 { | 425 { |
| 423 if (isHTMLScriptElement(element)) | 426 if (isHTMLScriptLoader(element)) |
| 424 return toHTMLScriptElement(element)->scriptElement(); | 427 return toHTMLScriptElement(element)->loader(); |
| 425 | 428 |
| 426 if (isSVGScriptElement(element)) | 429 if (isSVGScriptLoader(element)) |
| 427 return toSVGScriptElement(element)->scriptElement(); | 430 return toSVGScriptElement(element)->loader(); |
| 428 | 431 |
| 429 return 0; | 432 return 0; |
| 430 } | 433 } |
| 431 | 434 |
| 432 } | 435 } |
| OLD | NEW |