Chromium Code Reviews| Index: Source/core/dom/Range.cpp |
| diff --git a/Source/core/dom/Range.cpp b/Source/core/dom/Range.cpp |
| index 297a585406d2dd338481097fe27ea6b4a3c301b5..3909e34880467a20a9ae660a91eb6cdcc8c33018 100644 |
| --- a/Source/core/dom/Range.cpp |
| +++ b/Source/core/dom/Range.cpp |
| @@ -25,6 +25,7 @@ |
| #include "config.h" |
| #include "core/dom/Range.h" |
| +#include "HTMLNames.h" |
| #include "bindings/v8/ExceptionState.h" |
| #include "core/dom/ClientRect.h" |
| #include "core/dom/ClientRectList.h" |
| @@ -34,15 +35,19 @@ |
| #include "core/dom/NodeTraversal.h" |
| #include "core/dom/NodeWithIndex.h" |
| #include "core/dom/ProcessingInstruction.h" |
| -#include "core/events/ScopedEventQueue.h" |
| #include "core/dom/Text.h" |
| #include "core/editing/TextIterator.h" |
| #include "core/editing/VisiblePosition.h" |
| #include "core/editing/VisibleUnits.h" |
| #include "core/editing/markup.h" |
| +#include "core/events/ScopedEventQueue.h" |
| +#include "core/html/HTMLBodyElement.h" |
| #include "core/html/HTMLElement.h" |
| #include "core/rendering/RenderBoxModelObject.h" |
| #include "core/rendering/RenderText.h" |
| +#include "core/svg/SVGDocument.h" |
| +#include "core/svg/SVGElement.h" |
| +#include "core/svg/SVGSVGElement.h" |
| #include "platform/geometry/FloatQuad.h" |
| #include "wtf/RefCountedLeakCounter.h" |
| #include "wtf/text/CString.h" |
| @@ -1103,18 +1108,60 @@ String Range::text() const |
| PassRefPtr<DocumentFragment> Range::createContextualFragment(const String& markup, ExceptionState& exceptionState) |
| { |
| - if (!m_start.container()) { |
| + // Algorithm: http://domparsing.spec.whatwg.org/#extensions-to-the-range-interface |
| + |
| + Node* startContainer = m_start.container(); |
| + if (!startContainer) { |
| exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?"); |
| return 0; |
| } |
| - Node* element = m_start.container()->isElementNode() ? m_start.container() : m_start.container()->parentNode(); |
| - if (!element || !element->isHTMLElement()) { |
| - exceptionState.throwDOMException(NotSupportedError, "The range's container must be an HTML element."); |
| - return 0; |
| + // Step 1. |
| + Node* element; |
| + if (!m_start.offset() && (m_start.container()->isDocumentNode() || m_start.container()->isDocumentFragment())) { |
| + element = 0; |
| + } else if (startContainer->isElementNode()) { |
| + element = startContainer; |
| + } else { |
| + element = startContainer->parentNode(); |
| + if (!element || !element->isElementNode()) { |
| + exceptionState.throwDOMException(NotSupportedError, "The range's container must be an Element, Document, or DocumentFragment."); |
| + return 0; |
| + } |
| } |
| + ASSERT(!element || element->isElementNode()); |
| + |
| + // Step 2. |
| + RefPtr<Element> fakeBody = 0; |
| + if (!element || (element->isHTMLElement() && toHTMLElement(element)->hasLocalName(HTMLNames::htmlTag))) { |
| + Document& document = startContainer->document(); |
| + // Try to use the existing <body> element, if it is available. |
| + if (document.isHTMLDocument() || document.isXHTMLDocument()) |
| + element = document.body(); |
| + else if (document.isSVGDocument()) |
| + element = toSVGDocument(document).rootElement(); |
| + |
| + if (!element) { |
| + // SVG documents always have an <svg> root element, should never need a fake node. |
| + ASSERT(document.isHTMLDocument() || document.isXHTMLDocument()); |
| + fakeBody = HTMLBodyElement::create(document); |
| + element = fakeBody.get(); |
| + } |
| + } else { |
| + if (!element->isHTMLElement() && !element->isSVGElement()) { |
| + exceptionState.throwDOMException(NotSupportedError, "The range's container must be an Element, Document, or DocumentFragment."); |
| + return 0; |
| + } |
| + } |
| + ASSERT(element && (element->isHTMLElement() || element->isSVGElement())); |
|
yosin_UTC9
2014/05/29 03:53:06
Is this ASSERT always true?
We can set any node to
pwnall-personal
2014/06/02 06:57:57
The patch uses document.body() for HTML/XHTML docu
|
| + |
| + // Steps 3, 4, 5. |
| + RefPtr<DocumentFragment> fragment; |
| + if (element->isHTMLElement()) |
| + fragment = WebCore::createContextualFragment(markup, toHTMLElement(element), AllowScriptingContentAndDoNotMarkAlreadyStarted, exceptionState); |
| + else |
| + fragment = WebCore::createContextualFragment(markup, toSVGElement(element), AllowScriptingContentAndDoNotMarkAlreadyStarted, exceptionState); |
| - RefPtr<DocumentFragment> fragment = WebCore::createContextualFragment(markup, toHTMLElement(element), AllowScriptingContentAndDoNotMarkAlreadyStarted, exceptionState); |
| if (!fragment) |
| return 0; |