Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Side by Side Diff: third_party/WebKit/Source/core/html/parser/HTMLParserScriptRunner.cpp

Issue 2693423002: Do not re-initialize PendingScript in HTMLParserScriptRunner (Closed)
Patch Set: fix test Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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) {
sof 2017/02/16 08:15:16 I don't mind terribly, but null-initializing Membe
hiroshige 2017/02/17 23:15:15 I'd like to leave this to make it more explicitly
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
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
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; 323 TextPosition startingPosition;
sof 2017/02/16 08:15:16 nit: could you move these decls down to where they
hiroshige 2017/02/17 23:15:15 Done.
316 bool isParserInserted = false; 324 bool isParserInserted = false;
317 325
318 if (m_parserBlockingScript != pendingScript) 326 if (parserBlockingScript() != pendingScript)
319 return; 327 return;
320 328
321 Element* element = m_parserBlockingScript->element(); 329 if (!parserBlockingScript())
sof 2017/02/16 08:15:16 I think it makes sense to have this check first.
hiroshige 2017/02/17 23:15:15 Done.
322 if (!element)
323 return; 330 return;
324 331
332 Element* element = parserBlockingScript()->element();
333
325 ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element); 334 ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element);
326 if (!scriptLoader || !scriptLoader->disallowedFetchForDocWrittenScript()) 335 if (!scriptLoader || !scriptLoader->disallowedFetchForDocWrittenScript())
327 return; 336 return;
328 337
329 if (!pendingScript->errorOccurred()) { 338 if (!pendingScript->errorOccurred()) {
330 emitWarningForDocWriteScripts(pendingScript->resource()->url().getString(), 339 emitWarningForDocWriteScripts(pendingScript->resource()->url().getString(),
331 *m_document); 340 *m_document);
332 return; 341 return;
333 } 342 }
334 343
335 // Due to dependency violation, not able to check the exact error to be 344 // Due to dependency violation, not able to check the exact error to be
336 // ERR_CACHE_MISS but other errors are rare with 345 // ERR_CACHE_MISS but other errors are rare with
337 // WebCachePolicy::ReturnCacheDataDontLoad. 346 // WebCachePolicy::ReturnCacheDataDontLoad.
338 347
339 emitErrorForDocWriteScripts(pendingScript->resource()->url().getString(), 348 emitErrorForDocWriteScripts(pendingScript->resource()->url().getString(),
340 *m_document); 349 *m_document);
341 startingPosition = m_parserBlockingScript->startingPosition(); 350 startingPosition = parserBlockingScript()->startingPosition();
342 isParserInserted = scriptLoader->isParserInserted(); 351 isParserInserted = scriptLoader->isParserInserted();
343 // Remove this resource entry from memory cache as the new request 352 // Remove this resource entry from memory cache as the new request
344 // should not join onto this existing entry. 353 // should not join onto this existing entry.
345 memoryCache()->remove(pendingScript->resource()); 354 memoryCache()->remove(pendingScript->resource());
346 fetchBlockedDocWriteScript(element, isParserInserted, startingPosition); 355 fetchBlockedDocWriteScript(element, isParserInserted, startingPosition);
347 } 356 }
348 357
349 void HTMLParserScriptRunner::pendingScriptFinished( 358 void HTMLParserScriptRunner::pendingScriptFinished(
350 PendingScript* pendingScript) { 359 PendingScript* pendingScript) {
351 // Handle cancellations of parser-blocking script loads without 360 // Handle cancellations of parser-blocking script loads without
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 // "outer" tree construction stage.)" 403 // "outer" tree construction stage.)"
395 // TODO(hiroshige): set the parser pause flag to true here. 404 // TODO(hiroshige): set the parser pause flag to true here.
396 405
397 // Unwind to the outermost HTMLParserScriptRunner::processScriptElement 406 // Unwind to the outermost HTMLParserScriptRunner::processScriptElement
398 // before continuing parsing. 407 // before continuing parsing.
399 return; 408 return;
400 } 409 }
401 410
402 // - "Otherwise": 411 // - "Otherwise":
403 412
404 traceParserBlockingScript(m_parserBlockingScript.get(), 413 traceParserBlockingScript(parserBlockingScript(),
405 !m_document->isScriptExecutionReady()); 414 !m_document->isScriptExecutionReady());
406 m_parserBlockingScript->markParserBlockingLoadStartTime(); 415 m_parserBlockingScript->markParserBlockingLoadStartTime();
407 416
408 // If preload scanner got created, it is missing the source after the 417 // If preload scanner got created, it is missing the source after the
409 // current insertion point. Append it and scan. 418 // current insertion point. Append it and scan.
410 if (!hadPreloadScanner && m_host->hasPreloadScanner()) 419 if (!hadPreloadScanner && m_host->hasPreloadScanner())
411 m_host->appendCurrentInputStreamToPreloadScannerAndScan(); 420 m_host->appendCurrentInputStreamToPreloadScannerAndScan();
412 421
413 executeParsingBlockingScripts(); 422 executeParsingBlockingScripts();
414 } 423 }
415 } 424 }
416 425
417 bool HTMLParserScriptRunner::hasParserBlockingScript() const { 426 bool HTMLParserScriptRunner::hasParserBlockingScript() const {
418 return !!m_parserBlockingScript->element(); 427 return parserBlockingScript();
419 } 428 }
420 429
421 // Implements the "Otherwise" Clause of 'An end tag whose tag name is "script"' 430 // Implements the "Otherwise" Clause of 'An end tag whose tag name is "script"'
422 // https://html.spec.whatwg.org/#scriptEndTag 431 // https://html.spec.whatwg.org/#scriptEndTag
423 void HTMLParserScriptRunner::executeParsingBlockingScripts() { 432 void HTMLParserScriptRunner::executeParsingBlockingScripts() {
424 // 3. "If (1) the parser's Document has a style sheet that is blocking scripts 433 // 3. "If (1) the parser's Document has a style sheet that is blocking scripts
425 // or (2) the script's "ready to be parser-executed" flag is not set: 434 // or (2) the script's "ready to be parser-executed" flag is not set:
426 // spin the event loop 435 // spin the event loop
427 // until the parser's Document has no style sheet that is blocking scripts 436 // until the parser's Document has no style sheet that is blocking scripts
428 // and the script's "ready to be parser-executed" flag is set." 437 // and the script's "ready to be parser-executed" flag is set."
429 // These conditions correspond to isParserBlockingScriptReady() and 438 // These conditions correspond to isParserBlockingScriptReady() and
430 // if it is false, executeParsingBlockingScripts() will be called later 439 // if it is false, executeParsingBlockingScripts() will be called later
431 // when isParserBlockingScriptReady() becomes true: 440 // when isParserBlockingScriptReady() becomes true:
432 // (1) from HTMLParserScriptRunner::executeScriptsWaitingForResources(), or 441 // (1) from HTMLParserScriptRunner::executeScriptsWaitingForResources(), or
433 // (2) from HTMLParserScriptRunner::executeScriptsWaitingForLoad(). 442 // (2) from HTMLParserScriptRunner::executeScriptsWaitingForLoad().
434 while (hasParserBlockingScript() && isParserBlockingScriptReady()) { 443 while (hasParserBlockingScript() && isParserBlockingScriptReady()) {
435 DCHECK(m_document); 444 DCHECK(m_document);
436 DCHECK(!isExecutingScript()); 445 DCHECK(!isExecutingScript());
437 DCHECK(m_document->isScriptExecutionReady()); 446 DCHECK(m_document->isScriptExecutionReady());
438 447
439 // 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."
440 InsertionPointRecord insertionPointRecord(m_host->inputStream()); 449 InsertionPointRecord insertionPointRecord(m_host->inputStream());
441 450
442 // 1., 7.--9. 451 // 1., 7.--9.
443 executePendingScriptAndDispatchEvent(m_parserBlockingScript.get(), 452 executePendingScriptAndDispatchEvent(m_parserBlockingScript,
sof 2017/02/16 08:15:16 parserBlockingScript() for consistency.
hiroshige 2017/02/17 23:15:15 I used parserBlockingScript() for const ref and m_
444 ScriptStreamer::ParsingBlocking); 453 ScriptStreamer::ParsingBlocking);
445 454
446 // 10. "Let the insertion point be undefined again." 455 // 10. "Let the insertion point be undefined again."
447 // Implemented as scope out of InsertionPointRecord. 456 // Implemented as scope out of InsertionPointRecord.
448 457
449 // 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
450 // repeat these steps from step 1." 459 // repeat these steps from step 1."
451 } 460 }
452 } 461 }
453 462
454 void HTMLParserScriptRunner::executeScriptsWaitingForLoad( 463 void HTMLParserScriptRunner::executeScriptsWaitingForLoad(
455 PendingScript* pendingScript) { 464 PendingScript* pendingScript) {
456 TRACE_EVENT0("blink", "HTMLParserScriptRunner::executeScriptsWaitingForLoad"); 465 TRACE_EVENT0("blink", "HTMLParserScriptRunner::executeScriptsWaitingForLoad");
457 DCHECK(!isExecutingScript()); 466 DCHECK(!isExecutingScript());
458 DCHECK(hasParserBlockingScript()); 467 DCHECK(hasParserBlockingScript());
459 DCHECK_EQ(pendingScript, m_parserBlockingScript); 468 DCHECK_EQ(pendingScript, parserBlockingScript());
460 DCHECK(m_parserBlockingScript->isReady()); 469 DCHECK(parserBlockingScript()->isReady());
461 executeParsingBlockingScripts(); 470 executeParsingBlockingScripts();
462 } 471 }
463 472
464 void HTMLParserScriptRunner::executeScriptsWaitingForResources() { 473 void HTMLParserScriptRunner::executeScriptsWaitingForResources() {
465 TRACE_EVENT0("blink", 474 TRACE_EVENT0("blink",
466 "HTMLParserScriptRunner::executeScriptsWaitingForResources"); 475 "HTMLParserScriptRunner::executeScriptsWaitingForResources");
467 DCHECK(m_document); 476 DCHECK(m_document);
468 DCHECK(!isExecutingScript()); 477 DCHECK(!isExecutingScript());
469 DCHECK(m_document->isScriptExecutionReady()); 478 DCHECK(m_document->isScriptExecutionReady());
470 executeParsingBlockingScripts(); 479 executeParsingBlockingScripts();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 // from substep 1." 522 // from substep 1."
514 } 523 }
515 return true; 524 return true;
516 } 525 }
517 526
518 // 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
519 void HTMLParserScriptRunner::requestParsingBlockingScript(Element* element) { 528 void HTMLParserScriptRunner::requestParsingBlockingScript(Element* element) {
520 // "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
521 // the parser that created the element. 530 // the parser that created the element.
522 // (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.)"
523 if (!requestPendingScript(m_parserBlockingScript.get(), element)) 532 CHECK(!parserBlockingScript());
533 m_parserBlockingScript = requestPendingScript(element);
534 if (!parserBlockingScript())
524 return; 535 return;
525 536
526 DCHECK(m_parserBlockingScript->resource()); 537 DCHECK(parserBlockingScript()->resource());
527 538
528 // 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.
529 // Callers will attempt to run the m_parserBlockingScript if possible before 540 // Callers will attempt to run the m_parserBlockingScript if possible before
530 // returning control to the parser. 541 // returning control to the parser.
531 if (!m_parserBlockingScript->isReady()) { 542 if (!parserBlockingScript()->isReady()) {
532 if (m_document->frame()) { 543 if (m_document->frame()) {
533 ScriptState* scriptState = ScriptState::forMainWorld(m_document->frame()); 544 ScriptState* scriptState = ScriptState::forMainWorld(m_document->frame());
534 if (scriptState) { 545 if (scriptState) {
535 ScriptStreamer::startStreaming( 546 ScriptStreamer::startStreaming(
536 m_parserBlockingScript.get(), ScriptStreamer::ParsingBlocking, 547 m_parserBlockingScript, ScriptStreamer::ParsingBlocking,
537 m_document->frame()->settings(), scriptState, 548 m_document->frame()->settings(), scriptState,
538 TaskRunnerHelper::get(TaskType::Networking, m_document)); 549 TaskRunnerHelper::get(TaskType::Networking, m_document));
539 } 550 }
540 } 551 }
541 552
542 m_parserBlockingScript->watchForLoad(this); 553 m_parserBlockingScript->watchForLoad(this);
543 } 554 }
544 } 555 }
545 556
546 // 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
547 void HTMLParserScriptRunner::requestDeferredScript(Element* element) { 558 void HTMLParserScriptRunner::requestDeferredScript(Element* element) {
548 PendingScript* pendingScript = PendingScript::create(nullptr, nullptr); 559 PendingScript* pendingScript = requestPendingScript(element);
549 if (!requestPendingScript(pendingScript, element)) 560 if (!pendingScript)
550 return; 561 return;
551 562
552 if (m_document->frame() && !pendingScript->isReady()) { 563 if (m_document->frame() && !pendingScript->isReady()) {
553 ScriptState* scriptState = ScriptState::forMainWorld(m_document->frame()); 564 ScriptState* scriptState = ScriptState::forMainWorld(m_document->frame());
554 if (scriptState) { 565 if (scriptState) {
555 ScriptStreamer::startStreaming( 566 ScriptStreamer::startStreaming(
556 pendingScript, ScriptStreamer::Deferred, 567 pendingScript, ScriptStreamer::Deferred,
557 m_document->frame()->settings(), scriptState, 568 m_document->frame()->settings(), scriptState,
558 TaskRunnerHelper::get(TaskType::Networking, m_document)); 569 TaskRunnerHelper::get(TaskType::Networking, m_document));
559 } 570 }
560 } 571 }
561 572
562 DCHECK(pendingScript->resource()); 573 DCHECK(pendingScript->resource());
563 574
564 // "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
565 // when the document has finished parsing associated with the Document 576 // when the document has finished parsing associated with the Document
566 // of the parser that created the element." 577 // of the parser that created the element."
567 m_scriptsToExecuteAfterParsing.append(pendingScript); 578 m_scriptsToExecuteAfterParsing.append(pendingScript);
568 } 579 }
569 580
570 bool HTMLParserScriptRunner::requestPendingScript(PendingScript* pendingScript, 581 PendingScript* HTMLParserScriptRunner::requestPendingScript(
571 Element* script) const { 582 Element* element) const {
572 DCHECK(!pendingScript->element());
573 pendingScript->setElement(script);
574 // This should correctly return 0 for empty or invalid srcValues. 583 // This should correctly return 0 for empty or invalid srcValues.
575 ScriptResource* resource = toScriptLoaderIfPossible(script)->resource(); 584 ScriptResource* resource = toScriptLoaderIfPossible(element)->resource();
576 if (!resource) { 585 if (!resource) {
kouhei (in TOK) 2017/02/16 00:55:09 Do we ever get here?
hiroshige 2017/02/16 01:13:15 Probably no, because fetchScript() should have ret
hiroshige 2017/02/17 23:15:15 Created https://codereview.chromium.org/2692863013
577 DVLOG(1) << "Not implemented."; // Dispatch error event. 586 DVLOG(1) << "Not implemented."; // Dispatch error event.
578 return false; 587 return nullptr;
579 } 588 }
580 pendingScript->setScriptResource(resource); 589
581 return true; 590 return PendingScript::create(element, resource);
582 } 591 }
583 592
584 // Implements the initial steps for 'An end tag whose tag name is "script"' 593 // Implements the initial steps for 'An end tag whose tag name is "script"'
585 // https://html.spec.whatwg.org/#scriptEndTag 594 // https://html.spec.whatwg.org/#scriptEndTag
586 void HTMLParserScriptRunner::processScriptElementInternal( 595 void HTMLParserScriptRunner::processScriptElementInternal(
587 Element* script, 596 Element* script,
588 const TextPosition& scriptStartPosition) { 597 const TextPosition& scriptStartPosition) {
589 DCHECK(m_document); 598 DCHECK(m_document);
590 DCHECK(!hasParserBlockingScript()); 599 DCHECK(!hasParserBlockingScript());
591 { 600 {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 // 1st Clause of Step 23. 637 // 1st Clause of Step 23.
629 requestDeferredScript(script); 638 requestDeferredScript(script);
630 } else if (scriptLoader->readyToBeParserExecuted()) { 639 } else if (scriptLoader->readyToBeParserExecuted()) {
631 // 5th Clause of Step 23. 640 // 5th Clause of Step 23.
632 // "If ... it's an HTML parser 641 // "If ... it's an HTML parser
633 // whose script nesting level is not greater than one" 642 // whose script nesting level is not greater than one"
634 if (m_reentryPermit->scriptNestingLevel() == 1u) { 643 if (m_reentryPermit->scriptNestingLevel() == 1u) {
635 // "The element is the pending parsing-blocking script of the 644 // "The element is the pending parsing-blocking script of the
636 // Document of the parser that created the element. 645 // Document of the parser that created the element.
637 // (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.)"
638 m_parserBlockingScript->setElement(script); 647 CHECK(!m_parserBlockingScript);
639 m_parserBlockingScript->setStartingPosition(scriptStartPosition); 648 m_parserBlockingScript =
649 PendingScript::create(script, scriptStartPosition);
640 } else { 650 } else {
641 // 6th Clause of Step 23. 651 // 6th Clause of Step 23.
642 // "Immediately execute the script block, 652 // "Immediately execute the script block,
643 // even if other scripts are already executing." 653 // even if other scripts are already executing."
644 // TODO(hiroshige): Merge the block into ScriptLoader::prepareScript(). 654 // TODO(hiroshige): Merge the block into ScriptLoader::prepareScript().
645 DCHECK_GT(m_reentryPermit->scriptNestingLevel(), 1u); 655 DCHECK_GT(m_reentryPermit->scriptNestingLevel(), 1u);
646 m_parserBlockingScript->dispose(); 656 if (m_parserBlockingScript)
657 m_parserBlockingScript->dispose();
658 m_parserBlockingScript = nullptr;
647 ScriptSourceCode sourceCode(script->textContent(), 659 ScriptSourceCode sourceCode(script->textContent(),
648 documentURLForScriptExecution(m_document), 660 documentURLForScriptExecution(m_document),
649 scriptStartPosition); 661 scriptStartPosition);
650 doExecuteScript(script, sourceCode, scriptStartPosition); 662 doExecuteScript(script, sourceCode, scriptStartPosition);
651 } 663 }
652 } else { 664 } else {
653 // 2nd Clause of Step 23. 665 // 2nd Clause of Step 23.
654 requestParsingBlockingScript(script); 666 requestParsingBlockingScript(script);
655 } 667 }
656 668
657 // "Decrement the parser's script nesting level by one. 669 // "Decrement the parser's script nesting level by one.
658 // 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
659 // pause flag to false." 671 // pause flag to false."
660 // Implemented by scope out of ScriptNestingLevelIncrementer. 672 // Implemented by scope out of ScriptNestingLevelIncrementer.
661 673
662 // "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."
663 // Implemented by scope out of InsertionPointRecord. 675 // Implemented by scope out of InsertionPointRecord.
664 } 676 }
665 } 677 }
666 678
667 DEFINE_TRACE(HTMLParserScriptRunner) { 679 DEFINE_TRACE(HTMLParserScriptRunner) {
668 visitor->trace(m_document); 680 visitor->trace(m_document);
669 visitor->trace(m_host); 681 visitor->trace(m_host);
670 visitor->trace(m_parserBlockingScript); 682 visitor->trace(m_parserBlockingScript);
671 visitor->trace(m_scriptsToExecuteAfterParsing); 683 visitor->trace(m_scriptsToExecuteAfterParsing);
672 PendingScriptClient::trace(visitor); 684 PendingScriptClient::trace(visitor);
673 } 685 }
674 686
675 } // namespace blink 687 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698