| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. | 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 | 150 |
| 151 using namespace HTMLNames; | 151 using namespace HTMLNames; |
| 152 | 152 |
| 153 HTMLParserScriptRunner::HTMLParserScriptRunner( | 153 HTMLParserScriptRunner::HTMLParserScriptRunner( |
| 154 HTMLParserReentryPermit* reentryPermit, | 154 HTMLParserReentryPermit* reentryPermit, |
| 155 Document* document, | 155 Document* document, |
| 156 HTMLParserScriptRunnerHost* host) | 156 HTMLParserScriptRunnerHost* host) |
| 157 : m_reentryPermit(reentryPermit), | 157 : m_reentryPermit(reentryPermit), |
| 158 m_document(document), | 158 m_document(document), |
| 159 m_host(host), | 159 m_host(host), |
| 160 m_parserBlockingScript(PendingScript::create(nullptr, nullptr)) { | 160 m_parserBlockingScript(nullptr) { |
| 161 DCHECK(m_host); | 161 DCHECK(m_host); |
| 162 } | 162 } |
| 163 | 163 |
| 164 HTMLParserScriptRunner::~HTMLParserScriptRunner() { | 164 HTMLParserScriptRunner::~HTMLParserScriptRunner() { |
| 165 // Verify that detach() has been called. | 165 // Verify that detach() has been called. |
| 166 DCHECK(!m_document); | 166 DCHECK(!m_document); |
| 167 } | 167 } |
| 168 | 168 |
| 169 void HTMLParserScriptRunner::detach() { | 169 void HTMLParserScriptRunner::detach() { |
| 170 if (!m_document) | 170 if (!m_document) |
| 171 return; | 171 return; |
| 172 | 172 |
| 173 m_parserBlockingScript->dispose(); | 173 if (m_parserBlockingScript) |
| 174 m_parserBlockingScript->dispose(); |
| 175 m_parserBlockingScript = nullptr; |
| 174 | 176 |
| 175 while (!m_scriptsToExecuteAfterParsing.isEmpty()) { | 177 while (!m_scriptsToExecuteAfterParsing.isEmpty()) { |
| 176 PendingScript* pendingScript = m_scriptsToExecuteAfterParsing.takeFirst(); | 178 PendingScript* pendingScript = m_scriptsToExecuteAfterParsing.takeFirst(); |
| 177 pendingScript->dispose(); | 179 pendingScript->dispose(); |
| 178 } | 180 } |
| 179 m_document = nullptr; | 181 m_document = nullptr; |
| 180 // m_reentryPermit is not cleared here, because the script runner | 182 // m_reentryPermit is not cleared here, because the script runner |
| 181 // may continue to run pending scripts after the parser has | 183 // may continue to run pending scripts after the parser has |
| 182 // detached. | 184 // detached. |
| 183 } | 185 } |
| 184 | 186 |
| 185 bool HTMLParserScriptRunner::isParserBlockingScriptReady() { | 187 bool HTMLParserScriptRunner::isParserBlockingScriptReady() { |
| 188 DCHECK(parserBlockingScript()); |
| 186 if (!m_document->isScriptExecutionReady()) | 189 if (!m_document->isScriptExecutionReady()) |
| 187 return false; | 190 return false; |
| 188 return m_parserBlockingScript->isReady(); | 191 return parserBlockingScript()->isReady(); |
| 189 } | 192 } |
| 190 | 193 |
| 191 // This has two callers and corresponds to different concepts in the spec: | 194 // This has two callers and corresponds to different concepts in the spec: |
| 192 // - When called from executeParsingBlockingScripts(), this corresponds to some | 195 // - When called from executeParsingBlockingScripts(), this corresponds to some |
| 193 // steps of the "Otherwise" Clause of 'An end tag whose tag name is "script"' | 196 // steps of the "Otherwise" Clause of 'An end tag whose tag name is "script"' |
| 194 // https://html.spec.whatwg.org/#scriptEndTag | 197 // https://html.spec.whatwg.org/#scriptEndTag |
| 195 // - When called from executeScriptsWaitingForParsing(), this corresponds | 198 // - When called from executeScriptsWaitingForParsing(), this corresponds |
| 196 // https://html.spec.whatwg.org/#execute-the-script-block | 199 // https://html.spec.whatwg.org/#execute-the-script-block |
| 197 // and thus currently this function does more than specced. | 200 // and thus currently this function does more than specced. |
| 198 // TODO(hiroshige): Make the spec and implementation consistent. | 201 // TODO(hiroshige): Make the spec and implementation consistent. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 221 | 224 |
| 222 TextPosition scriptStartPosition = pendingScript->startingPosition(); | 225 TextPosition scriptStartPosition = pendingScript->startingPosition(); |
| 223 double scriptParserBlockingTime = | 226 double scriptParserBlockingTime = |
| 224 pendingScript->parserBlockingLoadStartTime(); | 227 pendingScript->parserBlockingLoadStartTime(); |
| 225 Element* element = pendingScript->element(); | 228 Element* element = pendingScript->element(); |
| 226 | 229 |
| 227 // 1. "Let the script be the pending parsing-blocking script. | 230 // 1. "Let the script be the pending parsing-blocking script. |
| 228 // There is no longer a pending parsing-blocking script." | 231 // There is no longer a pending parsing-blocking script." |
| 229 // Clear the pending script before possible re-entrancy from executeScript() | 232 // Clear the pending script before possible re-entrancy from executeScript() |
| 230 pendingScript->dispose(); | 233 pendingScript->dispose(); |
| 234 pendingScript = nullptr; |
| 235 |
| 236 if (pendingScriptType == ScriptStreamer::ParsingBlocking) { |
| 237 m_parserBlockingScript = nullptr; |
| 238 } |
| 231 | 239 |
| 232 if (ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element)) { | 240 if (ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element)) { |
| 233 // 7. "Increment the parser's script nesting level by one (it should be | 241 // 7. "Increment the parser's script nesting level by one (it should be |
| 234 // zero before this step, so this sets it to one)." | 242 // zero before this step, so this sets it to one)." |
| 235 HTMLParserReentryPermit::ScriptNestingLevelIncrementer | 243 HTMLParserReentryPermit::ScriptNestingLevelIncrementer |
| 236 nestingLevelIncrementer = | 244 nestingLevelIncrementer = |
| 237 m_reentryPermit->incrementScriptNestingLevel(); | 245 m_reentryPermit->incrementScriptNestingLevel(); |
| 238 | 246 |
| 239 IgnoreDestructiveWriteCountIncrementer | 247 IgnoreDestructiveWriteCountIncrementer |
| 240 ignoreDestructiveWriteCountIncrementer(m_document); | 248 ignoreDestructiveWriteCountIncrementer(m_document); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 "network connectivity. "; | 313 "network connectivity. "; |
| 306 document.addConsoleMessage( | 314 document.addConsoleMessage( |
| 307 ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, message)); | 315 ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, message)); |
| 308 WTFLogAlways("%s", message.utf8().data()); | 316 WTFLogAlways("%s", message.utf8().data()); |
| 309 } | 317 } |
| 310 | 318 |
| 311 void HTMLParserScriptRunner::possiblyFetchBlockedDocWriteScript( | 319 void HTMLParserScriptRunner::possiblyFetchBlockedDocWriteScript( |
| 312 PendingScript* pendingScript) { | 320 PendingScript* pendingScript) { |
| 313 // If the script was blocked as part of document.write intervention, | 321 // If the script was blocked as part of document.write intervention, |
| 314 // then send an asynchronous GET request with an interventions header. | 322 // then send an asynchronous GET request with an interventions header. |
| 315 TextPosition startingPosition; | |
| 316 bool isParserInserted = false; | |
| 317 | 323 |
| 318 if (m_parserBlockingScript != pendingScript) | 324 if (!parserBlockingScript()) |
| 319 return; | 325 return; |
| 320 | 326 |
| 321 Element* element = m_parserBlockingScript->element(); | 327 if (parserBlockingScript() != pendingScript) |
| 322 if (!element) | |
| 323 return; | 328 return; |
| 324 | 329 |
| 330 Element* element = parserBlockingScript()->element(); |
| 331 |
| 325 ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element); | 332 ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element); |
| 326 if (!scriptLoader || !scriptLoader->disallowedFetchForDocWrittenScript()) | 333 if (!scriptLoader || !scriptLoader->disallowedFetchForDocWrittenScript()) |
| 327 return; | 334 return; |
| 328 | 335 |
| 329 if (!pendingScript->errorOccurred()) { | 336 if (!pendingScript->errorOccurred()) { |
| 330 emitWarningForDocWriteScripts(pendingScript->resource()->url().getString(), | 337 emitWarningForDocWriteScripts(pendingScript->resource()->url().getString(), |
| 331 *m_document); | 338 *m_document); |
| 332 return; | 339 return; |
| 333 } | 340 } |
| 334 | 341 |
| 335 // Due to dependency violation, not able to check the exact error to be | 342 // Due to dependency violation, not able to check the exact error to be |
| 336 // ERR_CACHE_MISS but other errors are rare with | 343 // ERR_CACHE_MISS but other errors are rare with |
| 337 // WebCachePolicy::ReturnCacheDataDontLoad. | 344 // WebCachePolicy::ReturnCacheDataDontLoad. |
| 338 | 345 |
| 339 emitErrorForDocWriteScripts(pendingScript->resource()->url().getString(), | 346 emitErrorForDocWriteScripts(pendingScript->resource()->url().getString(), |
| 340 *m_document); | 347 *m_document); |
| 341 startingPosition = m_parserBlockingScript->startingPosition(); | 348 TextPosition startingPosition = parserBlockingScript()->startingPosition(); |
| 342 isParserInserted = scriptLoader->isParserInserted(); | 349 bool isParserInserted = scriptLoader->isParserInserted(); |
| 343 // Remove this resource entry from memory cache as the new request | 350 // Remove this resource entry from memory cache as the new request |
| 344 // should not join onto this existing entry. | 351 // should not join onto this existing entry. |
| 345 memoryCache()->remove(pendingScript->resource()); | 352 memoryCache()->remove(pendingScript->resource()); |
| 346 fetchBlockedDocWriteScript(element, isParserInserted, startingPosition); | 353 fetchBlockedDocWriteScript(element, isParserInserted, startingPosition); |
| 347 } | 354 } |
| 348 | 355 |
| 349 void HTMLParserScriptRunner::pendingScriptFinished( | 356 void HTMLParserScriptRunner::pendingScriptFinished( |
| 350 PendingScript* pendingScript) { | 357 PendingScript* pendingScript) { |
| 351 // Handle cancellations of parser-blocking script loads without | 358 // Handle cancellations of parser-blocking script loads without |
| 352 // notifying the host (i.e., parser) if these were initiated by nested | 359 // notifying the host (i.e., parser) if these were initiated by nested |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 // "outer" tree construction stage.)" | 402 // "outer" tree construction stage.)" |
| 396 // TODO(hiroshige): set the parser pause flag to true here. | 403 // TODO(hiroshige): set the parser pause flag to true here. |
| 397 | 404 |
| 398 // Unwind to the outermost HTMLParserScriptRunner::processScriptElement | 405 // Unwind to the outermost HTMLParserScriptRunner::processScriptElement |
| 399 // before continuing parsing. | 406 // before continuing parsing. |
| 400 return; | 407 return; |
| 401 } | 408 } |
| 402 | 409 |
| 403 // - "Otherwise": | 410 // - "Otherwise": |
| 404 | 411 |
| 405 traceParserBlockingScript(m_parserBlockingScript.get(), | 412 traceParserBlockingScript(parserBlockingScript(), |
| 406 !m_document->isScriptExecutionReady()); | 413 !m_document->isScriptExecutionReady()); |
| 407 m_parserBlockingScript->markParserBlockingLoadStartTime(); | 414 m_parserBlockingScript->markParserBlockingLoadStartTime(); |
| 408 | 415 |
| 409 // If preload scanner got created, it is missing the source after the | 416 // If preload scanner got created, it is missing the source after the |
| 410 // current insertion point. Append it and scan. | 417 // current insertion point. Append it and scan. |
| 411 if (!hadPreloadScanner && m_host->hasPreloadScanner()) | 418 if (!hadPreloadScanner && m_host->hasPreloadScanner()) |
| 412 m_host->appendCurrentInputStreamToPreloadScannerAndScan(); | 419 m_host->appendCurrentInputStreamToPreloadScannerAndScan(); |
| 413 | 420 |
| 414 executeParsingBlockingScripts(); | 421 executeParsingBlockingScripts(); |
| 415 } | 422 } |
| 416 } | 423 } |
| 417 | 424 |
| 418 bool HTMLParserScriptRunner::hasParserBlockingScript() const { | 425 bool HTMLParserScriptRunner::hasParserBlockingScript() const { |
| 419 return !!m_parserBlockingScript->element(); | 426 return parserBlockingScript(); |
| 420 } | 427 } |
| 421 | 428 |
| 422 // The "Otherwise" Clause of 'An end tag whose tag name is "script"' | 429 // The "Otherwise" Clause of 'An end tag whose tag name is "script"' |
| 423 // https://html.spec.whatwg.org/#scriptEndTag | 430 // https://html.spec.whatwg.org/#scriptEndTag |
| 424 void HTMLParserScriptRunner::executeParsingBlockingScripts() { | 431 void HTMLParserScriptRunner::executeParsingBlockingScripts() { |
| 425 // 3. "If (1) the parser's Document has a style sheet that is blocking scripts | 432 // 3. "If (1) the parser's Document has a style sheet that is blocking scripts |
| 426 // or (2) the script's "ready to be parser-executed" flag is not set: | 433 // or (2) the script's "ready to be parser-executed" flag is not set: |
| 427 // spin the event loop | 434 // spin the event loop |
| 428 // until the parser's Document has no style sheet that is blocking scripts | 435 // until the parser's Document has no style sheet that is blocking scripts |
| 429 // and the script's "ready to be parser-executed" flag is set." | 436 // and the script's "ready to be parser-executed" flag is set." |
| 430 // | 437 // |
| 431 // These conditions correspond to isParserBlockingScriptReady() and | 438 // These conditions correspond to isParserBlockingScriptReady() and |
| 432 // if it is false, executeParsingBlockingScripts() will be called later | 439 // if it is false, executeParsingBlockingScripts() will be called later |
| 433 // when isParserBlockingScriptReady() becomes true: | 440 // when isParserBlockingScriptReady() becomes true: |
| 434 // (1) from HTMLParserScriptRunner::executeScriptsWaitingForResources(), or | 441 // (1) from HTMLParserScriptRunner::executeScriptsWaitingForResources(), or |
| 435 // (2) from HTMLParserScriptRunner::executeScriptsWaitingForLoad(). | 442 // (2) from HTMLParserScriptRunner::executeScriptsWaitingForLoad(). |
| 436 while (hasParserBlockingScript() && isParserBlockingScriptReady()) { | 443 while (hasParserBlockingScript() && isParserBlockingScriptReady()) { |
| 437 DCHECK(m_document); | 444 DCHECK(m_document); |
| 438 DCHECK(!isExecutingScript()); | 445 DCHECK(!isExecutingScript()); |
| 439 DCHECK(m_document->isScriptExecutionReady()); | 446 DCHECK(m_document->isScriptExecutionReady()); |
| 440 | 447 |
| 441 // 6. "Let the insertion point be just before the next input character." | 448 // 6. "Let the insertion point be just before the next input character." |
| 442 InsertionPointRecord insertionPointRecord(m_host->inputStream()); | 449 InsertionPointRecord insertionPointRecord(m_host->inputStream()); |
| 443 | 450 |
| 444 // 1., 7.--9. | 451 // 1., 7.--9. |
| 445 executePendingScriptAndDispatchEvent(m_parserBlockingScript.get(), | 452 executePendingScriptAndDispatchEvent(m_parserBlockingScript, |
| 446 ScriptStreamer::ParsingBlocking); | 453 ScriptStreamer::ParsingBlocking); |
| 447 | 454 |
| 448 // 10. "Let the insertion point be undefined again." | 455 // 10. "Let the insertion point be undefined again." |
| 449 // Implemented as ~InsertionPointRecord(). | 456 // Implemented as ~InsertionPointRecord(). |
| 450 | 457 |
| 451 // 11. "If there is once again a pending parsing-blocking script, then | 458 // 11. "If there is once again a pending parsing-blocking script, then |
| 452 // repeat these steps from step 1." | 459 // repeat these steps from step 1." |
| 453 } | 460 } |
| 454 } | 461 } |
| 455 | 462 |
| 456 void HTMLParserScriptRunner::executeScriptsWaitingForLoad( | 463 void HTMLParserScriptRunner::executeScriptsWaitingForLoad( |
| 457 PendingScript* pendingScript) { | 464 PendingScript* pendingScript) { |
| 458 TRACE_EVENT0("blink", "HTMLParserScriptRunner::executeScriptsWaitingForLoad"); | 465 TRACE_EVENT0("blink", "HTMLParserScriptRunner::executeScriptsWaitingForLoad"); |
| 459 DCHECK(!isExecutingScript()); | 466 DCHECK(!isExecutingScript()); |
| 460 DCHECK(hasParserBlockingScript()); | 467 DCHECK(hasParserBlockingScript()); |
| 461 DCHECK_EQ(pendingScript, m_parserBlockingScript); | 468 DCHECK_EQ(pendingScript, parserBlockingScript()); |
| 462 DCHECK(m_parserBlockingScript->isReady()); | 469 DCHECK(parserBlockingScript()->isReady()); |
| 463 executeParsingBlockingScripts(); | 470 executeParsingBlockingScripts(); |
| 464 } | 471 } |
| 465 | 472 |
| 466 void HTMLParserScriptRunner::executeScriptsWaitingForResources() { | 473 void HTMLParserScriptRunner::executeScriptsWaitingForResources() { |
| 467 TRACE_EVENT0("blink", | 474 TRACE_EVENT0("blink", |
| 468 "HTMLParserScriptRunner::executeScriptsWaitingForResources"); | 475 "HTMLParserScriptRunner::executeScriptsWaitingForResources"); |
| 469 DCHECK(m_document); | 476 DCHECK(m_document); |
| 470 DCHECK(!isExecutingScript()); | 477 DCHECK(!isExecutingScript()); |
| 471 DCHECK(m_document->isScriptExecutionReady()); | 478 DCHECK(m_document->isScriptExecutionReady()); |
| 472 executeParsingBlockingScripts(); | 479 executeParsingBlockingScripts(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 // from substep 1." | 522 // from substep 1." |
| 516 } | 523 } |
| 517 return true; | 524 return true; |
| 518 } | 525 } |
| 519 | 526 |
| 520 // 2nd Clause, Step 23 of https://html.spec.whatwg.org/#prepare-a-script | 527 // 2nd Clause, Step 23 of https://html.spec.whatwg.org/#prepare-a-script |
| 521 void HTMLParserScriptRunner::requestParsingBlockingScript(Element* element) { | 528 void HTMLParserScriptRunner::requestParsingBlockingScript(Element* element) { |
| 522 // "The element is the pending parsing-blocking script of the Document of | 529 // "The element is the pending parsing-blocking script of the Document of |
| 523 // the parser that created the element. | 530 // the parser that created the element. |
| 524 // (There can only be one such script per Document at a time.)" | 531 // (There can only be one such script per Document at a time.)" |
| 525 if (!requestPendingScript(m_parserBlockingScript.get(), element)) | 532 CHECK(!parserBlockingScript()); |
| 533 m_parserBlockingScript = requestPendingScript(element); |
| 534 if (!parserBlockingScript()) |
| 526 return; | 535 return; |
| 527 | 536 |
| 528 DCHECK(m_parserBlockingScript->resource()); | 537 DCHECK(parserBlockingScript()->resource()); |
| 529 | 538 |
| 530 // We only care about a load callback if resource is not already in the cache. | 539 // We only care about a load callback if resource is not already in the cache. |
| 531 // Callers will attempt to run the m_parserBlockingScript if possible before | 540 // Callers will attempt to run the m_parserBlockingScript if possible before |
| 532 // returning control to the parser. | 541 // returning control to the parser. |
| 533 if (!m_parserBlockingScript->isReady()) { | 542 if (!parserBlockingScript()->isReady()) { |
| 534 if (m_document->frame()) { | 543 if (m_document->frame()) { |
| 535 ScriptState* scriptState = ScriptState::forMainWorld(m_document->frame()); | 544 ScriptState* scriptState = ScriptState::forMainWorld(m_document->frame()); |
| 536 if (scriptState) { | 545 if (scriptState) { |
| 537 ScriptStreamer::startStreaming( | 546 ScriptStreamer::startStreaming( |
| 538 m_parserBlockingScript.get(), ScriptStreamer::ParsingBlocking, | 547 m_parserBlockingScript, ScriptStreamer::ParsingBlocking, |
| 539 m_document->frame()->settings(), scriptState, | 548 m_document->frame()->settings(), scriptState, |
| 540 TaskRunnerHelper::get(TaskType::Networking, m_document)); | 549 TaskRunnerHelper::get(TaskType::Networking, m_document)); |
| 541 } | 550 } |
| 542 } | 551 } |
| 543 | 552 |
| 544 m_parserBlockingScript->watchForLoad(this); | 553 m_parserBlockingScript->watchForLoad(this); |
| 545 } | 554 } |
| 546 } | 555 } |
| 547 | 556 |
| 548 // 1st Clause, Step 23 of https://html.spec.whatwg.org/#prepare-a-script | 557 // 1st Clause, Step 23 of https://html.spec.whatwg.org/#prepare-a-script |
| 549 void HTMLParserScriptRunner::requestDeferredScript(Element* element) { | 558 void HTMLParserScriptRunner::requestDeferredScript(Element* element) { |
| 550 PendingScript* pendingScript = PendingScript::create(nullptr, nullptr); | 559 PendingScript* pendingScript = requestPendingScript(element); |
| 551 if (!requestPendingScript(pendingScript, element)) | 560 if (!pendingScript) |
| 552 return; | 561 return; |
| 553 | 562 |
| 554 if (m_document->frame() && !pendingScript->isReady()) { | 563 if (m_document->frame() && !pendingScript->isReady()) { |
| 555 ScriptState* scriptState = ScriptState::forMainWorld(m_document->frame()); | 564 ScriptState* scriptState = ScriptState::forMainWorld(m_document->frame()); |
| 556 if (scriptState) { | 565 if (scriptState) { |
| 557 ScriptStreamer::startStreaming( | 566 ScriptStreamer::startStreaming( |
| 558 pendingScript, ScriptStreamer::Deferred, | 567 pendingScript, ScriptStreamer::Deferred, |
| 559 m_document->frame()->settings(), scriptState, | 568 m_document->frame()->settings(), scriptState, |
| 560 TaskRunnerHelper::get(TaskType::Networking, m_document)); | 569 TaskRunnerHelper::get(TaskType::Networking, m_document)); |
| 561 } | 570 } |
| 562 } | 571 } |
| 563 | 572 |
| 564 DCHECK(pendingScript->resource()); | 573 DCHECK(pendingScript->resource()); |
| 565 | 574 |
| 566 // "Add the element to the end of the list of scripts that will execute | 575 // "Add the element to the end of the list of scripts that will execute |
| 567 // when the document has finished parsing associated with the Document | 576 // when the document has finished parsing associated with the Document |
| 568 // of the parser that created the element." | 577 // of the parser that created the element." |
| 569 m_scriptsToExecuteAfterParsing.append(pendingScript); | 578 m_scriptsToExecuteAfterParsing.append(pendingScript); |
| 570 } | 579 } |
| 571 | 580 |
| 572 bool HTMLParserScriptRunner::requestPendingScript(PendingScript* pendingScript, | 581 PendingScript* HTMLParserScriptRunner::requestPendingScript( |
| 573 Element* script) const { | 582 Element* element) const { |
| 574 DCHECK(!pendingScript->element()); | |
| 575 pendingScript->setElement(script); | |
| 576 // This should correctly return 0 for empty or invalid srcValues. | 583 // This should correctly return 0 for empty or invalid srcValues. |
| 577 ScriptResource* resource = toScriptLoaderIfPossible(script)->resource(); | 584 ScriptResource* resource = toScriptLoaderIfPossible(element)->resource(); |
| 578 if (!resource) { | 585 if (!resource) { |
| 579 DVLOG(1) << "Not implemented."; // Dispatch error event. | 586 DVLOG(1) << "Not implemented."; // Dispatch error event. |
| 580 return false; | 587 return nullptr; |
| 581 } | 588 } |
| 582 pendingScript->setScriptResource(resource); | 589 |
| 583 return true; | 590 return PendingScript::create(element, resource); |
| 584 } | 591 } |
| 585 | 592 |
| 586 // The initial steps for 'An end tag whose tag name is "script"' | 593 // The initial steps for 'An end tag whose tag name is "script"' |
| 587 // https://html.spec.whatwg.org/#scriptEndTag | 594 // https://html.spec.whatwg.org/#scriptEndTag |
| 588 void HTMLParserScriptRunner::processScriptElementInternal( | 595 void HTMLParserScriptRunner::processScriptElementInternal( |
| 589 Element* script, | 596 Element* script, |
| 590 const TextPosition& scriptStartPosition) { | 597 const TextPosition& scriptStartPosition) { |
| 591 DCHECK(m_document); | 598 DCHECK(m_document); |
| 592 DCHECK(!hasParserBlockingScript()); | 599 DCHECK(!hasParserBlockingScript()); |
| 593 { | 600 { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 // 1st Clause of Step 23. | 637 // 1st Clause of Step 23. |
| 631 requestDeferredScript(script); | 638 requestDeferredScript(script); |
| 632 } else if (scriptLoader->readyToBeParserExecuted()) { | 639 } else if (scriptLoader->readyToBeParserExecuted()) { |
| 633 // 5th Clause of Step 23. | 640 // 5th Clause of Step 23. |
| 634 // "If ... it's an HTML parser | 641 // "If ... it's an HTML parser |
| 635 // whose script nesting level is not greater than one" | 642 // whose script nesting level is not greater than one" |
| 636 if (m_reentryPermit->scriptNestingLevel() == 1u) { | 643 if (m_reentryPermit->scriptNestingLevel() == 1u) { |
| 637 // "The element is the pending parsing-blocking script of the | 644 // "The element is the pending parsing-blocking script of the |
| 638 // Document of the parser that created the element. | 645 // Document of the parser that created the element. |
| 639 // (There can only be one such script per Document at a time.)" | 646 // (There can only be one such script per Document at a time.)" |
| 640 m_parserBlockingScript->setElement(script); | 647 CHECK(!m_parserBlockingScript); |
| 641 m_parserBlockingScript->setStartingPosition(scriptStartPosition); | 648 m_parserBlockingScript = |
| 649 PendingScript::create(script, scriptStartPosition); |
| 642 } else { | 650 } else { |
| 643 // 6th Clause of Step 23. | 651 // 6th Clause of Step 23. |
| 644 // "Immediately execute the script block, | 652 // "Immediately execute the script block, |
| 645 // even if other scripts are already executing." | 653 // even if other scripts are already executing." |
| 646 // TODO(hiroshige): Merge the block into ScriptLoader::prepareScript(). | 654 // TODO(hiroshige): Merge the block into ScriptLoader::prepareScript(). |
| 647 DCHECK_GT(m_reentryPermit->scriptNestingLevel(), 1u); | 655 DCHECK_GT(m_reentryPermit->scriptNestingLevel(), 1u); |
| 648 m_parserBlockingScript->dispose(); | 656 if (m_parserBlockingScript) |
| 657 m_parserBlockingScript->dispose(); |
| 658 m_parserBlockingScript = nullptr; |
| 649 ScriptSourceCode sourceCode(script->textContent(), | 659 ScriptSourceCode sourceCode(script->textContent(), |
| 650 documentURLForScriptExecution(m_document), | 660 documentURLForScriptExecution(m_document), |
| 651 scriptStartPosition); | 661 scriptStartPosition); |
| 652 doExecuteScript(script, sourceCode, scriptStartPosition); | 662 doExecuteScript(script, sourceCode, scriptStartPosition); |
| 653 } | 663 } |
| 654 } else { | 664 } else { |
| 655 // 2nd Clause of Step 23. | 665 // 2nd Clause of Step 23. |
| 656 requestParsingBlockingScript(script); | 666 requestParsingBlockingScript(script); |
| 657 } | 667 } |
| 658 | 668 |
| 659 // "Decrement the parser's script nesting level by one. | 669 // "Decrement the parser's script nesting level by one. |
| 660 // If the parser's script nesting level is zero, then set the parser | 670 // If the parser's script nesting level is zero, then set the parser |
| 661 // pause flag to false." | 671 // pause flag to false." |
| 662 // Implemented by ~ScriptNestingLevelIncrementer(). | 672 // Implemented by ~ScriptNestingLevelIncrementer(). |
| 663 | 673 |
| 664 // "Let the insertion point have the value of the old insertion point." | 674 // "Let the insertion point have the value of the old insertion point." |
| 665 // Implemented by ~InsertionPointRecord(). | 675 // Implemented by ~InsertionPointRecord(). |
| 666 } | 676 } |
| 667 } | 677 } |
| 668 | 678 |
| 669 DEFINE_TRACE(HTMLParserScriptRunner) { | 679 DEFINE_TRACE(HTMLParserScriptRunner) { |
| 670 visitor->trace(m_document); | 680 visitor->trace(m_document); |
| 671 visitor->trace(m_host); | 681 visitor->trace(m_host); |
| 672 visitor->trace(m_parserBlockingScript); | 682 visitor->trace(m_parserBlockingScript); |
| 673 visitor->trace(m_scriptsToExecuteAfterParsing); | 683 visitor->trace(m_scriptsToExecuteAfterParsing); |
| 674 PendingScriptClient::trace(visitor); | 684 PendingScriptClient::trace(visitor); |
| 675 } | 685 } |
| 676 | 686 |
| 677 } // namespace blink | 687 } // namespace blink |
| OLD | NEW |