| 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 28 matching lines...) Expand all Loading... |
| 39 #include "core/html/parser/HTMLToken.h" | 39 #include "core/html/parser/HTMLToken.h" |
| 40 #include "core/loader/FrameLoaderClient.h" | 40 #include "core/loader/FrameLoaderClient.h" |
| 41 #include "platform/NotImplemented.h" | 41 #include "platform/NotImplemented.h" |
| 42 #include "platform/text/TextBreakIterator.h" | 42 #include "platform/text/TextBreakIterator.h" |
| 43 #include <limits> | 43 #include <limits> |
| 44 | 44 |
| 45 namespace blink { | 45 namespace blink { |
| 46 | 46 |
| 47 static const unsigned maximumHTMLParserDOMTreeDepth = 512; | 47 static const unsigned maximumHTMLParserDOMTreeDepth = 512; |
| 48 | 48 |
| 49 static inline void setAttributes(Element* element, AtomicHTMLToken* token, Parse
rContentPolicy parserContentPolicy) | 49 static inline void setAttributes(Element* element, AtomicHTMLToken* token) |
| 50 { | 50 { |
| 51 if (!scriptingContentIsAllowed(parserContentPolicy)) | 51 element->stripScriptingAttributes(token->attributes()); |
| 52 element->stripScriptingAttributes(token->attributes()); | |
| 53 element->parserSetAttributes(token->attributes()); | 52 element->parserSetAttributes(token->attributes()); |
| 54 } | 53 } |
| 55 | 54 |
| 56 static bool shouldUseLengthLimit(const ContainerNode& node) | 55 static bool shouldUseLengthLimit(const ContainerNode& node) |
| 57 { | 56 { |
| 58 return !isHTMLScriptElement(node) | 57 return !isHTMLScriptElement(node) |
| 59 && !isHTMLStyleElement(node); | 58 && !isHTMLStyleElement(node); |
| 60 } | 59 } |
| 61 | 60 |
| 62 static unsigned textLengthLimitForContainer(const ContainerNode& node) | 61 static unsigned textLengthLimitForContainer(const ContainerNode& node) |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 | 203 |
| 205 void HTMLConstructionSite::queueTask(const HTMLConstructionSiteTask& task) | 204 void HTMLConstructionSite::queueTask(const HTMLConstructionSiteTask& task) |
| 206 { | 205 { |
| 207 flushPendingText(); | 206 flushPendingText(); |
| 208 ASSERT(m_pendingText.isEmpty()); | 207 ASSERT(m_pendingText.isEmpty()); |
| 209 m_taskQueue.append(task); | 208 m_taskQueue.append(task); |
| 210 } | 209 } |
| 211 | 210 |
| 212 void HTMLConstructionSite::attachLater(ContainerNode* parent, PassRefPtrWillBeRa
wPtr<Node> prpChild, bool selfClosing) | 211 void HTMLConstructionSite::attachLater(ContainerNode* parent, PassRefPtrWillBeRa
wPtr<Node> prpChild, bool selfClosing) |
| 213 { | 212 { |
| 214 ASSERT(scriptingContentIsAllowed(m_parserContentPolicy) || !prpChild.get()->
isElementNode()); | |
| 215 | |
| 216 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert); | 213 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert); |
| 217 task.parent = parent; | 214 task.parent = parent; |
| 218 task.child = prpChild; | 215 task.child = prpChild; |
| 219 task.selfClosing = selfClosing; | 216 task.selfClosing = selfClosing; |
| 220 | 217 |
| 221 // Add as a sibling of the parent if we have reached the maximum depth allow
ed. | 218 // Add as a sibling of the parent if we have reached the maximum depth allow
ed. |
| 222 if (m_openElements.stackDepth() > maximumHTMLParserDOMTreeDepth && task.pare
nt->parentNode()) | 219 if (m_openElements.stackDepth() > maximumHTMLParserDOMTreeDepth && task.pare
nt->parentNode()) |
| 223 task.parent = task.parent->parentNode(); | 220 task.parent = task.parent->parentNode(); |
| 224 | 221 |
| 225 ASSERT(task.parent); | 222 ASSERT(task.parent); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 238 // re-enters the parser. | 235 // re-enters the parser. |
| 239 TaskQueue queue; | 236 TaskQueue queue; |
| 240 queue.swap(m_taskQueue); | 237 queue.swap(m_taskQueue); |
| 241 | 238 |
| 242 for (size_t i = 0; i < size; ++i) | 239 for (size_t i = 0; i < size; ++i) |
| 243 executeTask(queue[i]); | 240 executeTask(queue[i]); |
| 244 | 241 |
| 245 // We might be detached now. | 242 // We might be detached now. |
| 246 } | 243 } |
| 247 | 244 |
| 248 HTMLConstructionSite::HTMLConstructionSite(Document* document, ParserContentPoli
cy parserContentPolicy) | 245 HTMLConstructionSite::HTMLConstructionSite(Document* document) |
| 249 : m_document(document) | 246 : m_document(document) |
| 250 , m_attachmentRoot(document) | 247 , m_attachmentRoot(document) |
| 251 , m_parserContentPolicy(parserContentPolicy) | |
| 252 { | 248 { |
| 253 } | 249 } |
| 254 | 250 |
| 255 HTMLConstructionSite::HTMLConstructionSite(DocumentFragment* fragment, ParserCon
tentPolicy parserContentPolicy) | 251 HTMLConstructionSite::HTMLConstructionSite(DocumentFragment* fragment) |
| 256 : m_document(&fragment->document()) | 252 : m_document(&fragment->document()) |
| 257 , m_attachmentRoot(fragment) | 253 , m_attachmentRoot(fragment) |
| 258 , m_parserContentPolicy(parserContentPolicy) | |
| 259 { | 254 { |
| 260 } | 255 } |
| 261 | 256 |
| 262 HTMLConstructionSite::~HTMLConstructionSite() | 257 HTMLConstructionSite::~HTMLConstructionSite() |
| 263 { | 258 { |
| 264 // Depending on why we're being destroyed it might be OK | 259 // Depending on why we're being destroyed it might be OK |
| 265 // to forget queued tasks, but currently we don't expect to. | 260 // to forget queued tasks, but currently we don't expect to. |
| 266 ASSERT(m_taskQueue.isEmpty()); | 261 ASSERT(m_taskQueue.isEmpty()); |
| 267 // Currently we assume that text will never be the last token in the | 262 // Currently we assume that text will never be the last token in the |
| 268 // document and that we'll always queue some additional task to cause it to
flush. | 263 // document and that we'll always queue some additional task to cause it to
flush. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 // but self-closing elements are never in the element stack so the stack | 310 // but self-closing elements are never in the element stack so the stack |
| 316 // doesn't get a chance to tell them that we're done parsing their children. | 311 // doesn't get a chance to tell them that we're done parsing their children. |
| 317 attachLater(currentNode(), createHTMLElement(token), true); | 312 attachLater(currentNode(), createHTMLElement(token), true); |
| 318 // FIXME: Do we want to acknowledge the token's self-closing flag? | 313 // FIXME: Do we want to acknowledge the token's self-closing flag? |
| 319 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.
html#acknowledge-self-closing-flag | 314 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.
html#acknowledge-self-closing-flag |
| 320 } | 315 } |
| 321 | 316 |
| 322 void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token) | 317 void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token) |
| 323 { | 318 { |
| 324 RefPtrWillBeRawPtr<HTMLScriptElement> element = HTMLScriptElement::create(ow
nerDocumentForCurrentNode()); | 319 RefPtrWillBeRawPtr<HTMLScriptElement> element = HTMLScriptElement::create(ow
nerDocumentForCurrentNode()); |
| 325 setAttributes(element.get(), token, m_parserContentPolicy); | 320 setAttributes(element.get(), token); |
| 326 if (scriptingContentIsAllowed(m_parserContentPolicy)) | 321 attachLater(currentNode(), element); |
| 327 attachLater(currentNode(), element); | |
| 328 m_openElements.push(element.release()); | 322 m_openElements.push(element.release()); |
| 329 } | 323 } |
| 330 | 324 |
| 331 void HTMLConstructionSite::insertTextNode(const String& string, WhitespaceMode w
hitespaceMode) | 325 void HTMLConstructionSite::insertTextNode(const String& string, WhitespaceMode w
hitespaceMode) |
| 332 { | 326 { |
| 333 HTMLConstructionSiteTask dummyTask(HTMLConstructionSiteTask::Insert); | 327 HTMLConstructionSiteTask dummyTask(HTMLConstructionSiteTask::Insert); |
| 334 dummyTask.parent = currentNode(); | 328 dummyTask.parent = currentNode(); |
| 335 | 329 |
| 336 // FIXME: This probably doesn't need to be done both here and in insert(Task
). | 330 // FIXME: This probably doesn't need to be done both here and in insert(Task
). |
| 337 if (isHTMLTemplateElement(*dummyTask.parent)) | 331 if (isHTMLTemplateElement(*dummyTask.parent)) |
| 338 dummyTask.parent = toHTMLTemplateElement(dummyTask.parent.get())->conten
t(); | 332 dummyTask.parent = toHTMLTemplateElement(dummyTask.parent.get())->conten
t(); |
| 339 | 333 |
| 340 // Unclear when parent != case occurs. Somehow we insert text into two separ
ate nodes while processing the same Token. | 334 // Unclear when parent != case occurs. Somehow we insert text into two separ
ate nodes while processing the same Token. |
| 341 // The nextChild != dummy.nextChild case occurs whenever foster parenting ha
ppened and we hit a new text node "<table>a</table>b" | 335 // The nextChild != dummy.nextChild case occurs whenever foster parenting ha
ppened and we hit a new text node "<table>a</table>b" |
| 342 // In either case we have to flush the pending text into the task queue befo
re making more. | 336 // In either case we have to flush the pending text into the task queue befo
re making more. |
| 343 if (!m_pendingText.isEmpty() && (m_pendingText.parent != dummyTask.parent ||
m_pendingText.nextChild != dummyTask.nextChild)) | 337 if (!m_pendingText.isEmpty() && (m_pendingText.parent != dummyTask.parent ||
m_pendingText.nextChild != dummyTask.nextChild)) |
| 344 flushPendingText(); | 338 flushPendingText(); |
| 345 m_pendingText.append(dummyTask.parent, dummyTask.nextChild, string, whitespa
ceMode); | 339 m_pendingText.append(dummyTask.parent, dummyTask.nextChild, string, whitespa
ceMode); |
| 346 } | 340 } |
| 347 | 341 |
| 348 PassRefPtrWillBeRawPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLTo
ken* token, const AtomicString& namespaceURI) | 342 PassRefPtrWillBeRawPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLTo
ken* token, const AtomicString& namespaceURI) |
| 349 { | 343 { |
| 350 QualifiedName tagName(token->name()); | 344 QualifiedName tagName(token->name()); |
| 351 RefPtrWillBeRawPtr<Element> element = ownerDocumentForCurrentNode().createEl
ement(tagName, true); | 345 RefPtrWillBeRawPtr<Element> element = ownerDocumentForCurrentNode().createEl
ement(tagName, true); |
| 352 setAttributes(element.get(), token, m_parserContentPolicy); | 346 setAttributes(element.get(), token); |
| 353 return element.release(); | 347 return element.release(); |
| 354 } | 348 } |
| 355 | 349 |
| 356 inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode() | 350 inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode() |
| 357 { | 351 { |
| 358 if (isHTMLTemplateElement(*currentNode())) | 352 if (isHTMLTemplateElement(*currentNode())) |
| 359 return toHTMLTemplateElement(currentElement())->content()->document(); | 353 return toHTMLTemplateElement(currentElement())->content()->document(); |
| 360 return currentNode()->document(); | 354 return currentNode()->document(); |
| 361 } | 355 } |
| 362 | 356 |
| 363 PassRefPtrWillBeRawPtr<HTMLElement> HTMLConstructionSite::createHTMLElement(Atom
icHTMLToken* token) | 357 PassRefPtrWillBeRawPtr<HTMLElement> HTMLConstructionSite::createHTMLElement(Atom
icHTMLToken* token) |
| 364 { | 358 { |
| 365 Document& document = ownerDocumentForCurrentNode(); | 359 Document& document = ownerDocumentForCurrentNode(); |
| 366 RefPtrWillBeRawPtr<HTMLElement> element = HTMLElementFactory::createHTMLElem
ent(token->name(), document, true); | 360 RefPtrWillBeRawPtr<HTMLElement> element = HTMLElementFactory::createHTMLElem
ent(token->name(), document, true); |
| 367 setAttributes(element.get(), token, m_parserContentPolicy); | 361 setAttributes(element.get(), token); |
| 368 return element.release(); | 362 return element.release(); |
| 369 } | 363 } |
| 370 | 364 |
| 371 void HTMLConstructionSite::PendingText::trace(Visitor* visitor) | 365 void HTMLConstructionSite::PendingText::trace(Visitor* visitor) |
| 372 { | 366 { |
| 373 visitor->trace(parent); | 367 visitor->trace(parent); |
| 374 visitor->trace(nextChild); | 368 visitor->trace(nextChild); |
| 375 } | 369 } |
| 376 | 370 |
| 377 } | 371 } |
| OLD | NEW |