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 |