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

Side by Side Diff: third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.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 * Copyright (C) 2011 Apple Inc. All rights reserved. 3 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 if (task.operation == HTMLConstructionSiteTask::Reparent) 177 if (task.operation == HTMLConstructionSiteTask::Reparent)
178 return executeReparentTask(task); 178 return executeReparentTask(task);
179 179
180 if (task.operation == HTMLConstructionSiteTask::TakeAllChildren) 180 if (task.operation == HTMLConstructionSiteTask::TakeAllChildren)
181 return executeTakeAllChildrenTask(task); 181 return executeTakeAllChildrenTask(task);
182 182
183 ASSERT_NOT_REACHED(); 183 ASSERT_NOT_REACHED();
184 } 184 }
185 185
186 // This is only needed for TextDocuments where we might have text nodes 186 // This is only needed for TextDocuments where we might have text nodes
187 // approaching the default length limit (~64k) and we don't want to 187 // approaching the default length limit (~64k) and we don't want to break a text
188 // break a text node in the middle of a combining character. 188 // node in the middle of a combining character.
189 static unsigned findBreakIndexBetween(const StringBuilder& string, 189 static unsigned findBreakIndexBetween(const StringBuilder& string,
190 unsigned currentPosition, 190 unsigned currentPosition,
191 unsigned proposedBreakIndex) { 191 unsigned proposedBreakIndex) {
192 ASSERT(currentPosition < proposedBreakIndex); 192 ASSERT(currentPosition < proposedBreakIndex);
193 ASSERT(proposedBreakIndex <= string.length()); 193 ASSERT(proposedBreakIndex <= string.length());
194 // The end of the string is always a valid break. 194 // The end of the string is always a valid break.
195 if (proposedBreakIndex == string.length()) 195 if (proposedBreakIndex == string.length())
196 return proposedBreakIndex; 196 return proposedBreakIndex;
197 197
198 // Latin-1 does not have breakable boundaries. If we ever moved to a differnet 8-bit encoding this could be wrong. 198 // Latin-1 does not have breakable boundaries. If we ever moved to a different
199 // 8-bit encoding this could be wrong.
199 if (string.is8Bit()) 200 if (string.is8Bit())
200 return proposedBreakIndex; 201 return proposedBreakIndex;
201 202
202 const UChar* breakSearchCharacters = string.characters16() + currentPosition; 203 const UChar* breakSearchCharacters = string.characters16() + currentPosition;
203 // We need at least two characters look-ahead to account for UTF-16 surrogates , but can't search off the end of the buffer! 204 // We need at least two characters look-ahead to account for UTF-16
205 // surrogates, but can't search off the end of the buffer!
204 unsigned breakSearchLength = 206 unsigned breakSearchLength =
205 std::min(proposedBreakIndex - currentPosition + 2, 207 std::min(proposedBreakIndex - currentPosition + 2,
206 string.length() - currentPosition); 208 string.length() - currentPosition);
207 NonSharedCharacterBreakIterator it(breakSearchCharacters, breakSearchLength); 209 NonSharedCharacterBreakIterator it(breakSearchCharacters, breakSearchLength);
208 210
209 if (it.isBreak(proposedBreakIndex - currentPosition)) 211 if (it.isBreak(proposedBreakIndex - currentPosition))
210 return proposedBreakIndex; 212 return proposedBreakIndex;
211 213
212 int adjustedBreakIndexInSubstring = 214 int adjustedBreakIndexInSubstring =
213 it.preceding(proposedBreakIndex - currentPosition); 215 it.preceding(proposedBreakIndex - currentPosition);
214 if (adjustedBreakIndexInSubstring > 0) 216 if (adjustedBreakIndexInSubstring > 0)
215 return currentPosition + adjustedBreakIndexInSubstring; 217 return currentPosition + adjustedBreakIndexInSubstring;
216 // We failed to find a breakable point, let the caller figure out what to do. 218 // We failed to find a breakable point, let the caller figure out what to do.
217 return 0; 219 return 0;
218 } 220 }
219 221
220 static String atomizeIfAllWhitespace(const String& string, 222 static String atomizeIfAllWhitespace(const String& string,
221 WhitespaceMode whitespaceMode) { 223 WhitespaceMode whitespaceMode) {
222 // Strings composed entirely of whitespace are likely to be repeated. 224 // Strings composed entirely of whitespace are likely to be repeated. Turn
223 // Turn them into AtomicString so we share a single string for each. 225 // them into AtomicString so we share a single string for each.
224 if (whitespaceMode == AllWhitespace || 226 if (whitespaceMode == AllWhitespace ||
225 (whitespaceMode == WhitespaceUnknown && isAllWhitespace(string))) 227 (whitespaceMode == WhitespaceUnknown && isAllWhitespace(string)))
226 return AtomicString(string).getString(); 228 return AtomicString(string).getString();
227 return string; 229 return string;
228 } 230 }
229 231
230 void HTMLConstructionSite::flushPendingText(FlushMode mode) { 232 void HTMLConstructionSite::flushPendingText(FlushMode mode) {
231 if (m_pendingText.isEmpty()) 233 if (m_pendingText.isEmpty())
232 return; 234 return;
233 235
234 if (mode == FlushIfAtTextLimit && 236 if (mode == FlushIfAtTextLimit &&
235 !shouldUseLengthLimit(*m_pendingText.parent)) 237 !shouldUseLengthLimit(*m_pendingText.parent))
236 return; 238 return;
237 239
238 PendingText pendingText; 240 PendingText pendingText;
239 // Hold onto the current pending text on the stack so that queueTask doesn't r ecurse infinitely. 241 // Hold onto the current pending text on the stack so that queueTask doesn't
242 // recurse infinitely.
240 m_pendingText.swap(pendingText); 243 m_pendingText.swap(pendingText);
241 ASSERT(m_pendingText.isEmpty()); 244 ASSERT(m_pendingText.isEmpty());
242 245
243 // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is nec essary 246 // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is
244 // for performance, see: https://bugs.webkit.org/show_bug.cgi?id=55898 247 // necessary for performance, see:
248 // https://bugs.webkit.org/show_bug.cgi?id=55898
245 unsigned lengthLimit = textLengthLimitForContainer(*pendingText.parent); 249 unsigned lengthLimit = textLengthLimitForContainer(*pendingText.parent);
246 250
247 unsigned currentPosition = 0; 251 unsigned currentPosition = 0;
248 const StringBuilder& string = pendingText.stringBuilder; 252 const StringBuilder& string = pendingText.stringBuilder;
249 while (currentPosition < string.length()) { 253 while (currentPosition < string.length()) {
250 unsigned proposedBreakIndex = 254 unsigned proposedBreakIndex =
251 std::min(currentPosition + lengthLimit, string.length()); 255 std::min(currentPosition + lengthLimit, string.length());
252 unsigned breakIndex = 256 unsigned breakIndex =
253 findBreakIndexBetween(string, currentPosition, proposedBreakIndex); 257 findBreakIndexBetween(string, currentPosition, proposedBreakIndex);
254 ASSERT(breakIndex <= string.length()); 258 ASSERT(breakIndex <= string.length());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert); 291 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert);
288 task.parent = parent; 292 task.parent = parent;
289 task.child = child; 293 task.child = child;
290 task.selfClosing = selfClosing; 294 task.selfClosing = selfClosing;
291 295
292 if (shouldFosterParent()) { 296 if (shouldFosterParent()) {
293 fosterParent(task.child); 297 fosterParent(task.child);
294 return; 298 return;
295 } 299 }
296 300
297 // Add as a sibling of the parent if we have reached the maximum depth allowed . 301 // Add as a sibling of the parent if we have reached the maximum depth
302 // allowed.
298 if (m_openElements.stackDepth() > maximumHTMLParserDOMTreeDepth && 303 if (m_openElements.stackDepth() > maximumHTMLParserDOMTreeDepth &&
299 task.parent->parentNode()) 304 task.parent->parentNode())
300 task.parent = task.parent->parentNode(); 305 task.parent = task.parent->parentNode();
301 306
302 ASSERT(task.parent); 307 ASSERT(task.parent);
303 queueTask(task); 308 queueTask(task);
304 } 309 }
305 310
306 void HTMLConstructionSite::executeQueuedTasks() { 311 void HTMLConstructionSite::executeQueuedTasks() {
307 // This has no affect on pendingText, and we may have pendingText 312 // This has no affect on pendingText, and we may have pendingText remaining
308 // remaining after executing all other queued tasks. 313 // after executing all other queued tasks.
309 const size_t size = m_taskQueue.size(); 314 const size_t size = m_taskQueue.size();
310 if (!size) 315 if (!size)
311 return; 316 return;
312 317
313 // Copy the task queue into a local variable in case executeTask 318 // Copy the task queue into a local variable in case executeTask re-enters the
314 // re-enters the parser. 319 // parser.
315 TaskQueue queue; 320 TaskQueue queue;
316 queue.swap(m_taskQueue); 321 queue.swap(m_taskQueue);
317 322
318 for (size_t i = 0; i < size; ++i) 323 for (size_t i = 0; i < size; ++i)
319 executeTask(queue[i]); 324 executeTask(queue[i]);
320 325
321 // We might be detached now. 326 // We might be detached now.
322 } 327 }
323 328
324 HTMLConstructionSite::HTMLConstructionSite( 329 HTMLConstructionSite::HTMLConstructionSite(
(...skipping 19 matching lines...) Expand all
344 DCHECK(!m_form); 349 DCHECK(!m_form);
345 350
346 m_attachmentRoot = fragment; 351 m_attachmentRoot = fragment;
347 m_isParsingFragment = true; 352 m_isParsingFragment = true;
348 353
349 if (!contextElement->document().isTemplateDocument()) 354 if (!contextElement->document().isTemplateDocument())
350 m_form = Traversal<HTMLFormElement>::firstAncestorOrSelf(*contextElement); 355 m_form = Traversal<HTMLFormElement>::firstAncestorOrSelf(*contextElement);
351 } 356 }
352 357
353 HTMLConstructionSite::~HTMLConstructionSite() { 358 HTMLConstructionSite::~HTMLConstructionSite() {
354 // Depending on why we're being destroyed it might be OK 359 // Depending on why we're being destroyed it might be OK to forget queued
355 // to forget queued tasks, but currently we don't expect to. 360 // tasks, but currently we don't expect to.
356 ASSERT(m_taskQueue.isEmpty()); 361 ASSERT(m_taskQueue.isEmpty());
357 // Currently we assume that text will never be the last token in the 362 // Currently we assume that text will never be the last token in the document
358 // document and that we'll always queue some additional task to cause it to fl ush. 363 // and that we'll always queue some additional task to cause it to flush.
359 ASSERT(m_pendingText.isEmpty()); 364 ASSERT(m_pendingText.isEmpty());
360 } 365 }
361 366
362 DEFINE_TRACE(HTMLConstructionSite) { 367 DEFINE_TRACE(HTMLConstructionSite) {
363 visitor->trace(m_document); 368 visitor->trace(m_document);
364 visitor->trace(m_attachmentRoot); 369 visitor->trace(m_attachmentRoot);
365 visitor->trace(m_head); 370 visitor->trace(m_head);
366 visitor->trace(m_form); 371 visitor->trace(m_form);
367 visitor->trace(m_openElements); 372 visitor->trace(m_openElements);
368 visitor->trace(m_activeFormattingElements); 373 visitor->trace(m_activeFormattingElements);
369 visitor->trace(m_taskQueue); 374 visitor->trace(m_taskQueue);
370 visitor->trace(m_pendingText); 375 visitor->trace(m_pendingText);
371 } 376 }
372 377
373 void HTMLConstructionSite::detach() { 378 void HTMLConstructionSite::detach() {
374 // FIXME: We'd like to ASSERT here that we're canceling and not just discardin g 379 // FIXME: We'd like to ASSERT here that we're canceling and not just
375 // text that really should have made it into the DOM earlier, but there 380 // discarding text that really should have made it into the DOM earlier, but
376 // doesn't seem to be a nice way to do that. 381 // there doesn't seem to be a nice way to do that.
377 m_pendingText.discard(); 382 m_pendingText.discard();
378 m_document = nullptr; 383 m_document = nullptr;
379 m_attachmentRoot = nullptr; 384 m_attachmentRoot = nullptr;
380 } 385 }
381 386
382 HTMLFormElement* HTMLConstructionSite::takeForm() { 387 HTMLFormElement* HTMLConstructionSite::takeForm() {
383 return m_form.release(); 388 return m_form.release();
384 } 389 }
385 390
386 void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML( 391 void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 Document::CompatibilityMode mode) { 439 Document::CompatibilityMode mode) {
435 m_inQuirksMode = (mode == Document::QuirksMode); 440 m_inQuirksMode = (mode == Document::QuirksMode);
436 m_document->setCompatibilityMode(mode); 441 m_document->setCompatibilityMode(mode);
437 } 442 }
438 443
439 void HTMLConstructionSite::setCompatibilityModeFromDoctype( 444 void HTMLConstructionSite::setCompatibilityModeFromDoctype(
440 const String& name, 445 const String& name,
441 const String& publicId, 446 const String& publicId,
442 const String& systemId) { 447 const String& systemId) {
443 // There are three possible compatibility modes: 448 // There are three possible compatibility modes:
444 // Quirks - quirks mode emulates WinIE and NS4. CSS parsing is also relaxed in this mode, e.g., unit types can 449 // Quirks - quirks mode emulates WinIE and NS4. CSS parsing is also relaxed in
445 // be omitted from numbers. 450 // this mode, e.g., unit types can be omitted from numbers.
446 // Limited Quirks - This mode is identical to no-quirks mode except for its tr eatment of line-height in the inline box model. 451 // Limited Quirks - This mode is identical to no-quirks mode except for its
447 // No Quirks - no quirks apply. Web pages will obey the specifications to the letter. 452 // treatment of line-height in the inline box model.
453 // No Quirks - no quirks apply. Web pages will obey the specifications to the
454 // letter.
448 455
449 // Check for Quirks Mode. 456 // Check for Quirks Mode.
450 if (name != "html" || 457 if (name != "html" ||
451 publicId.startsWith("+//Silmaril//dtd html Pro v0r11 19970101//", 458 publicId.startsWith("+//Silmaril//dtd html Pro v0r11 19970101//",
452 TextCaseInsensitive) || 459 TextCaseInsensitive) ||
453 publicId.startsWith( 460 publicId.startsWith(
454 "-//AdvaSoft Ltd//DTD HTML 3.0 asWedit + extensions//", 461 "-//AdvaSoft Ltd//DTD HTML 3.0 asWedit + extensions//",
455 TextCaseInsensitive) || 462 TextCaseInsensitive) ||
456 publicId.startsWith("-//AS//DTD HTML 3.0 asWedit + extensions//", 463 publicId.startsWith("-//AS//DTD HTML 3.0 asWedit + extensions//",
457 TextCaseInsensitive) || 464 TextCaseInsensitive) ||
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 setCompatibilityMode(Document::NoQuirksMode); 593 setCompatibilityMode(Document::NoQuirksMode);
587 } 594 }
588 595
589 void HTMLConstructionSite::processEndOfFile() { 596 void HTMLConstructionSite::processEndOfFile() {
590 ASSERT(currentNode()); 597 ASSERT(currentNode());
591 flush(FlushAlways); 598 flush(FlushAlways);
592 openElements()->popAll(); 599 openElements()->popAll();
593 } 600 }
594 601
595 void HTMLConstructionSite::finishedParsing() { 602 void HTMLConstructionSite::finishedParsing() {
596 // We shouldn't have any queued tasks but we might have pending text which we need to promote to tasks and execute. 603 // We shouldn't have any queued tasks but we might have pending text which we
604 // need to promote to tasks and execute.
597 ASSERT(m_taskQueue.isEmpty()); 605 ASSERT(m_taskQueue.isEmpty());
598 flush(FlushAlways); 606 flush(FlushAlways);
599 m_document->finishedParsing(); 607 m_document->finishedParsing();
600 } 608 }
601 609
602 void HTMLConstructionSite::insertDoctype(AtomicHTMLToken* token) { 610 void HTMLConstructionSite::insertDoctype(AtomicHTMLToken* token) {
603 ASSERT(token->type() == HTMLToken::DOCTYPE); 611 ASSERT(token->type() == HTMLToken::DOCTYPE);
604 612
605 const String& publicId = 613 const String& publicId =
606 StringImpl::create8BitIfPossible(token->publicIdentifier()); 614 StringImpl::create8BitIfPossible(token->publicIdentifier());
607 const String& systemId = 615 const String& systemId =
608 StringImpl::create8BitIfPossible(token->systemIdentifier()); 616 StringImpl::create8BitIfPossible(token->systemIdentifier());
609 DocumentType* doctype = 617 DocumentType* doctype =
610 DocumentType::create(m_document, token->name(), publicId, systemId); 618 DocumentType::create(m_document, token->name(), publicId, systemId);
611 attachLater(m_attachmentRoot, doctype); 619 attachLater(m_attachmentRoot, doctype);
612 620
613 // DOCTYPE nodes are only processed when parsing fragments w/o contextElements , which 621 // DOCTYPE nodes are only processed when parsing fragments w/o
614 // never occurs. However, if we ever chose to support such, this code is subt ly wrong, 622 // contextElements, which never occurs. However, if we ever chose to support
615 // because context-less fragments can determine their own quirks mode, and thu s change 623 // such, this code is subtly wrong, because context-less fragments can
616 // parsing rules (like <p> inside <table>). For now we ASSERT that we never h it this code 624 // determine their own quirks mode, and thus change parsing rules (like <p>
617 // in a fragment, as changing the owning document's compatibility mode would b e wrong. 625 // inside <table>). For now we ASSERT that we never hit this code in a
626 // fragment, as changing the owning document's compatibility mode would be
627 // wrong.
618 ASSERT(!m_isParsingFragment); 628 ASSERT(!m_isParsingFragment);
619 if (m_isParsingFragment) 629 if (m_isParsingFragment)
620 return; 630 return;
621 631
622 if (token->forceQuirks()) 632 if (token->forceQuirks())
623 setCompatibilityMode(Document::QuirksMode); 633 setCompatibilityMode(Document::QuirksMode);
624 else { 634 else {
625 setCompatibilityModeFromDoctype(token->name(), publicId, systemId); 635 setCompatibilityModeFromDoctype(token->name(), publicId, systemId);
626 } 636 }
627 } 637 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#th e-stack-of-open-elements 704 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#th e-stack-of-open-elements
695 // Possible active formatting elements include: 705 // Possible active formatting elements include:
696 // a, b, big, code, em, font, i, nobr, s, small, strike, strong, tt, and u. 706 // a, b, big, code, em, font, i, nobr, s, small, strike, strong, tt, and u.
697 insertHTMLElement(token); 707 insertHTMLElement(token);
698 m_activeFormattingElements.append(currentElementRecord()->stackItem()); 708 m_activeFormattingElements.append(currentElementRecord()->stackItem());
699 } 709 }
700 710
701 void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token) { 711 void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token) {
702 // http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.htm l#already-started 712 // http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.htm l#already-started
703 // http://html5.org/specs/dom-parsing.html#dom-range-createcontextualfragment 713 // http://html5.org/specs/dom-parsing.html#dom-range-createcontextualfragment
704 // For createContextualFragment, the specifications say to mark it parser-inse rted and already-started and later unmark them. 714 // For createContextualFragment, the specifications say to mark it
705 // However, we short circuit that logic to avoid the subtree traversal to find script elements since scripts can never see 715 // parser-inserted and already-started and later unmark them. However, we
706 // those flags or effects thereof. 716 // short circuit that logic to avoid the subtree traversal to find script
717 // elements since scripts can never see those flags or effects thereof.
707 const bool parserInserted = 718 const bool parserInserted =
708 m_parserContentPolicy != AllowScriptingContentAndDoNotMarkAlreadyStarted; 719 m_parserContentPolicy != AllowScriptingContentAndDoNotMarkAlreadyStarted;
709 const bool alreadyStarted = m_isParsingFragment && parserInserted; 720 const bool alreadyStarted = m_isParsingFragment && parserInserted;
710 // TODO(csharrison): This logic only works if the tokenizer/parser was not 721 // TODO(csharrison): This logic only works if the tokenizer/parser was not
711 // blocked waiting for scripts when the element was inserted. This usually 722 // blocked waiting for scripts when the element was inserted. This usually
712 // fails for instance, on second document.write if a script writes twice in 723 // fails for instance, on second document.write if a script writes twice in a
713 // a row. To fix this, the parser might have to keep track of raw string 724 // row. To fix this, the parser might have to keep track of raw string
714 // position. 725 // position.
715 // TODO(csharrison): Refactor this so that the bools that are passed in are 726 // TODO(csharrison): Refactor this so that the bools that are passed
716 // packed in a bitfield from an enum class. 727 // in are packed in a bitfield from an enum class.
717 const bool createdDuringDocumentWrite = 728 const bool createdDuringDocumentWrite =
718 ownerDocumentForCurrentNode().isInDocumentWrite(); 729 ownerDocumentForCurrentNode().isInDocumentWrite();
719 HTMLScriptElement* element = 730 HTMLScriptElement* element =
720 HTMLScriptElement::create(ownerDocumentForCurrentNode(), parserInserted, 731 HTMLScriptElement::create(ownerDocumentForCurrentNode(), parserInserted,
721 alreadyStarted, createdDuringDocumentWrite); 732 alreadyStarted, createdDuringDocumentWrite);
722 setAttributes(element, token, m_parserContentPolicy); 733 setAttributes(element, token, m_parserContentPolicy);
723 if (scriptingContentIsAllowed(m_parserContentPolicy)) 734 if (scriptingContentIsAllowed(m_parserContentPolicy))
724 attachLater(currentNode(), element); 735 attachLater(currentNode(), element);
725 m_openElements.push(HTMLStackItem::create(element, token)); 736 m_openElements.push(HTMLStackItem::create(element, token));
726 } 737 }
727 738
728 void HTMLConstructionSite::insertForeignElement( 739 void HTMLConstructionSite::insertForeignElement(
729 AtomicHTMLToken* token, 740 AtomicHTMLToken* token,
730 const AtomicString& namespaceURI) { 741 const AtomicString& namespaceURI) {
731 ASSERT(token->type() == HTMLToken::StartTag); 742 ASSERT(token->type() == HTMLToken::StartTag);
732 DVLOG(1) 743 // parseError when xmlns or xmlns:xlink are wrong.
733 << "Not implemented."; // parseError when xmlns or xmlns:xlink are wrong. 744 DVLOG(1) << "Not implemented.";
734 745
735 Element* element = createElement(token, namespaceURI); 746 Element* element = createElement(token, namespaceURI);
736 if (scriptingContentIsAllowed(m_parserContentPolicy) || 747 if (scriptingContentIsAllowed(m_parserContentPolicy) ||
737 !toScriptLoaderIfPossible(element)) 748 !toScriptLoaderIfPossible(element))
738 attachLater(currentNode(), element, token->selfClosing()); 749 attachLater(currentNode(), element, token->selfClosing());
739 if (!token->selfClosing()) 750 if (!token->selfClosing())
740 m_openElements.push(HTMLStackItem::create(element, token, namespaceURI)); 751 m_openElements.push(HTMLStackItem::create(element, token, namespaceURI));
741 } 752 }
742 753
743 void HTMLConstructionSite::insertTextNode(const String& string, 754 void HTMLConstructionSite::insertTextNode(const String& string,
744 WhitespaceMode whitespaceMode) { 755 WhitespaceMode whitespaceMode) {
745 HTMLConstructionSiteTask dummyTask(HTMLConstructionSiteTask::Insert); 756 HTMLConstructionSiteTask dummyTask(HTMLConstructionSiteTask::Insert);
746 dummyTask.parent = currentNode(); 757 dummyTask.parent = currentNode();
747 758
748 if (shouldFosterParent()) 759 if (shouldFosterParent())
749 findFosterSite(dummyTask); 760 findFosterSite(dummyTask);
750 761
751 // FIXME: This probably doesn't need to be done both here and in insert(Task). 762 // FIXME: This probably doesn't need to be done both here and in insert(Task).
752 if (isHTMLTemplateElement(*dummyTask.parent)) 763 if (isHTMLTemplateElement(*dummyTask.parent))
753 dummyTask.parent = toHTMLTemplateElement(dummyTask.parent.get())->content(); 764 dummyTask.parent = toHTMLTemplateElement(dummyTask.parent.get())->content();
754 765
755 // Unclear when parent != case occurs. Somehow we insert text into two separat e nodes while processing the same Token. 766 // Unclear when parent != case occurs. Somehow we insert text into two
756 // The nextChild != dummy.nextChild case occurs whenever foster parenting happ ened and we hit a new text node "<table>a</table>b" 767 // separate nodes while processing the same Token. The nextChild !=
757 // In either case we have to flush the pending text into the task queue before making more. 768 // dummy.nextChild case occurs whenever foster parenting happened and we hit a
769 // new text node "<table>a</table>b" In either case we have to flush the
770 // pending text into the task queue before making more.
758 if (!m_pendingText.isEmpty() && 771 if (!m_pendingText.isEmpty() &&
759 (m_pendingText.parent != dummyTask.parent || 772 (m_pendingText.parent != dummyTask.parent ||
760 m_pendingText.nextChild != dummyTask.nextChild)) 773 m_pendingText.nextChild != dummyTask.nextChild))
761 flushPendingText(FlushAlways); 774 flushPendingText(FlushAlways);
762 m_pendingText.append(dummyTask.parent, dummyTask.nextChild, string, 775 m_pendingText.append(dummyTask.parent, dummyTask.nextChild, string,
763 whitespaceMode); 776 whitespaceMode);
764 } 777 }
765 778
766 void HTMLConstructionSite::reparent(HTMLElementStack::ElementRecord* newParent, 779 void HTMLConstructionSite::reparent(HTMLElementStack::ElementRecord* newParent,
767 HTMLElementStack::ElementRecord* child) { 780 HTMLElementStack::ElementRecord* child) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 const Attribute* isAttribute = token->getAttributeItem(HTMLNames::isAttr); 855 const Attribute* isAttribute = token->getAttributeItem(HTMLNames::isAttr);
843 const AtomicString& name = isAttribute ? isAttribute->value() : localName; 856 const AtomicString& name = isAttribute ? isAttribute->value() : localName;
844 CustomElementDescriptor descriptor(name, localName); 857 CustomElementDescriptor descriptor(name, localName);
845 858
846 // 4.-6. 859 // 4.-6.
847 return registry->definitionFor(descriptor); 860 return registry->definitionFor(descriptor);
848 } 861 }
849 862
850 // "create an element for a token" 863 // "create an element for a token"
851 // https://html.spec.whatwg.org/#create-an-element-for-the-token 864 // https://html.spec.whatwg.org/#create-an-element-for-the-token
852 // TODO(dominicc): When form association is separate from creation, 865 // TODO(dominicc): When form association is separate from creation, unify this
853 // unify this with foreign element creation. Add a namespace parameter 866 // with foreign element creation. Add a namespace parameter and check for HTML
854 // and check for HTML namespace to lookupCustomElementDefinition. 867 // namespace to lookupCustomElementDefinition.
855 HTMLElement* HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token) { 868 HTMLElement* HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token) {
856 // "1. Let document be intended parent's node document." 869 // "1. Let document be intended parent's node document."
857 Document& document = ownerDocumentForCurrentNode(); 870 Document& document = ownerDocumentForCurrentNode();
858 871
859 // Only associate the element with the current form if we're creating the new element 872 // Only associate the element with the current form if we're creating the new
860 // in a document with a browsing context (rather than in <template> contents). 873 // element in a document with a browsing context (rather than in <template>
874 // contents).
861 // TODO(dominicc): Change form to happen after element creation when 875 // TODO(dominicc): Change form to happen after element creation when
862 // implementing customized built-in elements. 876 // implementing customized built-in elements.
863 HTMLFormElement* form = document.frame() ? m_form.get() : nullptr; 877 HTMLFormElement* form = document.frame() ? m_form.get() : nullptr;
864 878
865 // "2. Let local name be the tag name of the token." 879 // "2. Let local name be the tag name of the token."
866 // "3. Let is be the value of the "is" attribute in the giev token ..." etc. 880 // "3. Let is be the value of the "is" attribute in the giev token ..." etc.
867 // "4. Let definition be the result of looking up a custom element ..." etc. 881 // "4. Let definition be the result of looking up a custom element ..." etc.
868 CustomElementDefinition* definition = 882 CustomElementDefinition* definition =
869 m_isParsingFragment ? nullptr 883 m_isParsingFragment ? nullptr
870 : lookUpCustomElementDefinition(document, token); 884 : lookUpCustomElementDefinition(document, token);
871 // "5. If definition is non-null and the parser was not originally created 885 // "5. If definition is non-null and the parser was not originally created
872 // for the HTML fragment parsing algorithm, then let will execute script 886 // for the HTML fragment parsing algorithm, then let will execute script
873 // be true." 887 // be true."
874 bool willExecuteScript = definition && !m_isParsingFragment; 888 bool willExecuteScript = definition && !m_isParsingFragment;
875 889
876 HTMLElement* element; 890 HTMLElement* element;
877 891
878 if (willExecuteScript) { 892 if (willExecuteScript) {
879 // "6.1 Increment the document's throw-on-dynamic-insertion counter." 893 // "6.1 Increment the document's throw-on-dynamic-insertion counter."
880 ThrowOnDynamicMarkupInsertionCountIncrementer 894 ThrowOnDynamicMarkupInsertionCountIncrementer
881 throwOnDynamicMarkupInsertions(&document); 895 throwOnDynamicMarkupInsertions(&document);
882 896
883 // "6.2 If the JavaScript execution context stack is empty, 897 // "6.2 If the JavaScript execution context stack is empty,
884 // then perform a microtask checkpoint." 898 // then perform a microtask checkpoint."
885 899
886 // TODO(dominicc): This is the way the Blink HTML parser 900 // TODO(dominicc): This is the way the Blink HTML parser performs
887 // performs checkpoints, but note the spec is different--it 901 // checkpoints, but note the spec is different--it talks about the
888 // talks about the JavaScript stack, not the script nesting 902 // JavaScript stack, not the script nesting level.
889 // level.
890 if (0u == m_reentryPermit->scriptNestingLevel()) 903 if (0u == m_reentryPermit->scriptNestingLevel())
891 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); 904 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate());
892 905
893 // "6.3 Push a new element queue onto the custom element 906 // "6.3 Push a new element queue onto the custom element
894 // reactions stack." 907 // reactions stack."
895 CEReactionsScope reactions; 908 CEReactionsScope reactions;
896 909
897 // 7. 910 // 7.
898 QualifiedName elementQName(nullAtom, token->name(), 911 QualifiedName elementQName(nullAtom, token->name(),
899 HTMLNames::xhtmlNamespaceURI); 912 HTMLNames::xhtmlNamespaceURI);
900 element = definition->createElementSync(document, elementQName); 913 element = definition->createElementSync(document, elementQName);
901 914
902 // "8. Append each attribute in the given token to element." 915 // "8. Append each attribute in the given token to element." We don't use
903 // We don't use setAttributes here because the custom element 916 // setAttributes here because the custom element constructor may have
904 // constructor may have manipulated attributes. 917 // manipulated attributes.
905 for (const auto& attribute : token->attributes()) 918 for (const auto& attribute : token->attributes())
906 element->setAttribute(attribute.name(), attribute.value()); 919 element->setAttribute(attribute.name(), attribute.value());
907 920
908 // "9. If will execute script is true, then ..." etc. The 921 // "9. If will execute script is true, then ..." etc. The CEReactionsScope
909 // CEReactionsScope and ThrowOnDynamicMarkupInsertionCountIncrementer 922 // and ThrowOnDynamicMarkupInsertionCountIncrementer destructors implement
910 // destructors implement steps 9.1-3. 923 // steps 9.1-3.
911 } else { 924 } else {
912 // FIXME: This can't use 925 // FIXME: This can't use HTMLConstructionSite::createElement because we have
913 // HTMLConstructionSite::createElement because we have to 926 // to pass the current form element. We should rework form association to
914 // pass the current form element. We should rework form 927 // occur after construction to allow better code sharing here.
915 // association to occur after construction to allow better
916 // code sharing here.
917 element = HTMLElementFactory::createHTMLElement( 928 element = HTMLElementFactory::createHTMLElement(
918 token->name(), document, form, getCreateElementFlags()); 929 token->name(), document, form, getCreateElementFlags());
919 // Definition for the created element does not exist here and 930 // Definition for the created element does not exist here and it cannot be
920 // it cannot be custom or failed. 931 // custom or failed.
921 DCHECK_NE(element->getCustomElementState(), CustomElementState::Custom); 932 DCHECK_NE(element->getCustomElementState(), CustomElementState::Custom);
922 DCHECK_NE(element->getCustomElementState(), CustomElementState::Failed); 933 DCHECK_NE(element->getCustomElementState(), CustomElementState::Failed);
923 934
924 // "8. Append each attribute in the given token to element." 935 // "8. Append each attribute in the given token to element."
925 setAttributes(element, token, m_parserContentPolicy); 936 setAttributes(element, token, m_parserContentPolicy);
926 } 937 }
927 938
928 // TODO(dominicc): Implement steps 10-12 when customized built-in 939 // TODO(dominicc): Implement steps 10-12 when customized built-in elements are
929 // elements are implemented. 940 // implemented.
930 941
931 return element; 942 return element;
932 } 943 }
933 944
934 HTMLStackItem* HTMLConstructionSite::createElementFromSavedToken( 945 HTMLStackItem* HTMLConstructionSite::createElementFromSavedToken(
935 HTMLStackItem* item) { 946 HTMLStackItem* item) {
936 Element* element; 947 Element* element;
937 // NOTE: Moving from item -> token -> item copies the Attribute vector twice! 948 // NOTE: Moving from item -> token -> item copies the Attribute vector twice!
938 AtomicHTMLToken fakeToken(HTMLToken::StartTag, item->localName(), 949 AtomicHTMLToken fakeToken(HTMLToken::StartTag, item->localName(),
939 item->attributes()); 950 item->attributes());
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 1001
991 void HTMLConstructionSite::generateImpliedEndTags() { 1002 void HTMLConstructionSite::generateImpliedEndTags() {
992 while (hasImpliedEndTag(currentStackItem())) 1003 while (hasImpliedEndTag(currentStackItem()))
993 m_openElements.pop(); 1004 m_openElements.pop();
994 } 1005 }
995 1006
996 bool HTMLConstructionSite::inQuirksMode() { 1007 bool HTMLConstructionSite::inQuirksMode() {
997 return m_inQuirksMode; 1008 return m_inQuirksMode;
998 } 1009 }
999 1010
1000 // Adjusts |task| to match the "adjusted insertion location" determined by the f oster parenting algorithm, 1011 // Adjusts |task| to match the "adjusted insertion location" determined by the
1001 // laid out as the substeps of step 2 of https://html.spec.whatwg.org/#appropria te-place-for-inserting-a-node 1012 // foster parenting algorithm, laid out as the substeps of step 2 of
1013 // https://html.spec.whatwg.org/#appropriate-place-for-inserting-a-node
1002 void HTMLConstructionSite::findFosterSite(HTMLConstructionSiteTask& task) { 1014 void HTMLConstructionSite::findFosterSite(HTMLConstructionSiteTask& task) {
1003 // 2.1 1015 // 2.1
1004 HTMLElementStack::ElementRecord* lastTemplate = 1016 HTMLElementStack::ElementRecord* lastTemplate =
1005 m_openElements.topmost(templateTag.localName()); 1017 m_openElements.topmost(templateTag.localName());
1006 1018
1007 // 2.2 1019 // 2.2
1008 HTMLElementStack::ElementRecord* lastTable = 1020 HTMLElementStack::ElementRecord* lastTable =
1009 m_openElements.topmost(tableTag.localName()); 1021 m_openElements.topmost(tableTag.localName());
1010 1022
1011 // 2.3 1023 // 2.3
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 ASSERT(task.parent); 1057 ASSERT(task.parent);
1046 queueTask(task); 1058 queueTask(task);
1047 } 1059 }
1048 1060
1049 DEFINE_TRACE(HTMLConstructionSite::PendingText) { 1061 DEFINE_TRACE(HTMLConstructionSite::PendingText) {
1050 visitor->trace(parent); 1062 visitor->trace(parent);
1051 visitor->trace(nextChild); 1063 visitor->trace(nextChild);
1052 } 1064 }
1053 1065
1054 } // namespace blink 1066 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698