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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
181 // may continue to run pending scripts after the parser has | 181 // may continue to run pending scripts after the parser has |
182 // detached. | 182 // detached. |
183 } | 183 } |
184 | 184 |
185 bool HTMLParserScriptRunner::isParserBlockingScriptReady() { | 185 bool HTMLParserScriptRunner::isParserBlockingScriptReady() { |
186 if (!m_document->isScriptExecutionReady()) | 186 if (!m_document->isScriptExecutionReady()) |
187 return false; | 187 return false; |
188 return m_parserBlockingScript->isReady(); | 188 return m_parserBlockingScript->isReady(); |
189 } | 189 } |
190 | 190 |
191 // This has two callers and corresponds to different concepts in the spec: | |
192 // - When called from executeParsingBlockingScripts(), this corresponds to some | |
193 // steps of the "Otherwise" Clause of 'An end tag whose tag name is "script"' | |
194 // https://html.spec.whatwg.org/#scriptEndTag | |
195 // - When called from executeScriptsWaitingForParsing(), this corresponds | |
196 // https://html.spec.whatwg.org/#execute-the-script-block | |
197 // and thus currently this function does more than specced. | |
198 // TODO(hiroshige): Make the spec and implementation consistent. | |
191 void HTMLParserScriptRunner::executePendingScriptAndDispatchEvent( | 199 void HTMLParserScriptRunner::executePendingScriptAndDispatchEvent( |
192 PendingScript* pendingScript, | 200 PendingScript* pendingScript, |
193 ScriptStreamer::Type pendingScriptType) { | 201 ScriptStreamer::Type pendingScriptType) { |
194 bool errorOccurred = false; | 202 bool errorOccurred = false; |
195 ScriptSourceCode sourceCode = pendingScript->getSource( | 203 ScriptSourceCode sourceCode = pendingScript->getSource( |
196 documentURLForScriptExecution(m_document), errorOccurred); | 204 documentURLForScriptExecution(m_document), errorOccurred); |
197 | 205 |
198 // Stop watching loads before executeScript to prevent recursion if the script | 206 // Stop watching loads before executeScript to prevent recursion if the script |
199 // reloads itself. | 207 // reloads itself. |
200 // TODO(kouhei): Consider merging this w/ pendingScript->dispose() after the | 208 // TODO(kouhei): Consider merging this w/ pendingScript->dispose() after the |
201 // if block. | 209 // if block. |
202 pendingScript->stopWatchingForLoad(); | 210 pendingScript->stopWatchingForLoad(); |
203 | 211 |
204 if (!isExecutingScript()) { | 212 if (!isExecutingScript()) { |
205 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); | 213 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); |
206 if (pendingScriptType == ScriptStreamer::ParsingBlocking) { | 214 if (pendingScriptType == ScriptStreamer::ParsingBlocking) { |
207 // The parser cannot be unblocked as a microtask requested another | 215 // The parser cannot be unblocked as a microtask requested another |
208 // resource | 216 // resource |
209 if (!m_document->isScriptExecutionReady()) | 217 if (!m_document->isScriptExecutionReady()) |
210 return; | 218 return; |
211 } | 219 } |
212 } | 220 } |
213 | 221 |
214 TextPosition scriptStartPosition = pendingScript->startingPosition(); | 222 TextPosition scriptStartPosition = pendingScript->startingPosition(); |
215 double scriptParserBlockingTime = | 223 double scriptParserBlockingTime = |
216 pendingScript->parserBlockingLoadStartTime(); | 224 pendingScript->parserBlockingLoadStartTime(); |
225 Element* element = pendingScript->element(); | |
226 | |
227 // 1. "Let the script be the pending parsing-blocking script. | |
228 // There is no longer a pending parsing-blocking script." | |
217 // Clear the pending script before possible re-entrancy from executeScript() | 229 // Clear the pending script before possible re-entrancy from executeScript() |
218 Element* element = pendingScript->element(); | |
219 pendingScript->dispose(); | 230 pendingScript->dispose(); |
220 | 231 |
221 if (ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element)) { | 232 if (ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element)) { |
233 // 7. "Increment the parser's script nesting level by one (it should be | |
234 // zero before this step, so this sets it to one)." | |
222 HTMLParserReentryPermit::ScriptNestingLevelIncrementer | 235 HTMLParserReentryPermit::ScriptNestingLevelIncrementer |
223 nestingLevelIncrementer = | 236 nestingLevelIncrementer = |
224 m_reentryPermit->incrementScriptNestingLevel(); | 237 m_reentryPermit->incrementScriptNestingLevel(); |
238 | |
225 IgnoreDestructiveWriteCountIncrementer | 239 IgnoreDestructiveWriteCountIncrementer |
226 ignoreDestructiveWriteCountIncrementer(m_document); | 240 ignoreDestructiveWriteCountIncrementer(m_document); |
241 | |
242 // 8. "Execute the script." | |
227 if (errorOccurred) { | 243 if (errorOccurred) { |
228 TRACE_EVENT_WITH_FLOW1( | 244 TRACE_EVENT_WITH_FLOW1( |
229 "blink", "HTMLParserScriptRunner ExecuteScriptFailed", element, | 245 "blink", "HTMLParserScriptRunner ExecuteScriptFailed", element, |
230 TRACE_EVENT_FLAG_FLOW_IN, "data", | 246 TRACE_EVENT_FLAG_FLOW_IN, "data", |
231 getTraceArgsForScriptElement(element, scriptStartPosition)); | 247 getTraceArgsForScriptElement(element, scriptStartPosition)); |
232 scriptLoader->dispatchErrorEvent(); | 248 scriptLoader->dispatchErrorEvent(); |
233 } else { | 249 } else { |
234 DCHECK(isExecutingScript()); | 250 DCHECK(isExecutingScript()); |
235 if (scriptParserBlockingTime > 0.0) { | 251 if (scriptParserBlockingTime > 0.0) { |
236 DocumentParserTiming::from(*m_document) | 252 DocumentParserTiming::from(*m_document) |
237 .recordParserBlockedOnScriptLoadDuration( | 253 .recordParserBlockedOnScriptLoadDuration( |
238 monotonicallyIncreasingTime() - scriptParserBlockingTime, | 254 monotonicallyIncreasingTime() - scriptParserBlockingTime, |
239 scriptLoader->wasCreatedDuringDocumentWrite()); | 255 scriptLoader->wasCreatedDuringDocumentWrite()); |
240 } | 256 } |
241 if (!doExecuteScript(element, sourceCode, scriptStartPosition)) { | 257 if (!doExecuteScript(element, sourceCode, scriptStartPosition)) { |
242 scriptLoader->dispatchErrorEvent(); | 258 scriptLoader->dispatchErrorEvent(); |
243 } else { | 259 } else { |
244 element->dispatchEvent(Event::create(EventTypeNames::load)); | 260 element->dispatchEvent(Event::create(EventTypeNames::load)); |
245 } | 261 } |
246 } | 262 } |
263 | |
264 // 9. "Decrement the parser's script nesting level by one. | |
265 // If the parser's script nesting level is zero | |
266 // (which it always should be at this point), | |
267 // then set the parser pause flag to false." | |
268 // This is implemented by scope out of ScriptNestingLevelIncrementer. | |
247 } | 269 } |
248 | 270 |
249 DCHECK(!isExecutingScript()); | 271 DCHECK(!isExecutingScript()); |
250 } | 272 } |
251 | 273 |
252 void fetchBlockedDocWriteScript(Element* script, | 274 void fetchBlockedDocWriteScript(Element* script, |
253 bool isParserInserted, | 275 bool isParserInserted, |
254 const TextPosition& scriptStartPosition) { | 276 const TextPosition& scriptStartPosition) { |
255 DCHECK(script); | 277 DCHECK(script); |
256 | 278 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
338 } | 360 } |
339 | 361 |
340 // If the script was blocked as part of document.write intervention, | 362 // If the script was blocked as part of document.write intervention, |
341 // then send an asynchronous GET request with an interventions header. | 363 // then send an asynchronous GET request with an interventions header. |
342 possiblyFetchBlockedDocWriteScript(pendingScript); | 364 possiblyFetchBlockedDocWriteScript(pendingScript); |
343 | 365 |
344 m_host->notifyScriptLoaded(pendingScript); | 366 m_host->notifyScriptLoaded(pendingScript); |
345 } | 367 } |
346 | 368 |
347 // Implements the steps for 'An end tag whose tag name is "script"' | 369 // Implements the steps for 'An end tag whose tag name is "script"' |
348 // http://whatwg.org/html#scriptEndTag | 370 // https://html.spec.whatwg.org/#scriptEndTag |
349 // Script handling lives outside the tree builder to keep each class simple. | 371 // Script handling lives outside the tree builder to keep each class simple. |
350 void HTMLParserScriptRunner::processScriptElement( | 372 void HTMLParserScriptRunner::processScriptElement( |
351 Element* scriptElement, | 373 Element* scriptElement, |
352 const TextPosition& scriptStartPosition) { | 374 const TextPosition& scriptStartPosition) { |
353 DCHECK(scriptElement); | 375 DCHECK(scriptElement); |
354 TRACE_EVENT1( | 376 TRACE_EVENT1( |
355 "blink", "HTMLParserScriptRunner::execute", "data", | 377 "blink", "HTMLParserScriptRunner::execute", "data", |
356 getTraceArgsForScriptElement(scriptElement, scriptStartPosition)); | 378 getTraceArgsForScriptElement(scriptElement, scriptStartPosition)); |
357 // FIXME: If scripting is disabled, always just return. | 379 // FIXME: If scripting is disabled, always just return. |
358 | 380 |
359 bool hadPreloadScanner = m_host->hasPreloadScanner(); | 381 bool hadPreloadScanner = m_host->hasPreloadScanner(); |
360 | 382 |
383 // Initial steps of 'An end tag whose tag name is "script"'. | |
361 // Try to execute the script given to us. | 384 // Try to execute the script given to us. |
362 processScriptElementInternal(scriptElement, scriptStartPosition); | 385 processScriptElementInternal(scriptElement, scriptStartPosition); |
363 | 386 |
387 // "At this stage, if there is a pending parsing-blocking script, then:" | |
364 if (hasParserBlockingScript()) { | 388 if (hasParserBlockingScript()) { |
389 // - "If the script nesting level is not zero:" | |
365 if (isExecutingScript()) { | 390 if (isExecutingScript()) { |
391 // "Set the parser pause flag to true, and abort the processing of any | |
392 // nested invocations of the tokenizer, yielding control back to the | |
393 // caller. (Tokenization will resume when the caller returns to the | |
394 // "outer" tree construction stage.)" | |
395 // TODO(hiroshige): set the parser pause flag to true here. | |
396 | |
366 // Unwind to the outermost HTMLParserScriptRunner::processScriptElement | 397 // Unwind to the outermost HTMLParserScriptRunner::processScriptElement |
367 // before continuing parsing. | 398 // before continuing parsing. |
368 return; | 399 return; |
369 } | 400 } |
370 | 401 |
402 // - "Otherwise": | |
403 | |
371 traceParserBlockingScript(m_parserBlockingScript.get(), | 404 traceParserBlockingScript(m_parserBlockingScript.get(), |
372 !m_document->isScriptExecutionReady()); | 405 !m_document->isScriptExecutionReady()); |
373 m_parserBlockingScript->markParserBlockingLoadStartTime(); | 406 m_parserBlockingScript->markParserBlockingLoadStartTime(); |
374 | 407 |
375 // If preload scanner got created, it is missing the source after the | 408 // If preload scanner got created, it is missing the source after the |
376 // current insertion point. Append it and scan. | 409 // current insertion point. Append it and scan. |
377 if (!hadPreloadScanner && m_host->hasPreloadScanner()) | 410 if (!hadPreloadScanner && m_host->hasPreloadScanner()) |
378 m_host->appendCurrentInputStreamToPreloadScannerAndScan(); | 411 m_host->appendCurrentInputStreamToPreloadScannerAndScan(); |
412 | |
379 executeParsingBlockingScripts(); | 413 executeParsingBlockingScripts(); |
380 } | 414 } |
381 } | 415 } |
382 | 416 |
383 bool HTMLParserScriptRunner::hasParserBlockingScript() const { | 417 bool HTMLParserScriptRunner::hasParserBlockingScript() const { |
384 return !!m_parserBlockingScript->element(); | 418 return !!m_parserBlockingScript->element(); |
385 } | 419 } |
386 | 420 |
421 // Implements the "Otherwise" Clause of 'An end tag whose tag name is "script"' | |
dominicc (has gone to gerrit)
2017/02/16 08:41:00
I would make this more succinct by dropping "imple
hiroshige
2017/02/20 23:56:40
Done.
| |
422 // https://html.spec.whatwg.org/#scriptEndTag | |
387 void HTMLParserScriptRunner::executeParsingBlockingScripts() { | 423 void HTMLParserScriptRunner::executeParsingBlockingScripts() { |
424 // 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: | |
426 // spin the event loop | |
427 // 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." | |
429 // These conditions correspond to isParserBlockingScriptReady() and | |
dominicc (has gone to gerrit)
2017/02/16 08:41:00
Great comment; thank you so much for doing this.
hiroshige
2017/02/20 23:56:40
Done.
| |
430 // if it is false, executeParsingBlockingScripts() will be called later | |
431 // when isParserBlockingScriptReady() becomes true: | |
432 // (1) from HTMLParserScriptRunner::executeScriptsWaitingForResources(), or | |
433 // (2) from HTMLParserScriptRunner::executeScriptsWaitingForLoad(). | |
388 while (hasParserBlockingScript() && isParserBlockingScriptReady()) { | 434 while (hasParserBlockingScript() && isParserBlockingScriptReady()) { |
389 DCHECK(m_document); | 435 DCHECK(m_document); |
390 DCHECK(!isExecutingScript()); | 436 DCHECK(!isExecutingScript()); |
391 DCHECK(m_document->isScriptExecutionReady()); | 437 DCHECK(m_document->isScriptExecutionReady()); |
392 | 438 |
439 // 6. "Let the insertion point be just before the next input character." | |
393 InsertionPointRecord insertionPointRecord(m_host->inputStream()); | 440 InsertionPointRecord insertionPointRecord(m_host->inputStream()); |
441 | |
442 // 1., 7.--9. | |
394 executePendingScriptAndDispatchEvent(m_parserBlockingScript.get(), | 443 executePendingScriptAndDispatchEvent(m_parserBlockingScript.get(), |
395 ScriptStreamer::ParsingBlocking); | 444 ScriptStreamer::ParsingBlocking); |
445 | |
446 // 10. "Let the insertion point be undefined again." | |
447 // Implemented as scope out of InsertionPointRecord. | |
dominicc (has gone to gerrit)
2017/02/16 08:41:00
"scope out of" is a bit awkward. Maybe say somethi
hiroshige
2017/02/20 23:56:40
Done.
| |
448 | |
449 // 11. "If there is once again a pending parsing-blocking script, then | |
450 // repeat these steps from step 1." | |
396 } | 451 } |
397 } | 452 } |
398 | 453 |
399 void HTMLParserScriptRunner::executeScriptsWaitingForLoad( | 454 void HTMLParserScriptRunner::executeScriptsWaitingForLoad( |
400 PendingScript* pendingScript) { | 455 PendingScript* pendingScript) { |
401 TRACE_EVENT0("blink", "HTMLParserScriptRunner::executeScriptsWaitingForLoad"); | 456 TRACE_EVENT0("blink", "HTMLParserScriptRunner::executeScriptsWaitingForLoad"); |
402 DCHECK(!isExecutingScript()); | 457 DCHECK(!isExecutingScript()); |
403 DCHECK(hasParserBlockingScript()); | 458 DCHECK(hasParserBlockingScript()); |
404 DCHECK_EQ(pendingScript, m_parserBlockingScript); | 459 DCHECK_EQ(pendingScript, m_parserBlockingScript); |
405 DCHECK(m_parserBlockingScript->isReady()); | 460 DCHECK(m_parserBlockingScript->isReady()); |
406 executeParsingBlockingScripts(); | 461 executeParsingBlockingScripts(); |
407 } | 462 } |
408 | 463 |
409 void HTMLParserScriptRunner::executeScriptsWaitingForResources() { | 464 void HTMLParserScriptRunner::executeScriptsWaitingForResources() { |
410 TRACE_EVENT0("blink", | 465 TRACE_EVENT0("blink", |
411 "HTMLParserScriptRunner::executeScriptsWaitingForResources"); | 466 "HTMLParserScriptRunner::executeScriptsWaitingForResources"); |
412 DCHECK(m_document); | 467 DCHECK(m_document); |
413 DCHECK(!isExecutingScript()); | 468 DCHECK(!isExecutingScript()); |
414 DCHECK(m_document->isScriptExecutionReady()); | 469 DCHECK(m_document->isScriptExecutionReady()); |
415 executeParsingBlockingScripts(); | 470 executeParsingBlockingScripts(); |
416 } | 471 } |
417 | 472 |
473 // Step 3 of https://html.spec.whatwg.org/#the-end: | |
474 // "If the list of scripts that will execute when the document has | |
475 // finished parsing is not empty, run these substeps:" | |
418 bool HTMLParserScriptRunner::executeScriptsWaitingForParsing() { | 476 bool HTMLParserScriptRunner::executeScriptsWaitingForParsing() { |
419 TRACE_EVENT0("blink", | 477 TRACE_EVENT0("blink", |
420 "HTMLParserScriptRunner::executeScriptsWaitingForParsing"); | 478 "HTMLParserScriptRunner::executeScriptsWaitingForParsing"); |
479 | |
421 while (!m_scriptsToExecuteAfterParsing.isEmpty()) { | 480 while (!m_scriptsToExecuteAfterParsing.isEmpty()) { |
422 DCHECK(!isExecutingScript()); | 481 DCHECK(!isExecutingScript()); |
423 DCHECK(!hasParserBlockingScript()); | 482 DCHECK(!hasParserBlockingScript()); |
424 DCHECK(m_scriptsToExecuteAfterParsing.first()->resource()); | 483 DCHECK(m_scriptsToExecuteAfterParsing.first()->resource()); |
484 | |
485 // 1. "Spin the event loop until the first script in the list of scripts | |
486 // that will execute when the document has finished parsing | |
487 // has its "ready to be parser-executed" flag set and | |
488 // the parser's Document has no style sheet that is blocking scripts." | |
489 // TODO(hiroshige): Is the latter part checked anywhere? | |
425 if (!m_scriptsToExecuteAfterParsing.first()->isReady()) { | 490 if (!m_scriptsToExecuteAfterParsing.first()->isReady()) { |
426 m_scriptsToExecuteAfterParsing.first()->watchForLoad(this); | 491 m_scriptsToExecuteAfterParsing.first()->watchForLoad(this); |
427 traceParserBlockingScript(m_scriptsToExecuteAfterParsing.first().get(), | 492 traceParserBlockingScript(m_scriptsToExecuteAfterParsing.first().get(), |
428 !m_document->isScriptExecutionReady()); | 493 !m_document->isScriptExecutionReady()); |
429 m_scriptsToExecuteAfterParsing.first()->markParserBlockingLoadStartTime(); | 494 m_scriptsToExecuteAfterParsing.first()->markParserBlockingLoadStartTime(); |
430 return false; | 495 return false; |
431 } | 496 } |
497 | |
498 // 3. "Remove the first script element from the list of scripts that will | |
499 // execute when the document has finished parsing (i.e. shift out the | |
500 // first entry in the list)." | |
432 PendingScript* first = m_scriptsToExecuteAfterParsing.takeFirst(); | 501 PendingScript* first = m_scriptsToExecuteAfterParsing.takeFirst(); |
502 | |
503 // 2. "Execute the first script in the list of scripts that will execute | |
504 // when the document has finished parsing." | |
433 executePendingScriptAndDispatchEvent(first, ScriptStreamer::Deferred); | 505 executePendingScriptAndDispatchEvent(first, ScriptStreamer::Deferred); |
506 | |
434 // FIXME: What is this m_document check for? | 507 // FIXME: What is this m_document check for? |
435 if (!m_document) | 508 if (!m_document) |
436 return false; | 509 return false; |
510 | |
511 // 4. "If the list of scripts that will execute when the document has | |
512 // finished parsing is still not empty, repeat these substeps again | |
513 // from substep 1." | |
437 } | 514 } |
438 return true; | 515 return true; |
439 } | 516 } |
440 | 517 |
441 // 2nd Clause, Step 23 of https://html.spec.whatwg.org/#prepare-a-script | 518 // 2nd Clause, Step 23 of https://html.spec.whatwg.org/#prepare-a-script |
442 void HTMLParserScriptRunner::requestParsingBlockingScript(Element* element) { | 519 void HTMLParserScriptRunner::requestParsingBlockingScript(Element* element) { |
443 // "The element is the pending parsing-blocking script of the Document of | 520 // "The element is the pending parsing-blocking script of the Document of |
444 // the parser that created the element. | 521 // the parser that created the element. |
445 // (There can only be one such script per Document at a time.)" | 522 // (There can only be one such script per Document at a time.)" |
446 if (!requestPendingScript(m_parserBlockingScript.get(), element)) | 523 if (!requestPendingScript(m_parserBlockingScript.get(), element)) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
498 ScriptResource* resource = toScriptLoaderIfPossible(script)->resource(); | 575 ScriptResource* resource = toScriptLoaderIfPossible(script)->resource(); |
499 if (!resource) { | 576 if (!resource) { |
500 DVLOG(1) << "Not implemented."; // Dispatch error event. | 577 DVLOG(1) << "Not implemented."; // Dispatch error event. |
501 return false; | 578 return false; |
502 } | 579 } |
503 pendingScript->setScriptResource(resource); | 580 pendingScript->setScriptResource(resource); |
504 return true; | 581 return true; |
505 } | 582 } |
506 | 583 |
507 // Implements the initial steps for 'An end tag whose tag name is "script"' | 584 // Implements the initial steps for 'An end tag whose tag name is "script"' |
508 // http://whatwg.org/html#scriptEndTag | 585 // https://html.spec.whatwg.org/#scriptEndTag |
509 void HTMLParserScriptRunner::processScriptElementInternal( | 586 void HTMLParserScriptRunner::processScriptElementInternal( |
510 Element* script, | 587 Element* script, |
511 const TextPosition& scriptStartPosition) { | 588 const TextPosition& scriptStartPosition) { |
512 DCHECK(m_document); | 589 DCHECK(m_document); |
513 DCHECK(!hasParserBlockingScript()); | 590 DCHECK(!hasParserBlockingScript()); |
514 { | 591 { |
515 ScriptLoader* scriptLoader = toScriptLoaderIfPossible(script); | 592 ScriptLoader* scriptLoader = toScriptLoaderIfPossible(script); |
516 | 593 |
517 // This contains both a DCHECK and a null check since we should not | 594 // This contains both a DCHECK and a null check since we should not |
518 // be getting into the case of a null script element, but seem to be from | 595 // be getting into the case of a null script element, but seem to be from |
519 // time to time. The assertion is left in to help find those cases and | 596 // time to time. The assertion is left in to help find those cases and |
520 // is being tracked by <https://bugs.webkit.org/show_bug.cgi?id=60559>. | 597 // is being tracked by <https://bugs.webkit.org/show_bug.cgi?id=60559>. |
521 DCHECK(scriptLoader); | 598 DCHECK(scriptLoader); |
522 if (!scriptLoader) | 599 if (!scriptLoader) |
523 return; | 600 return; |
524 | 601 |
525 DCHECK(scriptLoader->isParserInserted()); | 602 DCHECK(scriptLoader->isParserInserted()); |
526 | 603 |
527 if (!isExecutingScript()) | 604 if (!isExecutingScript()) |
528 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); | 605 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); |
529 | 606 |
607 // "Let the old insertion point have the same value as the current | |
608 // insertion point. | |
609 // Let the insertion point be just before the next input character." | |
530 InsertionPointRecord insertionPointRecord(m_host->inputStream()); | 610 InsertionPointRecord insertionPointRecord(m_host->inputStream()); |
611 | |
612 // "Increment the parser's script nesting level by one." | |
531 HTMLParserReentryPermit::ScriptNestingLevelIncrementer | 613 HTMLParserReentryPermit::ScriptNestingLevelIncrementer |
532 nestingLevelIncrementer = | 614 nestingLevelIncrementer = |
533 m_reentryPermit->incrementScriptNestingLevel(); | 615 m_reentryPermit->incrementScriptNestingLevel(); |
534 | 616 |
617 // "Prepare the script. This might cause some script to execute, which | |
618 // might cause new characters to be inserted into the tokenizer, and | |
619 // might cause the tokenizer to output more tokens, resulting in a | |
620 // reentrant invocation of the parser." | |
535 scriptLoader->prepareScript(scriptStartPosition); | 621 scriptLoader->prepareScript(scriptStartPosition); |
536 | 622 |
537 // A part of Step 23 of https://html.spec.whatwg.org/#prepare-a-script: | 623 // A part of Step 23 of https://html.spec.whatwg.org/#prepare-a-script: |
538 if (!scriptLoader->willBeParserExecuted()) | 624 if (!scriptLoader->willBeParserExecuted()) |
539 return; | 625 return; |
540 | 626 |
541 if (scriptLoader->willExecuteWhenDocumentFinishedParsing()) { | 627 if (scriptLoader->willExecuteWhenDocumentFinishedParsing()) { |
542 // 1st Clause of Step 23. | 628 // 1st Clause of Step 23. |
543 requestDeferredScript(script); | 629 requestDeferredScript(script); |
544 } else if (scriptLoader->readyToBeParserExecuted()) { | 630 } else if (scriptLoader->readyToBeParserExecuted()) { |
(...skipping 15 matching lines...) Expand all Loading... | |
560 m_parserBlockingScript->dispose(); | 646 m_parserBlockingScript->dispose(); |
561 ScriptSourceCode sourceCode(script->textContent(), | 647 ScriptSourceCode sourceCode(script->textContent(), |
562 documentURLForScriptExecution(m_document), | 648 documentURLForScriptExecution(m_document), |
563 scriptStartPosition); | 649 scriptStartPosition); |
564 doExecuteScript(script, sourceCode, scriptStartPosition); | 650 doExecuteScript(script, sourceCode, scriptStartPosition); |
565 } | 651 } |
566 } else { | 652 } else { |
567 // 2nd Clause of Step 23. | 653 // 2nd Clause of Step 23. |
568 requestParsingBlockingScript(script); | 654 requestParsingBlockingScript(script); |
569 } | 655 } |
656 | |
657 // "Decrement the parser's script nesting level by one. | |
658 // If the parser's script nesting level is zero, then set the parser | |
659 // pause flag to false." | |
660 // Implemented by scope out of ScriptNestingLevelIncrementer. | |
661 | |
662 // "Let the insertion point have the value of the old insertion point." | |
663 // Implemented by scope out of InsertionPointRecord. | |
570 } | 664 } |
571 } | 665 } |
572 | 666 |
573 DEFINE_TRACE(HTMLParserScriptRunner) { | 667 DEFINE_TRACE(HTMLParserScriptRunner) { |
574 visitor->trace(m_document); | 668 visitor->trace(m_document); |
575 visitor->trace(m_host); | 669 visitor->trace(m_host); |
576 visitor->trace(m_parserBlockingScript); | 670 visitor->trace(m_parserBlockingScript); |
577 visitor->trace(m_scriptsToExecuteAfterParsing); | 671 visitor->trace(m_scriptsToExecuteAfterParsing); |
578 PendingScriptClient::trace(visitor); | 672 PendingScriptClient::trace(visitor); |
579 } | 673 } |
580 | 674 |
581 } // namespace blink | 675 } // namespace blink |
OLD | NEW |