Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * (C) 1999 Lars Knoll (knoll@kde.org) | 2 * (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 2000 Gunnstein Lye (gunnstein@netcom.no) | 3 * (C) 2000 Gunnstein Lye (gunnstein@netcom.no) |
| 4 * (C) 2000 Frederik Holljen (frederik.holljen@hig.no) | 4 * (C) 2000 Frederik Holljen (frederik.holljen@hig.no) |
| 5 * (C) 2001 Peter Kelly (pmk@post.com) | 5 * (C) 2001 Peter Kelly (pmk@post.com) |
| 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All |
| 7 * rights reserved. | 7 * rights reserved. |
| 8 * Copyright (C) 2011 Motorola Mobility. All rights reserved. | 8 * Copyright (C) 2011 Motorola Mobility. All rights reserved. |
| 9 * | 9 * |
| 10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 int nodeIndex = node.nodeIndex(); | 240 int nodeIndex = node.nodeIndex(); |
| 241 return isPointInRange(parentNode, nodeIndex, | 241 return isPointInRange(parentNode, nodeIndex, |
| 242 IGNORE_EXCEPTION) // starts in the middle of this | 242 IGNORE_EXCEPTION) // starts in the middle of this |
| 243 // range, or on the boundary points. | 243 // range, or on the boundary points. |
| 244 && isPointInRange(parentNode, nodeIndex + 1, | 244 && isPointInRange(parentNode, nodeIndex + 1, |
| 245 IGNORE_EXCEPTION); // ends in the middle of this | 245 IGNORE_EXCEPTION); // ends in the middle of this |
| 246 // range, or on the boundary | 246 // range, or on the boundary |
| 247 // points. | 247 // points. |
| 248 } | 248 } |
| 249 | 249 |
| 250 bool Range::hasSameRoot(const Node& node) const { | |
| 251 if (node.document() != m_ownerDocument) | |
| 252 return false; | |
| 253 // commonAncestorContainer() is O(depth). We should avoid to call it in common | |
| 254 // cases. | |
| 255 if (node.isConnected() && m_start.container()->isConnected() && | |
|
yosin_UTC9
2016/10/17 04:14:30
Q: Is it better to use isInTreeScope() == isConnec
tkent
2016/10/17 04:48:03
Yeah, that's a good idea. It improves the coverag
| |
| 256 &node.treeScope() == &m_start.container()->treeScope()) | |
| 257 return true; | |
| 258 return commonAncestorContainer(m_start.container(), &node); | |
|
yosin_UTC9
2016/10/17 04:14:30
nit: Is m_start.container()->treeScope().commonAnc
tkent
2016/10/17 04:48:03
The comparison doesn't make sense because we can't
| |
| 259 } | |
| 260 | |
| 250 bool Range::isPointInRange(Node* refNode, | 261 bool Range::isPointInRange(Node* refNode, |
| 251 int offset, | 262 int offset, |
| 252 ExceptionState& exceptionState) const { | 263 ExceptionState& exceptionState) const { |
| 253 if (!refNode) { | 264 if (!refNode) { |
| 254 // FIXME: Generated bindings code never calls with null, and neither should | 265 // FIXME: Generated bindings code never calls with null, and neither should |
| 255 // other callers! | 266 // other callers! |
| 256 exceptionState.throwTypeError("The node provided is null."); | 267 exceptionState.throwTypeError("The node provided is null."); |
| 257 return false; | 268 return false; |
| 258 } | 269 } |
| 259 | 270 if (!hasSameRoot(*refNode)) |
| 260 if (!refNode->inActiveDocument() || refNode->document() != m_ownerDocument) { | |
| 261 return false; | 271 return false; |
| 262 } | |
| 263 | 272 |
| 264 checkNodeWOffset(refNode, offset, exceptionState); | 273 checkNodeWOffset(refNode, offset, exceptionState); |
| 265 if (exceptionState.hadException()) | 274 if (exceptionState.hadException()) |
| 266 return false; | 275 return false; |
| 267 | 276 |
| 268 return compareBoundaryPoints(refNode, offset, m_start.container(), | 277 return compareBoundaryPoints(refNode, offset, m_start.container(), |
| 269 m_start.offset(), exceptionState) >= 0 && | 278 m_start.offset(), exceptionState) >= 0 && |
| 270 !exceptionState.hadException() && | 279 !exceptionState.hadException() && |
| 271 compareBoundaryPoints(refNode, offset, m_end.container(), | 280 compareBoundaryPoints(refNode, offset, m_end.container(), |
| 272 m_end.offset(), exceptionState) <= 0 && | 281 m_end.offset(), exceptionState) <= 0 && |
| 273 !exceptionState.hadException(); | 282 !exceptionState.hadException(); |
| 274 } | 283 } |
| 275 | 284 |
| 276 short Range::comparePoint(Node* refNode, | 285 short Range::comparePoint(Node* refNode, |
| 277 int offset, | 286 int offset, |
| 278 ExceptionState& exceptionState) const { | 287 ExceptionState& exceptionState) const { |
| 279 // http://developer.mozilla.org/en/docs/DOM:range.comparePoint | 288 // http://developer.mozilla.org/en/docs/DOM:range.comparePoint |
| 280 // This method returns -1, 0 or 1 depending on if the point described by the | 289 // This method returns -1, 0 or 1 depending on if the point described by the |
| 281 // refNode node and an offset within the node is before, same as, or after the | 290 // refNode node and an offset within the node is before, same as, or after the |
| 282 // range respectively. | 291 // range respectively. |
| 283 | 292 |
| 284 if (!refNode->inActiveDocument()) { | 293 if (!hasSameRoot(*refNode)) { |
| 285 exceptionState.throwDOMException( | 294 exceptionState.throwDOMException( |
| 286 WrongDocumentError, "The node provided is not in an active document."); | 295 WrongDocumentError, |
| 296 "The node provided and the Range are not in the same tree."); | |
| 287 return 0; | 297 return 0; |
| 288 } | 298 } |
| 289 | 299 |
| 290 if (refNode->document() != m_ownerDocument) { | |
| 291 exceptionState.throwDOMException( | |
| 292 WrongDocumentError, | |
| 293 "The node provided is not in this Range's Document."); | |
| 294 return 0; | |
| 295 } | |
| 296 | |
| 297 checkNodeWOffset(refNode, offset, exceptionState); | 300 checkNodeWOffset(refNode, offset, exceptionState); |
| 298 if (exceptionState.hadException()) | 301 if (exceptionState.hadException()) |
| 299 return 0; | 302 return 0; |
| 300 | 303 |
| 301 // compare to start, and point comes before | 304 // compare to start, and point comes before |
| 302 if (compareBoundaryPoints(refNode, offset, m_start.container(), | 305 if (compareBoundaryPoints(refNode, offset, m_start.container(), |
| 303 m_start.offset(), exceptionState) < 0) | 306 m_start.offset(), exceptionState) < 0) |
| 304 return -1; | 307 return -1; |
| 305 | 308 |
| 306 if (exceptionState.hadException()) | 309 if (exceptionState.hadException()) |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 | 401 |
| 399 void Range::deleteContents(ExceptionState& exceptionState) { | 402 void Range::deleteContents(ExceptionState& exceptionState) { |
| 400 DCHECK(boundaryPointsValid()); | 403 DCHECK(boundaryPointsValid()); |
| 401 | 404 |
| 402 { | 405 { |
| 403 EventQueueScope eventQueueScope; | 406 EventQueueScope eventQueueScope; |
| 404 processContents(DELETE_CONTENTS, exceptionState); | 407 processContents(DELETE_CONTENTS, exceptionState); |
| 405 } | 408 } |
| 406 } | 409 } |
| 407 | 410 |
| 408 static bool nodeValidForIntersects(Node* refNode, | 411 bool Range::intersectsNode(Node* refNode, ExceptionState& exceptionState) { |
| 409 Document* expectedDocument, | 412 // http://developer.mozilla.org/en/docs/DOM:range.intersectsNode |
| 410 ExceptionState& exceptionState) { | 413 // Returns a bool if the node intersects the range. |
| 411 if (!refNode) { | 414 if (!refNode) { |
| 412 // FIXME: Generated bindings code never calls with null, and neither should | 415 // FIXME: Generated bindings code never calls with null, and neither should |
| 413 // other callers! | 416 // other callers! |
| 414 exceptionState.throwTypeError("The node provided is null."); | 417 exceptionState.throwTypeError("The node provided is null."); |
| 415 return false; | 418 return false; |
| 416 } | 419 } |
| 417 | 420 if (!hasSameRoot(*refNode)) |
| 418 if (!refNode->inActiveDocument() || refNode->document() != expectedDocument) { | |
| 419 // Firefox doesn't throw an exception for these cases; it returns false. | |
| 420 return false; | |
| 421 } | |
| 422 | |
| 423 return true; | |
| 424 } | |
| 425 | |
| 426 bool Range::intersectsNode(Node* refNode, ExceptionState& exceptionState) { | |
| 427 // http://developer.mozilla.org/en/docs/DOM:range.intersectsNode | |
| 428 // Returns a bool if the node intersects the range. | |
| 429 if (!nodeValidForIntersects(refNode, m_ownerDocument.get(), exceptionState)) | |
| 430 return false; | 421 return false; |
| 431 | 422 |
| 432 ContainerNode* parentNode = refNode->parentNode(); | 423 ContainerNode* parentNode = refNode->parentNode(); |
| 433 if (!parentNode) | 424 if (!parentNode) |
| 434 return true; | 425 return true; |
| 435 | 426 |
| 436 int nodeIndex = refNode->nodeIndex(); | 427 int nodeIndex = refNode->nodeIndex(); |
| 437 | 428 |
| 438 if (comparePoint(parentNode, nodeIndex, exceptionState) < | 429 if (comparePoint(parentNode, nodeIndex, exceptionState) < |
| 439 0 // starts before start | 430 0 // starts before start |
| (...skipping 1287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1727 .data() | 1718 .data() |
| 1728 << "start offset: " << range->startOffset() | 1719 << "start offset: " << range->startOffset() |
| 1729 << ", end offset: " << range->endOffset(); | 1720 << ", end offset: " << range->endOffset(); |
| 1730 } else { | 1721 } else { |
| 1731 LOG(INFO) << "Cannot show tree if range is null, or if boundary points are " | 1722 LOG(INFO) << "Cannot show tree if range is null, or if boundary points are " |
| 1732 "invalid."; | 1723 "invalid."; |
| 1733 } | 1724 } |
| 1734 } | 1725 } |
| 1735 | 1726 |
| 1736 #endif | 1727 #endif |
| OLD | NEW |