| OLD | NEW |
| 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 // https://html.spec.whatwg.org/#insert-a-foreign-element | 106 // https://html.spec.whatwg.org/#insert-a-foreign-element |
| 107 // 3.1, (3) Push (pop) an element queue | 107 // 3.1, (3) Push (pop) an element queue |
| 108 CEReactionsScope reactions; | 108 CEReactionsScope reactions; |
| 109 if (task.nextChild) | 109 if (task.nextChild) |
| 110 task.parent->parserInsertBefore(task.child.get(), *task.nextChild); | 110 task.parent->parserInsertBefore(task.child.get(), *task.nextChild); |
| 111 else | 111 else |
| 112 task.parent->parserAppendChild(task.child.get()); | 112 task.parent->parserAppendChild(task.child.get()); |
| 113 } | 113 } |
| 114 | 114 |
| 115 static inline void executeInsertTask(HTMLConstructionSiteTask& task) { | 115 static inline void executeInsertTask(HTMLConstructionSiteTask& task) { |
| 116 ASSERT(task.operation == HTMLConstructionSiteTask::Insert); | 116 DCHECK_EQ(task.operation, HTMLConstructionSiteTask::Insert); |
| 117 | 117 |
| 118 insert(task); | 118 insert(task); |
| 119 | 119 |
| 120 if (task.child->isElementNode()) { | 120 if (task.child->isElementNode()) { |
| 121 Element& child = toElement(*task.child); | 121 Element& child = toElement(*task.child); |
| 122 child.beginParsingChildren(); | 122 child.beginParsingChildren(); |
| 123 if (task.selfClosing) | 123 if (task.selfClosing) |
| 124 child.finishParsingChildren(); | 124 child.finishParsingChildren(); |
| 125 } | 125 } |
| 126 } | 126 } |
| 127 | 127 |
| 128 static inline void executeInsertTextTask(HTMLConstructionSiteTask& task) { | 128 static inline void executeInsertTextTask(HTMLConstructionSiteTask& task) { |
| 129 ASSERT(task.operation == HTMLConstructionSiteTask::InsertText); | 129 DCHECK_EQ(task.operation, HTMLConstructionSiteTask::InsertText); |
| 130 ASSERT(task.child->isTextNode()); | 130 DCHECK(task.child->isTextNode()); |
| 131 | 131 |
| 132 // Merge text nodes into previous ones if possible: | 132 // Merge text nodes into previous ones if possible: |
| 133 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-constructi
on.html#insert-a-character | 133 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-constructi
on.html#insert-a-character |
| 134 Text* newText = toText(task.child.get()); | 134 Text* newText = toText(task.child.get()); |
| 135 Node* previousChild = task.nextChild ? task.nextChild->previousSibling() | 135 Node* previousChild = task.nextChild ? task.nextChild->previousSibling() |
| 136 : task.parent->lastChild(); | 136 : task.parent->lastChild(); |
| 137 if (previousChild && previousChild->isTextNode()) { | 137 if (previousChild && previousChild->isTextNode()) { |
| 138 Text* previousText = toText(previousChild); | 138 Text* previousText = toText(previousChild); |
| 139 unsigned lengthLimit = textLengthLimitForContainer(*task.parent); | 139 unsigned lengthLimit = textLengthLimitForContainer(*task.parent); |
| 140 if (previousText->length() + newText->length() < lengthLimit) { | 140 if (previousText->length() + newText->length() < lengthLimit) { |
| 141 previousText->parserAppendData(newText->data()); | 141 previousText->parserAppendData(newText->data()); |
| 142 return; | 142 return; |
| 143 } | 143 } |
| 144 } | 144 } |
| 145 | 145 |
| 146 insert(task); | 146 insert(task); |
| 147 } | 147 } |
| 148 | 148 |
| 149 static inline void executeReparentTask(HTMLConstructionSiteTask& task) { | 149 static inline void executeReparentTask(HTMLConstructionSiteTask& task) { |
| 150 ASSERT(task.operation == HTMLConstructionSiteTask::Reparent); | 150 DCHECK_EQ(task.operation, HTMLConstructionSiteTask::Reparent); |
| 151 | 151 |
| 152 task.parent->parserAppendChild(task.child); | 152 task.parent->parserAppendChild(task.child); |
| 153 } | 153 } |
| 154 | 154 |
| 155 static inline void executeInsertAlreadyParsedChildTask( | 155 static inline void executeInsertAlreadyParsedChildTask( |
| 156 HTMLConstructionSiteTask& task) { | 156 HTMLConstructionSiteTask& task) { |
| 157 ASSERT(task.operation == HTMLConstructionSiteTask::InsertAlreadyParsedChild); | 157 DCHECK_EQ(task.operation, HTMLConstructionSiteTask::InsertAlreadyParsedChild); |
| 158 | 158 |
| 159 insert(task); | 159 insert(task); |
| 160 } | 160 } |
| 161 | 161 |
| 162 static inline void executeTakeAllChildrenTask(HTMLConstructionSiteTask& task) { | 162 static inline void executeTakeAllChildrenTask(HTMLConstructionSiteTask& task) { |
| 163 ASSERT(task.operation == HTMLConstructionSiteTask::TakeAllChildren); | 163 DCHECK_EQ(task.operation, HTMLConstructionSiteTask::TakeAllChildren); |
| 164 | 164 |
| 165 task.parent->parserTakeAllChildrenFrom(*task.oldParent()); | 165 task.parent->parserTakeAllChildrenFrom(*task.oldParent()); |
| 166 } | 166 } |
| 167 | 167 |
| 168 void HTMLConstructionSite::executeTask(HTMLConstructionSiteTask& task) { | 168 void HTMLConstructionSite::executeTask(HTMLConstructionSiteTask& task) { |
| 169 ASSERT(m_taskQueue.isEmpty()); | 169 DCHECK(m_taskQueue.isEmpty()); |
| 170 if (task.operation == HTMLConstructionSiteTask::Insert) | 170 if (task.operation == HTMLConstructionSiteTask::Insert) |
| 171 return executeInsertTask(task); | 171 return executeInsertTask(task); |
| 172 | 172 |
| 173 if (task.operation == HTMLConstructionSiteTask::InsertText) | 173 if (task.operation == HTMLConstructionSiteTask::InsertText) |
| 174 return executeInsertTextTask(task); | 174 return executeInsertTextTask(task); |
| 175 | 175 |
| 176 // All the cases below this point are only used by the adoption agency. | 176 // All the cases below this point are only used by the adoption agency. |
| 177 | 177 |
| 178 if (task.operation == HTMLConstructionSiteTask::InsertAlreadyParsedChild) | 178 if (task.operation == HTMLConstructionSiteTask::InsertAlreadyParsedChild) |
| 179 return executeInsertAlreadyParsedChildTask(task); | 179 return executeInsertAlreadyParsedChildTask(task); |
| 180 | 180 |
| 181 if (task.operation == HTMLConstructionSiteTask::Reparent) | 181 if (task.operation == HTMLConstructionSiteTask::Reparent) |
| 182 return executeReparentTask(task); | 182 return executeReparentTask(task); |
| 183 | 183 |
| 184 if (task.operation == HTMLConstructionSiteTask::TakeAllChildren) | 184 if (task.operation == HTMLConstructionSiteTask::TakeAllChildren) |
| 185 return executeTakeAllChildrenTask(task); | 185 return executeTakeAllChildrenTask(task); |
| 186 | 186 |
| 187 ASSERT_NOT_REACHED(); | 187 NOTREACHED(); |
| 188 } | 188 } |
| 189 | 189 |
| 190 // This is only needed for TextDocuments where we might have text nodes | 190 // This is only needed for TextDocuments where we might have text nodes |
| 191 // approaching the default length limit (~64k) and we don't want to break a text | 191 // approaching the default length limit (~64k) and we don't want to break a text |
| 192 // node in the middle of a combining character. | 192 // node in the middle of a combining character. |
| 193 static unsigned findBreakIndexBetween(const StringBuilder& string, | 193 static unsigned findBreakIndexBetween(const StringBuilder& string, |
| 194 unsigned currentPosition, | 194 unsigned currentPosition, |
| 195 unsigned proposedBreakIndex) { | 195 unsigned proposedBreakIndex) { |
| 196 ASSERT(currentPosition < proposedBreakIndex); | 196 DCHECK_LT(currentPosition, proposedBreakIndex); |
| 197 ASSERT(proposedBreakIndex <= string.length()); | 197 DCHECK_LE(proposedBreakIndex, string.length()); |
| 198 // The end of the string is always a valid break. | 198 // The end of the string is always a valid break. |
| 199 if (proposedBreakIndex == string.length()) | 199 if (proposedBreakIndex == string.length()) |
| 200 return proposedBreakIndex; | 200 return proposedBreakIndex; |
| 201 | 201 |
| 202 // Latin-1 does not have breakable boundaries. If we ever moved to a different | 202 // Latin-1 does not have breakable boundaries. If we ever moved to a different |
| 203 // 8-bit encoding this could be wrong. | 203 // 8-bit encoding this could be wrong. |
| 204 if (string.is8Bit()) | 204 if (string.is8Bit()) |
| 205 return proposedBreakIndex; | 205 return proposedBreakIndex; |
| 206 | 206 |
| 207 const UChar* breakSearchCharacters = string.characters16() + currentPosition; | 207 const UChar* breakSearchCharacters = string.characters16() + currentPosition; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 238 return; | 238 return; |
| 239 | 239 |
| 240 if (mode == FlushIfAtTextLimit && | 240 if (mode == FlushIfAtTextLimit && |
| 241 !shouldUseLengthLimit(*m_pendingText.parent)) | 241 !shouldUseLengthLimit(*m_pendingText.parent)) |
| 242 return; | 242 return; |
| 243 | 243 |
| 244 PendingText pendingText; | 244 PendingText pendingText; |
| 245 // Hold onto the current pending text on the stack so that queueTask doesn't | 245 // Hold onto the current pending text on the stack so that queueTask doesn't |
| 246 // recurse infinitely. | 246 // recurse infinitely. |
| 247 m_pendingText.swap(pendingText); | 247 m_pendingText.swap(pendingText); |
| 248 ASSERT(m_pendingText.isEmpty()); | 248 DCHECK(m_pendingText.isEmpty()); |
| 249 | 249 |
| 250 // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is | 250 // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is |
| 251 // necessary for performance, see: | 251 // necessary for performance, see: |
| 252 // https://bugs.webkit.org/show_bug.cgi?id=55898 | 252 // https://bugs.webkit.org/show_bug.cgi?id=55898 |
| 253 unsigned lengthLimit = textLengthLimitForContainer(*pendingText.parent); | 253 unsigned lengthLimit = textLengthLimitForContainer(*pendingText.parent); |
| 254 | 254 |
| 255 unsigned currentPosition = 0; | 255 unsigned currentPosition = 0; |
| 256 const StringBuilder& string = pendingText.stringBuilder; | 256 const StringBuilder& string = pendingText.stringBuilder; |
| 257 while (currentPosition < string.length()) { | 257 while (currentPosition < string.length()) { |
| 258 unsigned proposedBreakIndex = | 258 unsigned proposedBreakIndex = |
| 259 std::min(currentPosition + lengthLimit, string.length()); | 259 std::min(currentPosition + lengthLimit, string.length()); |
| 260 unsigned breakIndex = | 260 unsigned breakIndex = |
| 261 findBreakIndexBetween(string, currentPosition, proposedBreakIndex); | 261 findBreakIndexBetween(string, currentPosition, proposedBreakIndex); |
| 262 ASSERT(breakIndex <= string.length()); | 262 DCHECK_LE(breakIndex, string.length()); |
| 263 String substring = | 263 String substring = |
| 264 string.substring(currentPosition, breakIndex - currentPosition); | 264 string.substring(currentPosition, breakIndex - currentPosition); |
| 265 substring = atomizeIfAllWhitespace(substring, pendingText.whitespaceMode); | 265 substring = atomizeIfAllWhitespace(substring, pendingText.whitespaceMode); |
| 266 | 266 |
| 267 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertText); | 267 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertText); |
| 268 task.parent = pendingText.parent; | 268 task.parent = pendingText.parent; |
| 269 task.nextChild = pendingText.nextChild; | 269 task.nextChild = pendingText.nextChild; |
| 270 task.child = Text::create(task.parent->document(), substring); | 270 task.child = Text::create(task.parent->document(), substring); |
| 271 queueTask(task); | 271 queueTask(task); |
| 272 | 272 |
| 273 ASSERT(breakIndex > currentPosition); | 273 DCHECK_GT(breakIndex, currentPosition); |
| 274 ASSERT(breakIndex - currentPosition == substring.length()); | 274 DCHECK_EQ(breakIndex - currentPosition, substring.length()); |
| 275 ASSERT(toText(task.child.get())->length() == substring.length()); | 275 DCHECK_EQ(toText(task.child.get())->length(), substring.length()); |
| 276 currentPosition = breakIndex; | 276 currentPosition = breakIndex; |
| 277 } | 277 } |
| 278 } | 278 } |
| 279 | 279 |
| 280 void HTMLConstructionSite::queueTask(const HTMLConstructionSiteTask& task) { | 280 void HTMLConstructionSite::queueTask(const HTMLConstructionSiteTask& task) { |
| 281 flushPendingText(FlushAlways); | 281 flushPendingText(FlushAlways); |
| 282 ASSERT(m_pendingText.isEmpty()); | 282 DCHECK(m_pendingText.isEmpty()); |
| 283 m_taskQueue.push_back(task); | 283 m_taskQueue.push_back(task); |
| 284 } | 284 } |
| 285 | 285 |
| 286 void HTMLConstructionSite::attachLater(ContainerNode* parent, | 286 void HTMLConstructionSite::attachLater(ContainerNode* parent, |
| 287 Node* child, | 287 Node* child, |
| 288 bool selfClosing) { | 288 bool selfClosing) { |
| 289 ASSERT(scriptingContentIsAllowed(m_parserContentPolicy) || | 289 DCHECK(scriptingContentIsAllowed(m_parserContentPolicy) || |
| 290 !child->isElementNode() || | 290 !child->isElementNode() || |
| 291 !toScriptLoaderIfPossible(toElement(child))); | 291 !toScriptLoaderIfPossible(toElement(child))); |
| 292 ASSERT(pluginContentIsAllowed(m_parserContentPolicy) || | 292 DCHECK(pluginContentIsAllowed(m_parserContentPolicy) || |
| 293 !isHTMLPlugInElement(child)); | 293 !isHTMLPlugInElement(child)); |
| 294 | 294 |
| 295 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert); | 295 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert); |
| 296 task.parent = parent; | 296 task.parent = parent; |
| 297 task.child = child; | 297 task.child = child; |
| 298 task.selfClosing = selfClosing; | 298 task.selfClosing = selfClosing; |
| 299 | 299 |
| 300 if (shouldFosterParent()) { | 300 if (shouldFosterParent()) { |
| 301 fosterParent(task.child); | 301 fosterParent(task.child); |
| 302 return; | 302 return; |
| 303 } | 303 } |
| 304 | 304 |
| 305 // Add as a sibling of the parent if we have reached the maximum depth | 305 // Add as a sibling of the parent if we have reached the maximum depth |
| 306 // allowed. | 306 // allowed. |
| 307 if (m_openElements.stackDepth() > maximumHTMLParserDOMTreeDepth && | 307 if (m_openElements.stackDepth() > maximumHTMLParserDOMTreeDepth && |
| 308 task.parent->parentNode()) | 308 task.parent->parentNode()) |
| 309 task.parent = task.parent->parentNode(); | 309 task.parent = task.parent->parentNode(); |
| 310 | 310 |
| 311 ASSERT(task.parent); | 311 DCHECK(task.parent); |
| 312 queueTask(task); | 312 queueTask(task); |
| 313 } | 313 } |
| 314 | 314 |
| 315 void HTMLConstructionSite::executeQueuedTasks() { | 315 void HTMLConstructionSite::executeQueuedTasks() { |
| 316 // This has no affect on pendingText, and we may have pendingText remaining | 316 // This has no affect on pendingText, and we may have pendingText remaining |
| 317 // after executing all other queued tasks. | 317 // after executing all other queued tasks. |
| 318 const size_t size = m_taskQueue.size(); | 318 const size_t size = m_taskQueue.size(); |
| 319 if (!size) | 319 if (!size) |
| 320 return; | 320 return; |
| 321 | 321 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 334 HTMLParserReentryPermit* reentryPermit, | 334 HTMLParserReentryPermit* reentryPermit, |
| 335 Document& document, | 335 Document& document, |
| 336 ParserContentPolicy parserContentPolicy) | 336 ParserContentPolicy parserContentPolicy) |
| 337 : m_reentryPermit(reentryPermit), | 337 : m_reentryPermit(reentryPermit), |
| 338 m_document(&document), | 338 m_document(&document), |
| 339 m_attachmentRoot(document), | 339 m_attachmentRoot(document), |
| 340 m_parserContentPolicy(parserContentPolicy), | 340 m_parserContentPolicy(parserContentPolicy), |
| 341 m_isParsingFragment(false), | 341 m_isParsingFragment(false), |
| 342 m_redirectAttachToFosterParent(false), | 342 m_redirectAttachToFosterParent(false), |
| 343 m_inQuirksMode(document.inQuirksMode()) { | 343 m_inQuirksMode(document.inQuirksMode()) { |
| 344 ASSERT(m_document->isHTMLDocument() || m_document->isXHTMLDocument()); | 344 DCHECK(m_document->isHTMLDocument() || m_document->isXHTMLDocument()); |
| 345 } | 345 } |
| 346 | 346 |
| 347 void HTMLConstructionSite::initFragmentParsing(DocumentFragment* fragment, | 347 void HTMLConstructionSite::initFragmentParsing(DocumentFragment* fragment, |
| 348 Element* contextElement) { | 348 Element* contextElement) { |
| 349 DCHECK(contextElement); | 349 DCHECK(contextElement); |
| 350 DCHECK_EQ(m_document, &fragment->document()); | 350 DCHECK_EQ(m_document, &fragment->document()); |
| 351 DCHECK_EQ(m_inQuirksMode, fragment->document().inQuirksMode()); | 351 DCHECK_EQ(m_inQuirksMode, fragment->document().inQuirksMode()); |
| 352 DCHECK(!m_isParsingFragment); | 352 DCHECK(!m_isParsingFragment); |
| 353 DCHECK(!m_form); | 353 DCHECK(!m_form); |
| 354 | 354 |
| 355 m_attachmentRoot = fragment; | 355 m_attachmentRoot = fragment; |
| 356 m_isParsingFragment = true; | 356 m_isParsingFragment = true; |
| 357 | 357 |
| 358 if (!contextElement->document().isTemplateDocument()) | 358 if (!contextElement->document().isTemplateDocument()) |
| 359 m_form = Traversal<HTMLFormElement>::firstAncestorOrSelf(*contextElement); | 359 m_form = Traversal<HTMLFormElement>::firstAncestorOrSelf(*contextElement); |
| 360 } | 360 } |
| 361 | 361 |
| 362 HTMLConstructionSite::~HTMLConstructionSite() { | 362 HTMLConstructionSite::~HTMLConstructionSite() { |
| 363 // Depending on why we're being destroyed it might be OK to forget queued | 363 // Depending on why we're being destroyed it might be OK to forget queued |
| 364 // tasks, but currently we don't expect to. | 364 // tasks, but currently we don't expect to. |
| 365 ASSERT(m_taskQueue.isEmpty()); | 365 DCHECK(m_taskQueue.isEmpty()); |
| 366 // Currently we assume that text will never be the last token in the document | 366 // Currently we assume that text will never be the last token in the document |
| 367 // and that we'll always queue some additional task to cause it to flush. | 367 // and that we'll always queue some additional task to cause it to flush. |
| 368 ASSERT(m_pendingText.isEmpty()); | 368 DCHECK(m_pendingText.isEmpty()); |
| 369 } | 369 } |
| 370 | 370 |
| 371 DEFINE_TRACE(HTMLConstructionSite) { | 371 DEFINE_TRACE(HTMLConstructionSite) { |
| 372 visitor->trace(m_document); | 372 visitor->trace(m_document); |
| 373 visitor->trace(m_attachmentRoot); | 373 visitor->trace(m_attachmentRoot); |
| 374 visitor->trace(m_head); | 374 visitor->trace(m_head); |
| 375 visitor->trace(m_form); | 375 visitor->trace(m_form); |
| 376 visitor->trace(m_openElements); | 376 visitor->trace(m_openElements); |
| 377 visitor->trace(m_activeFormattingElements); | 377 visitor->trace(m_activeFormattingElements); |
| 378 visitor->trace(m_taskQueue); | 378 visitor->trace(m_taskQueue); |
| 379 visitor->trace(m_pendingText); | 379 visitor->trace(m_pendingText); |
| 380 } | 380 } |
| 381 | 381 |
| 382 void HTMLConstructionSite::detach() { | 382 void HTMLConstructionSite::detach() { |
| 383 // FIXME: We'd like to ASSERT here that we're canceling and not just | 383 // FIXME: We'd like to ASSERT here that we're canceling and not just |
| 384 // discarding text that really should have made it into the DOM earlier, but | 384 // discarding text that really should have made it into the DOM earlier, but |
| 385 // there doesn't seem to be a nice way to do that. | 385 // there doesn't seem to be a nice way to do that. |
| 386 m_pendingText.discard(); | 386 m_pendingText.discard(); |
| 387 m_document = nullptr; | 387 m_document = nullptr; |
| 388 m_attachmentRoot = nullptr; | 388 m_attachmentRoot = nullptr; |
| 389 } | 389 } |
| 390 | 390 |
| 391 HTMLFormElement* HTMLConstructionSite::takeForm() { | 391 HTMLFormElement* HTMLConstructionSite::takeForm() { |
| 392 return m_form.release(); | 392 return m_form.release(); |
| 393 } | 393 } |
| 394 | 394 |
| 395 void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML( | 395 void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML( |
| 396 AtomicHTMLToken* token) { | 396 AtomicHTMLToken* token) { |
| 397 ASSERT(m_document); | 397 DCHECK(m_document); |
| 398 HTMLHtmlElement* element = HTMLHtmlElement::create(*m_document); | 398 HTMLHtmlElement* element = HTMLHtmlElement::create(*m_document); |
| 399 setAttributes(element, token, m_parserContentPolicy); | 399 setAttributes(element, token, m_parserContentPolicy); |
| 400 attachLater(m_attachmentRoot, element); | 400 attachLater(m_attachmentRoot, element); |
| 401 m_openElements.pushHTMLHtmlElement(HTMLStackItem::create(element, token)); | 401 m_openElements.pushHTMLHtmlElement(HTMLStackItem::create(element, token)); |
| 402 | 402 |
| 403 executeQueuedTasks(); | 403 executeQueuedTasks(); |
| 404 element->insertedByParser(); | 404 element->insertedByParser(); |
| 405 } | 405 } |
| 406 | 406 |
| 407 void HTMLConstructionSite::mergeAttributesFromTokenIntoElement( | 407 void HTMLConstructionSite::mergeAttributesFromTokenIntoElement( |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 TextCaseASCIIInsensitive))) { | 600 TextCaseASCIIInsensitive))) { |
| 601 setCompatibilityMode(Document::LimitedQuirksMode); | 601 setCompatibilityMode(Document::LimitedQuirksMode); |
| 602 return; | 602 return; |
| 603 } | 603 } |
| 604 | 604 |
| 605 // Otherwise we are No Quirks Mode. | 605 // Otherwise we are No Quirks Mode. |
| 606 setCompatibilityMode(Document::NoQuirksMode); | 606 setCompatibilityMode(Document::NoQuirksMode); |
| 607 } | 607 } |
| 608 | 608 |
| 609 void HTMLConstructionSite::processEndOfFile() { | 609 void HTMLConstructionSite::processEndOfFile() { |
| 610 ASSERT(currentNode()); | 610 DCHECK(currentNode()); |
| 611 flush(FlushAlways); | 611 flush(FlushAlways); |
| 612 openElements()->popAll(); | 612 openElements()->popAll(); |
| 613 } | 613 } |
| 614 | 614 |
| 615 void HTMLConstructionSite::finishedParsing() { | 615 void HTMLConstructionSite::finishedParsing() { |
| 616 // We shouldn't have any queued tasks but we might have pending text which we | 616 // We shouldn't have any queued tasks but we might have pending text which we |
| 617 // need to promote to tasks and execute. | 617 // need to promote to tasks and execute. |
| 618 ASSERT(m_taskQueue.isEmpty()); | 618 DCHECK(m_taskQueue.isEmpty()); |
| 619 flush(FlushAlways); | 619 flush(FlushAlways); |
| 620 m_document->finishedParsing(); | 620 m_document->finishedParsing(); |
| 621 } | 621 } |
| 622 | 622 |
| 623 void HTMLConstructionSite::insertDoctype(AtomicHTMLToken* token) { | 623 void HTMLConstructionSite::insertDoctype(AtomicHTMLToken* token) { |
| 624 ASSERT(token->type() == HTMLToken::DOCTYPE); | 624 DCHECK_EQ(token->type(), HTMLToken::DOCTYPE); |
| 625 | 625 |
| 626 const String& publicId = | 626 const String& publicId = |
| 627 StringImpl::create8BitIfPossible(token->publicIdentifier()); | 627 StringImpl::create8BitIfPossible(token->publicIdentifier()); |
| 628 const String& systemId = | 628 const String& systemId = |
| 629 StringImpl::create8BitIfPossible(token->systemIdentifier()); | 629 StringImpl::create8BitIfPossible(token->systemIdentifier()); |
| 630 DocumentType* doctype = | 630 DocumentType* doctype = |
| 631 DocumentType::create(m_document, token->name(), publicId, systemId); | 631 DocumentType::create(m_document, token->name(), publicId, systemId); |
| 632 attachLater(m_attachmentRoot, doctype); | 632 attachLater(m_attachmentRoot, doctype); |
| 633 | 633 |
| 634 // DOCTYPE nodes are only processed when parsing fragments w/o | 634 // DOCTYPE nodes are only processed when parsing fragments w/o |
| 635 // contextElements, which never occurs. However, if we ever chose to support | 635 // contextElements, which never occurs. However, if we ever chose to support |
| 636 // such, this code is subtly wrong, because context-less fragments can | 636 // such, this code is subtly wrong, because context-less fragments can |
| 637 // determine their own quirks mode, and thus change parsing rules (like <p> | 637 // determine their own quirks mode, and thus change parsing rules (like <p> |
| 638 // inside <table>). For now we ASSERT that we never hit this code in a | 638 // inside <table>). For now we ASSERT that we never hit this code in a |
| 639 // fragment, as changing the owning document's compatibility mode would be | 639 // fragment, as changing the owning document's compatibility mode would be |
| 640 // wrong. | 640 // wrong. |
| 641 ASSERT(!m_isParsingFragment); | 641 DCHECK(!m_isParsingFragment); |
| 642 if (m_isParsingFragment) | 642 if (m_isParsingFragment) |
| 643 return; | 643 return; |
| 644 | 644 |
| 645 if (token->forceQuirks()) | 645 if (token->forceQuirks()) |
| 646 setCompatibilityMode(Document::QuirksMode); | 646 setCompatibilityMode(Document::QuirksMode); |
| 647 else { | 647 else { |
| 648 setCompatibilityModeFromDoctype(token->name(), publicId, systemId); | 648 setCompatibilityModeFromDoctype(token->name(), publicId, systemId); |
| 649 } | 649 } |
| 650 } | 650 } |
| 651 | 651 |
| 652 void HTMLConstructionSite::insertComment(AtomicHTMLToken* token) { | 652 void HTMLConstructionSite::insertComment(AtomicHTMLToken* token) { |
| 653 ASSERT(token->type() == HTMLToken::Comment); | 653 DCHECK_EQ(token->type(), HTMLToken::Comment); |
| 654 attachLater(currentNode(), | 654 attachLater(currentNode(), |
| 655 Comment::create(ownerDocumentForCurrentNode(), token->comment())); | 655 Comment::create(ownerDocumentForCurrentNode(), token->comment())); |
| 656 } | 656 } |
| 657 | 657 |
| 658 void HTMLConstructionSite::insertCommentOnDocument(AtomicHTMLToken* token) { | 658 void HTMLConstructionSite::insertCommentOnDocument(AtomicHTMLToken* token) { |
| 659 ASSERT(token->type() == HTMLToken::Comment); | 659 DCHECK_EQ(token->type(), HTMLToken::Comment); |
| 660 ASSERT(m_document); | 660 DCHECK(m_document); |
| 661 attachLater(m_attachmentRoot, Comment::create(*m_document, token->comment())); | 661 attachLater(m_attachmentRoot, Comment::create(*m_document, token->comment())); |
| 662 } | 662 } |
| 663 | 663 |
| 664 void HTMLConstructionSite::insertCommentOnHTMLHtmlElement( | 664 void HTMLConstructionSite::insertCommentOnHTMLHtmlElement( |
| 665 AtomicHTMLToken* token) { | 665 AtomicHTMLToken* token) { |
| 666 ASSERT(token->type() == HTMLToken::Comment); | 666 DCHECK_EQ(token->type(), HTMLToken::Comment); |
| 667 ContainerNode* parent = m_openElements.rootNode(); | 667 ContainerNode* parent = m_openElements.rootNode(); |
| 668 attachLater(parent, Comment::create(parent->document(), token->comment())); | 668 attachLater(parent, Comment::create(parent->document(), token->comment())); |
| 669 } | 669 } |
| 670 | 670 |
| 671 void HTMLConstructionSite::insertHTMLHeadElement(AtomicHTMLToken* token) { | 671 void HTMLConstructionSite::insertHTMLHeadElement(AtomicHTMLToken* token) { |
| 672 ASSERT(!shouldFosterParent()); | 672 DCHECK(!shouldFosterParent()); |
| 673 m_head = HTMLStackItem::create(createHTMLElement(token), token); | 673 m_head = HTMLStackItem::create(createHTMLElement(token), token); |
| 674 attachLater(currentNode(), m_head->element()); | 674 attachLater(currentNode(), m_head->element()); |
| 675 m_openElements.pushHTMLHeadElement(m_head); | 675 m_openElements.pushHTMLHeadElement(m_head); |
| 676 } | 676 } |
| 677 | 677 |
| 678 void HTMLConstructionSite::insertHTMLBodyElement(AtomicHTMLToken* token) { | 678 void HTMLConstructionSite::insertHTMLBodyElement(AtomicHTMLToken* token) { |
| 679 ASSERT(!shouldFosterParent()); | 679 DCHECK(!shouldFosterParent()); |
| 680 HTMLElement* body = createHTMLElement(token); | 680 HTMLElement* body = createHTMLElement(token); |
| 681 attachLater(currentNode(), body); | 681 attachLater(currentNode(), body); |
| 682 m_openElements.pushHTMLBodyElement(HTMLStackItem::create(body, token)); | 682 m_openElements.pushHTMLBodyElement(HTMLStackItem::create(body, token)); |
| 683 if (m_document) | 683 if (m_document) |
| 684 m_document->willInsertBody(); | 684 m_document->willInsertBody(); |
| 685 } | 685 } |
| 686 | 686 |
| 687 void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken* token, | 687 void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken* token, |
| 688 bool isDemoted) { | 688 bool isDemoted) { |
| 689 HTMLElement* element = createHTMLElement(token); | 689 HTMLElement* element = createHTMLElement(token); |
| 690 ASSERT(isHTMLFormElement(element)); | 690 DCHECK(isHTMLFormElement(element)); |
| 691 HTMLFormElement* formElement = toHTMLFormElement(element); | 691 HTMLFormElement* formElement = toHTMLFormElement(element); |
| 692 if (!openElements()->hasTemplateInHTMLScope()) | 692 if (!openElements()->hasTemplateInHTMLScope()) |
| 693 m_form = formElement; | 693 m_form = formElement; |
| 694 formElement->setDemoted(isDemoted); | 694 formElement->setDemoted(isDemoted); |
| 695 attachLater(currentNode(), formElement); | 695 attachLater(currentNode(), formElement); |
| 696 m_openElements.push(HTMLStackItem::create(formElement, token)); | 696 m_openElements.push(HTMLStackItem::create(formElement, token)); |
| 697 } | 697 } |
| 698 | 698 |
| 699 void HTMLConstructionSite::insertHTMLElement(AtomicHTMLToken* token) { | 699 void HTMLConstructionSite::insertHTMLElement(AtomicHTMLToken* token) { |
| 700 HTMLElement* element = createHTMLElement(token); | 700 HTMLElement* element = createHTMLElement(token); |
| 701 attachLater(currentNode(), element); | 701 attachLater(currentNode(), element); |
| 702 m_openElements.push(HTMLStackItem::create(element, token)); | 702 m_openElements.push(HTMLStackItem::create(element, token)); |
| 703 } | 703 } |
| 704 | 704 |
| 705 void HTMLConstructionSite::insertSelfClosingHTMLElementDestroyingToken( | 705 void HTMLConstructionSite::insertSelfClosingHTMLElementDestroyingToken( |
| 706 AtomicHTMLToken* token) { | 706 AtomicHTMLToken* token) { |
| 707 ASSERT(token->type() == HTMLToken::StartTag); | 707 DCHECK_EQ(token->type(), HTMLToken::StartTag); |
| 708 // Normally HTMLElementStack is responsible for calling finishParsingChildren, | 708 // Normally HTMLElementStack is responsible for calling finishParsingChildren, |
| 709 // but self-closing elements are never in the element stack so the stack | 709 // but self-closing elements are never in the element stack so the stack |
| 710 // doesn't get a chance to tell them that we're done parsing their children. | 710 // doesn't get a chance to tell them that we're done parsing their children. |
| 711 attachLater(currentNode(), createHTMLElement(token), true); | 711 attachLater(currentNode(), createHTMLElement(token), true); |
| 712 // FIXME: Do we want to acknowledge the token's self-closing flag? | 712 // FIXME: Do we want to acknowledge the token's self-closing flag? |
| 713 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.ht
ml#acknowledge-self-closing-flag | 713 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.ht
ml#acknowledge-self-closing-flag |
| 714 } | 714 } |
| 715 | 715 |
| 716 void HTMLConstructionSite::insertFormattingElement(AtomicHTMLToken* token) { | 716 void HTMLConstructionSite::insertFormattingElement(AtomicHTMLToken* token) { |
| 717 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#th
e-stack-of-open-elements | 717 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#th
e-stack-of-open-elements |
| (...skipping 27 matching lines...) Expand all Loading... |
| 745 alreadyStarted, createdDuringDocumentWrite); | 745 alreadyStarted, createdDuringDocumentWrite); |
| 746 setAttributes(element, token, m_parserContentPolicy); | 746 setAttributes(element, token, m_parserContentPolicy); |
| 747 if (scriptingContentIsAllowed(m_parserContentPolicy)) | 747 if (scriptingContentIsAllowed(m_parserContentPolicy)) |
| 748 attachLater(currentNode(), element); | 748 attachLater(currentNode(), element); |
| 749 m_openElements.push(HTMLStackItem::create(element, token)); | 749 m_openElements.push(HTMLStackItem::create(element, token)); |
| 750 } | 750 } |
| 751 | 751 |
| 752 void HTMLConstructionSite::insertForeignElement( | 752 void HTMLConstructionSite::insertForeignElement( |
| 753 AtomicHTMLToken* token, | 753 AtomicHTMLToken* token, |
| 754 const AtomicString& namespaceURI) { | 754 const AtomicString& namespaceURI) { |
| 755 ASSERT(token->type() == HTMLToken::StartTag); | 755 DCHECK_EQ(token->type(), HTMLToken::StartTag); |
| 756 // parseError when xmlns or xmlns:xlink are wrong. | 756 // parseError when xmlns or xmlns:xlink are wrong. |
| 757 DVLOG(1) << "Not implemented."; | 757 DVLOG(1) << "Not implemented."; |
| 758 | 758 |
| 759 Element* element = createElement(token, namespaceURI); | 759 Element* element = createElement(token, namespaceURI); |
| 760 if (scriptingContentIsAllowed(m_parserContentPolicy) || | 760 if (scriptingContentIsAllowed(m_parserContentPolicy) || |
| 761 !toScriptLoaderIfPossible(element)) | 761 !toScriptLoaderIfPossible(element)) |
| 762 attachLater(currentNode(), element, token->selfClosing()); | 762 attachLater(currentNode(), element, token->selfClosing()); |
| 763 if (!token->selfClosing()) | 763 if (!token->selfClosing()) |
| 764 m_openElements.push(HTMLStackItem::create(element, token, namespaceURI)); | 764 m_openElements.push(HTMLStackItem::create(element, token, namespaceURI)); |
| 765 } | 765 } |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 firstUnopenElementIndex = index; | 989 firstUnopenElementIndex = index; |
| 990 return true; | 990 return true; |
| 991 } | 991 } |
| 992 | 992 |
| 993 void HTMLConstructionSite::reconstructTheActiveFormattingElements() { | 993 void HTMLConstructionSite::reconstructTheActiveFormattingElements() { |
| 994 unsigned firstUnopenElementIndex; | 994 unsigned firstUnopenElementIndex; |
| 995 if (!indexOfFirstUnopenFormattingElement(firstUnopenElementIndex)) | 995 if (!indexOfFirstUnopenFormattingElement(firstUnopenElementIndex)) |
| 996 return; | 996 return; |
| 997 | 997 |
| 998 unsigned unopenEntryIndex = firstUnopenElementIndex; | 998 unsigned unopenEntryIndex = firstUnopenElementIndex; |
| 999 ASSERT(unopenEntryIndex < m_activeFormattingElements.size()); | 999 DCHECK_LT(unopenEntryIndex, m_activeFormattingElements.size()); |
| 1000 for (; unopenEntryIndex < m_activeFormattingElements.size(); | 1000 for (; unopenEntryIndex < m_activeFormattingElements.size(); |
| 1001 ++unopenEntryIndex) { | 1001 ++unopenEntryIndex) { |
| 1002 HTMLFormattingElementList::Entry& unopenedEntry = | 1002 HTMLFormattingElementList::Entry& unopenedEntry = |
| 1003 m_activeFormattingElements.at(unopenEntryIndex); | 1003 m_activeFormattingElements.at(unopenEntryIndex); |
| 1004 HTMLStackItem* reconstructed = | 1004 HTMLStackItem* reconstructed = |
| 1005 createElementFromSavedToken(unopenedEntry.stackItem()); | 1005 createElementFromSavedToken(unopenedEntry.stackItem()); |
| 1006 attachLater(currentNode(), reconstructed->node()); | 1006 attachLater(currentNode(), reconstructed->node()); |
| 1007 m_openElements.push(reconstructed); | 1007 m_openElements.push(reconstructed); |
| 1008 unopenedEntry.replaceElement(reconstructed); | 1008 unopenedEntry.replaceElement(reconstructed); |
| 1009 } | 1009 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1064 bool HTMLConstructionSite::shouldFosterParent() const { | 1064 bool HTMLConstructionSite::shouldFosterParent() const { |
| 1065 return m_redirectAttachToFosterParent && | 1065 return m_redirectAttachToFosterParent && |
| 1066 currentStackItem()->isElementNode() && | 1066 currentStackItem()->isElementNode() && |
| 1067 currentStackItem()->causesFosterParenting(); | 1067 currentStackItem()->causesFosterParenting(); |
| 1068 } | 1068 } |
| 1069 | 1069 |
| 1070 void HTMLConstructionSite::fosterParent(Node* node) { | 1070 void HTMLConstructionSite::fosterParent(Node* node) { |
| 1071 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert); | 1071 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert); |
| 1072 findFosterSite(task); | 1072 findFosterSite(task); |
| 1073 task.child = node; | 1073 task.child = node; |
| 1074 ASSERT(task.parent); | 1074 DCHECK(task.parent); |
| 1075 queueTask(task); | 1075 queueTask(task); |
| 1076 } | 1076 } |
| 1077 | 1077 |
| 1078 DEFINE_TRACE(HTMLConstructionSite::PendingText) { | 1078 DEFINE_TRACE(HTMLConstructionSite::PendingText) { |
| 1079 visitor->trace(parent); | 1079 visitor->trace(parent); |
| 1080 visitor->trace(nextChild); | 1080 visitor->trace(nextChild); |
| 1081 } | 1081 } |
| 1082 | 1082 |
| 1083 } // namespace blink | 1083 } // namespace blink |
| OLD | NEW |