| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 } | 68 } |
| 69 | 69 |
| 70 static inline void insert(HTMLConstructionSiteTask& task) | 70 static inline void insert(HTMLConstructionSiteTask& task) |
| 71 { | 71 { |
| 72 if (isHTMLTemplateElement(*task.parent)) | 72 if (isHTMLTemplateElement(*task.parent)) |
| 73 task.parent = toHTMLTemplateElement(task.parent.get())->content(); | 73 task.parent = toHTMLTemplateElement(task.parent.get())->content(); |
| 74 | 74 |
| 75 if (ContainerNode* parent = task.child->parentNode()) | 75 if (ContainerNode* parent = task.child->parentNode()) |
| 76 parent->parserRemoveChild(*task.child); | 76 parent->parserRemoveChild(*task.child); |
| 77 | 77 |
| 78 if (task.nextChild) | 78 task.parent->parserAppendChild(task.child.get()); |
| 79 task.parent->parserInsertBefore(task.child.get(), *task.nextChild); | |
| 80 else | |
| 81 task.parent->parserAppendChild(task.child.get()); | |
| 82 } | 79 } |
| 83 | 80 |
| 84 static inline void executeInsertTask(HTMLConstructionSiteTask& task) | 81 static inline void executeInsertTask(HTMLConstructionSiteTask& task) |
| 85 { | 82 { |
| 86 ASSERT(task.operation == HTMLConstructionSiteTask::Insert); | 83 ASSERT(task.operation == HTMLConstructionSiteTask::Insert); |
| 87 | 84 |
| 88 insert(task); | 85 insert(task); |
| 89 | 86 |
| 90 if (task.child->isElementNode()) { | 87 if (task.child->isElementNode()) { |
| 91 Element& child = toElement(*task.child); | 88 Element& child = toElement(*task.child); |
| 92 if (task.selfClosing) | 89 if (task.selfClosing) |
| 93 child.finishParsingChildren(); | 90 child.finishParsingChildren(); |
| 94 } | 91 } |
| 95 } | 92 } |
| 96 | 93 |
| 97 static inline void executeInsertTextTask(HTMLConstructionSiteTask& task) | 94 static inline void executeInsertTextTask(HTMLConstructionSiteTask& task) |
| 98 { | 95 { |
| 99 ASSERT(task.operation == HTMLConstructionSiteTask::InsertText); | 96 ASSERT(task.operation == HTMLConstructionSiteTask::InsertText); |
| 100 ASSERT(task.child->isTextNode()); | 97 ASSERT(task.child->isTextNode()); |
| 101 | 98 |
| 102 // Merge text nodes into previous ones if possible: | 99 // Merge text nodes into previous ones if possible: |
| 103 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construc
tion.html#insert-a-character | 100 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construc
tion.html#insert-a-character |
| 104 Text* newText = toText(task.child.get()); | 101 Text* newText = toText(task.child.get()); |
| 105 Node* previousChild = task.nextChild ? task.nextChild->previousSibling() : t
ask.parent->lastChild(); | 102 Node* previousChild = task.parent->lastChild(); |
| 106 if (previousChild && previousChild->isTextNode()) { | 103 if (previousChild && previousChild->isTextNode()) { |
| 107 Text* previousText = toText(previousChild); | 104 Text* previousText = toText(previousChild); |
| 108 unsigned lengthLimit = textLengthLimitForContainer(*task.parent); | 105 unsigned lengthLimit = textLengthLimitForContainer(*task.parent); |
| 109 if (previousText->length() + newText->length() < lengthLimit) { | 106 if (previousText->length() + newText->length() < lengthLimit) { |
| 110 previousText->parserAppendData(newText->data()); | 107 previousText->parserAppendData(newText->data()); |
| 111 return; | 108 return; |
| 112 } | 109 } |
| 113 } | 110 } |
| 114 | 111 |
| 115 insert(task); | 112 insert(task); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 const StringBuilder& string = pendingText.stringBuilder; | 178 const StringBuilder& string = pendingText.stringBuilder; |
| 182 while (currentPosition < string.length()) { | 179 while (currentPosition < string.length()) { |
| 183 unsigned proposedBreakIndex = std::min(currentPosition + lengthLimit, st
ring.length()); | 180 unsigned proposedBreakIndex = std::min(currentPosition + lengthLimit, st
ring.length()); |
| 184 unsigned breakIndex = findBreakIndexBetween(string, currentPosition, pro
posedBreakIndex); | 181 unsigned breakIndex = findBreakIndexBetween(string, currentPosition, pro
posedBreakIndex); |
| 185 ASSERT(breakIndex <= string.length()); | 182 ASSERT(breakIndex <= string.length()); |
| 186 String substring = string.substring(currentPosition, breakIndex - curren
tPosition); | 183 String substring = string.substring(currentPosition, breakIndex - curren
tPosition); |
| 187 substring = atomizeIfAllWhitespace(substring, pendingText.whitespaceMode
); | 184 substring = atomizeIfAllWhitespace(substring, pendingText.whitespaceMode
); |
| 188 | 185 |
| 189 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertText); | 186 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertText); |
| 190 task.parent = pendingText.parent; | 187 task.parent = pendingText.parent; |
| 191 task.nextChild = pendingText.nextChild; | |
| 192 task.child = Text::create(task.parent->document(), substring); | 188 task.child = Text::create(task.parent->document(), substring); |
| 193 queueTask(task); | 189 queueTask(task); |
| 194 | 190 |
| 195 ASSERT(breakIndex > currentPosition); | 191 ASSERT(breakIndex > currentPosition); |
| 196 ASSERT(breakIndex - currentPosition == substring.length()); | 192 ASSERT(breakIndex - currentPosition == substring.length()); |
| 197 ASSERT(toText(task.child.get())->length() == substring.length()); | 193 ASSERT(toText(task.child.get())->length() == substring.length()); |
| 198 currentPosition = breakIndex; | 194 currentPosition = breakIndex; |
| 199 } | 195 } |
| 200 } | 196 } |
| 201 | 197 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 | 310 |
| 315 void HTMLConstructionSite::insertTextNode(const String& string, WhitespaceMode w
hitespaceMode) | 311 void HTMLConstructionSite::insertTextNode(const String& string, WhitespaceMode w
hitespaceMode) |
| 316 { | 312 { |
| 317 HTMLConstructionSiteTask dummyTask(HTMLConstructionSiteTask::Insert); | 313 HTMLConstructionSiteTask dummyTask(HTMLConstructionSiteTask::Insert); |
| 318 dummyTask.parent = currentNode(); | 314 dummyTask.parent = currentNode(); |
| 319 | 315 |
| 320 // FIXME: This probably doesn't need to be done both here and in insert(Task
). | 316 // FIXME: This probably doesn't need to be done both here and in insert(Task
). |
| 321 if (isHTMLTemplateElement(*dummyTask.parent)) | 317 if (isHTMLTemplateElement(*dummyTask.parent)) |
| 322 dummyTask.parent = toHTMLTemplateElement(dummyTask.parent.get())->conten
t(); | 318 dummyTask.parent = toHTMLTemplateElement(dummyTask.parent.get())->conten
t(); |
| 323 | 319 |
| 324 // Unclear when parent != case occurs. Somehow we insert text into two separ
ate nodes while processing the same Token. | 320 // Unclear when parent != case occurs. Somehow we insert text into two separ
ate |
| 325 // The nextChild != dummy.nextChild case occurs whenever foster parenting ha
ppened and we hit a new text node "<table>a</table>b" | 321 // nodes while processing the same Token. When it happens we have to flush t
he |
| 326 // In either case we have to flush the pending text into the task queue befo
re making more. | 322 // pending text into the task queue before making more. |
| 327 if (!m_pendingText.isEmpty() && (m_pendingText.parent != dummyTask.parent ||
m_pendingText.nextChild != dummyTask.nextChild)) | 323 if (!m_pendingText.isEmpty() && (m_pendingText.parent != dummyTask.parent)) |
| 328 flushPendingText(); | 324 flushPendingText(); |
| 329 m_pendingText.append(dummyTask.parent, dummyTask.nextChild, string, whitespa
ceMode); | 325 m_pendingText.append(dummyTask.parent, string, whitespaceMode); |
| 330 } | 326 } |
| 331 | 327 |
| 332 PassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken* token,
const AtomicString& namespaceURI) | 328 PassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken* token,
const AtomicString& namespaceURI) |
| 333 { | 329 { |
| 334 QualifiedName tagName(token->name()); | 330 QualifiedName tagName(token->name()); |
| 335 RefPtr<Element> element = ownerDocumentForCurrentNode().createElement(tagNam
e, true); | 331 RefPtr<Element> element = ownerDocumentForCurrentNode().createElement(tagNam
e, true); |
| 336 setAttributes(element.get(), token); | 332 setAttributes(element.get(), token); |
| 337 return element.release(); | 333 return element.release(); |
| 338 } | 334 } |
| 339 | 335 |
| 340 inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode() | 336 inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode() |
| 341 { | 337 { |
| 342 if (isHTMLTemplateElement(*currentNode())) | 338 if (isHTMLTemplateElement(*currentNode())) |
| 343 return toHTMLTemplateElement(currentElement())->content()->document(); | 339 return toHTMLTemplateElement(currentElement())->content()->document(); |
| 344 return currentNode()->document(); | 340 return currentNode()->document(); |
| 345 } | 341 } |
| 346 | 342 |
| 347 PassRefPtr<HTMLElement> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken*
token) | 343 PassRefPtr<HTMLElement> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken*
token) |
| 348 { | 344 { |
| 349 Document& document = ownerDocumentForCurrentNode(); | 345 Document& document = ownerDocumentForCurrentNode(); |
| 350 RefPtr<HTMLElement> element = HTMLElementFactory::createHTMLElement(token->n
ame(), document, true); | 346 RefPtr<HTMLElement> element = HTMLElementFactory::createHTMLElement(token->n
ame(), document, true); |
| 351 setAttributes(element.get(), token); | 347 setAttributes(element.get(), token); |
| 352 return element.release(); | 348 return element.release(); |
| 353 } | 349 } |
| 354 | 350 |
| 355 } | 351 } |
| OLD | NEW |