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 | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights |
6 * reserved. | 6 * reserved. |
7 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> | 7 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
11 * License as published by the Free Software Foundation; either | 11 * License as published by the Free Software Foundation; either |
12 * version 2 of the License, or (at your option) any later version. | 12 * version 2 of the License, or (at your option) any later version. |
13 * | 13 * |
14 * This library is distributed in the hope that it will be useful, | 14 * This library is distributed in the hope that it will be useful, |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 * Library General Public License for more details. | 17 * Library General Public License for more details. |
18 * | 18 * |
19 * You should have received a copy of the GNU Library General Public License | 19 * You should have received a copy of the GNU Library General Public License |
20 * along with this library; see the file COPYING.LIB. If not, write to | 20 * along with this library; see the file COPYING.LIB. If not, write to |
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
22 * Boston, MA 02110-1301, USA. | 22 * Boston, MA 02110-1301, USA. |
23 */ | 23 */ |
24 | 24 |
25 #include "core/dom/ScriptLoader.h" | 25 #include "core/dom/ScriptLoader.h" |
26 | 26 |
27 #include "bindings/core/v8/ScriptController.h" | 27 #include "bindings/core/v8/ScriptController.h" |
28 #include "bindings/core/v8/ScriptSourceCode.h" | 28 #include "bindings/core/v8/ScriptSourceCode.h" |
29 #include "bindings/core/v8/V8Binding.h" | |
30 #include "core/HTMLNames.h" | 29 #include "core/HTMLNames.h" |
31 #include "core/SVGNames.h" | 30 #include "core/SVGNames.h" |
31 #include "core/dom/ClassicPendingScript.h" | |
32 #include "core/dom/ClassicScript.h" | 32 #include "core/dom/ClassicScript.h" |
33 #include "core/dom/Document.h" | 33 #include "core/dom/Document.h" |
34 #include "core/dom/DocumentParserTiming.h" | 34 #include "core/dom/DocumentParserTiming.h" |
35 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" | 35 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" |
36 #include "core/dom/Script.h" | 36 #include "core/dom/Script.h" |
37 #include "core/dom/ScriptElementBase.h" | 37 #include "core/dom/ScriptElementBase.h" |
38 #include "core/dom/ScriptRunner.h" | 38 #include "core/dom/ScriptRunner.h" |
39 #include "core/dom/ScriptableDocumentParser.h" | 39 #include "core/dom/ScriptableDocumentParser.h" |
40 #include "core/dom/Text.h" | 40 #include "core/dom/Text.h" |
41 #include "core/events/Event.h" | 41 #include "core/events/Event.h" |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 // 22.2. "Switch on the script's type:" | 316 // 22.2. "Switch on the script's type:" |
317 // TODO(hiroshige): Clarify how Step 22.2 is implemented for "classic". | 317 // TODO(hiroshige): Clarify how Step 22.2 is implemented for "classic". |
318 // TODO(hiroshige): Implement Step 22.2 for "module". | 318 // TODO(hiroshige): Implement Step 22.2 for "module". |
319 | 319 |
320 // [Intervention] | 320 // [Intervention] |
321 // Since the asynchronous, low priority fetch for doc.written blocked | 321 // Since the asynchronous, low priority fetch for doc.written blocked |
322 // script is not for execution, return early from here. Watch for its | 322 // script is not for execution, return early from here. Watch for its |
323 // completion to be able to remove it from the memory cache. | 323 // completion to be able to remove it from the memory cache. |
324 if (m_documentWriteIntervention == | 324 if (m_documentWriteIntervention == |
325 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { | 325 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { |
326 m_pendingScript = PendingScript::create(m_element.get(), m_resource.get()); | 326 m_pendingScript = |
327 ClassicPendingScript::create(m_element.get(), m_resource.get()); | |
327 m_pendingScript->watchForLoad(this); | 328 m_pendingScript->watchForLoad(this); |
328 return true; | 329 return true; |
329 } | 330 } |
330 | 331 |
331 // 23. "Then, follow the first of the following options that describes the | 332 // 23. "Then, follow the first of the following options that describes the |
332 // situation:" | 333 // situation:" |
333 | 334 |
334 // Three flags are used to instruct the caller of prepareScript() to execute | 335 // Three flags are used to instruct the caller of prepareScript() to execute |
335 // a part of Step 23, when |m_willBeParserExecuted| is true: | 336 // a part of Step 23, when |m_willBeParserExecuted| is true: |
336 // - |m_willBeParserExecuted| | 337 // - |m_willBeParserExecuted| |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
402 // - "If the script's type is "classic", | 403 // - "If the script's type is "classic", |
403 // and the element has a src attribute, | 404 // and the element has a src attribute, |
404 // and the element does not have an async attribute, | 405 // and the element does not have an async attribute, |
405 // and the element does not have the "non-blocking" flag set" | 406 // and the element does not have the "non-blocking" flag set" |
406 // TODO(hiroshige): Check the script's type and implement "module" case. | 407 // TODO(hiroshige): Check the script's type and implement "module" case. |
407 if (m_element->hasSourceAttribute() && !m_element->asyncAttributeValue() && | 408 if (m_element->hasSourceAttribute() && !m_element->asyncAttributeValue() && |
408 !m_nonBlocking) { | 409 !m_nonBlocking) { |
409 // "Add the element to the end of the list of scripts that will execute | 410 // "Add the element to the end of the list of scripts that will execute |
410 // in order as soon as possible associated with the node document of the | 411 // in order as soon as possible associated with the node document of the |
411 // script element at the time the prepare a script algorithm started." | 412 // script element at the time the prepare a script algorithm started." |
412 m_pendingScript = PendingScript::create(m_element.get(), m_resource.get()); | 413 m_pendingScript = |
414 ClassicPendingScript::create(m_element.get(), m_resource.get()); | |
413 m_asyncExecType = ScriptRunner::InOrder; | 415 m_asyncExecType = ScriptRunner::InOrder; |
414 // TODO(hiroshige): Here |contextDocument| is used as "node document" | 416 // TODO(hiroshige): Here |contextDocument| is used as "node document" |
415 // while Step 14 uses |elementDocument| as "node document". Fix this. | 417 // while Step 14 uses |elementDocument| as "node document". Fix this. |
416 contextDocument->scriptRunner()->queueScriptForExecution(this, | 418 contextDocument->scriptRunner()->queueScriptForExecution(this, |
417 m_asyncExecType); | 419 m_asyncExecType); |
418 // Note that watchForLoad can immediately call pendingScriptFinished. | 420 // Note that watchForLoad can immediately call pendingScriptFinished. |
419 m_pendingScript->watchForLoad(this); | 421 m_pendingScript->watchForLoad(this); |
420 // The part "When the script is ready..." is implemented in | 422 // The part "When the script is ready..." is implemented in |
421 // ScriptRunner::notifyScriptReady(). | 423 // ScriptRunner::notifyScriptReady(). |
422 // TODO(hiroshige): Annotate it. | 424 // TODO(hiroshige): Annotate it. |
423 | 425 |
424 return true; | 426 return true; |
425 } | 427 } |
426 | 428 |
427 // 4th Clause: | 429 // 4th Clause: |
428 // - "If the script's type is "classic", and the element has a src attribute" | 430 // - "If the script's type is "classic", and the element has a src attribute" |
429 // TODO(hiroshige): Check the script's type and implement "module" case. | 431 // TODO(hiroshige): Check the script's type and implement "module" case. |
430 if (m_element->hasSourceAttribute()) { | 432 if (m_element->hasSourceAttribute()) { |
431 // "The element must be added to the set of scripts that will execute | 433 // "The element must be added to the set of scripts that will execute |
432 // as soon as possible of the node document of the script element at the | 434 // as soon as possible of the node document of the script element at the |
433 // time the prepare a script algorithm started." | 435 // time the prepare a script algorithm started." |
434 m_pendingScript = PendingScript::create(m_element.get(), m_resource.get()); | 436 m_pendingScript = |
437 ClassicPendingScript::create(m_element.get(), m_resource.get()); | |
435 m_asyncExecType = ScriptRunner::Async; | 438 m_asyncExecType = ScriptRunner::Async; |
436 m_pendingScript->startStreamingIfPossible(&m_element->document(), | 439 m_pendingScript->startStreamingIfPossible(&m_element->document(), |
437 ScriptStreamer::Async); | 440 ScriptStreamer::Async); |
438 // TODO(hiroshige): Here |contextDocument| is used as "node document" | 441 // TODO(hiroshige): Here |contextDocument| is used as "node document" |
439 // while Step 14 uses |elementDocument| as "node document". Fix this. | 442 // while Step 14 uses |elementDocument| as "node document". Fix this. |
440 contextDocument->scriptRunner()->queueScriptForExecution(this, | 443 contextDocument->scriptRunner()->queueScriptForExecution(this, |
441 m_asyncExecType); | 444 m_asyncExecType); |
442 // Note that watchForLoad can immediately call pendingScriptFinished. | 445 // Note that watchForLoad can immediately call pendingScriptFinished. |
443 m_pendingScript->watchForLoad(this); | 446 m_pendingScript->watchForLoad(this); |
444 // The part "When the script is ready..." is implemented in | 447 // The part "When the script is ready..." is implemented in |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
684 return true; | 687 return true; |
685 | 688 |
686 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc, | 689 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc, |
687 // if it was incremented in the earlier step." | 690 // if it was incremented in the earlier step." |
688 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer. | 691 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer. |
689 } | 692 } |
690 | 693 |
691 void ScriptLoader::execute() { | 694 void ScriptLoader::execute() { |
692 DCHECK(!m_willBeParserExecuted); | 695 DCHECK(!m_willBeParserExecuted); |
693 DCHECK(m_asyncExecType != ScriptRunner::None); | 696 DCHECK(m_asyncExecType != ScriptRunner::None); |
694 DCHECK(m_pendingScript->resource()); | 697 DCHECK(m_pendingScript->isExternal()); |
695 bool errorOccurred = false; | 698 bool errorOccurred = false; |
696 Script* script = m_pendingScript->getSource(KURL(), errorOccurred); | 699 Script* script = m_pendingScript->getSource(KURL(), errorOccurred); |
700 const bool wasCanceled = m_pendingScript->wasCanceled(); | |
697 detachPendingScript(); | 701 detachPendingScript(); |
698 if (errorOccurred) { | 702 if (errorOccurred) { |
699 dispatchErrorEvent(); | 703 dispatchErrorEvent(); |
700 } else if (!m_resource->wasCanceled()) { | 704 } else if (!wasCanceled) { |
701 if (executeScript(script)) | 705 if (executeScript(script)) |
702 dispatchLoadEvent(); | 706 dispatchLoadEvent(); |
703 else | 707 else |
704 dispatchErrorEvent(); | 708 dispatchErrorEvent(); |
705 } | 709 } |
706 m_resource = nullptr; | 710 m_resource = nullptr; |
707 } | 711 } |
708 | 712 |
709 void ScriptLoader::pendingScriptFinished(PendingScript* pendingScript) { | 713 void ScriptLoader::pendingScriptFinished(PendingScript* pendingScript) { |
710 DCHECK(!m_willBeParserExecuted); | 714 DCHECK(!m_willBeParserExecuted); |
711 DCHECK_EQ(m_pendingScript, pendingScript); | 715 DCHECK_EQ(m_pendingScript, pendingScript); |
712 DCHECK_EQ(pendingScript->resource(), m_resource); | 716 // DCHECK_EQ(pendingScript->resource(), m_resource); |
hiroshige
2017/04/07 22:40:40
Previously I thought this has a slight chance of f
| |
713 | 717 |
714 // We do not need this script in the memory cache. The primary goals of | 718 // We do not need this script in the memory cache. The primary goals of |
715 // sending this fetch request are to let the third party server know | 719 // sending this fetch request are to let the third party server know |
716 // about the document.write scripts intervention and populate the http | 720 // about the document.write scripts intervention and populate the http |
717 // cache for subsequent uses. | 721 // cache for subsequent uses. |
718 if (m_documentWriteIntervention == | 722 if (m_documentWriteIntervention == |
719 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { | 723 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { |
720 memoryCache()->remove(m_pendingScript->resource()); | 724 // memoryCache()->remove(m_pendingScript->resource()); |
721 m_pendingScript->stopWatchingForLoad(); | 725 m_pendingScript->stopWatchingForLoad(); |
722 return; | 726 return; |
723 } | 727 } |
724 | 728 |
725 DCHECK(m_asyncExecType != ScriptRunner::None); | 729 DCHECK(m_asyncExecType != ScriptRunner::None); |
726 | 730 |
727 Document* contextDocument = m_element->document().contextDocument(); | 731 Document* contextDocument = m_element->document().contextDocument(); |
728 if (!contextDocument) { | 732 if (!contextDocument) { |
729 detachPendingScript(); | 733 detachPendingScript(); |
730 return; | 734 return; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
772 // then abort these steps at this point. The script is not executed. | 776 // then abort these steps at this point. The script is not executed. |
773 return equalIgnoringCase(eventAttribute, "onload") || | 777 return equalIgnoringCase(eventAttribute, "onload") || |
774 equalIgnoringCase(eventAttribute, "onload()"); | 778 equalIgnoringCase(eventAttribute, "onload()"); |
775 } | 779 } |
776 | 780 |
777 String ScriptLoader::scriptContent() const { | 781 String ScriptLoader::scriptContent() const { |
778 return m_element->textFromChildren(); | 782 return m_element->textFromChildren(); |
779 } | 783 } |
780 | 784 |
781 } // namespace blink | 785 } // namespace blink |
OLD | NEW |