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 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 | 104 |
105 ScriptLoader::~ScriptLoader() {} | 105 ScriptLoader::~ScriptLoader() {} |
106 | 106 |
107 DEFINE_TRACE(ScriptLoader) { | 107 DEFINE_TRACE(ScriptLoader) { |
108 visitor->trace(m_element); | 108 visitor->trace(m_element); |
109 visitor->trace(m_resource); | 109 visitor->trace(m_resource); |
110 visitor->trace(m_pendingScript); | 110 visitor->trace(m_pendingScript); |
111 PendingScriptClient::trace(visitor); | 111 PendingScriptClient::trace(visitor); |
112 } | 112 } |
113 | 113 |
| 114 // static |
| 115 AccessControlStatus ScriptLoader::accessControlStatusForScript( |
| 116 bool isExternalScript, |
| 117 const ScriptResource* resource, |
| 118 const SecurityOrigin* scriptElementOrigin) { |
| 119 if (!isExternalScript) |
| 120 return SharableCrossOrigin; |
| 121 |
| 122 // TODO(jbroman): DCHECK(resource)? |
| 123 if (!resource) |
| 124 return NotSharableCrossOrigin; |
| 125 |
| 126 const auto& response = resource->response(); |
| 127 if (response.wasFetchedViaServiceWorker()) { |
| 128 return response.serviceWorkerResponseType() == |
| 129 WebServiceWorkerResponseTypeOpaque |
| 130 ? OpaqueResource |
| 131 : SharableCrossOrigin; |
| 132 } |
| 133 |
| 134 return resource->passesAccessControlCheck(scriptElementOrigin) |
| 135 ? SharableCrossOrigin |
| 136 : NotSharableCrossOrigin; |
| 137 } |
| 138 |
114 void ScriptLoader::setFetchDocWrittenScriptDeferIdle() { | 139 void ScriptLoader::setFetchDocWrittenScriptDeferIdle() { |
115 DCHECK(!m_createdDuringDocumentWrite); | 140 DCHECK(!m_createdDuringDocumentWrite); |
116 m_documentWriteIntervention = | 141 m_documentWriteIntervention = |
117 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle; | 142 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle; |
118 } | 143 } |
119 | 144 |
120 void ScriptLoader::didNotifySubtreeInsertionsToDocument() { | 145 void ScriptLoader::didNotifySubtreeInsertionsToDocument() { |
121 if (!m_parserInserted) | 146 if (!m_parserInserted) |
122 prepareScript(); // FIXME: Provide a real starting line number here. | 147 prepareScript(); // FIXME: Provide a real starting line number here. |
123 } | 148 } |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 ? (isText ? UseCounter::SameOriginTextScript | 678 ? (isText ? UseCounter::SameOriginTextScript |
654 : isApplication ? UseCounter::SameOriginApplicationScript | 679 : isApplication ? UseCounter::SameOriginApplicationScript |
655 : UseCounter::SameOriginOtherScript) | 680 : UseCounter::SameOriginOtherScript) |
656 : (isText ? UseCounter::CrossOriginTextScript | 681 : (isText ? UseCounter::CrossOriginTextScript |
657 : isApplication ? UseCounter::CrossOriginApplicationScript | 682 : isApplication ? UseCounter::CrossOriginApplicationScript |
658 : UseCounter::CrossOriginOtherScript); | 683 : UseCounter::CrossOriginOtherScript); |
659 | 684 |
660 UseCounter::count(frame, feature); | 685 UseCounter::count(frame, feature); |
661 } | 686 } |
662 | 687 |
663 bool ScriptLoader::executeScript(const ScriptSourceCode& sourceCode) { | 688 bool ScriptLoader::executeScript(const ScriptSourceCode& sourceCode, |
| 689 CompiledScript* compiledScript) { |
664 double scriptExecStartTime = monotonicallyIncreasingTime(); | 690 double scriptExecStartTime = monotonicallyIncreasingTime(); |
665 bool result = doExecuteScript(sourceCode); | 691 bool result = doExecuteScript(sourceCode, compiledScript); |
666 | 692 |
667 // NOTE: we do not check m_willBeParserExecuted here, since | 693 // NOTE: we do not check m_willBeParserExecuted here, since |
668 // m_willBeParserExecuted is false for inline scripts, and we want to | 694 // m_willBeParserExecuted is false for inline scripts, and we want to |
669 // include inline script execution time as part of parser blocked script | 695 // include inline script execution time as part of parser blocked script |
670 // execution time. | 696 // execution time. |
671 if (m_asyncExecType == ScriptRunner::None) | 697 if (m_asyncExecType == ScriptRunner::None) |
672 DocumentParserTiming::from(m_element->document()) | 698 DocumentParserTiming::from(m_element->document()) |
673 .recordParserBlockedOnScriptExecutionDuration( | 699 .recordParserBlockedOnScriptExecutionDuration( |
674 monotonicallyIncreasingTime() - scriptExecStartTime, | 700 monotonicallyIncreasingTime() - scriptExecStartTime, |
675 wasCreatedDuringDocumentWrite()); | 701 wasCreatedDuringDocumentWrite()); |
676 return result; | 702 return result; |
677 } | 703 } |
678 | 704 |
679 // https://html.spec.whatwg.org/#execute-the-script-block | 705 // https://html.spec.whatwg.org/#execute-the-script-block |
680 // with additional support for HTML imports. | 706 // with additional support for HTML imports. |
681 // Note that Steps 2 and 8 must be handled by the caller of doExecuteScript(), | 707 // Note that Steps 2 and 8 must be handled by the caller of doExecuteScript(), |
682 // i.e. load/error events are dispatched by the caller. | 708 // i.e. load/error events are dispatched by the caller. |
683 // Steps 3--7 are implemented here in doExecuteScript(). | 709 // Steps 3--7 are implemented here in doExecuteScript(). |
684 // TODO(hiroshige): Move event dispatching code to doExecuteScript(). | 710 // TODO(hiroshige): Move event dispatching code to doExecuteScript(). |
685 bool ScriptLoader::doExecuteScript(const ScriptSourceCode& sourceCode) { | 711 bool ScriptLoader::doExecuteScript(const ScriptSourceCode& sourceCode, |
| 712 CompiledScript* compiledScript) { |
686 DCHECK(m_alreadyStarted); | 713 DCHECK(m_alreadyStarted); |
687 | 714 |
688 if (sourceCode.isEmpty()) | 715 if (sourceCode.isEmpty()) |
689 return true; | 716 return true; |
690 | 717 |
691 Document* elementDocument = &(m_element->document()); | 718 Document* elementDocument = &(m_element->document()); |
692 Document* contextDocument = elementDocument->contextDocument(); | 719 Document* contextDocument = elementDocument->contextDocument(); |
693 if (!contextDocument) | 720 if (!contextDocument) |
694 return true; | 721 return true; |
695 | 722 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 else if (mimeType.startsWith("video/")) | 771 else if (mimeType.startsWith("video/")) |
745 UseCounter::count(frame, UseCounter::BlockedSniffingVideoToScript); | 772 UseCounter::count(frame, UseCounter::BlockedSniffingVideoToScript); |
746 else if (mimeType == "text/csv") | 773 else if (mimeType == "text/csv") |
747 UseCounter::count(frame, UseCounter::BlockedSniffingCSVToScript); | 774 UseCounter::count(frame, UseCounter::BlockedSniffingCSVToScript); |
748 return false; | 775 return false; |
749 } | 776 } |
750 | 777 |
751 logScriptMIMEType(frame, resource, mimeType); | 778 logScriptMIMEType(frame, resource, mimeType); |
752 } | 779 } |
753 | 780 |
754 AccessControlStatus accessControlStatus = NotSharableCrossOrigin; | 781 AccessControlStatus accessControlStatus = |
755 if (!m_isExternalScript) { | 782 accessControlStatusForScript(m_isExternalScript, sourceCode.resource(), |
756 accessControlStatus = SharableCrossOrigin; | 783 elementDocument->getSecurityOrigin()); |
757 } else if (sourceCode.resource()) { | |
758 if (sourceCode.resource()->response().wasFetchedViaServiceWorker()) { | |
759 if (sourceCode.resource()->response().serviceWorkerResponseType() == | |
760 WebServiceWorkerResponseTypeOpaque) | |
761 accessControlStatus = OpaqueResource; | |
762 else | |
763 accessControlStatus = SharableCrossOrigin; | |
764 } else if (sourceCode.resource()->passesAccessControlCheck( | |
765 m_element->document().getSecurityOrigin())) { | |
766 accessControlStatus = SharableCrossOrigin; | |
767 } | |
768 } | |
769 | 784 |
770 const bool isImportedScript = contextDocument != elementDocument; | 785 const bool isImportedScript = contextDocument != elementDocument; |
771 | 786 |
772 // 3. "If the script is from an external file, | 787 // 3. "If the script is from an external file, |
773 // or the script's type is module", | 788 // or the script's type is module", |
774 // then increment the ignore-destructive-writes counter of the | 789 // then increment the ignore-destructive-writes counter of the |
775 // script element's node document. Let neutralized doc be that Document." | 790 // script element's node document. Let neutralized doc be that Document." |
776 // TODO(hiroshige): Implement "module" case. | 791 // TODO(hiroshige): Implement "module" case. |
777 IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer( | 792 IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer( |
778 m_isExternalScript || isImportedScript ? contextDocument : 0); | 793 m_isExternalScript || isImportedScript ? contextDocument : 0); |
779 | 794 |
780 // 4. "Let old script element be the value to which the script element's | 795 // 4. "Let old script element be the value to which the script element's |
781 // node document's currentScript object was most recently set." | 796 // node document's currentScript object was most recently set." |
782 // This is implemented as push/popCurrentScript(). | 797 // This is implemented as push/popCurrentScript(). |
783 | 798 |
784 // 5. "Switch on the script's type:" | 799 // 5. "Switch on the script's type:" |
785 // - "classic": | 800 // - "classic": |
786 // 1. "If the script element's root is not a shadow root, | 801 // 1. "If the script element's root is not a shadow root, |
787 // then set the script element's node document's currentScript | 802 // then set the script element's node document's currentScript |
788 // attribute to the script element. Otherwise, set it to null." | 803 // attribute to the script element. Otherwise, set it to null." |
789 if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) | 804 if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) |
790 contextDocument->pushCurrentScript(m_element); | 805 contextDocument->pushCurrentScript(m_element); |
791 | 806 |
792 // 2. "Run the classic script given by the script's script." | 807 // 2. "Run the classic script given by the script's script." |
793 // Note: This is where the script is compiled and actually executed. | 808 // Note: This is where the script is compiled and actually executed. |
794 frame->script().executeScriptInMainWorld(sourceCode, accessControlStatus); | 809 if (compiledScript) { |
| 810 frame->script().executeScriptInMainWorld(*compiledScript); |
| 811 } else { |
| 812 frame->script().executeScriptInMainWorld(sourceCode, accessControlStatus); |
| 813 } |
795 | 814 |
796 // - "module": | 815 // - "module": |
797 // TODO(hiroshige): Implement this. | 816 // TODO(hiroshige): Implement this. |
798 | 817 |
799 // 6. "Set the script element's node document's currentScript attribute | 818 // 6. "Set the script element's node document's currentScript attribute |
800 // to old script element." | 819 // to old script element." |
801 if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) { | 820 if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) { |
802 DCHECK(contextDocument->currentScript() == m_element); | 821 DCHECK(contextDocument->currentScript() == m_element); |
803 contextDocument->popCurrentScript(); | 822 contextDocument->popCurrentScript(); |
804 } | 823 } |
805 | 824 |
806 return true; | 825 return true; |
807 | 826 |
808 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc, | 827 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc, |
809 // if it was incremented in the earlier step." | 828 // if it was incremented in the earlier step." |
810 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer. | 829 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer. |
811 } | 830 } |
812 | 831 |
813 void ScriptLoader::execute() { | 832 void ScriptLoader::execute() { |
814 DCHECK(!m_willBeParserExecuted); | 833 DCHECK(!m_willBeParserExecuted); |
815 DCHECK(m_asyncExecType != ScriptRunner::None); | 834 DCHECK(m_asyncExecType != ScriptRunner::None); |
816 DCHECK(m_pendingScript->resource()); | 835 DCHECK(m_pendingScript->resource()); |
817 bool errorOccurred = false; | 836 bool errorOccurred = false; |
818 ScriptSourceCode source = m_pendingScript->getSource(KURL(), errorOccurred); | 837 ScriptSourceCode source = m_pendingScript->getSource(KURL(), errorOccurred); |
| 838 CompiledScript* compiledScript = m_pendingScript->getCompiledScript(); |
819 detachPendingScript(); | 839 detachPendingScript(); |
820 if (errorOccurred) { | 840 if (errorOccurred) { |
821 dispatchErrorEvent(); | 841 dispatchErrorEvent(); |
822 } else if (!m_resource->wasCanceled()) { | 842 } else if (!m_resource->wasCanceled()) { |
823 if (executeScript(source)) | 843 if (executeScript(source, compiledScript)) |
824 dispatchLoadEvent(); | 844 dispatchLoadEvent(); |
825 else | 845 else |
826 dispatchErrorEvent(); | 846 dispatchErrorEvent(); |
827 } | 847 } |
828 m_resource = nullptr; | 848 m_resource = nullptr; |
829 } | 849 } |
830 | 850 |
831 void ScriptLoader::pendingScriptFinished(PendingScript* pendingScript) { | 851 void ScriptLoader::pendingScriptFinished(PendingScript* pendingScript) { |
| 852 LOG(ERROR) << "Finished loading pending script of size " |
| 853 << pendingScript->resource()->size(); |
832 DCHECK(!m_willBeParserExecuted); | 854 DCHECK(!m_willBeParserExecuted); |
833 DCHECK_EQ(m_pendingScript, pendingScript); | 855 DCHECK_EQ(m_pendingScript, pendingScript); |
834 DCHECK_EQ(pendingScript->resource(), m_resource); | 856 DCHECK_EQ(pendingScript->resource(), m_resource); |
835 | 857 |
836 // We do not need this script in the memory cache. The primary goals of | 858 // We do not need this script in the memory cache. The primary goals of |
837 // sending this fetch request are to let the third party server know | 859 // sending this fetch request are to let the third party server know |
838 // about the document.write scripts intervention and populate the http | 860 // about the document.write scripts intervention and populate the http |
839 // cache for subsequent uses. | 861 // cache for subsequent uses. |
840 if (m_documentWriteIntervention == | 862 if (m_documentWriteIntervention == |
841 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { | 863 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
915 if (isHTMLScriptLoader(element)) | 937 if (isHTMLScriptLoader(element)) |
916 return toHTMLScriptElement(element)->loader(); | 938 return toHTMLScriptElement(element)->loader(); |
917 | 939 |
918 if (isSVGScriptLoader(element)) | 940 if (isSVGScriptLoader(element)) |
919 return toSVGScriptElement(element)->loader(); | 941 return toSVGScriptElement(element)->loader(); |
920 | 942 |
921 return 0; | 943 return 0; |
922 } | 944 } |
923 | 945 |
924 } // namespace blink | 946 } // namespace blink |
OLD | NEW |