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 |