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 |