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

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

Issue 2386893002: Reformat comments in core/html/parser (Closed)
Patch Set: self review Created 4 years, 2 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, 105 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment,
106 Element* contextElement, 106 Element* contextElement,
107 ParserContentPolicy parserContentPolicy) 107 ParserContentPolicy parserContentPolicy)
108 : HTMLDocumentParser(fragment->document(), 108 : HTMLDocumentParser(fragment->document(),
109 parserContentPolicy, 109 parserContentPolicy,
110 ForceSynchronousParsing) { 110 ForceSynchronousParsing) {
111 // No m_scriptRunner in fragment parser. 111 // No m_scriptRunner in fragment parser.
112 m_treeBuilder = HTMLTreeBuilder::create(this, fragment, contextElement, 112 m_treeBuilder = HTMLTreeBuilder::create(this, fragment, contextElement,
113 parserContentPolicy, m_options); 113 parserContentPolicy, m_options);
114 114
115 bool reportErrors = 115 // For now document fragment parsing never reports errors.
116 false; // For now document fragment parsing never reports errors. 116 bool reportErrors = false;
117 m_tokenizer->setState( 117 m_tokenizer->setState(
118 tokenizerStateForContextElement(contextElement, reportErrors, m_options)); 118 tokenizerStateForContextElement(contextElement, reportErrors, m_options));
119 m_xssAuditor.initForFragment(); 119 m_xssAuditor.initForFragment();
120 } 120 }
121 121
122 HTMLDocumentParser::HTMLDocumentParser(Document& document, 122 HTMLDocumentParser::HTMLDocumentParser(Document& document,
123 ParserContentPolicy contentPolicy, 123 ParserContentPolicy contentPolicy,
124 ParserSynchronizationPolicy syncPolicy) 124 ParserSynchronizationPolicy syncPolicy)
125 : ScriptableDocumentParser(document, contentPolicy), 125 : ScriptableDocumentParser(document, contentPolicy),
126 m_options(&document), 126 m_options(&document),
(...skipping 26 matching lines...) Expand all
153 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); 153 ASSERT(shouldUseThreading() || (m_token && m_tokenizer));
154 // Threading is not allowed in prefetch mode. 154 // Threading is not allowed in prefetch mode.
155 DCHECK(!document.isPrefetchOnly() || !shouldUseThreading()); 155 DCHECK(!document.isPrefetchOnly() || !shouldUseThreading());
156 156
157 ThreadState::current()->registerPreFinalizer(this); 157 ThreadState::current()->registerPreFinalizer(this);
158 } 158 }
159 159
160 HTMLDocumentParser::~HTMLDocumentParser() {} 160 HTMLDocumentParser::~HTMLDocumentParser() {}
161 161
162 void HTMLDocumentParser::dispose() { 162 void HTMLDocumentParser::dispose() {
163 // In Oilpan, HTMLDocumentParser can die together with Document, and 163 // In Oilpan, HTMLDocumentParser can die together with Document, and detach()
164 // detach() is not called in this case. 164 // is not called in this case.
165 if (m_haveBackgroundParser) 165 if (m_haveBackgroundParser)
166 stopBackgroundParser(); 166 stopBackgroundParser();
167 } 167 }
168 168
169 DEFINE_TRACE(HTMLDocumentParser) { 169 DEFINE_TRACE(HTMLDocumentParser) {
170 visitor->trace(m_treeBuilder); 170 visitor->trace(m_treeBuilder);
171 visitor->trace(m_parserScheduler); 171 visitor->trace(m_parserScheduler);
172 visitor->trace(m_xssAuditorDelegate); 172 visitor->trace(m_xssAuditorDelegate);
173 visitor->trace(m_scriptRunner); 173 visitor->trace(m_scriptRunner);
174 visitor->trace(m_preloader); 174 visitor->trace(m_preloader);
(...skipping 13 matching lines...) Expand all
188 peakPendingTokenHistogram.count( 188 peakPendingTokenHistogram.count(
189 m_tokenizedChunkQueue->peakPendingTokenCount()); 189 m_tokenizedChunkQueue->peakPendingTokenCount());
190 } 190 }
191 191
192 if (m_haveBackgroundParser) 192 if (m_haveBackgroundParser)
193 stopBackgroundParser(); 193 stopBackgroundParser();
194 DocumentParser::detach(); 194 DocumentParser::detach();
195 if (m_scriptRunner) 195 if (m_scriptRunner)
196 m_scriptRunner->detach(); 196 m_scriptRunner->detach();
197 m_treeBuilder->detach(); 197 m_treeBuilder->detach();
198 // FIXME: It seems wrong that we would have a preload scanner here. 198 // FIXME: It seems wrong that we would have a preload scanner here. Yet during
199 // Yet during fast/dom/HTMLScriptElement/script-load-events.html we do. 199 // fast/dom/HTMLScriptElement/script-load-events.html we do.
200 m_preloadScanner.reset(); 200 m_preloadScanner.reset();
201 m_insertionPreloadScanner.reset(); 201 m_insertionPreloadScanner.reset();
202 if (m_parserScheduler) { 202 if (m_parserScheduler) {
203 m_parserScheduler->detach(); 203 m_parserScheduler->detach();
204 m_parserScheduler.clear(); 204 m_parserScheduler.clear();
205 } 205 }
206 // Oilpan: It is important to clear m_token to deallocate backing memory of 206 // Oilpan: It is important to clear m_token to deallocate backing memory of
207 // HTMLToken::m_data and let the allocator reuse the memory for 207 // HTMLToken::m_data and let the allocator reuse the memory for
208 // HTMLToken::m_data of a next HTMLDocumentParser. We need to clear 208 // HTMLToken::m_data of a next HTMLDocumentParser. We need to clear
209 // m_tokenizer first because m_tokenizer has a raw pointer to m_token. 209 // m_tokenizer first because m_tokenizer has a raw pointer to m_token.
(...skipping 26 matching lines...) Expand all
236 236
237 if (isStopped()) 237 if (isStopped())
238 return; 238 return;
239 239
240 DocumentParser::prepareToStopParsing(); 240 DocumentParser::prepareToStopParsing();
241 241
242 // We will not have a scriptRunner when parsing a DocumentFragment. 242 // We will not have a scriptRunner when parsing a DocumentFragment.
243 if (m_scriptRunner) 243 if (m_scriptRunner)
244 document()->setReadyState(Document::Interactive); 244 document()->setReadyState(Document::Interactive);
245 245
246 // Setting the ready state above can fire mutation event and detach us 246 // Setting the ready state above can fire mutation event and detach us from
247 // from underneath. In that case, just bail out. 247 // underneath. In that case, just bail out.
248 if (isDetached()) 248 if (isDetached())
249 return; 249 return;
250 250
251 attemptToRunDeferredScriptsAndEnd(); 251 attemptToRunDeferredScriptsAndEnd();
252 } 252 }
253 253
254 bool HTMLDocumentParser::isParsingFragment() const { 254 bool HTMLDocumentParser::isParsingFragment() const {
255 return m_treeBuilder->isParsingFragment(); 255 return m_treeBuilder->isParsingFragment();
256 } 256 }
257 257
(...skipping 24 matching lines...) Expand all
282 m_treeBuilder->takeScriptToProcess(scriptStartPosition); 282 m_treeBuilder->takeScriptToProcess(scriptStartPosition);
283 // We will not have a scriptRunner when parsing a DocumentFragment. 283 // We will not have a scriptRunner when parsing a DocumentFragment.
284 if (m_scriptRunner) 284 if (m_scriptRunner)
285 m_scriptRunner->execute(scriptElement, scriptStartPosition); 285 m_scriptRunner->execute(scriptElement, scriptStartPosition);
286 } 286 }
287 287
288 bool HTMLDocumentParser::canTakeNextToken() { 288 bool HTMLDocumentParser::canTakeNextToken() {
289 if (isStopped()) 289 if (isStopped())
290 return false; 290 return false;
291 291
292 // If we're paused waiting for a script, we try to execute scripts before cont inuing. 292 // If we're paused waiting for a script, we try to execute scripts before
293 // continuing.
293 if (m_treeBuilder->hasParserBlockingScript()) 294 if (m_treeBuilder->hasParserBlockingScript())
294 runScriptsForPausedTreeBuilder(); 295 runScriptsForPausedTreeBuilder();
295 if (isStopped() || isWaitingForScripts()) 296 if (isStopped() || isWaitingForScripts())
296 return false; 297 return false;
297 298
298 // FIXME: It's wrong for the HTMLDocumentParser to reach back to the 299 // FIXME: It's wrong for the HTMLDocumentParser to reach back to the
299 // LocalFrame, but this approach is how the old parser handled 300 // LocalFrame, but this approach is how the old parser handled stopping when
300 // stopping when the page assigns window.location. What really 301 // the page assigns window.location. What really should happen is that
301 // should happen is that assigning window.location causes the 302 // assigning window.location causes the parser to stop parsing cleanly. The
302 // parser to stop parsing cleanly. The problem is we're not 303 // problem is we're not perpared to do that at every point where we run
303 // perpared to do that at every point where we run JavaScript. 304 // JavaScript.
304 if (!isParsingFragment() && document()->frame() && 305 if (!isParsingFragment() && document()->frame() &&
305 document()->frame()->navigationScheduler().locationChangePending()) 306 document()->frame()->navigationScheduler().locationChangePending())
306 return false; 307 return false;
307 308
308 return true; 309 return true;
309 } 310 }
310 311
311 void HTMLDocumentParser::notifyPendingTokenizedChunks() { 312 void HTMLDocumentParser::notifyPendingTokenizedChunks() {
312 TRACE_EVENT0("blink", "HTMLDocumentParser::notifyPendingTokenizedChunks"); 313 TRACE_EVENT0("blink", "HTMLDocumentParser::notifyPendingTokenizedChunks");
313 DCHECK(m_tokenizedChunkQueue); 314 DCHECK(m_tokenizedChunkQueue);
314 315
315 Vector<std::unique_ptr<TokenizedChunk>> pendingChunks; 316 Vector<std::unique_ptr<TokenizedChunk>> pendingChunks;
316 m_tokenizedChunkQueue->takeAll(pendingChunks); 317 m_tokenizedChunkQueue->takeAll(pendingChunks);
317 318
318 if (!isParsing()) 319 if (!isParsing())
319 return; 320 return;
320 321
321 // ApplicationCache needs to be initialized before issuing preloads. 322 // ApplicationCache needs to be initialized before issuing preloads. We
322 // We suspend preload until HTMLHTMLElement is inserted and 323 // suspend preload until HTMLHTMLElement is inserted and ApplicationCache is
323 // ApplicationCache is initialized. Note: link rel preloads don't follow 324 // initialized. Note: link rel preloads don't follow this policy per the spec.
324 // this policy per the spec. These directives should initiate a fetch as 325 // These directives should initiate a fetch as fast as possible.
325 // fast as possible.
326 if (!m_triedLoadingLinkHeaders && document()->loader() && 326 if (!m_triedLoadingLinkHeaders && document()->loader() &&
327 !pendingChunks.isEmpty()) { 327 !pendingChunks.isEmpty()) {
328 // Note that on commit, the loader dispatched preloads for all the 328 // Note that on commit, the loader dispatched preloads for all the non-media
329 // non-media links. 329 // links.
330 document()->loader()->dispatchLinkHeaderPreloads( 330 document()->loader()->dispatchLinkHeaderPreloads(
331 &pendingChunks.first()->viewport, LinkLoader::OnlyLoadMedia); 331 &pendingChunks.first()->viewport, LinkLoader::OnlyLoadMedia);
332 m_triedLoadingLinkHeaders = true; 332 m_triedLoadingLinkHeaders = true;
333 } 333 }
334 334
335 // Defer preloads if any of the chunks contains a <meta> csp tag. 335 // Defer preloads if any of the chunks contains a <meta> csp tag.
336 for (auto& chunk : pendingChunks) { 336 for (auto& chunk : pendingChunks) {
337 if (chunk->pendingCSPMetaTokenIndex != TokenizedChunk::noPendingToken) { 337 if (chunk->pendingCSPMetaTokenIndex != TokenizedChunk::noPendingToken) {
338 m_pendingCSPMetaToken = 338 m_pendingCSPMetaToken =
339 &chunk->tokens->at(chunk->pendingCSPMetaTokenIndex); 339 &chunk->tokens->at(chunk->pendingCSPMetaTokenIndex);
(...skipping 12 matching lines...) Expand all
352 m_queuedPreloads.append(std::move(request)); 352 m_queuedPreloads.append(std::move(request));
353 } 353 }
354 for (auto& index : chunk->likelyDocumentWriteScriptIndices) { 354 for (auto& index : chunk->likelyDocumentWriteScriptIndices) {
355 const CompactHTMLToken& token = chunk->tokens->at(index); 355 const CompactHTMLToken& token = chunk->tokens->at(index);
356 ASSERT(token.type() == HTMLToken::TokenType::Character); 356 ASSERT(token.type() == HTMLToken::TokenType::Character);
357 m_queuedDocumentWriteScripts.append(token.data()); 357 m_queuedDocumentWriteScripts.append(token.data());
358 } 358 }
359 } 359 }
360 m_preloader->takeAndPreload(linkRelPreloads); 360 m_preloader->takeAndPreload(linkRelPreloads);
361 } else { 361 } else {
362 // We can safely assume that there are no queued preloads request after 362 // We can safely assume that there are no queued preloads request after the
363 // the document element is available, as we empty the queue immediately 363 // document element is available, as we empty the queue immediately after
364 // after the document element is created in documentElementAvailable(). 364 // the document element is created in documentElementAvailable().
365 ASSERT(m_queuedPreloads.isEmpty()); 365 ASSERT(m_queuedPreloads.isEmpty());
366 ASSERT(m_queuedDocumentWriteScripts.isEmpty()); 366 ASSERT(m_queuedDocumentWriteScripts.isEmpty());
367 // Loop through the chunks to generate preloads before any 367 // Loop through the chunks to generate preloads before any document.write
368 // document.write script evaluation takes place. Preloading these 368 // script evaluation takes place. Preloading these scripts is valuable and
369 // scripts is valuable and comparably cheap, while evaluating JS can be 369 // comparably cheap, while evaluating JS can be expensive.
370 // expensive.
371 for (auto& chunk : pendingChunks) { 370 for (auto& chunk : pendingChunks) {
372 m_preloader->takeAndPreload(chunk->preloads); 371 m_preloader->takeAndPreload(chunk->preloads);
373 } 372 }
374 for (auto& chunk : pendingChunks) { 373 for (auto& chunk : pendingChunks) {
375 for (auto& index : chunk->likelyDocumentWriteScriptIndices) { 374 for (auto& index : chunk->likelyDocumentWriteScriptIndices) {
376 const CompactHTMLToken& token = chunk->tokens->at(index); 375 const CompactHTMLToken& token = chunk->tokens->at(index);
377 ASSERT(token.type() == HTMLToken::TokenType::Character); 376 ASSERT(token.type() == HTMLToken::TokenType::Character);
378 evaluateAndPreloadScriptForDocumentWrite(token.data()); 377 evaluateAndPreloadScriptForDocumentWrite(token.data());
379 } 378 }
380 } 379 }
(...skipping 12 matching lines...) Expand all
393 392
394 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser( 393 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(
395 const DocumentEncodingData& data) { 394 const DocumentEncodingData& data) {
396 document()->setEncodingData(data); 395 document()->setEncodingData(data);
397 } 396 }
398 397
399 void HTMLDocumentParser::validateSpeculations( 398 void HTMLDocumentParser::validateSpeculations(
400 std::unique_ptr<TokenizedChunk> chunk) { 399 std::unique_ptr<TokenizedChunk> chunk) {
401 ASSERT(chunk); 400 ASSERT(chunk);
402 if (isWaitingForScripts()) { 401 if (isWaitingForScripts()) {
403 // We're waiting on a network script, just save the chunk, we'll get 402 // We're waiting on a network script, just save the chunk, we'll get a
404 // a second validateSpeculations call after the script completes. 403 // second validateSpeculations call after the script completes. This call
405 // This call should have been made immediately after runScriptsForPausedTree Builder 404 // should have been made immediately after runScriptsForPausedTreeBuilder
406 // which may have started a network load and left us waiting. 405 // which may have started a network load and left us waiting.
407 ASSERT(!m_lastChunkBeforeScript); 406 ASSERT(!m_lastChunkBeforeScript);
408 m_lastChunkBeforeScript = std::move(chunk); 407 m_lastChunkBeforeScript = std::move(chunk);
409 return; 408 return;
410 } 409 }
411 410
412 ASSERT(!m_lastChunkBeforeScript); 411 ASSERT(!m_lastChunkBeforeScript);
413 std::unique_ptr<HTMLTokenizer> tokenizer = std::move(m_tokenizer); 412 std::unique_ptr<HTMLTokenizer> tokenizer = std::move(m_tokenizer);
414 std::unique_ptr<HTMLToken> token = std::move(m_token); 413 std::unique_ptr<HTMLToken> token = std::move(m_token);
415 414
416 if (!tokenizer) { 415 if (!tokenizer) {
417 // There must not have been any changes to the HTMLTokenizer state on 416 // There must not have been any changes to the HTMLTokenizer state on the
418 // the main thread, which means the speculation buffer is correct. 417 // main thread, which means the speculation buffer is correct.
419 return; 418 return;
420 } 419 }
421 420
422 // Currently we're only smart enough to reuse the speculation buffer if the to kenizer 421 // Currently we're only smart enough to reuse the speculation buffer if the
423 // both starts and ends in the DataState. That state is simplest because the H TMLToken 422 // tokenizer both starts and ends in the DataState. That state is simplest
424 // is always in the Uninitialized state. We should consider whether we can reu se the 423 // because the HTMLToken is always in the Uninitialized state. We should
425 // speculation buffer in other states, but we'd likely need to do something mo re 424 // consider whether we can reuse the speculation buffer in other states, but
426 // sophisticated with the HTMLToken. 425 // we'd likely need to do something more sophisticated with the HTMLToken.
427 if (chunk->tokenizerState == HTMLTokenizer::DataState && 426 if (chunk->tokenizerState == HTMLTokenizer::DataState &&
428 tokenizer->getState() == HTMLTokenizer::DataState && 427 tokenizer->getState() == HTMLTokenizer::DataState &&
429 m_input.current().isEmpty() && 428 m_input.current().isEmpty() &&
430 chunk->treeBuilderState == 429 chunk->treeBuilderState ==
431 HTMLTreeBuilderSimulator::stateFor(m_treeBuilder.get())) { 430 HTMLTreeBuilderSimulator::stateFor(m_treeBuilder.get())) {
432 ASSERT(token->isUninitialized()); 431 ASSERT(token->isUninitialized());
433 return; 432 return;
434 } 433 }
435 434
436 discardSpeculationsAndResumeFrom(std::move(chunk), std::move(token), 435 discardSpeculationsAndResumeFrom(std::move(chunk), std::move(token),
(...skipping 22 matching lines...) Expand all
459 wrapUnique(new BackgroundHTMLParser::Checkpoint); 458 wrapUnique(new BackgroundHTMLParser::Checkpoint);
460 checkpoint->parser = m_weakFactory.createWeakPtr(); 459 checkpoint->parser = m_weakFactory.createWeakPtr();
461 checkpoint->token = std::move(token); 460 checkpoint->token = std::move(token);
462 checkpoint->tokenizer = std::move(tokenizer); 461 checkpoint->tokenizer = std::move(tokenizer);
463 checkpoint->treeBuilderState = 462 checkpoint->treeBuilderState =
464 HTMLTreeBuilderSimulator::stateFor(m_treeBuilder.get()); 463 HTMLTreeBuilderSimulator::stateFor(m_treeBuilder.get());
465 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; 464 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint;
466 checkpoint->preloadScannerCheckpoint = 465 checkpoint->preloadScannerCheckpoint =
467 lastChunkBeforeScript->preloadScannerCheckpoint; 466 lastChunkBeforeScript->preloadScannerCheckpoint;
468 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); 467 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy();
469 m_input.current() 468 // FIXME: This should be passed in instead of cleared.
470 .clear(); // FIXME: This should be passed in instead of cleared. 469 m_input.current().clear();
471 470
472 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); 471 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread());
473 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::resumeFrom, 472 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::resumeFrom,
474 m_backgroundParser, passed(std::move(checkpoint))); 473 m_backgroundParser, passed(std::move(checkpoint)));
475 } 474 }
476 475
477 size_t HTMLDocumentParser::processTokenizedChunkFromBackgroundParser( 476 size_t HTMLDocumentParser::processTokenizedChunkFromBackgroundParser(
478 std::unique_ptr<TokenizedChunk> popChunk) { 477 std::unique_ptr<TokenizedChunk> popChunk) {
479 TRACE_EVENT_WITH_FLOW0( 478 TRACE_EVENT_WITH_FLOW0(
480 "blink,loading", 479 "blink,loading",
(...skipping 18 matching lines...) Expand all
499 postTaskToLookaheadParser(Asynchronous, 498 postTaskToLookaheadParser(Asynchronous,
500 &BackgroundHTMLParser::startedChunkWithCheckpoint, 499 &BackgroundHTMLParser::startedChunkWithCheckpoint,
501 m_backgroundParser, chunk->inputCheckpoint); 500 m_backgroundParser, chunk->inputCheckpoint);
502 501
503 for (const auto& xssInfo : chunk->xssInfos) { 502 for (const auto& xssInfo : chunk->xssInfos) {
504 m_textPosition = xssInfo->m_textPosition; 503 m_textPosition = xssInfo->m_textPosition;
505 m_xssAuditorDelegate.didBlockScript(*xssInfo); 504 m_xssAuditorDelegate.didBlockScript(*xssInfo);
506 if (isStopped()) 505 if (isStopped())
507 break; 506 break;
508 } 507 }
509 // XSSAuditorDelegate can detach the parser if it decides to block the entire current document. 508 // XSSAuditorDelegate can detach the parser if it decides to block the entire
509 // current document.
510 if (isDetached()) 510 if (isDetached())
511 return elementTokenCount; 511 return elementTokenCount;
512 512
513 for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin(); 513 for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin();
514 it != tokens->end(); ++it) { 514 it != tokens->end(); ++it) {
515 ASSERT(!isWaitingForScripts()); 515 ASSERT(!isWaitingForScripts());
516 516
517 if (!chunk->startingScript && 517 if (!chunk->startingScript &&
518 (it->type() == HTMLToken::StartTag || it->type() == HTMLToken::EndTag)) 518 (it->type() == HTMLToken::StartTag || it->type() == HTMLToken::EndTag))
519 elementTokenCount++; 519 elementTokenCount++;
520 520
521 if (document()->frame() && 521 if (document()->frame() &&
522 document()->frame()->navigationScheduler().locationChangePending()) { 522 document()->frame()->navigationScheduler().locationChangePending()) {
523 // To match main-thread parser behavior (which never checks locationChange Pending on the EOF path) 523 // To match main-thread parser behavior (which never checks
524 // we peek to see if this chunk has an EOF and process it anyway. 524 // locationChangePending on the EOF path) we peek to see if this chunk has
525 // an EOF and process it anyway.
525 if (tokens->last().type() == HTMLToken::EndOfFile) { 526 if (tokens->last().type() == HTMLToken::EndOfFile) {
526 ASSERT( 527 ASSERT(
527 m_speculations 528 m_speculations
528 .isEmpty()); // There should never be any chunks after the EOF. 529 .isEmpty()); // There should never be any chunks after the EOF.
529 prepareToStopParsing(); 530 prepareToStopParsing();
530 } 531 }
531 break; 532 break;
532 } 533 }
533 534
534 m_textPosition = it->textPosition(); 535 m_textPosition = it->textPosition();
535 536
536 constructTreeFromCompactHTMLToken(*it); 537 constructTreeFromCompactHTMLToken(*it);
537 538
538 if (isStopped()) 539 if (isStopped())
539 break; 540 break;
540 541
541 // Preloads were queued if there was a <meta> csp token in a tokenized 542 // Preloads were queued if there was a <meta> csp token in a tokenized
542 // chunk. 543 // chunk.
543 if (m_pendingCSPMetaToken && it == m_pendingCSPMetaToken) { 544 if (m_pendingCSPMetaToken && it == m_pendingCSPMetaToken) {
544 m_pendingCSPMetaToken = nullptr; 545 m_pendingCSPMetaToken = nullptr;
545 fetchQueuedPreloads(); 546 fetchQueuedPreloads();
546 } 547 }
547 548
548 if (isWaitingForScripts()) { 549 if (isWaitingForScripts()) {
549 ASSERT( 550 // The </script> is assumed to be the last token of this bunch.
550 it + 1 == 551 ASSERT(it + 1 == tokens->end());
551 tokens
552 ->end()); // The </script> is assumed to be the last token of thi s bunch.
553 runScriptsForPausedTreeBuilder(); 552 runScriptsForPausedTreeBuilder();
554 validateSpeculations(std::move(chunk)); 553 validateSpeculations(std::move(chunk));
555 break; 554 break;
556 } 555 }
557 556
558 if (it->type() == HTMLToken::EndOfFile) { 557 if (it->type() == HTMLToken::EndOfFile) {
559 ASSERT( 558 // The EOF is assumed to be the last token of this bunch.
560 it + 1 == 559 ASSERT(it + 1 == tokens->end());
561 tokens 560 // There should never be any chunks after the EOF.
562 ->end()); // The EOF is assumed to be the last token of this bunc h. 561 ASSERT(m_speculations.isEmpty());
563 ASSERT(
564 m_speculations
565 .isEmpty()); // There should never be any chunks after the EOF.
566 prepareToStopParsing(); 562 prepareToStopParsing();
567 break; 563 break;
568 } 564 }
569 565
570 ASSERT(!m_tokenizer); 566 ASSERT(!m_tokenizer);
571 ASSERT(!m_token); 567 ASSERT(!m_token);
572 } 568 }
573 569
574 // Make sure all required pending text nodes are emitted before returning. 570 // Make sure all required pending text nodes are emitted before returning.
575 // This leaves "script", "style" and "svg" nodes text nodes intact. 571 // This leaves "script", "style" and "svg" nodes text nodes intact.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 InspectorParseHtmlEvent::beginData( 606 InspectorParseHtmlEvent::beginData(
611 document(), lineNumber().zeroBasedInt())); 607 document(), lineNumber().zeroBasedInt()));
612 608
613 SpeculationsPumpSession session(m_pumpSpeculationsSessionNestingLevel); 609 SpeculationsPumpSession session(m_pumpSpeculationsSessionNestingLevel);
614 while (!m_speculations.isEmpty()) { 610 while (!m_speculations.isEmpty()) {
615 ASSERT(!isScheduledForResume()); 611 ASSERT(!isScheduledForResume());
616 size_t elementTokenCount = 612 size_t elementTokenCount =
617 processTokenizedChunkFromBackgroundParser(m_speculations.takeFirst()); 613 processTokenizedChunkFromBackgroundParser(m_speculations.takeFirst());
618 session.addedElementTokens(elementTokenCount); 614 session.addedElementTokens(elementTokenCount);
619 615
620 // Always check isParsing first as m_document may be null. 616 // Always check isParsing first as m_document may be null. Surprisingly,
621 // Surprisingly, isScheduledForResume() may be set here as a result of 617 // isScheduledForResume() may be set here as a result of
622 // processTokenizedChunkFromBackgroundParser running arbitrary javascript 618 // processTokenizedChunkFromBackgroundParser running arbitrary javascript
623 // which invokes nested event loops. (e.g. inspector breakpoints) 619 // which invokes nested event loops. (e.g. inspector breakpoints)
624 if (!isParsing() || isWaitingForScripts() || isScheduledForResume()) 620 if (!isParsing() || isWaitingForScripts() || isScheduledForResume())
625 break; 621 break;
626 622
627 if (m_speculations.isEmpty() || 623 if (m_speculations.isEmpty() ||
628 m_parserScheduler->yieldIfNeeded( 624 m_parserScheduler->yieldIfNeeded(
629 session, m_speculations.first()->startingScript)) 625 session, m_speculations.first()->startingScript))
630 break; 626 break;
631 } 627 }
(...skipping 22 matching lines...) Expand all
654 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState); 650 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState);
655 } 651 }
656 652
657 void HTMLDocumentParser::pumpTokenizer() { 653 void HTMLDocumentParser::pumpTokenizer() {
658 ASSERT(!isStopped()); 654 ASSERT(!isStopped());
659 ASSERT(m_tokenizer); 655 ASSERT(m_tokenizer);
660 ASSERT(m_token); 656 ASSERT(m_token);
661 657
662 PumpSession session(m_pumpSessionNestingLevel); 658 PumpSession session(m_pumpSessionNestingLevel);
663 659
664 // We tell the InspectorInstrumentation about every pump, even if we 660 // We tell the InspectorInstrumentation about every pump, even if we end up
665 // end up pumping nothing. It can filter out empty pumps itself. 661 // pumping nothing. It can filter out empty pumps itself.
666 // FIXME: m_input.current().length() is only accurate if we 662 // FIXME: m_input.current().length() is only accurate if we end up parsing the
667 // end up parsing the whole buffer in this pump. We should pass how 663 // whole buffer in this pump. We should pass how much we parsed as part of
668 // much we parsed as part of didWriteHTML instead of willWriteHTML. 664 // didWriteHTML instead of willWriteHTML.
669 TRACE_EVENT_BEGIN1( 665 TRACE_EVENT_BEGIN1(
670 "devtools.timeline", "ParseHTML", "beginData", 666 "devtools.timeline", "ParseHTML", "beginData",
671 InspectorParseHtmlEvent::beginData( 667 InspectorParseHtmlEvent::beginData(
672 document(), m_input.current().currentLine().zeroBasedInt())); 668 document(), m_input.current().currentLine().zeroBasedInt()));
673 669
674 if (!isParsingFragment()) 670 if (!isParsingFragment())
675 m_xssAuditor.init(document(), &m_xssAuditorDelegate); 671 m_xssAuditor.init(document(), &m_xssAuditorDelegate);
676 672
677 while (canTakeNextToken()) { 673 while (canTakeNextToken()) {
678 if (m_xssAuditor.isEnabled()) 674 if (m_xssAuditor.isEnabled())
(...skipping 22 matching lines...) Expand all
701 697
702 // There should only be PendingText left since the tree-builder always flushes 698 // There should only be PendingText left since the tree-builder always flushes
703 // the task queue before returning. In case that ever changes, crash. 699 // the task queue before returning. In case that ever changes, crash.
704 m_treeBuilder->flush(FlushAlways); 700 m_treeBuilder->flush(FlushAlways);
705 RELEASE_ASSERT(!isStopped()); 701 RELEASE_ASSERT(!isStopped());
706 702
707 if (isWaitingForScripts()) { 703 if (isWaitingForScripts()) {
708 ASSERT(m_tokenizer->getState() == HTMLTokenizer::DataState); 704 ASSERT(m_tokenizer->getState() == HTMLTokenizer::DataState);
709 705
710 ASSERT(m_preloader); 706 ASSERT(m_preloader);
711 // TODO(kouhei): m_preloader should be always available for synchronous pars ing case, 707 // TODO(kouhei): m_preloader should be always available for synchronous
712 // adding paranoia if for speculative crash fix for crbug.com/465478 708 // parsing case, adding paranoia if for speculative crash fix for
709 // crbug.com/465478
713 if (m_preloader) { 710 if (m_preloader) {
714 if (!m_preloadScanner) { 711 if (!m_preloadScanner) {
715 m_preloadScanner = createPreloadScanner(); 712 m_preloadScanner = createPreloadScanner();
716 m_preloadScanner->appendToEnd(m_input.current()); 713 m_preloadScanner->appendToEnd(m_input.current());
717 } 714 }
718 m_preloadScanner->scanAndPreload( 715 m_preloadScanner->scanAndPreload(
719 m_preloader.get(), document()->validBaseElementURL(), nullptr); 716 m_preloader.get(), document()->validBaseElementURL(), nullptr);
720 } 717 }
721 } 718 }
722 719
(...skipping 30 matching lines...) Expand all
753 } 750 }
754 } 751 }
755 752
756 void HTMLDocumentParser::constructTreeFromCompactHTMLToken( 753 void HTMLDocumentParser::constructTreeFromCompactHTMLToken(
757 const CompactHTMLToken& compactToken) { 754 const CompactHTMLToken& compactToken) {
758 AtomicHTMLToken token(compactToken); 755 AtomicHTMLToken token(compactToken);
759 m_treeBuilder->constructTree(&token); 756 m_treeBuilder->constructTree(&token);
760 } 757 }
761 758
762 bool HTMLDocumentParser::hasInsertionPoint() { 759 bool HTMLDocumentParser::hasInsertionPoint() {
763 // FIXME: The wasCreatedByScript() branch here might not be fully correct. 760 // FIXME: The wasCreatedByScript() branch here might not be fully correct. Our
764 // Our model of the EOF character differs slightly from the one in 761 // model of the EOF character differs slightly from the one in the spec
765 // the spec because our treatment is uniform between network-sourced 762 // because our treatment is uniform between network-sourced and script-sourced
766 // and script-sourced input streams whereas the spec treats them 763 // input streams whereas the spec treats them differently.
767 // differently.
768 return m_input.hasInsertionPoint() || 764 return m_input.hasInsertionPoint() ||
769 (wasCreatedByScript() && !m_input.haveSeenEndOfFile()); 765 (wasCreatedByScript() && !m_input.haveSeenEndOfFile());
770 } 766 }
771 767
772 void HTMLDocumentParser::insert(const SegmentedString& source) { 768 void HTMLDocumentParser::insert(const SegmentedString& source) {
773 if (isStopped()) 769 if (isStopped())
774 return; 770 return;
775 771
776 TRACE_EVENT1("blink", "HTMLDocumentParser::insert", "source_length", 772 TRACE_EVENT1("blink", "HTMLDocumentParser::insert", "source_length",
777 source.length()); 773 source.length());
(...skipping 23 matching lines...) Expand all
801 endIfDelayed(); 797 endIfDelayed();
802 } 798 }
803 799
804 void HTMLDocumentParser::startBackgroundParser() { 800 void HTMLDocumentParser::startBackgroundParser() {
805 ASSERT(!isStopped()); 801 ASSERT(!isStopped());
806 ASSERT(shouldUseThreading()); 802 ASSERT(shouldUseThreading());
807 ASSERT(!m_haveBackgroundParser); 803 ASSERT(!m_haveBackgroundParser);
808 ASSERT(document()); 804 ASSERT(document());
809 m_haveBackgroundParser = true; 805 m_haveBackgroundParser = true;
810 806
811 // TODO(alexclarke): Remove WebFrameScheduler::setDocumentParsingInBackground when background parser goes away. 807 // TODO(alexclarke): Remove WebFrameScheduler::setDocumentParsingInBackground
808 // when background parser goes away.
812 if (document()->frame() && document()->frame()->frameScheduler()) 809 if (document()->frame() && document()->frame()->frameScheduler())
813 document()->frame()->frameScheduler()->setDocumentParsingInBackground(true); 810 document()->frame()->frameScheduler()->setDocumentParsingInBackground(true);
814 811
815 // Make sure that a resolver is set up, so that the correct viewport dimension s will be fed to the background parser and preload scanner. 812 // Make sure that a resolver is set up, so that the correct viewport
813 // dimensions will be fed to the background parser and preload scanner.
816 if (document()->loader()) 814 if (document()->loader())
817 document()->ensureStyleResolver(); 815 document()->ensureStyleResolver();
818 816
819 std::unique_ptr<BackgroundHTMLParser::Configuration> config = 817 std::unique_ptr<BackgroundHTMLParser::Configuration> config =
820 wrapUnique(new BackgroundHTMLParser::Configuration); 818 wrapUnique(new BackgroundHTMLParser::Configuration);
821 config->options = m_options; 819 config->options = m_options;
822 config->parser = m_weakFactory.createWeakPtr(); 820 config->parser = m_weakFactory.createWeakPtr();
823 config->xssAuditor = wrapUnique(new XSSAuditor); 821 config->xssAuditor = wrapUnique(new XSSAuditor);
824 config->xssAuditor->init(document(), &m_xssAuditorDelegate); 822 config->xssAuditor->init(document(), &m_xssAuditorDelegate);
825 823
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 // ParseHTMLOnMainThread lands (the lookahead parser will be a member). 864 // ParseHTMLOnMainThread lands (the lookahead parser will be a member).
867 postTaskToLookaheadParser(Synchronous, &BackgroundHTMLParser::stop, 865 postTaskToLookaheadParser(Synchronous, &BackgroundHTMLParser::stop,
868 m_backgroundParser); 866 m_backgroundParser);
869 m_weakFactory.revokeAll(); 867 m_weakFactory.revokeAll();
870 } 868 }
871 869
872 void HTMLDocumentParser::append(const String& inputSource) { 870 void HTMLDocumentParser::append(const String& inputSource) {
873 if (isStopped()) 871 if (isStopped())
874 return; 872 return;
875 873
876 // We should never reach this point if we're using a parser thread, 874 // We should never reach this point if we're using a parser thread, as
877 // as appendBytes() will directly ship the data to the thread. 875 // appendBytes() will directly ship the data to the thread.
878 ASSERT(!shouldUseThreading()); 876 ASSERT(!shouldUseThreading());
879 877
880 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), 878 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"),
881 "HTMLDocumentParser::append", "size", inputSource.length()); 879 "HTMLDocumentParser::append", "size", inputSource.length());
882 const SegmentedString source(inputSource); 880 const SegmentedString source(inputSource);
883 881
884 if (document()->isPrefetchOnly()) { 882 if (document()->isPrefetchOnly()) {
885 if (!m_preloadScanner) 883 if (!m_preloadScanner)
886 m_preloadScanner = createPreloadScanner(); 884 m_preloadScanner = createPreloadScanner();
887 885
888 m_preloadScanner->appendToEnd(source); 886 m_preloadScanner->appendToEnd(source);
889 m_preloadScanner->scanAndPreload( 887 m_preloadScanner->scanAndPreload(
890 m_preloader.get(), document()->validBaseElementURL(), nullptr); 888 m_preloader.get(), document()->validBaseElementURL(), nullptr);
891 889
892 // Return after the preload scanner, do not actually parse the document. 890 // Return after the preload scanner, do not actually parse the document.
893 return; 891 return;
894 } 892 }
895 893
896 if (m_preloadScanner) { 894 if (m_preloadScanner) {
897 if (m_input.current().isEmpty() && !isWaitingForScripts()) { 895 if (m_input.current().isEmpty() && !isWaitingForScripts()) {
898 // We have parsed until the end of the current input and so are now moving ahead of the preload scanner. 896 // We have parsed until the end of the current input and so are now moving
899 // Clear the scanner so we know to scan starting from the current input po int if we block again. 897 // ahead of the preload scanner. Clear the scanner so we know to scan
898 // starting from the current input point if we block again.
900 m_preloadScanner.reset(); 899 m_preloadScanner.reset();
901 } else { 900 } else {
902 m_preloadScanner->appendToEnd(source); 901 m_preloadScanner->appendToEnd(source);
903 if (isWaitingForScripts()) 902 if (isWaitingForScripts())
904 m_preloadScanner->scanAndPreload( 903 m_preloadScanner->scanAndPreload(
905 m_preloader.get(), document()->validBaseElementURL(), nullptr); 904 m_preloader.get(), document()->validBaseElementURL(), nullptr);
906 } 905 }
907 } 906 }
908 907
909 m_input.appendToEnd(source); 908 m_input.appendToEnd(source);
910 909
911 if (inPumpSession()) { 910 if (inPumpSession()) {
912 // We've gotten data off the network in a nested write. 911 // We've gotten data off the network in a nested write. We don't want to
913 // We don't want to consume any more of the input stream now. Do 912 // consume any more of the input stream now. Do not worry. We'll consume
914 // not worry. We'll consume this data in a less-nested write(). 913 // this data in a less-nested write().
915 return; 914 return;
916 } 915 }
917 916
918 pumpTokenizerIfPossible(); 917 pumpTokenizerIfPossible();
919 918
920 endIfDelayed(); 919 endIfDelayed();
921 } 920 }
922 921
923 void HTMLDocumentParser::end() { 922 void HTMLDocumentParser::end() {
924 ASSERT(!isDetached()); 923 ASSERT(!isDetached());
925 ASSERT(!isScheduledForResume()); 924 ASSERT(!isScheduledForResume());
926 925
927 if (m_haveBackgroundParser) 926 if (m_haveBackgroundParser)
928 stopBackgroundParser(); 927 stopBackgroundParser();
929 928
930 // Informs the the rest of WebCore that parsing is really finished (and delete s this). 929 // Informs the the rest of WebCore that parsing is really finished (and
930 // deletes this).
931 m_treeBuilder->finished(); 931 m_treeBuilder->finished();
932 932
933 DocumentParser::stopParsing(); 933 DocumentParser::stopParsing();
934 } 934 }
935 935
936 void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd() { 936 void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd() {
937 ASSERT(isStopping()); 937 ASSERT(isStopping());
938 // FIXME: It may not be correct to disable this for the background parser. 938 // FIXME: It may not be correct to disable this for the background parser.
939 // That means hasInsertionPoint() may not be correct in some cases. 939 // That means hasInsertionPoint() may not be correct in some cases.
940 ASSERT(!hasInsertionPoint() || m_haveBackgroundParser); 940 ASSERT(!hasInsertionPoint() || m_haveBackgroundParser);
(...skipping 19 matching lines...) Expand all
960 return; 960 return;
961 961
962 if (!m_endWasDelayed || shouldDelayEnd()) 962 if (!m_endWasDelayed || shouldDelayEnd())
963 return; 963 return;
964 964
965 m_endWasDelayed = false; 965 m_endWasDelayed = false;
966 prepareToStopParsing(); 966 prepareToStopParsing();
967 } 967 }
968 968
969 void HTMLDocumentParser::finish() { 969 void HTMLDocumentParser::finish() {
970 // FIXME: We should ASSERT(!m_parserStopped) here, since it does not 970 // FIXME: We should ASSERT(!m_parserStopped) here, since it does not makes
971 // makes sense to call any methods on DocumentParser once it's been stopped. 971 // sense to call any methods on DocumentParser once it's been stopped.
972 // However, FrameLoader::stop calls DocumentParser::finish unconditionally. 972 // However, FrameLoader::stop calls DocumentParser::finish unconditionally.
973 973
974 flush(); 974 flush();
975 if (isDetached()) 975 if (isDetached())
976 return; 976 return;
977 977
978 // Empty documents never got an append() call, and thus have never started 978 // Empty documents never got an append() call, and thus have never started a
979 // a background parser. In those cases, we ignore shouldUseThreading() 979 // background parser. In those cases, we ignore shouldUseThreading() and fall
980 // and fall through to the non-threading case. 980 // through to the non-threading case.
981 if (m_haveBackgroundParser) { 981 if (m_haveBackgroundParser) {
982 if (!m_input.haveSeenEndOfFile()) 982 if (!m_input.haveSeenEndOfFile())
983 m_input.closeWithoutMarkingEndOfFile(); 983 m_input.closeWithoutMarkingEndOfFile();
984 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::finish, 984 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::finish,
985 m_backgroundParser); 985 m_backgroundParser);
986 return; 986 return;
987 } 987 }
988 988
989 if (!m_tokenizer) { 989 if (!m_tokenizer) {
990 ASSERT(!m_token); 990 ASSERT(!m_token);
991 // We're finishing before receiving any data. Rather than booting up 991 // We're finishing before receiving any data. Rather than booting up the
992 // the background parser just to spin it down, we finish parsing 992 // background parser just to spin it down, we finish parsing synchronously.
993 // synchronously.
994 m_token = wrapUnique(new HTMLToken); 993 m_token = wrapUnique(new HTMLToken);
995 m_tokenizer = HTMLTokenizer::create(m_options); 994 m_tokenizer = HTMLTokenizer::create(m_options);
996 } 995 }
997 996
998 // We're not going to get any more data off the network, so we tell the 997 // We're not going to get any more data off the network, so we tell the input
999 // input stream we've reached the end of file. finish() can be called more 998 // stream we've reached the end of file. finish() can be called more than
1000 // than once, if the first time does not call end(). 999 // once, if the first time does not call end().
1001 if (!m_input.haveSeenEndOfFile()) 1000 if (!m_input.haveSeenEndOfFile())
1002 m_input.markEndOfFile(); 1001 m_input.markEndOfFile();
1003 1002
1004 attemptToEnd(); 1003 attemptToEnd();
1005 } 1004 }
1006 1005
1007 bool HTMLDocumentParser::isExecutingScript() const { 1006 bool HTMLDocumentParser::isExecutingScript() const {
1008 if (!m_scriptRunner) 1007 if (!m_scriptRunner)
1009 return false; 1008 return false;
1010 return m_scriptRunner->isExecutingScript(); 1009 return m_scriptRunner->isExecutingScript();
(...skipping 16 matching lines...) Expand all
1027 return m_textPosition; 1026 return m_textPosition;
1028 1027
1029 const SegmentedString& currentString = m_input.current(); 1028 const SegmentedString& currentString = m_input.current();
1030 OrdinalNumber line = currentString.currentLine(); 1029 OrdinalNumber line = currentString.currentLine();
1031 OrdinalNumber column = currentString.currentColumn(); 1030 OrdinalNumber column = currentString.currentColumn();
1032 1031
1033 return TextPosition(line, column); 1032 return TextPosition(line, column);
1034 } 1033 }
1035 1034
1036 bool HTMLDocumentParser::isWaitingForScripts() const { 1035 bool HTMLDocumentParser::isWaitingForScripts() const {
1037 // When the TreeBuilder encounters a </script> tag, it returns to the HTMLDocu mentParser 1036 // When the TreeBuilder encounters a </script> tag, it returns to the
1038 // where the script is transfered from the treebuilder to the script runner. 1037 // HTMLDocumentParser where the script is transfered from the treebuilder to
1039 // The script runner will hold the script until its loaded and run. During 1038 // the script runner. The script runner will hold the script until its loaded
1040 // any of this time, we want to count ourselves as "waiting for a script" and thus 1039 // and run. During any of this time, we want to count ourselves as "waiting
1041 // run the preload scanner, as well as delay completion of parsing. 1040 // for a script" and thus run the preload scanner, as well as delay completion
1041 // of parsing.
1042 bool treeBuilderHasBlockingScript = m_treeBuilder->hasParserBlockingScript(); 1042 bool treeBuilderHasBlockingScript = m_treeBuilder->hasParserBlockingScript();
1043 bool scriptRunnerHasBlockingScript = 1043 bool scriptRunnerHasBlockingScript =
1044 m_scriptRunner && m_scriptRunner->hasParserBlockingScript(); 1044 m_scriptRunner && m_scriptRunner->hasParserBlockingScript();
1045 // Since the parser is paused while a script runner has a blocking script, it should 1045 // Since the parser is paused while a script runner has a blocking script, it
1046 // never be possible to end up with both objects holding a blocking script. 1046 // should never be possible to end up with both objects holding a blocking
1047 // script.
1047 ASSERT(!(treeBuilderHasBlockingScript && scriptRunnerHasBlockingScript)); 1048 ASSERT(!(treeBuilderHasBlockingScript && scriptRunnerHasBlockingScript));
1048 // If either object has a blocking script, the parser should be paused. 1049 // If either object has a blocking script, the parser should be paused.
1049 return treeBuilderHasBlockingScript || scriptRunnerHasBlockingScript || 1050 return treeBuilderHasBlockingScript || scriptRunnerHasBlockingScript ||
1050 m_reentryPermit->parserPauseFlag(); 1051 m_reentryPermit->parserPauseFlag();
1051 } 1052 }
1052 1053
1053 void HTMLDocumentParser::resumeParsingAfterScriptExecution() { 1054 void HTMLDocumentParser::resumeParsingAfterScriptExecution() {
1054 ASSERT(!isExecutingScript()); 1055 ASSERT(!isExecutingScript());
1055 ASSERT(!isWaitingForScripts()); 1056 ASSERT(!isWaitingForScripts());
1056 1057
(...skipping 28 matching lines...) Expand all
1085 attemptToRunDeferredScriptsAndEnd(); 1086 attemptToRunDeferredScriptsAndEnd();
1086 return; 1087 return;
1087 } 1088 }
1088 1089
1089 m_scriptRunner->executeScriptsWaitingForLoad(cachedResource); 1090 m_scriptRunner->executeScriptsWaitingForLoad(cachedResource);
1090 if (!isWaitingForScripts()) 1091 if (!isWaitingForScripts())
1091 resumeParsingAfterScriptExecution(); 1092 resumeParsingAfterScriptExecution();
1092 } 1093 }
1093 1094
1094 void HTMLDocumentParser::executeScriptsWaitingForResources() { 1095 void HTMLDocumentParser::executeScriptsWaitingForResources() {
1095 // Document only calls this when the Document owns the DocumentParser 1096 // Document only calls this when the Document owns the DocumentParser so this
1096 // so this will not be called in the DocumentFragment case. 1097 // will not be called in the DocumentFragment case.
1097 ASSERT(m_scriptRunner); 1098 ASSERT(m_scriptRunner);
1098 // Ignore calls unless we have a script blocking the parser waiting on a 1099 // Ignore calls unless we have a script blocking the parser waiting on a
1099 // stylesheet load. Otherwise we are currently parsing and this 1100 // stylesheet load. Otherwise we are currently parsing and this is a
1100 // is a re-entrant call from encountering a </ style> tag. 1101 // re-entrant call from encountering a </ style> tag.
1101 if (!m_scriptRunner->hasScriptsWaitingForResources()) 1102 if (!m_scriptRunner->hasScriptsWaitingForResources())
1102 return; 1103 return;
1103 m_scriptRunner->executeScriptsWaitingForResources(); 1104 m_scriptRunner->executeScriptsWaitingForResources();
1104 if (!isWaitingForScripts()) 1105 if (!isWaitingForScripts())
1105 resumeParsingAfterScriptExecution(); 1106 resumeParsingAfterScriptExecution();
1106 } 1107 }
1107 1108
1108 void HTMLDocumentParser::parseDocumentFragment( 1109 void HTMLDocumentParser::parseDocumentFragment(
1109 const String& source, 1110 const String& source,
1110 DocumentFragment* fragment, 1111 DocumentFragment* fragment,
1111 Element* contextElement, 1112 Element* contextElement,
1112 ParserContentPolicy parserContentPolicy) { 1113 ParserContentPolicy parserContentPolicy) {
1113 HTMLDocumentParser* parser = 1114 HTMLDocumentParser* parser =
1114 HTMLDocumentParser::create(fragment, contextElement, parserContentPolicy); 1115 HTMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
1115 parser->append(source); 1116 parser->append(source);
1116 parser->finish(); 1117 parser->finish();
1117 parser 1118 // Allows ~DocumentParser to assert it was detached before destruction.
1118 ->detach(); // Allows ~DocumentParser to assert it was detached before de struction. 1119 parser->detach();
1119 } 1120 }
1120 1121
1121 void HTMLDocumentParser::suspendScheduledTasks() { 1122 void HTMLDocumentParser::suspendScheduledTasks() {
1122 ASSERT(!m_tasksWereSuspended); 1123 ASSERT(!m_tasksWereSuspended);
1123 m_tasksWereSuspended = true; 1124 m_tasksWereSuspended = true;
1124 if (m_parserScheduler) 1125 if (m_parserScheduler)
1125 m_parserScheduler->suspend(); 1126 m_parserScheduler->suspend();
1126 } 1127 }
1127 1128
1128 void HTMLDocumentParser::resumeScheduledTasks() { 1129 void HTMLDocumentParser::resumeScheduledTasks() {
(...skipping 30 matching lines...) Expand all
1159 1160
1160 DecodedDataDocumentParser::appendBytes(data, length); 1161 DecodedDataDocumentParser::appendBytes(data, length);
1161 } 1162 }
1162 1163
1163 void HTMLDocumentParser::flush() { 1164 void HTMLDocumentParser::flush() {
1164 // If we've got no decoder, we never received any data. 1165 // If we've got no decoder, we never received any data.
1165 if (isDetached() || needsDecoder()) 1166 if (isDetached() || needsDecoder())
1166 return; 1167 return;
1167 1168
1168 if (shouldUseThreading()) { 1169 if (shouldUseThreading()) {
1169 // In some cases, flush() is called without any invocation of 1170 // In some cases, flush() is called without any invocation of appendBytes.
1170 // appendBytes. Fallback to synchronous parsing in that case. 1171 // Fallback to synchronous parsing in that case.
1171 if (!m_haveBackgroundParser) { 1172 if (!m_haveBackgroundParser) {
1172 m_shouldUseThreading = false; 1173 m_shouldUseThreading = false;
1173 m_token = wrapUnique(new HTMLToken); 1174 m_token = wrapUnique(new HTMLToken);
1174 m_tokenizer = HTMLTokenizer::create(m_options); 1175 m_tokenizer = HTMLTokenizer::create(m_options);
1175 DecodedDataDocumentParser::flush(); 1176 DecodedDataDocumentParser::flush();
1176 return; 1177 return;
1177 } 1178 }
1178 1179
1179 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::flush, 1180 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::flush,
1180 m_backgroundParser); 1181 m_backgroundParser);
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 case Asynchronous: 1295 case Asynchronous:
1295 m_loadingTaskRunner->postTask( 1296 m_loadingTaskRunner->postTask(
1296 BLINK_FROM_HERE, 1297 BLINK_FROM_HERE,
1297 WTF::bind(function, std::forward<Ps>(parameters)...)); 1298 WTF::bind(function, std::forward<Ps>(parameters)...));
1298 return; 1299 return;
1299 } 1300 }
1300 NOTREACHED(); 1301 NOTREACHED();
1301 } 1302 }
1302 1303
1303 } // namespace blink 1304 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698