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