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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 ASSERT(task.operation == HTMLConstructionSiteTask::Insert); | 112 ASSERT(task.operation == HTMLConstructionSiteTask::Insert); |
113 | 113 |
114 insert(task); | 114 insert(task); |
115 | 115 |
116 task.child->beginParsingChildren(); | 116 task.child->beginParsingChildren(); |
117 | 117 |
118 if (task.selfClosing) | 118 if (task.selfClosing) |
119 task.child->finishParsingChildren(); | 119 task.child->finishParsingChildren(); |
120 } | 120 } |
121 | 121 |
| 122 static inline void executeInsertTextTask(HTMLConstructionSiteTask& task) |
| 123 { |
| 124 ASSERT(task.operation == HTMLConstructionSiteTask::InsertText); |
| 125 ASSERT(task.child->isTextNode()); |
| 126 |
| 127 // Merge text nodes into previous ones if possible: |
| 128 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construc
tion.html#insert-a-character |
| 129 Text* newText = toText(task.child.get()); |
| 130 Node* previousChild = task.nextChild ? task.nextChild->previousSibling() : t
ask.parent->lastChild(); |
| 131 if (previousChild && previousChild->isTextNode()) { |
| 132 Text* previousText = toText(previousChild); |
| 133 unsigned lengthLimit = textLengthLimitForContainer(task.parent.get()); |
| 134 if (previousText->length() + newText->length() < lengthLimit) { |
| 135 previousText->parserAppendData(newText->data()); |
| 136 return; |
| 137 } |
| 138 } |
| 139 |
| 140 insert(task); |
| 141 } |
| 142 |
122 static inline void executeReparentTask(HTMLConstructionSiteTask& task) | 143 static inline void executeReparentTask(HTMLConstructionSiteTask& task) |
123 { | 144 { |
124 ASSERT(task.operation == HTMLConstructionSiteTask::Reparent); | 145 ASSERT(task.operation == HTMLConstructionSiteTask::Reparent); |
125 | 146 |
126 if (ContainerNode* parent = task.child->parentNode()) | 147 if (ContainerNode* parent = task.child->parentNode()) |
127 parent->parserRemoveChild(*task.child); | 148 parent->parserRemoveChild(*task.child); |
128 | 149 |
129 task.parent->parserAppendChild(task.child); | 150 task.parent->parserAppendChild(task.child); |
130 } | 151 } |
131 | 152 |
(...skipping 10 matching lines...) Expand all Loading... |
142 | 163 |
143 task.parent->parserTakeAllChildrenFrom(*task.oldParent()); | 164 task.parent->parserTakeAllChildrenFrom(*task.oldParent()); |
144 } | 165 } |
145 | 166 |
146 void HTMLConstructionSite::executeTask(HTMLConstructionSiteTask& task) | 167 void HTMLConstructionSite::executeTask(HTMLConstructionSiteTask& task) |
147 { | 168 { |
148 ASSERT(m_taskQueue.isEmpty()); | 169 ASSERT(m_taskQueue.isEmpty()); |
149 if (task.operation == HTMLConstructionSiteTask::Insert) | 170 if (task.operation == HTMLConstructionSiteTask::Insert) |
150 return executeInsertTask(task); | 171 return executeInsertTask(task); |
151 | 172 |
| 173 if (task.operation == HTMLConstructionSiteTask::InsertText) |
| 174 return executeInsertTextTask(task); |
| 175 |
152 // 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. |
153 | 177 |
154 if (task.operation == HTMLConstructionSiteTask::InsertAlreadyParsedChild) | 178 if (task.operation == HTMLConstructionSiteTask::InsertAlreadyParsedChild) |
155 return executeInsertAlreadyParsedChildTask(task); | 179 return executeInsertAlreadyParsedChildTask(task); |
156 | 180 |
157 if (task.operation == HTMLConstructionSiteTask::Reparent) | 181 if (task.operation == HTMLConstructionSiteTask::Reparent) |
158 return executeReparentTask(task); | 182 return executeReparentTask(task); |
159 | 183 |
160 if (task.operation == HTMLConstructionSiteTask::TakeAllChildren) | 184 if (task.operation == HTMLConstructionSiteTask::TakeAllChildren) |
161 return executeTakeAllChildrenTask(task); | 185 return executeTakeAllChildrenTask(task); |
162 | 186 |
163 ASSERT_NOT_REACHED(); | 187 ASSERT_NOT_REACHED(); |
164 } | 188 } |
165 | 189 |
166 // 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 |
167 // approaching the default length limit (~64k) and we don't want to | 191 // approaching the default length limit (~64k) and we don't want to |
168 // break a text node in the middle of a combining character. | 192 // break a text node in the middle of a combining character. |
169 static unsigned findBreakIndexBetween(const String& string, unsigned currentPosi
tion, unsigned proposedBreakIndex) | 193 static unsigned findBreakIndexBetween(const StringBuilder& string, unsigned curr
entPosition, unsigned proposedBreakIndex) |
170 { | 194 { |
171 ASSERT(currentPosition < proposedBreakIndex); | 195 ASSERT(currentPosition < proposedBreakIndex); |
172 ASSERT(proposedBreakIndex <= string.length()); | 196 ASSERT(proposedBreakIndex <= string.length()); |
173 // The end of the string is always a valid break. | 197 // The end of the string is always a valid break. |
174 if (proposedBreakIndex == string.length()) | 198 if (proposedBreakIndex == string.length()) |
175 return proposedBreakIndex; | 199 return proposedBreakIndex; |
176 | 200 |
177 // Latin-1 does not have breakable boundaries. If we ever moved to a differn
et 8-bit encoding this could be wrong. | 201 // Latin-1 does not have breakable boundaries. If we ever moved to a differn
et 8-bit encoding this could be wrong. |
178 if (string.is8Bit()) | 202 if (string.is8Bit()) |
179 return proposedBreakIndex; | 203 return proposedBreakIndex; |
(...skipping 15 matching lines...) Expand all Loading... |
195 | 219 |
196 static String atomizeIfAllWhitespace(const String& string, WhitespaceMode whites
paceMode) | 220 static String atomizeIfAllWhitespace(const String& string, WhitespaceMode whites
paceMode) |
197 { | 221 { |
198 // Strings composed entirely of whitespace are likely to be repeated. | 222 // Strings composed entirely of whitespace are likely to be repeated. |
199 // Turn them into AtomicString so we share a single string for each. | 223 // Turn them into AtomicString so we share a single string for each. |
200 if (whitespaceMode == AllWhitespace || (whitespaceMode == WhitespaceUnknown
&& isAllWhitespace(string))) | 224 if (whitespaceMode == AllWhitespace || (whitespaceMode == WhitespaceUnknown
&& isAllWhitespace(string))) |
201 return AtomicString(string).string(); | 225 return AtomicString(string).string(); |
202 return string; | 226 return string; |
203 } | 227 } |
204 | 228 |
| 229 void HTMLConstructionSite::flushPendingText() |
| 230 { |
| 231 if (m_pendingText.isEmpty()) |
| 232 return; |
| 233 |
| 234 PendingText pendingText; |
| 235 // Hold onto the current pending text on the stack so that queueTask doesn't
recurse infinitely. |
| 236 m_pendingText.swap(pendingText); |
| 237 ASSERT(m_pendingText.isEmpty()); |
| 238 |
| 239 // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is n
ecessary |
| 240 // for performance, see: https://bugs.webkit.org/show_bug.cgi?id=55898 |
| 241 unsigned lengthLimit = textLengthLimitForContainer(pendingText.parent.get())
; |
| 242 |
| 243 unsigned currentPosition = 0; |
| 244 const StringBuilder& string = pendingText.stringBuilder; |
| 245 while (currentPosition < string.length()) { |
| 246 unsigned proposedBreakIndex = std::min(currentPosition + lengthLimit, st
ring.length()); |
| 247 unsigned breakIndex = findBreakIndexBetween(string, currentPosition, pro
posedBreakIndex); |
| 248 ASSERT(breakIndex <= string.length()); |
| 249 String substring = string.substring(currentPosition, breakIndex - curren
tPosition); |
| 250 substring = atomizeIfAllWhitespace(substring, pendingText.whitespaceMode
); |
| 251 |
| 252 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertText); |
| 253 task.parent = pendingText.parent; |
| 254 task.nextChild = pendingText.nextChild; |
| 255 task.child = Text::create(task.parent->document(), substring); |
| 256 queueTask(task); |
| 257 |
| 258 ASSERT(breakIndex > currentPosition); |
| 259 ASSERT(breakIndex - currentPosition == substring.length()); |
| 260 ASSERT(toText(task.child.get())->length() == substring.length()); |
| 261 currentPosition = breakIndex; |
| 262 } |
| 263 } |
| 264 |
205 void HTMLConstructionSite::queueTask(const HTMLConstructionSiteTask& task) | 265 void HTMLConstructionSite::queueTask(const HTMLConstructionSiteTask& task) |
206 { | 266 { |
| 267 flushPendingText(); |
| 268 ASSERT(m_pendingText.isEmpty()); |
207 m_taskQueue.append(task); | 269 m_taskQueue.append(task); |
208 } | 270 } |
209 | 271 |
210 void HTMLConstructionSite::attachLater(ContainerNode* parent, PassRefPtr<Node> p
rpChild, bool selfClosing) | 272 void HTMLConstructionSite::attachLater(ContainerNode* parent, PassRefPtr<Node> p
rpChild, bool selfClosing) |
211 { | 273 { |
212 ASSERT(scriptingContentIsAllowed(m_parserContentPolicy) || !prpChild.get()->
isElementNode() || !toScriptLoaderIfPossible(toElement(prpChild.get()))); | 274 ASSERT(scriptingContentIsAllowed(m_parserContentPolicy) || !prpChild.get()->
isElementNode() || !toScriptLoaderIfPossible(toElement(prpChild.get()))); |
213 ASSERT(pluginContentIsAllowed(m_parserContentPolicy) || !prpChild->isPluginE
lement()); | 275 ASSERT(pluginContentIsAllowed(m_parserContentPolicy) || !prpChild->isPluginE
lement()); |
214 | 276 |
215 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert); | 277 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert); |
216 task.parent = parent; | 278 task.parent = parent; |
217 task.child = prpChild; | 279 task.child = prpChild; |
218 task.selfClosing = selfClosing; | 280 task.selfClosing = selfClosing; |
219 | 281 |
220 if (shouldFosterParent()) { | 282 if (shouldFosterParent()) { |
221 fosterParent(task.child); | 283 fosterParent(task.child); |
222 return; | 284 return; |
223 } | 285 } |
224 | 286 |
225 // Add as a sibling of the parent if we have reached the maximum depth allow
ed. | 287 // Add as a sibling of the parent if we have reached the maximum depth allow
ed. |
226 if (m_openElements.stackDepth() > maximumHTMLParserDOMTreeDepth && task.pare
nt->parentNode()) | 288 if (m_openElements.stackDepth() > maximumHTMLParserDOMTreeDepth && task.pare
nt->parentNode()) |
227 task.parent = task.parent->parentNode(); | 289 task.parent = task.parent->parentNode(); |
228 | 290 |
229 ASSERT(task.parent); | 291 ASSERT(task.parent); |
230 queueTask(task); | 292 queueTask(task); |
231 } | 293 } |
232 | 294 |
233 void HTMLConstructionSite::executeQueuedTasks() | 295 void HTMLConstructionSite::executeQueuedTasks() |
234 { | 296 { |
| 297 // This has no affect on pendingText, and we may have pendingText |
| 298 // remaining after executing all other queued tasks. |
235 const size_t size = m_taskQueue.size(); | 299 const size_t size = m_taskQueue.size(); |
236 if (!size) | 300 if (!size) |
237 return; | 301 return; |
238 | 302 |
239 // Copy the task queue into a local variable in case executeTask | 303 // Copy the task queue into a local variable in case executeTask |
240 // re-enters the parser. | 304 // re-enters the parser. |
241 TaskQueue queue; | 305 TaskQueue queue; |
242 queue.swap(m_taskQueue); | 306 queue.swap(m_taskQueue); |
243 | 307 |
244 for (size_t i = 0; i < size; ++i) | 308 for (size_t i = 0; i < size; ++i) |
(...skipping 22 matching lines...) Expand all Loading... |
267 , m_inQuirksMode(fragment->document().inQuirksMode()) | 331 , m_inQuirksMode(fragment->document().inQuirksMode()) |
268 { | 332 { |
269 ASSERT(m_document->isHTMLDocument() || m_document->isXHTMLDocument()); | 333 ASSERT(m_document->isHTMLDocument() || m_document->isXHTMLDocument()); |
270 } | 334 } |
271 | 335 |
272 HTMLConstructionSite::~HTMLConstructionSite() | 336 HTMLConstructionSite::~HTMLConstructionSite() |
273 { | 337 { |
274 // Depending on why we're being destroyed it might be OK | 338 // Depending on why we're being destroyed it might be OK |
275 // to forget queued tasks, but currently we don't expect to. | 339 // to forget queued tasks, but currently we don't expect to. |
276 ASSERT(m_taskQueue.isEmpty()); | 340 ASSERT(m_taskQueue.isEmpty()); |
| 341 // Currently we assume that text will never be the last token in the |
| 342 // document and that we'll always queue some additional task to cause it to
flush. |
| 343 ASSERT(m_pendingText.isEmpty()); |
277 } | 344 } |
278 | 345 |
279 void HTMLConstructionSite::detach() | 346 void HTMLConstructionSite::detach() |
280 { | 347 { |
| 348 // FIXME: We'd like to ASSERT here that we're canceling and not just discard
ing |
| 349 // text that really should have made it into the DOM earlier, but there |
| 350 // doesn't seem to be a nice way to do that. |
| 351 m_pendingText.discard(); |
281 m_document = 0; | 352 m_document = 0; |
282 m_attachmentRoot = 0; | 353 m_attachmentRoot = 0; |
283 } | 354 } |
284 | 355 |
285 void HTMLConstructionSite::setForm(HTMLFormElement* form) | 356 void HTMLConstructionSite::setForm(HTMLFormElement* form) |
286 { | 357 { |
287 // This method should only be needed for HTMLTreeBuilder in the fragment cas
e. | 358 // This method should only be needed for HTMLTreeBuilder in the fragment cas
e. |
288 ASSERT(!m_form); | 359 ASSERT(!m_form); |
289 m_form = form; | 360 m_form = form; |
290 } | 361 } |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 return; | 511 return; |
441 } | 512 } |
442 | 513 |
443 // Otherwise we are No Quirks Mode. | 514 // Otherwise we are No Quirks Mode. |
444 setCompatibilityMode(Document::NoQuirksMode); | 515 setCompatibilityMode(Document::NoQuirksMode); |
445 } | 516 } |
446 | 517 |
447 void HTMLConstructionSite::processEndOfFile() | 518 void HTMLConstructionSite::processEndOfFile() |
448 { | 519 { |
449 ASSERT(currentNode()); | 520 ASSERT(currentNode()); |
| 521 flush(); |
450 openElements()->popAll(); | 522 openElements()->popAll(); |
451 } | 523 } |
452 | 524 |
453 void HTMLConstructionSite::finishedParsing() | 525 void HTMLConstructionSite::finishedParsing() |
454 { | 526 { |
| 527 // We shouldn't have any queued tasks but we might have pending text which w
e need to promote to tasks and execute. |
455 ASSERT(m_taskQueue.isEmpty()); | 528 ASSERT(m_taskQueue.isEmpty()); |
| 529 flush(); |
456 m_document->finishedParsing(); | 530 m_document->finishedParsing(); |
457 } | 531 } |
458 | 532 |
459 void HTMLConstructionSite::insertDoctype(AtomicHTMLToken* token) | 533 void HTMLConstructionSite::insertDoctype(AtomicHTMLToken* token) |
460 { | 534 { |
461 ASSERT(token->type() == HTMLToken::DOCTYPE); | 535 ASSERT(token->type() == HTMLToken::DOCTYPE); |
462 | 536 |
463 const String& publicId = StringImpl::create8BitIfPossible(token->publicIdent
ifier()); | 537 const String& publicId = StringImpl::create8BitIfPossible(token->publicIdent
ifier()); |
464 const String& systemId = StringImpl::create8BitIfPossible(token->systemIdent
ifier()); | 538 const String& systemId = StringImpl::create8BitIfPossible(token->systemIdent
ifier()); |
465 RefPtr<DocumentType> doctype = DocumentType::create(m_document, token->name(
), publicId, systemId); | 539 RefPtr<DocumentType> doctype = DocumentType::create(m_document, token->name(
), publicId, systemId); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 | 653 |
580 RefPtr<Element> element = createElement(token, namespaceURI); | 654 RefPtr<Element> element = createElement(token, namespaceURI); |
581 if (scriptingContentIsAllowed(m_parserContentPolicy) || !toScriptLoaderIfPos
sible(element.get())) | 655 if (scriptingContentIsAllowed(m_parserContentPolicy) || !toScriptLoaderIfPos
sible(element.get())) |
582 attachLater(currentNode(), element, token->selfClosing()); | 656 attachLater(currentNode(), element, token->selfClosing()); |
583 if (!token->selfClosing()) | 657 if (!token->selfClosing()) |
584 m_openElements.push(HTMLStackItem::create(element.release(), token, name
spaceURI)); | 658 m_openElements.push(HTMLStackItem::create(element.release(), token, name
spaceURI)); |
585 } | 659 } |
586 | 660 |
587 void HTMLConstructionSite::insertTextNode(const String& string, WhitespaceMode w
hitespaceMode) | 661 void HTMLConstructionSite::insertTextNode(const String& string, WhitespaceMode w
hitespaceMode) |
588 { | 662 { |
589 HTMLConstructionSiteTask protoTask(HTMLConstructionSiteTask::Insert); | 663 HTMLConstructionSiteTask dummyTask(HTMLConstructionSiteTask::Insert); |
590 protoTask.parent = currentNode(); | 664 dummyTask.parent = currentNode(); |
591 | 665 |
592 if (shouldFosterParent()) | 666 if (shouldFosterParent()) |
593 findFosterSite(protoTask); | 667 findFosterSite(dummyTask); |
594 | 668 |
595 // FIXME: This probably doesn't need to be done both here and in insert(Task
). | 669 // FIXME: This probably doesn't need to be done both here and in insert(Task
). |
596 if (protoTask.parent->hasTagName(templateTag)) | 670 if (dummyTask.parent->hasTagName(templateTag)) |
597 protoTask.parent = toHTMLTemplateElement(protoTask.parent.get())->conten
t(); | 671 dummyTask.parent = toHTMLTemplateElement(dummyTask.parent.get())->conten
t(); |
598 | 672 |
599 // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is n
ecessary | 673 // Unclear when parent != case occurs. Somehow we insert text into two separ
ate nodes while processing the same Token. |
600 // for performance, see: https://bugs.webkit.org/show_bug.cgi?id=55898 | 674 // The nextChild != dummy.nextChild case occurs whenever foster parenting ha
ppened and we hit a new text node "<table>a</table>b" |
601 unsigned lengthLimit = textLengthLimitForContainer(protoTask.parent.get()); | 675 // In either case we have to flush the pending text into the task queue befo
re making more. |
602 unsigned currentPosition = 0; | 676 if (!m_pendingText.isEmpty() && (m_pendingText.parent != dummyTask.parent ||
m_pendingText.nextChild != dummyTask.nextChild)) |
603 | 677 flushPendingText(); |
604 // Merge text nodes into previous ones if possible: | 678 m_pendingText.append(dummyTask.parent, dummyTask.nextChild, string, whitespa
ceMode); |
605 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construc
tion.html#insert-a-character | |
606 Node* previousChild = protoTask.nextChild ? protoTask.nextChild->previousSib
ling() : protoTask.parent->lastChild(); | |
607 if (previousChild && previousChild->isTextNode()) { | |
608 Text* previousText = toText(previousChild); | |
609 unsigned appendLengthLimit = lengthLimit - previousText->length(); | |
610 | |
611 unsigned proposedBreakIndex = std::min(currentPosition + appendLengthLim
it, string.length()); | |
612 unsigned breakIndex = findBreakIndexBetween(string, currentPosition, pro
posedBreakIndex); | |
613 ASSERT(breakIndex <= string.length()); | |
614 // If we didn't find a breable piece to append, forget it. | |
615 if (breakIndex) { | |
616 String substring = string.substring(currentPosition, breakIndex - cu
rrentPosition); | |
617 substring = atomizeIfAllWhitespace(substring, whitespaceMode); | |
618 previousText->parserAppendData(substring); | |
619 currentPosition += substring.length(); | |
620 } | |
621 } | |
622 | |
623 while (currentPosition < string.length()) { | |
624 unsigned proposedBreakIndex = std::min(currentPosition + lengthLimit, st
ring.length()); | |
625 unsigned breakIndex = findBreakIndexBetween(string, currentPosition, pro
posedBreakIndex); | |
626 // We failed to find a breakable boudary between the minimum and the pro
posed, just give up and break at the proposed index. | |
627 // We could go searching after the proposed index, but current callers a
re attempting to break after 65k chars! | |
628 // 65k of unbreakable characters isn't worth trying to handle "correctly
". | |
629 if (!breakIndex) | |
630 breakIndex = proposedBreakIndex; | |
631 ASSERT(breakIndex <= string.length()); | |
632 String substring = string.substring(currentPosition, breakIndex - curren
tPosition); | |
633 substring = atomizeIfAllWhitespace(substring, whitespaceMode); | |
634 | |
635 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert); | |
636 task.parent = protoTask.parent; | |
637 task.nextChild = protoTask.nextChild; | |
638 task.child = Text::create(task.parent->document(), substring); | |
639 queueTask(task); | |
640 | |
641 ASSERT(breakIndex > currentPosition); | |
642 ASSERT(breakIndex - currentPosition == substring.length()); | |
643 ASSERT(toText(task.child)->length() == substring.length()); | |
644 currentPosition = breakIndex; | |
645 } | |
646 } | 679 } |
647 | 680 |
648 void HTMLConstructionSite::reparent(HTMLElementStack::ElementRecord* newParent,
HTMLElementStack::ElementRecord* child) | 681 void HTMLConstructionSite::reparent(HTMLElementStack::ElementRecord* newParent,
HTMLElementStack::ElementRecord* child) |
649 { | 682 { |
650 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Reparent); | 683 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Reparent); |
651 task.parent = newParent->node(); | 684 task.parent = newParent->node(); |
652 task.child = child->node(); | 685 task.child = child->node(); |
653 queueTask(task); | 686 queueTask(task); |
654 } | 687 } |
655 | 688 |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 void HTMLConstructionSite::fosterParent(PassRefPtr<Node> node) | 851 void HTMLConstructionSite::fosterParent(PassRefPtr<Node> node) |
819 { | 852 { |
820 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert); | 853 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert); |
821 findFosterSite(task); | 854 findFosterSite(task); |
822 task.child = node; | 855 task.child = node; |
823 ASSERT(task.parent); | 856 ASSERT(task.parent); |
824 queueTask(task); | 857 queueTask(task); |
825 } | 858 } |
826 | 859 |
827 } | 860 } |
OLD | NEW |