| 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/CompiledScript.h" |
| 27 #include "bindings/core/v8/ScriptController.h" | 28 #include "bindings/core/v8/ScriptController.h" |
| 28 #include "bindings/core/v8/ScriptSourceCode.h" | 29 #include "bindings/core/v8/ScriptSourceCode.h" |
| 29 #include "core/HTMLNames.h" | 30 #include "core/HTMLNames.h" |
| 30 #include "core/SVGNames.h" | 31 #include "core/SVGNames.h" |
| 31 #include "core/dom/Document.h" | 32 #include "core/dom/Document.h" |
| 32 #include "core/dom/DocumentParserTiming.h" | 33 #include "core/dom/DocumentParserTiming.h" |
| 33 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" | 34 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" |
| 34 #include "core/dom/ScriptLoaderClient.h" | 35 #include "core/dom/ScriptLoaderClient.h" |
| 35 #include "core/dom/ScriptRunner.h" | 36 #include "core/dom/ScriptRunner.h" |
| 36 #include "core/dom/ScriptableDocumentParser.h" | 37 #include "core/dom/ScriptableDocumentParser.h" |
| 38 #include "core/dom/TaskRunnerHelper.h" |
| 37 #include "core/dom/Text.h" | 39 #include "core/dom/Text.h" |
| 38 #include "core/events/Event.h" | 40 #include "core/events/Event.h" |
| 39 #include "core/fetch/AccessControlStatus.h" | 41 #include "core/fetch/AccessControlStatus.h" |
| 40 #include "core/fetch/FetchRequest.h" | 42 #include "core/fetch/FetchRequest.h" |
| 41 #include "core/fetch/MemoryCache.h" | 43 #include "core/fetch/MemoryCache.h" |
| 42 #include "core/fetch/ResourceFetcher.h" | 44 #include "core/fetch/ResourceFetcher.h" |
| 43 #include "core/frame/LocalFrame.h" | 45 #include "core/frame/LocalFrame.h" |
| 44 #include "core/frame/SubresourceIntegrity.h" | 46 #include "core/frame/SubresourceIntegrity.h" |
| 45 #include "core/frame/UseCounter.h" | 47 #include "core/frame/UseCounter.h" |
| 46 #include "core/frame/csp/ContentSecurityPolicy.h" | 48 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 47 #include "core/html/CrossOriginAttribute.h" | 49 #include "core/html/CrossOriginAttribute.h" |
| 48 #include "core/html/HTMLScriptElement.h" | 50 #include "core/html/HTMLScriptElement.h" |
| 49 #include "core/html/imports/HTMLImport.h" | 51 #include "core/html/imports/HTMLImport.h" |
| 50 #include "core/html/parser/HTMLParserIdioms.h" | 52 #include "core/html/parser/HTMLParserIdioms.h" |
| 51 #include "core/inspector/ConsoleMessage.h" | 53 #include "core/inspector/ConsoleMessage.h" |
| 52 #include "core/svg/SVGScriptElement.h" | 54 #include "core/svg/SVGScriptElement.h" |
| 53 #include "platform/WebFrameScheduler.h" | 55 #include "platform/WebFrameScheduler.h" |
| 54 #include "platform/network/mime/MIMETypeRegistry.h" | 56 #include "platform/network/mime/MIMETypeRegistry.h" |
| 55 #include "platform/weborigin/SecurityOrigin.h" | 57 #include "platform/weborigin/SecurityOrigin.h" |
| 58 #include "public/platform/Platform.h" |
| 56 #include "public/platform/WebCachePolicy.h" | 59 #include "public/platform/WebCachePolicy.h" |
| 57 #include "wtf/StdLibExtras.h" | 60 #include "wtf/StdLibExtras.h" |
| 58 #include "wtf/text/StringBuilder.h" | 61 #include "wtf/text/StringBuilder.h" |
| 59 #include "wtf/text/StringHash.h" | 62 #include "wtf/text/StringHash.h" |
| 60 | 63 |
| 61 namespace blink { | 64 namespace blink { |
| 62 | 65 |
| 63 ScriptLoader::ScriptLoader(Element* element, | 66 ScriptLoader::ScriptLoader(Element* element, |
| 64 bool parserInserted, | 67 bool parserInserted, |
| 65 bool alreadyStarted, | 68 bool alreadyStarted, |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 : UseCounter::SameOriginOtherScript) | 426 : UseCounter::SameOriginOtherScript) |
| 424 : (isText ? UseCounter::CrossOriginTextScript | 427 : (isText ? UseCounter::CrossOriginTextScript |
| 425 : isApplication ? UseCounter::CrossOriginApplicationScript | 428 : isApplication ? UseCounter::CrossOriginApplicationScript |
| 426 : UseCounter::CrossOriginOtherScript); | 429 : UseCounter::CrossOriginOtherScript); |
| 427 | 430 |
| 428 UseCounter::count(frame, feature); | 431 UseCounter::count(frame, feature); |
| 429 } | 432 } |
| 430 | 433 |
| 431 bool ScriptLoader::executeScript(const ScriptSourceCode& sourceCode) { | 434 bool ScriptLoader::executeScript(const ScriptSourceCode& sourceCode) { |
| 432 double scriptExecStartTime = monotonicallyIncreasingTime(); | 435 double scriptExecStartTime = monotonicallyIncreasingTime(); |
| 433 bool result = doExecuteScript(sourceCode); | |
| 434 | 436 |
| 435 // NOTE: we do not check m_willBeParserExecuted here, since | 437 CheckScriptResult result = checkScript(sourceCode); |
| 436 // m_willBeParserExecuted is false for inline scripts, and we want to | 438 if (result == CheckScriptResult::Proceed) { |
| 437 // include inline script execution time as part of parser blocked script | 439 AccessControlStatus accessControlStatus = |
| 438 // execution time. | 440 computeAccessControlStatus(sourceCode); |
| 439 if (m_asyncExecType == ScriptRunner::None) | 441 asCurrentScript( |
| 440 DocumentParserTiming::from(m_element->document()) | 442 [&sourceCode, accessControlStatus](ScriptController& scriptController) { |
| 441 .recordParserBlockedOnScriptExecutionDuration( | 443 scriptController.executeScriptInMainWorld(sourceCode, |
| 442 monotonicallyIncreasingTime() - scriptExecStartTime, | 444 accessControlStatus); |
| 443 wasCreatedDuringDocumentWrite()); | 445 }); |
| 444 return result; | 446 } |
| 447 |
| 448 recordParserBlockedOnScriptExecutionSince(scriptExecStartTime); |
| 449 return result != CheckScriptResult::Abort; |
| 445 } | 450 } |
| 446 | 451 |
| 447 bool ScriptLoader::doExecuteScript(const ScriptSourceCode& sourceCode) { | 452 void ScriptLoader::executeScriptAsync( |
| 453 const ScriptSourceCode& sourceCode, |
| 454 std::unique_ptr<ExecuteScriptAsyncCallback> completionCallback) { |
| 455 DCHECK(completionCallback); |
| 456 double scriptCompileStartTime = monotonicallyIncreasingTime(); |
| 457 |
| 458 AccessControlStatus accessControlStatus = |
| 459 computeAccessControlStatus(sourceCode); |
| 460 Document* elementDocument = &(m_element->document()); |
| 461 Document* contextDocument = elementDocument->contextDocument(); |
| 462 LocalFrame* frame = contextDocument->frame(); |
| 463 |
| 464 // TODO(jbroman): Could call checkScript here first. |
| 465 // This would arguably be redundant, especially if we call it synchronously. |
| 466 // On the other hand, it could also avoid compiling something that cannot |
| 467 // execute. |
| 468 |
| 469 CompiledScript* compiled = |
| 470 frame->script().compileScriptInMainWorld(sourceCode, accessControlStatus); |
| 471 recordParserBlockedOnScriptExecutionSince(scriptCompileStartTime); |
| 472 |
| 473 if (!compiled) { |
| 474 (*completionCallback)(true); |
| 475 return; |
| 476 } |
| 477 |
| 478 static const unsigned kSmallScriptSize = 30 * 1024; |
| 479 const bool shouldYield = sourceCode.source().length() >= kSmallScriptSize && |
| 480 Platform::current() |
| 481 ->mainThread() |
| 482 ->scheduler() |
| 483 ->shouldYieldForHighPriorityWork(); |
| 484 if (shouldYield) { |
| 485 std::unique_ptr<WTF::Closure> continuation = WTF::bind( |
| 486 &ScriptLoader::continueExecuteScriptAsync, wrapPersistent(this), |
| 487 wrapPersistent(compiled), wrapPersistent(elementDocument), |
| 488 WTF::passed(std::move(completionCallback))); |
| 489 TaskRunnerHelper::get(TaskType::Networking, frame) |
| 490 ->postTask(BLINK_FROM_HERE, std::move(continuation)); |
| 491 } else { |
| 492 continueExecuteScriptAsync(compiled, elementDocument, |
| 493 std::move(completionCallback)); |
| 494 } |
| 495 } |
| 496 |
| 497 void ScriptLoader::continueExecuteScriptAsync( |
| 498 CompiledScript* compiled, |
| 499 Document* elementDocumentWhenCompiled, |
| 500 std::unique_ptr<ExecuteScriptAsyncCallback> completionCallback) { |
| 501 double scriptExecStartTime = monotonicallyIncreasingTime(); |
| 502 |
| 503 CheckScriptResult result = checkScript(compiled->sourceCode()); |
| 504 if (result == CheckScriptResult::Proceed) { |
| 505 asCurrentScript([this, compiled, elementDocumentWhenCompiled]( |
| 506 ScriptController& scriptController) { |
| 507 if (m_element->document() == elementDocumentWhenCompiled) { |
| 508 scriptController.executeScriptInMainWorld(*compiled); |
| 509 } else { |
| 510 // This will recompile the source code. But it only happens when the |
| 511 // element moves to a new document at an inopportune time, which |
| 512 // should be rare. |
| 513 scriptController.executeScriptInMainWorld(compiled->sourceCode()); |
| 514 } |
| 515 }); |
| 516 } |
| 517 |
| 518 recordParserBlockedOnScriptExecutionSince(scriptExecStartTime); |
| 519 (*completionCallback)(result != CheckScriptResult::Abort); |
| 520 } |
| 521 |
| 522 ScriptLoader::CheckScriptResult ScriptLoader::checkScript( |
| 523 const ScriptSourceCode& sourceCode) { |
| 448 DCHECK(m_alreadyStarted); | 524 DCHECK(m_alreadyStarted); |
| 449 | 525 |
| 450 if (sourceCode.isEmpty()) | 526 if (sourceCode.isEmpty()) |
| 451 return true; | 527 return CheckScriptResult::NothingToDo; |
| 452 | 528 |
| 453 Document* elementDocument = &(m_element->document()); | 529 Document* elementDocument = &(m_element->document()); |
| 454 Document* contextDocument = elementDocument->contextDocument(); | 530 Document* contextDocument = elementDocument->contextDocument(); |
| 455 if (!contextDocument) | 531 if (!contextDocument) |
| 456 return true; | 532 return CheckScriptResult::NothingToDo; |
| 457 | 533 |
| 458 LocalFrame* frame = contextDocument->frame(); | 534 LocalFrame* frame = contextDocument->frame(); |
| 535 if (!frame) |
| 536 return CheckScriptResult::NothingToDo; |
| 459 | 537 |
| 460 const ContentSecurityPolicy* csp = elementDocument->contentSecurityPolicy(); | 538 const ContentSecurityPolicy* csp = elementDocument->contentSecurityPolicy(); |
| 461 bool shouldBypassMainWorldCSP = | 539 bool shouldBypassMainWorldCSP = |
| 462 (frame && frame->script().shouldBypassMainWorldCSP()) || | 540 (frame && frame->script().shouldBypassMainWorldCSP()) || |
| 463 csp->allowScriptWithHash(sourceCode.source(), | 541 csp->allowScriptWithHash(sourceCode.source(), |
| 464 ContentSecurityPolicy::InlineType::Block); | 542 ContentSecurityPolicy::InlineType::Block); |
| 465 | 543 |
| 466 AtomicString nonce = | 544 AtomicString nonce = |
| 467 ContentSecurityPolicy::isNonceableElement(m_element.get()) | 545 ContentSecurityPolicy::isNonceableElement(m_element.get()) |
| 468 ? m_element->fastGetAttribute(HTMLNames::nonceAttr) | 546 ? m_element->fastGetAttribute(HTMLNames::nonceAttr) |
| 469 : AtomicString(); | 547 : AtomicString(); |
| 470 if (!m_isExternalScript && | 548 if (!m_isExternalScript && |
| 471 (!shouldBypassMainWorldCSP && | 549 (!shouldBypassMainWorldCSP && |
| 472 !csp->allowInlineScript(m_element, elementDocument->url(), nonce, | 550 !csp->allowInlineScript(m_element, elementDocument->url(), nonce, |
| 473 m_startLineNumber, sourceCode.source()))) { | 551 m_startLineNumber, sourceCode.source()))) { |
| 474 return false; | 552 return CheckScriptResult::Abort; |
| 475 } | 553 } |
| 476 | 554 |
| 477 if (m_isExternalScript) { | 555 if (m_isExternalScript) { |
| 478 ScriptResource* resource = | 556 ScriptResource* resource = |
| 479 m_resource ? m_resource.get() : sourceCode.resource(); | 557 m_resource ? m_resource.get() : sourceCode.resource(); |
| 480 if (resource) { | 558 if (resource) { |
| 481 if (!resource->mimeTypeAllowedByNosniff()) { | 559 if (!resource->mimeTypeAllowedByNosniff()) { |
| 482 contextDocument->addConsoleMessage(ConsoleMessage::create( | 560 contextDocument->addConsoleMessage(ConsoleMessage::create( |
| 483 SecurityMessageSource, ErrorMessageLevel, | 561 SecurityMessageSource, ErrorMessageLevel, |
| 484 "Refused to execute script from '" + | 562 "Refused to execute script from '" + |
| 485 resource->url().elidedString() + "' because its MIME type ('" + | 563 resource->url().elidedString() + "' because its MIME type ('" + |
| 486 resource->httpContentType() + "') is not executable, and " | 564 resource->httpContentType() + "') is not executable, and " |
| 487 "strict MIME type checking is " | 565 "strict MIME type checking is " |
| 488 "enabled.")); | 566 "enabled.")); |
| 489 return false; | 567 return CheckScriptResult::Abort; |
| 490 } | 568 } |
| 491 | 569 |
| 492 String mimeType = resource->httpContentType(); | 570 String mimeType = resource->httpContentType(); |
| 493 if (mimeType.startsWith("image/") || mimeType == "text/csv" || | 571 if (mimeType.startsWith("image/") || mimeType == "text/csv" || |
| 494 mimeType.startsWith("audio/") || mimeType.startsWith("video/")) { | 572 mimeType.startsWith("audio/") || mimeType.startsWith("video/")) { |
| 495 contextDocument->addConsoleMessage(ConsoleMessage::create( | 573 contextDocument->addConsoleMessage(ConsoleMessage::create( |
| 496 SecurityMessageSource, ErrorMessageLevel, | 574 SecurityMessageSource, ErrorMessageLevel, |
| 497 "Refused to execute script from '" + | 575 "Refused to execute script from '" + |
| 498 resource->url().elidedString() + "' because its MIME type ('" + | 576 resource->url().elidedString() + "' because its MIME type ('" + |
| 499 mimeType + "') is not executable.")); | 577 mimeType + "') is not executable.")); |
| 500 if (mimeType.startsWith("image/")) | 578 if (mimeType.startsWith("image/")) |
| 501 UseCounter::count(frame, UseCounter::BlockedSniffingImageToScript); | 579 UseCounter::count(frame, UseCounter::BlockedSniffingImageToScript); |
| 502 else if (mimeType.startsWith("audio/")) | 580 else if (mimeType.startsWith("audio/")) |
| 503 UseCounter::count(frame, UseCounter::BlockedSniffingAudioToScript); | 581 UseCounter::count(frame, UseCounter::BlockedSniffingAudioToScript); |
| 504 else if (mimeType.startsWith("video/")) | 582 else if (mimeType.startsWith("video/")) |
| 505 UseCounter::count(frame, UseCounter::BlockedSniffingVideoToScript); | 583 UseCounter::count(frame, UseCounter::BlockedSniffingVideoToScript); |
| 506 else if (mimeType == "text/csv") | 584 else if (mimeType == "text/csv") |
| 507 UseCounter::count(frame, UseCounter::BlockedSniffingCSVToScript); | 585 UseCounter::count(frame, UseCounter::BlockedSniffingCSVToScript); |
| 508 return false; | 586 return CheckScriptResult::Abort; |
| 509 } | 587 } |
| 510 | 588 |
| 511 logScriptMIMEType(frame, resource, mimeType); | 589 logScriptMIMEType(frame, resource, mimeType); |
| 512 } | 590 } |
| 513 } | 591 } |
| 514 | 592 |
| 515 // FIXME: Can this be moved earlier in the function? | 593 return CheckScriptResult::Proceed; |
| 516 // Why are we ever attempting to execute scripts without a frame? | 594 } |
| 517 if (!frame) | |
| 518 return true; | |
| 519 | 595 |
| 596 AccessControlStatus ScriptLoader::computeAccessControlStatus( |
| 597 const ScriptSourceCode& sourceCode) { |
| 520 AccessControlStatus accessControlStatus = NotSharableCrossOrigin; | 598 AccessControlStatus accessControlStatus = NotSharableCrossOrigin; |
| 521 if (!m_isExternalScript) { | 599 if (!m_isExternalScript) { |
| 522 accessControlStatus = SharableCrossOrigin; | 600 accessControlStatus = SharableCrossOrigin; |
| 523 } else if (sourceCode.resource()) { | 601 } else if (sourceCode.resource()) { |
| 524 if (sourceCode.resource()->response().wasFetchedViaServiceWorker()) { | 602 if (sourceCode.resource()->response().wasFetchedViaServiceWorker()) { |
| 525 if (sourceCode.resource()->response().serviceWorkerResponseType() == | 603 if (sourceCode.resource()->response().serviceWorkerResponseType() == |
| 526 WebServiceWorkerResponseTypeOpaque) | 604 WebServiceWorkerResponseTypeOpaque) |
| 527 accessControlStatus = OpaqueResource; | 605 accessControlStatus = OpaqueResource; |
| 528 else | 606 else |
| 529 accessControlStatus = SharableCrossOrigin; | 607 accessControlStatus = SharableCrossOrigin; |
| 530 } else if (sourceCode.resource()->passesAccessControlCheck( | 608 } else if (sourceCode.resource()->passesAccessControlCheck( |
| 531 m_element->document().getSecurityOrigin())) { | 609 m_element->document().getSecurityOrigin())) { |
| 532 accessControlStatus = SharableCrossOrigin; | 610 accessControlStatus = SharableCrossOrigin; |
| 533 } | 611 } |
| 534 } | 612 } |
| 613 return accessControlStatus; |
| 614 } |
| 535 | 615 |
| 536 const bool isImportedScript = contextDocument != elementDocument; | 616 template <typename Functor> |
| 617 void ScriptLoader::asCurrentScript(const Functor& functor) { |
| 618 Document* elementDocument = &m_element->document(); |
| 619 Document* contextDocument = elementDocument->contextDocument(); |
| 620 LocalFrame* frame = contextDocument->frame(); |
| 621 if (!frame) |
| 622 return; |
| 623 |
| 537 // http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-block | 624 // http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-block |
| 538 // step 2.3 with additional support for HTML imports. | 625 // step 2.3 with additional support for HTML imports. |
| 626 const bool isImportedScript = contextDocument != elementDocument; |
| 539 IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer( | 627 IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer( |
| 540 m_isExternalScript || isImportedScript ? contextDocument : 0); | 628 m_isExternalScript || isImportedScript ? contextDocument : 0); |
| 541 | 629 |
| 542 if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) | 630 if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) |
| 543 contextDocument->pushCurrentScript(m_element); | 631 contextDocument->pushCurrentScript(m_element); |
| 544 | 632 |
| 545 // Create a script from the script element node, using the script | 633 functor(frame->script()); |
| 546 // block's source and the script block's type. | |
| 547 // Note: This is where the script is compiled and actually executed. | |
| 548 frame->script().executeScriptInMainWorld(sourceCode, accessControlStatus); | |
| 549 | 634 |
| 550 if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) { | 635 if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) { |
| 551 DCHECK(contextDocument->currentScript() == m_element); | 636 DCHECK(contextDocument->currentScript() == m_element); |
| 552 contextDocument->popCurrentScript(); | 637 contextDocument->popCurrentScript(); |
| 553 } | 638 } |
| 639 } |
| 554 | 640 |
| 555 return true; | 641 void ScriptLoader::recordParserBlockedOnScriptExecutionSince(double startTime) { |
| 642 // NOTE: we do not check m_willBeParserExecuted here, since |
| 643 // m_willBeParserExecuted is false for inline scripts, and we want to |
| 644 // include inline script execution time as part of parser blocked script |
| 645 // execution time. |
| 646 if (m_asyncExecType == ScriptRunner::None) { |
| 647 DocumentParserTiming::from(m_element->document()) |
| 648 .recordParserBlockedOnScriptExecutionDuration( |
| 649 monotonicallyIncreasingTime() - startTime, |
| 650 wasCreatedDuringDocumentWrite()); |
| 651 } |
| 556 } | 652 } |
| 557 | 653 |
| 558 void ScriptLoader::execute() { | 654 void ScriptLoader::execute() { |
| 559 DCHECK(!m_willBeParserExecuted); | 655 DCHECK(!m_willBeParserExecuted); |
| 560 DCHECK(m_asyncExecType != ScriptRunner::None); | 656 DCHECK(m_asyncExecType != ScriptRunner::None); |
| 561 DCHECK(m_pendingScript->resource()); | 657 DCHECK(m_pendingScript->resource()); |
| 562 bool errorOccurred = false; | 658 bool errorOccurred = false; |
| 563 ScriptSourceCode source = m_pendingScript->getSource(KURL(), errorOccurred); | 659 ScriptSourceCode source = m_pendingScript->getSource(KURL(), errorOccurred); |
| 564 m_pendingScript->dispose(); | 660 m_pendingScript->dispose(); |
| 565 if (errorOccurred) { | 661 if (errorOccurred) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 if (isHTMLScriptLoader(element)) | 742 if (isHTMLScriptLoader(element)) |
| 647 return toHTMLScriptElement(element)->loader(); | 743 return toHTMLScriptElement(element)->loader(); |
| 648 | 744 |
| 649 if (isSVGScriptLoader(element)) | 745 if (isSVGScriptLoader(element)) |
| 650 return toSVGScriptElement(element)->loader(); | 746 return toSVGScriptElement(element)->loader(); |
| 651 | 747 |
| 652 return 0; | 748 return 0; |
| 653 } | 749 } |
| 654 | 750 |
| 655 } // namespace blink | 751 } // namespace blink |
| OLD | NEW |