| 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 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 , m_isExternalScript(false) | 61 , m_isExternalScript(false) |
| 62 , m_alreadyStarted(alreadyStarted) | 62 , m_alreadyStarted(alreadyStarted) |
| 63 , m_haveFiredLoad(false) | 63 , m_haveFiredLoad(false) |
| 64 , m_willBeParserExecuted(false) | 64 , m_willBeParserExecuted(false) |
| 65 , m_readyToBeParserExecuted(false) | 65 , m_readyToBeParserExecuted(false) |
| 66 , m_willExecuteWhenDocumentFinishedParsing(false) | 66 , m_willExecuteWhenDocumentFinishedParsing(false) |
| 67 , m_forceAsync(!parserInserted) | 67 , m_forceAsync(!parserInserted) |
| 68 , m_willExecuteInOrder(false) | 68 , m_willExecuteInOrder(false) |
| 69 { | 69 { |
| 70 ASSERT(m_element); | 70 ASSERT(m_element); |
| 71 if (parserInserted && element->document()->scriptableDocumentParser() && !el
ement->document()->isInDocumentWrite()) | 71 if (parserInserted && element->document().scriptableDocumentParser() && !ele
ment->document().isInDocumentWrite()) |
| 72 m_startLineNumber = element->document()->scriptableDocumentParser()->lin
eNumber(); | 72 m_startLineNumber = element->document().scriptableDocumentParser()->line
Number(); |
| 73 } | 73 } |
| 74 | 74 |
| 75 ScriptLoader::~ScriptLoader() | 75 ScriptLoader::~ScriptLoader() |
| 76 { | 76 { |
| 77 stopLoadRequest(); | 77 stopLoadRequest(); |
| 78 } | 78 } |
| 79 | 79 |
| 80 void ScriptLoader::insertedInto(ContainerNode* insertionPoint) | 80 void ScriptLoader::insertedInto(ContainerNode* insertionPoint) |
| 81 { | 81 { |
| 82 if (insertionPoint->inDocument() && !m_parserInserted) | 82 if (insertionPoint->inDocument() && !m_parserInserted) |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 return true; | 161 return true; |
| 162 } 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))) { |
| 163 return true; | 163 return true; |
| 164 } | 164 } |
| 165 | 165 |
| 166 return false; | 166 return false; |
| 167 } | 167 } |
| 168 | 168 |
| 169 Document* ScriptLoader::executingDocument() const | 169 Document* ScriptLoader::executingDocument() const |
| 170 { | 170 { |
| 171 Document* document = m_element->document(); | 171 Document& document = m_element->document(); |
| 172 if (!document->import()) | 172 if (!document.import()) |
| 173 return document; | 173 return &document; |
| 174 return document->import()->master(); | 174 return document.import()->master(); |
| 175 } | 175 } |
| 176 | 176 |
| 177 // http://dev.w3.org/html5/spec/Overview.html#prepare-a-script | 177 // http://dev.w3.org/html5/spec/Overview.html#prepare-a-script |
| 178 bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy
TypeSupport supportLegacyTypes) | 178 bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy
TypeSupport supportLegacyTypes) |
| 179 { | 179 { |
| 180 if (m_alreadyStarted) | 180 if (m_alreadyStarted) |
| 181 return false; | 181 return false; |
| 182 | 182 |
| 183 ScriptLoaderClient* client = this->client(); | 183 ScriptLoaderClient* client = this->client(); |
| 184 | 184 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 205 | 205 |
| 206 if (wasParserInserted) { | 206 if (wasParserInserted) { |
| 207 m_parserInserted = true; | 207 m_parserInserted = true; |
| 208 m_forceAsync = false; | 208 m_forceAsync = false; |
| 209 } | 209 } |
| 210 | 210 |
| 211 m_alreadyStarted = true; | 211 m_alreadyStarted = true; |
| 212 | 212 |
| 213 // FIXME: If script is parser inserted, verify it's still in the original do
cument. | 213 // FIXME: If script is parser inserted, verify it's still in the original do
cument. |
| 214 Document* executingDocument = this->executingDocument(); | 214 Document* executingDocument = this->executingDocument(); |
| 215 Document* elementDocument = m_element->document(); | 215 Document& elementDocument = m_element->document(); |
| 216 | 216 |
| 217 // FIXME: Eventually we'd like to evaluate scripts which are inserted into a | 217 // FIXME: Eventually we'd like to evaluate scripts which are inserted into a |
| 218 // viewless document but this'll do for now. | 218 // viewless document but this'll do for now. |
| 219 // See http://bugs.webkit.org/show_bug.cgi?id=5727 | 219 // See http://bugs.webkit.org/show_bug.cgi?id=5727 |
| 220 if (!executingDocument->frame()) | 220 if (!executingDocument->frame()) |
| 221 return false; | 221 return false; |
| 222 | 222 |
| 223 if (!executingDocument->frame()->script()->canExecuteScripts(AboutToExecuteS
cript)) | 223 if (!executingDocument->frame()->script()->canExecuteScripts(AboutToExecuteS
cript)) |
| 224 return false; | 224 return false; |
| 225 | 225 |
| 226 if (!isScriptForEventSupported()) | 226 if (!isScriptForEventSupported()) |
| 227 return false; | 227 return false; |
| 228 | 228 |
| 229 if (!client->charsetAttributeValue().isEmpty()) | 229 if (!client->charsetAttributeValue().isEmpty()) |
| 230 m_characterEncoding = client->charsetAttributeValue(); | 230 m_characterEncoding = client->charsetAttributeValue(); |
| 231 else | 231 else |
| 232 m_characterEncoding = elementDocument->charset(); | 232 m_characterEncoding = elementDocument.charset(); |
| 233 | 233 |
| 234 if (client->hasSourceAttribute()) { | 234 if (client->hasSourceAttribute()) { |
| 235 if (!fetchScript(client->sourceAttributeValue())) | 235 if (!fetchScript(client->sourceAttributeValue())) |
| 236 return false; | 236 return false; |
| 237 } | 237 } |
| 238 | 238 |
| 239 if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parse
rInserted && !client->asyncAttributeValue()) { | 239 if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parse
rInserted && !client->asyncAttributeValue()) { |
| 240 m_willExecuteWhenDocumentFinishedParsing = true; | 240 m_willExecuteWhenDocumentFinishedParsing = true; |
| 241 m_willBeParserExecuted = true; | 241 m_willBeParserExecuted = true; |
| 242 } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyn
cAttributeValue()) { | 242 } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyn
cAttributeValue()) { |
| 243 m_willBeParserExecuted = true; | 243 m_willBeParserExecuted = true; |
| 244 } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocu
ment->haveStylesheetsAndImportsLoaded()) { | 244 } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocu
ment.haveStylesheetsAndImportsLoaded()) { |
| 245 m_willBeParserExecuted = true; | 245 m_willBeParserExecuted = true; |
| 246 m_readyToBeParserExecuted = true; | 246 m_readyToBeParserExecuted = true; |
| 247 } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() &&
!m_forceAsync) { | 247 } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() &&
!m_forceAsync) { |
| 248 m_willExecuteInOrder = true; | 248 m_willExecuteInOrder = true; |
| 249 executingDocument->scriptRunner()->queueScriptForExecution(this, m_resou
rce, ScriptRunner::IN_ORDER_EXECUTION); | 249 executingDocument->scriptRunner()->queueScriptForExecution(this, m_resou
rce, ScriptRunner::IN_ORDER_EXECUTION); |
| 250 m_resource->addClient(this); | 250 m_resource->addClient(this); |
| 251 } else if (client->hasSourceAttribute()) { | 251 } else if (client->hasSourceAttribute()) { |
| 252 executingDocument->scriptRunner()->queueScriptForExecution(this, m_resou
rce, ScriptRunner::ASYNC_EXECUTION); | 252 executingDocument->scriptRunner()->queueScriptForExecution(this, m_resou
rce, ScriptRunner::ASYNC_EXECUTION); |
| 253 m_resource->addClient(this); | 253 m_resource->addClient(this); |
| 254 } else { | 254 } else { |
| 255 // Reset line numbering for nested writes. | 255 // Reset line numbering for nested writes. |
| 256 TextPosition position = elementDocument->isInDocumentWrite() ? TextPosit
ion() : scriptStartPosition; | 256 TextPosition position = elementDocument.isInDocumentWrite() ? TextPositi
on() : scriptStartPosition; |
| 257 KURL scriptURL = (!elementDocument->isInDocumentWrite() && m_parserInser
ted) ? elementDocument->url() : KURL(); | 257 KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInsert
ed) ? elementDocument.url() : KURL(); |
| 258 executeScript(ScriptSourceCode(scriptContent(), scriptURL, position)); | 258 executeScript(ScriptSourceCode(scriptContent(), scriptURL, position)); |
| 259 } | 259 } |
| 260 | 260 |
| 261 return true; | 261 return true; |
| 262 } | 262 } |
| 263 | 263 |
| 264 bool ScriptLoader::fetchScript(const String& sourceUrl) | 264 bool ScriptLoader::fetchScript(const String& sourceUrl) |
| 265 { | 265 { |
| 266 ASSERT(m_element); | 266 ASSERT(m_element); |
| 267 | 267 |
| 268 RefPtr<Document> elementDocument = m_element->document(); | 268 RefPtr<Document> elementDocument = &m_element->document(); |
| 269 if (!m_element->dispatchBeforeLoadEvent(sourceUrl)) | 269 if (!m_element->dispatchBeforeLoadEvent(sourceUrl)) |
| 270 return false; | 270 return false; |
| 271 if (!m_element->inDocument() || m_element->document() != elementDocument) | 271 if (!m_element->inDocument() || &m_element->document() != elementDocument) |
| 272 return false; | 272 return false; |
| 273 | 273 |
| 274 ASSERT(!m_resource); | 274 ASSERT(!m_resource); |
| 275 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { | 275 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { |
| 276 FetchRequest request(ResourceRequest(elementDocument->completeURL(source
Url)), m_element->localName()); | 276 FetchRequest request(ResourceRequest(elementDocument->completeURL(source
Url)), m_element->localName()); |
| 277 | 277 |
| 278 String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossori
ginAttr); | 278 String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossori
ginAttr); |
| 279 if (!crossOriginMode.isNull()) { | 279 if (!crossOriginMode.isNull()) { |
| 280 StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMo
de, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; | 280 StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMo
de, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; |
| 281 request.setPotentiallyCrossOriginEnabled(elementDocument->securityOr
igin(), allowCredentials); | 281 request.setPotentiallyCrossOriginEnabled(elementDocument->securityOr
igin(), allowCredentials); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 309 } | 309 } |
| 310 | 310 |
| 311 void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode) | 311 void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode) |
| 312 { | 312 { |
| 313 ASSERT(m_alreadyStarted); | 313 ASSERT(m_alreadyStarted); |
| 314 | 314 |
| 315 if (sourceCode.isEmpty()) | 315 if (sourceCode.isEmpty()) |
| 316 return; | 316 return; |
| 317 | 317 |
| 318 RefPtr<Document> executingDocument = this->executingDocument(); | 318 RefPtr<Document> executingDocument = this->executingDocument(); |
| 319 RefPtr<Document> elementDocument = m_element->document(); | 319 RefPtr<Document> elementDocument = &m_element->document(); |
| 320 Frame* frame = executingDocument->frame(); | 320 Frame* frame = executingDocument->frame(); |
| 321 | 321 |
| 322 bool shouldBypassMainWorldContentSecurityPolicy = (frame && frame->script()-
>shouldBypassMainWorldContentSecurityPolicy()) || elementDocument->contentSecuri
tyPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)); | 322 bool shouldBypassMainWorldContentSecurityPolicy = (frame && frame->script()-
>shouldBypassMainWorldContentSecurityPolicy()) || elementDocument->contentSecuri
tyPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)); |
| 323 | 323 |
| 324 if (!m_isExternalScript && (!shouldBypassMainWorldContentSecurityPolicy && !
elementDocument->contentSecurityPolicy()->allowInlineScript(elementDocument->url
(), m_startLineNumber))) | 324 if (!m_isExternalScript && (!shouldBypassMainWorldContentSecurityPolicy && !
elementDocument->contentSecurityPolicy()->allowInlineScript(elementDocument->url
(), m_startLineNumber))) |
| 325 return; | 325 return; |
| 326 | 326 |
| 327 if (m_isExternalScript && m_resource && !m_resource->mimeTypeAllowedByNosnif
f()) { | 327 if (m_isExternalScript && m_resource && !m_resource->mimeTypeAllowedByNosnif
f()) { |
| 328 executingDocument->addConsoleMessage(SecurityMessageSource, ErrorMessage
Level, "Refused to execute script from '" + m_resource->url().elidedString() + "
' because its MIME type ('" + m_resource->mimeType() + "') is not executable, an
d strict MIME type checking is enabled."); | 328 executingDocument->addConsoleMessage(SecurityMessageSource, ErrorMessage
Level, "Refused to execute script from '" + m_resource->url().elidedString() + "
' because its MIME type ('" + m_resource->mimeType() + "') is not executable, an
d strict MIME type checking is enabled."); |
| 329 return; | 329 return; |
| 330 } | 330 } |
| 331 | 331 |
| 332 if (frame) { | 332 if (frame) { |
| 333 IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncre
menter(m_isExternalScript ? executingDocument.get() : 0); | 333 IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncre
menter(m_isExternalScript ? executingDocument.get() : 0); |
| 334 | 334 |
| 335 if (isHTMLScriptLoader(m_element)) | 335 if (isHTMLScriptLoader(m_element)) |
| 336 executingDocument->pushCurrentScript(toHTMLScriptElement(m_element))
; | 336 executingDocument->pushCurrentScript(toHTMLScriptElement(m_element))
; |
| 337 | 337 |
| 338 AccessControlStatus corsCheck = NotSharableCrossOrigin; | 338 AccessControlStatus corsCheck = NotSharableCrossOrigin; |
| 339 if (sourceCode.resource() && sourceCode.resource()->passesAccessControlC
heck(m_element->document()->securityOrigin())) | 339 if (sourceCode.resource() && sourceCode.resource()->passesAccessControlC
heck(m_element->document().securityOrigin())) |
| 340 corsCheck = SharableCrossOrigin; | 340 corsCheck = SharableCrossOrigin; |
| 341 | 341 |
| 342 // Create a script from the script element node, using the script | 342 // Create a script from the script element node, using the script |
| 343 // block's source and the script block's type. | 343 // block's source and the script block's type. |
| 344 // Note: This is where the script is compiled and actually executed. | 344 // Note: This is where the script is compiled and actually executed. |
| 345 frame->script()->executeScriptInMainWorld(sourceCode, corsCheck); | 345 frame->script()->executeScriptInMainWorld(sourceCode, corsCheck); |
| 346 | 346 |
| 347 if (isHTMLScriptLoader(m_element)) { | 347 if (isHTMLScriptLoader(m_element)) { |
| 348 ASSERT(executingDocument->currentScript() == m_element); | 348 ASSERT(executingDocument->currentScript() == m_element); |
| 349 executingDocument->popCurrentScript(); | 349 executingDocument->popCurrentScript(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 371 dispatchLoadEvent(); | 371 dispatchLoadEvent(); |
| 372 } | 372 } |
| 373 resource->removeClient(this); | 373 resource->removeClient(this); |
| 374 } | 374 } |
| 375 | 375 |
| 376 void ScriptLoader::notifyFinished(Resource* resource) | 376 void ScriptLoader::notifyFinished(Resource* resource) |
| 377 { | 377 { |
| 378 ASSERT(!m_willBeParserExecuted); | 378 ASSERT(!m_willBeParserExecuted); |
| 379 | 379 |
| 380 RefPtr<Document> executingDocument = this->executingDocument(); | 380 RefPtr<Document> executingDocument = this->executingDocument(); |
| 381 RefPtr<Document> elementDocument = m_element->document(); | 381 RefPtr<Document> elementDocument = &m_element->document(); |
| 382 | 382 |
| 383 // Resource possibly invokes this notifyFinished() more than | 383 // Resource possibly invokes this notifyFinished() more than |
| 384 // once because ScriptLoader doesn't unsubscribe itself from | 384 // once because ScriptLoader doesn't unsubscribe itself from |
| 385 // Resource here and does it in execute() instead. | 385 // Resource here and does it in execute() instead. |
| 386 // We use m_resource to check if this function is already called. | 386 // We use m_resource to check if this function is already called. |
| 387 ASSERT_UNUSED(resource, resource == m_resource); | 387 ASSERT_UNUSED(resource, resource == m_resource); |
| 388 if (!m_resource) | 388 if (!m_resource) |
| 389 return; | 389 return; |
| 390 if (!elementDocument->fetcher()->canAccess(m_resource.get())) { | 390 if (!elementDocument->fetcher()->canAccess(m_resource.get())) { |
| 391 dispatchErrorEvent(); | 391 dispatchErrorEvent(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 if (isHTMLScriptLoader(element)) | 443 if (isHTMLScriptLoader(element)) |
| 444 return toHTMLScriptElement(element)->loader(); | 444 return toHTMLScriptElement(element)->loader(); |
| 445 | 445 |
| 446 if (isSVGScriptLoader(element)) | 446 if (isSVGScriptLoader(element)) |
| 447 return toSVGScriptElement(element)->loader(); | 447 return toSVGScriptElement(element)->loader(); |
| 448 | 448 |
| 449 return 0; | 449 return 0; |
| 450 } | 450 } |
| 451 | 451 |
| 452 } | 452 } |
| OLD | NEW |