Index: Source/core/dom/Range.cpp |
diff --git a/Source/core/dom/Range.cpp b/Source/core/dom/Range.cpp |
index efa129d85a14badec6a8da30f5838c7cf5a7aa53..2dfe490833187d14359d7498dd85a582985d9995 100644 |
--- a/Source/core/dom/Range.cpp |
+++ b/Source/core/dom/Range.cpp |
@@ -470,20 +470,28 @@ void Range::deleteContents(ExceptionState& exceptionState) |
} |
} |
-bool Range::intersectsNode(Node* refNode, ExceptionState& exceptionState) |
+static bool nodeValidForIntersects(Node* refNode, Document* expectedDocument, ExceptionState& exceptionState) |
{ |
- // http://developer.mozilla.org/en/docs/DOM:range.intersectsNode |
- // Returns a bool if the node intersects the range. |
if (!refNode) { |
exceptionState.throwDOMException(NotFoundError, "The node provided is null."); |
return false; |
} |
- if (!refNode->inActiveDocument() || refNode->document() != m_ownerDocument) { |
+ if (!refNode->inActiveDocument() || refNode->document() != expectedDocument) { |
// Firefox doesn't throw an exception for these cases; it returns false. |
return false; |
} |
+ return true; |
+} |
+ |
+bool Range::intersectsNode(Node* refNode, ExceptionState& exceptionState) |
+{ |
+ // http://developer.mozilla.org/en/docs/DOM:range.intersectsNode |
+ // Returns a bool if the node intersects the range. |
+ if (!nodeValidForIntersects(refNode, m_ownerDocument.get(), exceptionState)) |
+ return false; |
+ |
ContainerNode* parentNode = refNode->parentNode(); |
int nodeIndex = refNode->nodeIndex(); |
@@ -507,6 +515,44 @@ bool Range::intersectsNode(Node* refNode, ExceptionState& exceptionState) |
return true; // all other cases |
} |
+bool Range::intersectsNode(Node* refNode, const Position& start, const Position& end, ExceptionState& exceptionState) |
+{ |
+ // http://developer.mozilla.org/en/docs/DOM:range.intersectsNode |
+ // Returns a bool if the node intersects the range. |
+ if (!nodeValidForIntersects(refNode, start.document(), exceptionState)) |
+ return false; |
+ |
+ ContainerNode* parentNode = refNode->parentNode(); |
+ int nodeIndex = refNode->nodeIndex(); |
+ |
+ if (!parentNode) { |
+ // if the node is the top document we should return NODE_BEFORE_AND_AFTER |
+ // but we throw to match firefox behavior |
+ exceptionState.throwDOMException(NotFoundError, "The node provided has no parent."); |
+ return false; |
+ } |
+ |
+ Node* startContainerNode = start.containerNode(); |
+ int startOffset = start.computeOffsetInContainerNode(); |
+ |
+ if (compareBoundaryPoints(parentNode, nodeIndex, startContainerNode, startOffset, exceptionState) < 0 // starts before start |
+ && compareBoundaryPoints(parentNode, nodeIndex + 1, startContainerNode, startOffset, exceptionState) < 0) { // ends before start |
+ ASSERT(!exceptionState.hadException()); |
+ return false; |
+ } |
+ |
+ Node* endContainerNode = end.containerNode(); |
+ int endOffset = end.computeOffsetInContainerNode(); |
+ |
+ if (compareBoundaryPoints(parentNode, nodeIndex, endContainerNode, endOffset, exceptionState) > 0 // starts after end |
+ && compareBoundaryPoints(parentNode, nodeIndex + 1, endContainerNode, endOffset, exceptionState) > 0) { // ends after end |
+ ASSERT(!exceptionState.hadException()); |
+ return false; |
+ } |
+ |
+ return true; // all other cases |
+} |
+ |
static inline Node* highestAncestorUnderCommonRoot(Node* node, Node* commonRoot) |
{ |
if (node == commonRoot) |