Index: Source/core/dom/Range.cpp |
diff --git a/Source/core/dom/Range.cpp b/Source/core/dom/Range.cpp |
index 10e4029cd0d6d752462117ea2f51264371c24b63..241c62f3c20656a65b4b824ff15af8159d15036e 100644 |
--- a/Source/core/dom/Range.cpp |
+++ b/Source/core/dom/Range.cpp |
@@ -40,9 +40,11 @@ |
#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/SVGSVGElement.h" |
#include "platform/geometry/FloatQuad.h" |
#include "wtf/RefCountedLeakCounter.h" |
#include "wtf/text/CString.h" |
@@ -53,8 +55,6 @@ |
namespace WebCore { |
-using namespace HTMLNames; |
- |
DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, rangeCounter, ("Range")); |
inline Range::Range(Document& ownerDocument) |
@@ -959,13 +959,42 @@ String Range::text() const |
PassRefPtrWillBeRawPtr<DocumentFragment> Range::createContextualFragment(const String& markup, ExceptionState& exceptionState) |
{ |
- 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."); |
+ // Algorithm: http://domparsing.spec.whatwg.org/#extensions-to-the-range-interface |
+ |
+ Node* node = m_start.container(); |
+ |
+ // Step 1. |
+ RefPtrWillBeRawPtr<Element> element; |
+ if (!m_start.offset() && (node->isDocumentNode() || node->isDocumentFragment())) |
+ element = nullptr; |
+ else if (node->isElementNode()) |
+ element = toElement(node); |
+ else |
+ element = node->parentElement(); |
+ |
+ // Step 2. |
+ if (!element || isHTMLHtmlElement(element)) { |
+ Document& document = node->document(); |
+ |
+ if (document.isHTMLDocument() || document.isXHTMLDocument()) { |
+ // Optimization over spec: try to reuse the existing <body> element, if it is available. |
+ element = document.body(); |
+ if (!element) |
+ element = HTMLBodyElement::create(document); |
+ } else if (document.isSVGDocument()) { |
+ element = document.documentElement(); |
+ if (!element) |
+ element = SVGSVGElement::create(document); |
+ } |
+ } |
+ |
+ if (!element || (!element->isHTMLElement() && !element->isSVGElement())) { |
+ exceptionState.throwDOMException(NotSupportedError, "The range's container must be an HTML or SVG Element, Document, or DocumentFragment."); |
return nullptr; |
} |
- RefPtrWillBeRawPtr<DocumentFragment> fragment = WebCore::createContextualFragment(markup, toHTMLElement(element), AllowScriptingContentAndDoNotMarkAlreadyStarted, exceptionState); |
+ // Steps 3, 4, 5. |
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = WebCore::createContextualFragment(markup, element.get(), AllowScriptingContentAndDoNotMarkAlreadyStarted, exceptionState); |
if (!fragment) |
return nullptr; |