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 |