| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 , m_forceAsync(!parserInserted) | 68 , m_forceAsync(!parserInserted) |
| 69 , m_willExecuteInOrder(false) | 69 , m_willExecuteInOrder(false) |
| 70 { | 70 { |
| 71 ASSERT(m_element); | 71 ASSERT(m_element); |
| 72 if (parserInserted && element->document().scriptableDocumentParser() && !ele
ment->document().isInDocumentWrite()) | 72 if (parserInserted && element->document().scriptableDocumentParser() && !ele
ment->document().isInDocumentWrite()) |
| 73 m_startLineNumber = element->document().scriptableDocumentParser()->line
Number(); | 73 m_startLineNumber = element->document().scriptableDocumentParser()->line
Number(); |
| 74 } | 74 } |
| 75 | 75 |
| 76 ScriptLoader::~ScriptLoader() | 76 ScriptLoader::~ScriptLoader() |
| 77 { | 77 { |
| 78 stopLoadRequest(); | 78 m_pendingScript.stopWatchingForLoad(this); |
| 79 } | 79 } |
| 80 | 80 |
| 81 void ScriptLoader::didNotifySubtreeInsertionsToDocument() | 81 void ScriptLoader::didNotifySubtreeInsertionsToDocument() |
| 82 { | 82 { |
| 83 if (!m_parserInserted) | 83 if (!m_parserInserted) |
| 84 prepareScript(); // FIXME: Provide a real starting line number here. | 84 prepareScript(); // FIXME: Provide a real starting line number here. |
| 85 } | 85 } |
| 86 | 86 |
| 87 void ScriptLoader::childrenChanged() | 87 void ScriptLoader::childrenChanged() |
| 88 { | 88 { |
| 89 if (!m_parserInserted && m_element->inDocument()) | 89 if (!m_parserInserted && m_element->inDocument()) |
| 90 prepareScript(); // FIXME: Provide a real starting line number here. | 90 prepareScript(); // FIXME: Provide a real starting line number here. |
| 91 } | 91 } |
| 92 | 92 |
| 93 void ScriptLoader::handleSourceAttribute(const String& sourceUrl) | 93 void ScriptLoader::handleSourceAttribute(const String& sourceUrl) |
| 94 { | 94 { |
| 95 if (ignoresLoadRequest() || sourceUrl.isEmpty()) | 95 if (ignoresLoadRequest() || sourceUrl.isEmpty()) |
| 96 return; | 96 return; |
| 97 | 97 |
| 98 prepareScript(); // FIXME: Provide a real starting line number here. | 98 prepareScript(); // FIXME: Provide a real starting line number here. |
| 99 } | 99 } |
| 100 | 100 |
| 101 void ScriptLoader::handleAsyncAttribute() | 101 void ScriptLoader::handleAsyncAttribute() |
| 102 { | 102 { |
| 103 m_forceAsync = false; | 103 m_forceAsync = false; |
| 104 } | 104 } |
| 105 | 105 |
| 106 void ScriptLoader::detach() |
| 107 { |
| 108 m_pendingScript.stopWatchingForLoad(this); |
| 109 m_pendingScript.releaseElementAndClear(); |
| 110 } |
| 111 |
| 106 // Helper function | 112 // Helper function |
| 107 static bool isLegacySupportedJavaScriptLanguage(const String& language) | 113 static bool isLegacySupportedJavaScriptLanguage(const String& language) |
| 108 { | 114 { |
| 109 // Mozilla 1.8 accepts javascript1.0 - javascript1.7, but WinIE 7 accepts on
ly javascript1.1 - javascript1.3. | 115 // Mozilla 1.8 accepts javascript1.0 - javascript1.7, but WinIE 7 accepts on
ly javascript1.1 - javascript1.3. |
| 110 // Mozilla 1.8 and WinIE 7 both accept javascript and livescript. | 116 // Mozilla 1.8 and WinIE 7 both accept javascript and livescript. |
| 111 // WinIE 7 accepts ecmascript and jscript, but Mozilla 1.8 doesn't. | 117 // WinIE 7 accepts ecmascript and jscript, but Mozilla 1.8 doesn't. |
| 112 // Neither Mozilla 1.8 nor WinIE 7 accept leading or trailing whitespace. | 118 // Neither Mozilla 1.8 nor WinIE 7 accept leading or trailing whitespace. |
| 113 // We want to accept all the values that either of these browsers accept, bu
t not other values. | 119 // We want to accept all the values that either of these browsers accept, bu
t not other values. |
| 114 | 120 |
| 115 // FIXME: This function is not HTML5 compliant. These belong in the MIME reg
istry as "text/javascript<version>" entries. | 121 // FIXME: This function is not HTML5 compliant. These belong in the MIME reg
istry as "text/javascript<version>" entries. |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parse
rInserted && !client->asyncAttributeValue()) { | 234 if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parse
rInserted && !client->asyncAttributeValue()) { |
| 229 m_willExecuteWhenDocumentFinishedParsing = true; | 235 m_willExecuteWhenDocumentFinishedParsing = true; |
| 230 m_willBeParserExecuted = true; | 236 m_willBeParserExecuted = true; |
| 231 } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyn
cAttributeValue()) { | 237 } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyn
cAttributeValue()) { |
| 232 m_willBeParserExecuted = true; | 238 m_willBeParserExecuted = true; |
| 233 } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocu
ment.isRenderingReady()) { | 239 } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocu
ment.isRenderingReady()) { |
| 234 m_willBeParserExecuted = true; | 240 m_willBeParserExecuted = true; |
| 235 m_readyToBeParserExecuted = true; | 241 m_readyToBeParserExecuted = true; |
| 236 } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() &&
!m_forceAsync) { | 242 } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() &&
!m_forceAsync) { |
| 237 m_willExecuteInOrder = true; | 243 m_willExecuteInOrder = true; |
| 238 contextDocument->scriptRunner()->queueScriptForExecution(this, m_resourc
e, ScriptRunner::IN_ORDER_EXECUTION); | 244 m_pendingScript = PendingScript(m_element, m_resource.get()); |
| 239 m_resource->addClient(this); | 245 contextDocument->scriptRunner()->queueScriptForExecution(this, ScriptRun
ner::IN_ORDER_EXECUTION); |
| 246 // Note that watchForLoad can immediately call notifyFinished. |
| 247 m_pendingScript.watchForLoad(this); |
| 240 } else if (client->hasSourceAttribute()) { | 248 } else if (client->hasSourceAttribute()) { |
| 241 contextDocument->scriptRunner()->queueScriptForExecution(this, m_resourc
e, ScriptRunner::ASYNC_EXECUTION); | 249 m_pendingScript = PendingScript(m_element, m_resource.get()); |
| 242 m_resource->addClient(this); | 250 contextDocument->scriptRunner()->queueScriptForExecution(this, ScriptRun
ner::ASYNC_EXECUTION); |
| 251 // Note that watchForLoad can immediately call notifyFinished. |
| 252 m_pendingScript.watchForLoad(this); |
| 243 } else { | 253 } else { |
| 244 // Reset line numbering for nested writes. | 254 // Reset line numbering for nested writes. |
| 245 TextPosition position = elementDocument.isInDocumentWrite() ? TextPositi
on() : scriptStartPosition; | 255 TextPosition position = elementDocument.isInDocumentWrite() ? TextPositi
on() : scriptStartPosition; |
| 246 KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInsert
ed) ? elementDocument.url() : KURL(); | 256 KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInsert
ed) ? elementDocument.url() : KURL(); |
| 247 executeScript(ScriptSourceCode(scriptContent(), scriptURL, position)); | 257 executeScript(ScriptSourceCode(scriptContent(), scriptURL, position)); |
| 248 } | 258 } |
| 249 | 259 |
| 250 return true; | 260 return true; |
| 251 } | 261 } |
| 252 | 262 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 // block's source and the script block's type. | 359 // block's source and the script block's type. |
| 350 // Note: This is where the script is compiled and actually executed. | 360 // Note: This is where the script is compiled and actually executed. |
| 351 frame->script().executeScriptInMainWorld(sourceCode, corsCheck, compilationF
inishTime); | 361 frame->script().executeScriptInMainWorld(sourceCode, corsCheck, compilationF
inishTime); |
| 352 | 362 |
| 353 if (isHTMLScriptLoader(m_element)) { | 363 if (isHTMLScriptLoader(m_element)) { |
| 354 ASSERT(contextDocument->currentScript() == m_element); | 364 ASSERT(contextDocument->currentScript() == m_element); |
| 355 contextDocument->popCurrentScript(); | 365 contextDocument->popCurrentScript(); |
| 356 } | 366 } |
| 357 } | 367 } |
| 358 | 368 |
| 359 void ScriptLoader::stopLoadRequest() | 369 void ScriptLoader::execute() |
| 360 { | |
| 361 if (m_resource) { | |
| 362 if (!m_willBeParserExecuted) | |
| 363 m_resource->removeClient(this); | |
| 364 m_resource = 0; | |
| 365 } | |
| 366 } | |
| 367 | |
| 368 void ScriptLoader::execute(ScriptResource* resource) | |
| 369 { | 370 { |
| 370 ASSERT(!m_willBeParserExecuted); | 371 ASSERT(!m_willBeParserExecuted); |
| 371 ASSERT(resource); | 372 ASSERT(m_pendingScript.resource()); |
| 372 if (resource->errorOccurred()) { | 373 bool errorOccurred = false; |
| 374 ScriptSourceCode source = m_pendingScript.getSource(KURL(), errorOccurred); |
| 375 RefPtr<Element> element = m_pendingScript.releaseElementAndClear(); |
| 376 if (errorOccurred) { |
| 373 dispatchErrorEvent(); | 377 dispatchErrorEvent(); |
| 374 } else if (!resource->wasCanceled()) { | 378 } else if (!m_resource->wasCanceled()) { |
| 375 executeScript(ScriptSourceCode(resource)); | 379 executeScript(source); |
| 376 dispatchLoadEvent(); | 380 dispatchLoadEvent(); |
| 377 } | 381 } |
| 378 resource->removeClient(this); | 382 m_resource = 0; |
| 379 } | 383 } |
| 380 | 384 |
| 381 void ScriptLoader::notifyFinished(Resource* resource) | 385 void ScriptLoader::notifyFinished(Resource* resource) |
| 382 { | 386 { |
| 383 ASSERT(!m_willBeParserExecuted); | 387 ASSERT(!m_willBeParserExecuted); |
| 384 | 388 |
| 385 RefPtrWillBeRawPtr<Document> elementDocument(m_element->document()); | 389 RefPtrWillBeRawPtr<Document> elementDocument(m_element->document()); |
| 386 RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocum
ent().get(); | 390 RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocum
ent().get(); |
| 387 if (!contextDocument) | 391 if (!contextDocument) |
| 388 return; | 392 return; |
| 389 | 393 |
| 390 // Resource possibly invokes this notifyFinished() more than | |
| 391 // once because ScriptLoader doesn't unsubscribe itself from | |
| 392 // Resource here and does it in execute() instead. | |
| 393 // We use m_resource to check if this function is already called. | |
| 394 ASSERT_UNUSED(resource, resource == m_resource); | 394 ASSERT_UNUSED(resource, resource == m_resource); |
| 395 if (!m_resource) | 395 |
| 396 return; | |
| 397 if (m_resource->errorOccurred()) { | 396 if (m_resource->errorOccurred()) { |
| 398 dispatchErrorEvent(); | 397 dispatchErrorEvent(); |
| 399 contextDocument->scriptRunner()->notifyScriptLoadError(this, m_willExecu
teInOrder ? ScriptRunner::IN_ORDER_EXECUTION : ScriptRunner::ASYNC_EXECUTION); | 398 contextDocument->scriptRunner()->notifyScriptLoadError(this, m_willExecu
teInOrder ? ScriptRunner::IN_ORDER_EXECUTION : ScriptRunner::ASYNC_EXECUTION); |
| 400 return; | 399 return; |
| 401 } | 400 } |
| 402 if (m_willExecuteInOrder) | 401 if (m_willExecuteInOrder) |
| 403 contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::I
N_ORDER_EXECUTION); | 402 contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::I
N_ORDER_EXECUTION); |
| 404 else | 403 else |
| 405 contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::A
SYNC_EXECUTION); | 404 contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::A
SYNC_EXECUTION); |
| 406 | 405 |
| 407 m_resource = 0; | 406 m_pendingScript.stopWatchingForLoad(this); |
| 408 } | 407 } |
| 409 | 408 |
| 410 bool ScriptLoader::ignoresLoadRequest() const | 409 bool ScriptLoader::ignoresLoadRequest() const |
| 411 { | 410 { |
| 412 return m_alreadyStarted || m_isExternalScript || m_parserInserted || !elemen
t() || !element()->inDocument(); | 411 return m_alreadyStarted || m_isExternalScript || m_parserInserted || !elemen
t() || !element()->inDocument(); |
| 413 } | 412 } |
| 414 | 413 |
| 415 bool ScriptLoader::isScriptForEventSupported() const | 414 bool ScriptLoader::isScriptForEventSupported() const |
| 416 { | 415 { |
| 417 String eventAttribute = client()->eventAttributeValue(); | 416 String eventAttribute = client()->eventAttributeValue(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 if (isHTMLScriptLoader(element)) | 449 if (isHTMLScriptLoader(element)) |
| 451 return toHTMLScriptElement(element)->loader(); | 450 return toHTMLScriptElement(element)->loader(); |
| 452 | 451 |
| 453 if (isSVGScriptLoader(element)) | 452 if (isSVGScriptLoader(element)) |
| 454 return toSVGScriptElement(element)->loader(); | 453 return toSVGScriptElement(element)->loader(); |
| 455 | 454 |
| 456 return 0; | 455 return 0; |
| 457 } | 456 } |
| 458 | 457 |
| 459 } | 458 } |
| OLD | NEW |