| 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 r
ights reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ights reserved. |
| 7 * Copyright (C) 2011 Motorola Mobility. All rights reserved. | 7 * Copyright (C) 2011 Motorola Mobility. All rights reserved. |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 m_ownerDocument->detachRange(this); | 124 m_ownerDocument->detachRange(this); |
| 125 m_ownerDocument = &document; | 125 m_ownerDocument = &document; |
| 126 m_start.setToStartOfNode(&document); | 126 m_start.setToStartOfNode(&document); |
| 127 m_end.setToStartOfNode(&document); | 127 m_end.setToStartOfNode(&document); |
| 128 m_ownerDocument->attachRange(this); | 128 m_ownerDocument->attachRange(this); |
| 129 } | 129 } |
| 130 | 130 |
| 131 Node* Range::startContainer(ExceptionState& es) const | 131 Node* Range::startContainer(ExceptionState& es) const |
| 132 { | 132 { |
| 133 if (!m_start.container()) { | 133 if (!m_start.container()) { |
| 134 es.throwDOMException(InvalidStateError); | 134 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("startContainer", "Range", "The range has no container. Perhaps 'detatch()' h
as been invoked on this object?")); |
| 135 return 0; | 135 return 0; |
| 136 } | 136 } |
| 137 | 137 |
| 138 return m_start.container(); | 138 return m_start.container(); |
| 139 } | 139 } |
| 140 | 140 |
| 141 int Range::startOffset(ExceptionState& es) const | 141 int Range::startOffset(ExceptionState& es) const |
| 142 { | 142 { |
| 143 if (!m_start.container()) { | 143 if (!m_start.container()) { |
| 144 es.throwDOMException(InvalidStateError); | 144 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("startOffset", "Range", "The range has no container. Perhaps 'detatch()' has
been invoked on this object?")); |
| 145 return 0; | 145 return 0; |
| 146 } | 146 } |
| 147 | 147 |
| 148 return m_start.offset(); | 148 return m_start.offset(); |
| 149 } | 149 } |
| 150 | 150 |
| 151 Node* Range::endContainer(ExceptionState& es) const | 151 Node* Range::endContainer(ExceptionState& es) const |
| 152 { | 152 { |
| 153 if (!m_start.container()) { | 153 if (!m_start.container()) { |
| 154 es.throwDOMException(InvalidStateError); | 154 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("endContainer", "Range", "The range has no container. Perhaps 'detatch()' has
been invoked on this object?")); |
| 155 return 0; | 155 return 0; |
| 156 } | 156 } |
| 157 | 157 |
| 158 return m_end.container(); | 158 return m_end.container(); |
| 159 } | 159 } |
| 160 | 160 |
| 161 int Range::endOffset(ExceptionState& es) const | 161 int Range::endOffset(ExceptionState& es) const |
| 162 { | 162 { |
| 163 if (!m_start.container()) { | 163 if (!m_start.container()) { |
| 164 es.throwDOMException(InvalidStateError); | 164 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("endOffset", "Range", "The range has no container. Perhaps 'detatch()' has be
en invoked on this object?")); |
| 165 return 0; | 165 return 0; |
| 166 } | 166 } |
| 167 | 167 |
| 168 return m_end.offset(); | 168 return m_end.offset(); |
| 169 } | 169 } |
| 170 | 170 |
| 171 Node* Range::commonAncestorContainer(ExceptionState& es) const | 171 Node* Range::commonAncestorContainer(ExceptionState& es) const |
| 172 { | 172 { |
| 173 if (!m_start.container()) { | 173 if (!m_start.container()) { |
| 174 es.throwDOMException(InvalidStateError); | 174 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("commonAncestorContainer", "Range", "The range has no container. Perhaps 'det
atch()' has been invoked on this object?")); |
| 175 return 0; | 175 return 0; |
| 176 } | 176 } |
| 177 | 177 |
| 178 return commonAncestorContainer(m_start.container(), m_end.container()); | 178 return commonAncestorContainer(m_start.container(), m_end.container()); |
| 179 } | 179 } |
| 180 | 180 |
| 181 Node* Range::commonAncestorContainer(Node* containerA, Node* containerB) | 181 Node* Range::commonAncestorContainer(Node* containerA, Node* containerB) |
| 182 { | 182 { |
| 183 for (Node* parentA = containerA; parentA; parentA = parentA->parentNode()) { | 183 for (Node* parentA = containerA; parentA; parentA = parentA->parentNode()) { |
| 184 for (Node* parentB = containerB; parentB; parentB = parentB->parentNode(
)) { | 184 for (Node* parentB = containerB; parentB; parentB = parentB->parentNode(
)) { |
| 185 if (parentA == parentB) | 185 if (parentA == parentB) |
| 186 return parentA; | 186 return parentA; |
| 187 } | 187 } |
| 188 } | 188 } |
| 189 return 0; | 189 return 0; |
| 190 } | 190 } |
| 191 | 191 |
| 192 bool Range::collapsed(ExceptionState& es) const | 192 bool Range::collapsed(ExceptionState& es) const |
| 193 { | 193 { |
| 194 if (!m_start.container()) { | 194 if (!m_start.container()) { |
| 195 es.throwDOMException(InvalidStateError); | 195 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("collapsed", "Range", "The range has no container. Perhaps 'detatch()' has be
en invoked on this object?")); |
| 196 return 0; | 196 return 0; |
| 197 } | 197 } |
| 198 | 198 |
| 199 return m_start == m_end; | 199 return m_start == m_end; |
| 200 } | 200 } |
| 201 | 201 |
| 202 static inline bool checkForDifferentRootContainer(const RangeBoundaryPoint& star
t, const RangeBoundaryPoint& end) | 202 static inline bool checkForDifferentRootContainer(const RangeBoundaryPoint& star
t, const RangeBoundaryPoint& end) |
| 203 { | 203 { |
| 204 Node* endRootContainer = end.container(); | 204 Node* endRootContainer = end.container(); |
| 205 while (endRootContainer->parentNode()) | 205 while (endRootContainer->parentNode()) |
| 206 endRootContainer = endRootContainer->parentNode(); | 206 endRootContainer = endRootContainer->parentNode(); |
| 207 Node* startRootContainer = start.container(); | 207 Node* startRootContainer = start.container(); |
| 208 while (startRootContainer->parentNode()) | 208 while (startRootContainer->parentNode()) |
| 209 startRootContainer = startRootContainer->parentNode(); | 209 startRootContainer = startRootContainer->parentNode(); |
| 210 | 210 |
| 211 return startRootContainer != endRootContainer || (Range::compareBoundaryPoin
ts(start, end, ASSERT_NO_EXCEPTION) > 0); | 211 return startRootContainer != endRootContainer || (Range::compareBoundaryPoin
ts(start, end, ASSERT_NO_EXCEPTION) > 0); |
| 212 } | 212 } |
| 213 | 213 |
| 214 void Range::setStart(PassRefPtr<Node> refNode, int offset, ExceptionState& es) | 214 void Range::setStart(PassRefPtr<Node> refNode, int offset, ExceptionState& es) |
| 215 { | 215 { |
| 216 if (!m_start.container()) { | 216 if (!m_start.container()) { |
| 217 es.throwDOMException(InvalidStateError); | 217 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("setStart", "Range", "The range has no container. Perhaps 'detatch()' has bee
n invoked on this object?")); |
| 218 return; | 218 return; |
| 219 } | 219 } |
| 220 | 220 |
| 221 if (!refNode) { | 221 if (!refNode) { |
| 222 es.throwDOMException(NotFoundError); | 222 es.throwDOMException(NotFoundError); |
| 223 return; | 223 return; |
| 224 } | 224 } |
| 225 | 225 |
| 226 bool didMoveDocument = false; | 226 bool didMoveDocument = false; |
| 227 if (&refNode->document() != m_ownerDocument) { | 227 if (&refNode->document() != m_ownerDocument) { |
| 228 setDocument(refNode->document()); | 228 setDocument(refNode->document()); |
| 229 didMoveDocument = true; | 229 didMoveDocument = true; |
| 230 } | 230 } |
| 231 | 231 |
| 232 Node* childNode = checkNodeWOffset(refNode.get(), offset, es); | 232 Node* childNode = checkNodeWOffset(refNode.get(), offset, es); |
| 233 if (es.hadException()) | 233 if (es.hadException()) |
| 234 return; | 234 return; |
| 235 | 235 |
| 236 m_start.set(refNode, offset, childNode); | 236 m_start.set(refNode, offset, childNode); |
| 237 | 237 |
| 238 if (didMoveDocument || checkForDifferentRootContainer(m_start, m_end)) | 238 if (didMoveDocument || checkForDifferentRootContainer(m_start, m_end)) |
| 239 collapse(true, es); | 239 collapse(true, es); |
| 240 } | 240 } |
| 241 | 241 |
| 242 void Range::setEnd(PassRefPtr<Node> refNode, int offset, ExceptionState& es) | 242 void Range::setEnd(PassRefPtr<Node> refNode, int offset, ExceptionState& es) |
| 243 { | 243 { |
| 244 if (!m_start.container()) { | 244 if (!m_start.container()) { |
| 245 es.throwDOMException(InvalidStateError); | 245 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("setEnd", "Range", "The range has no container. Perhaps 'detatch()' has been
invoked on this object?")); |
| 246 return; | 246 return; |
| 247 } | 247 } |
| 248 | 248 |
| 249 if (!refNode) { | 249 if (!refNode) { |
| 250 es.throwDOMException(NotFoundError); | 250 es.throwDOMException(NotFoundError); |
| 251 return; | 251 return; |
| 252 } | 252 } |
| 253 | 253 |
| 254 bool didMoveDocument = false; | 254 bool didMoveDocument = false; |
| 255 if (&refNode->document() != m_ownerDocument) { | 255 if (&refNode->document() != m_ownerDocument) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 275 | 275 |
| 276 void Range::setEnd(const Position& end, ExceptionState& es) | 276 void Range::setEnd(const Position& end, ExceptionState& es) |
| 277 { | 277 { |
| 278 Position parentAnchored = end.parentAnchoredEquivalent(); | 278 Position parentAnchored = end.parentAnchoredEquivalent(); |
| 279 setEnd(parentAnchored.containerNode(), parentAnchored.offsetInContainerNode(
), es); | 279 setEnd(parentAnchored.containerNode(), parentAnchored.offsetInContainerNode(
), es); |
| 280 } | 280 } |
| 281 | 281 |
| 282 void Range::collapse(bool toStart, ExceptionState& es) | 282 void Range::collapse(bool toStart, ExceptionState& es) |
| 283 { | 283 { |
| 284 if (!m_start.container()) { | 284 if (!m_start.container()) { |
| 285 es.throwDOMException(InvalidStateError); | 285 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("collapse", "Range", "The range has no container. Perhaps 'detatch()' has bee
n invoked on this object?")); |
| 286 return; | 286 return; |
| 287 } | 287 } |
| 288 | 288 |
| 289 if (toStart) | 289 if (toStart) |
| 290 m_end = m_start; | 290 m_end = m_start; |
| 291 else | 291 else |
| 292 m_start = m_end; | 292 m_start = m_end; |
| 293 } | 293 } |
| 294 | 294 |
| 295 bool Range::isPointInRange(Node* refNode, int offset, ExceptionState& es) | 295 bool Range::isPointInRange(Node* refNode, int offset, ExceptionState& es) |
| 296 { | 296 { |
| 297 if (!m_start.container()) { | 297 if (!m_start.container()) { |
| 298 es.throwDOMException(InvalidStateError); | 298 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("isPointInRange", "Range", "The range has no container. Perhaps 'detatch()' h
as been invoked on this object?")); |
| 299 return false; | 299 return false; |
| 300 } | 300 } |
| 301 | 301 |
| 302 if (!refNode) { | 302 if (!refNode) { |
| 303 es.throwDOMException(HierarchyRequestError); | 303 es.throwDOMException(HierarchyRequestError); |
| 304 return false; | 304 return false; |
| 305 } | 305 } |
| 306 | 306 |
| 307 if (!refNode->attached() || &refNode->document() != m_ownerDocument) { | 307 if (!refNode->attached() || &refNode->document() != m_ownerDocument) { |
| 308 return false; | 308 return false; |
| 309 } | 309 } |
| 310 | 310 |
| 311 checkNodeWOffset(refNode, offset, es); | 311 checkNodeWOffset(refNode, offset, es); |
| 312 if (es.hadException()) | 312 if (es.hadException()) |
| 313 return false; | 313 return false; |
| 314 | 314 |
| 315 return compareBoundaryPoints(refNode, offset, m_start.container(), m_start.o
ffset(), es) >= 0 && !es.hadException() | 315 return compareBoundaryPoints(refNode, offset, m_start.container(), m_start.o
ffset(), es) >= 0 && !es.hadException() |
| 316 && compareBoundaryPoints(refNode, offset, m_end.container(), m_end.offse
t(), es) <= 0 && !es.hadException(); | 316 && compareBoundaryPoints(refNode, offset, m_end.container(), m_end.offse
t(), es) <= 0 && !es.hadException(); |
| 317 } | 317 } |
| 318 | 318 |
| 319 short Range::comparePoint(Node* refNode, int offset, ExceptionState& es) const | 319 short Range::comparePoint(Node* refNode, int offset, ExceptionState& es) const |
| 320 { | 320 { |
| 321 // http://developer.mozilla.org/en/docs/DOM:range.comparePoint | 321 // http://developer.mozilla.org/en/docs/DOM:range.comparePoint |
| 322 // This method returns -1, 0 or 1 depending on if the point described by the | 322 // This method returns -1, 0 or 1 depending on if the point described by the |
| 323 // refNode node and an offset within the node is before, same as, or after t
he range respectively. | 323 // refNode node and an offset within the node is before, same as, or after t
he range respectively. |
| 324 | 324 |
| 325 if (!m_start.container()) { | 325 if (!m_start.container()) { |
| 326 es.throwDOMException(InvalidStateError); | 326 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("comparePoint", "Range", "The range has no container. Perhaps 'detatch()' has
been invoked on this object?")); |
| 327 return 0; | 327 return 0; |
| 328 } | 328 } |
| 329 | 329 |
| 330 if (!refNode) { | 330 if (!refNode) { |
| 331 es.throwDOMException(HierarchyRequestError); | 331 es.throwDOMException(HierarchyRequestError); |
| 332 return 0; | 332 return 0; |
| 333 } | 333 } |
| 334 | 334 |
| 335 if (!refNode->attached() || &refNode->document() != m_ownerDocument) { | 335 if (!refNode->attached() || &refNode->document() != m_ownerDocument) { |
| 336 es.throwDOMException(WrongDocumentError); | 336 es.throwDOMException(WrongDocumentError); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 } | 399 } |
| 400 // starts at or after the range start | 400 // starts at or after the range start |
| 401 if (comparePoint(parentNode, nodeIndex + 1, es) > 0) // ends after the range | 401 if (comparePoint(parentNode, nodeIndex + 1, es) > 0) // ends after the range |
| 402 return NODE_AFTER; | 402 return NODE_AFTER; |
| 403 return NODE_INSIDE; // ends inside the range | 403 return NODE_INSIDE; // ends inside the range |
| 404 } | 404 } |
| 405 | 405 |
| 406 short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, Exc
eptionState& es) const | 406 short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, Exc
eptionState& es) const |
| 407 { | 407 { |
| 408 if (!m_start.container()) { | 408 if (!m_start.container()) { |
| 409 es.throwDOMException(InvalidStateError); | 409 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("compareBoundaryPoints", "Range", "The range has no container. Perhaps 'detat
ch()' has been invoked on this object?")); |
| 410 return 0; | 410 return 0; |
| 411 } | 411 } |
| 412 | 412 |
| 413 if (!sourceRange) { | 413 if (!sourceRange) { |
| 414 es.throwDOMException(NotFoundError); | 414 es.throwDOMException(NotFoundError); |
| 415 return 0; | 415 return 0; |
| 416 } | 416 } |
| 417 | 417 |
| 418 Node* thisCont = commonAncestorContainer(es); | 418 Node* thisCont = commonAncestorContainer(es); |
| 419 if (es.hadException()) | 419 if (es.hadException()) |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 } | 552 } |
| 553 | 553 |
| 554 bool Range::boundaryPointsValid() const | 554 bool Range::boundaryPointsValid() const |
| 555 { | 555 { |
| 556 TrackExceptionState es; | 556 TrackExceptionState es; |
| 557 return m_start.container() && compareBoundaryPoints(m_start, m_end, es) <= 0
&& !es.hadException(); | 557 return m_start.container() && compareBoundaryPoints(m_start, m_end, es) <= 0
&& !es.hadException(); |
| 558 } | 558 } |
| 559 | 559 |
| 560 void Range::deleteContents(ExceptionState& es) | 560 void Range::deleteContents(ExceptionState& es) |
| 561 { | 561 { |
| 562 checkDeleteExtract(es); | 562 checkDeleteExtract("deleteContents", es); |
| 563 if (es.hadException()) | 563 if (es.hadException()) |
| 564 return; | 564 return; |
| 565 | 565 |
| 566 processContents(DELETE_CONTENTS, es); | 566 processContents(DELETE_CONTENTS, es); |
| 567 } | 567 } |
| 568 | 568 |
| 569 bool Range::intersectsNode(Node* refNode, ExceptionState& es) | 569 bool Range::intersectsNode(Node* refNode, ExceptionState& es) |
| 570 { | 570 { |
| 571 // http://developer.mozilla.org/en/docs/DOM:range.intersectsNode | 571 // http://developer.mozilla.org/en/docs/DOM:range.intersectsNode |
| 572 // Returns a bool if the node intersects the range. | 572 // Returns a bool if the node intersects the range. |
| 573 | 573 |
| 574 // Throw exception if the range is already detached. | 574 // Throw exception if the range is already detached. |
| 575 if (!m_start.container()) { | 575 if (!m_start.container()) { |
| 576 es.throwDOMException(InvalidStateError); | 576 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("intersectsNode", "Range", "The range has no container. Perhaps 'detatch()' h
as been invoked on this object?")); |
| 577 return false; | 577 return false; |
| 578 } | 578 } |
| 579 if (!refNode) { | 579 if (!refNode) { |
| 580 es.throwDOMException(NotFoundError); | 580 es.throwDOMException(NotFoundError); |
| 581 return false; | 581 return false; |
| 582 } | 582 } |
| 583 | 583 |
| 584 if (!refNode->attached() || &refNode->document() != m_ownerDocument) { | 584 if (!refNode->attached() || &refNode->document() != m_ownerDocument) { |
| 585 // Firefox doesn't throw an exception for these cases; it returns false. | 585 // Firefox doesn't throw an exception for these cases; it returns false. |
| 586 return false; | 586 return false; |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 921 } | 921 } |
| 922 } | 922 } |
| 923 firstChildInAncestorToProcess = direction == ProcessContentsForward ? an
cestor->nextSibling() : ancestor->previousSibling(); | 923 firstChildInAncestorToProcess = direction == ProcessContentsForward ? an
cestor->nextSibling() : ancestor->previousSibling(); |
| 924 } | 924 } |
| 925 | 925 |
| 926 return clonedContainer.release(); | 926 return clonedContainer.release(); |
| 927 } | 927 } |
| 928 | 928 |
| 929 PassRefPtr<DocumentFragment> Range::extractContents(ExceptionState& es) | 929 PassRefPtr<DocumentFragment> Range::extractContents(ExceptionState& es) |
| 930 { | 930 { |
| 931 checkDeleteExtract(es); | 931 checkDeleteExtract("extractContents", es); |
| 932 if (es.hadException()) | 932 if (es.hadException()) |
| 933 return 0; | 933 return 0; |
| 934 | 934 |
| 935 return processContents(EXTRACT_CONTENTS, es); | 935 return processContents(EXTRACT_CONTENTS, es); |
| 936 } | 936 } |
| 937 | 937 |
| 938 PassRefPtr<DocumentFragment> Range::cloneContents(ExceptionState& es) | 938 PassRefPtr<DocumentFragment> Range::cloneContents(ExceptionState& es) |
| 939 { | 939 { |
| 940 if (!m_start.container()) { | 940 if (!m_start.container()) { |
| 941 es.throwDOMException(InvalidStateError); | 941 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("cloneContents", "Range", "The range has no container. Perhaps 'detatch()' ha
s been invoked on this object?")); |
| 942 return 0; | 942 return 0; |
| 943 } | 943 } |
| 944 | 944 |
| 945 return processContents(CLONE_CONTENTS, es); | 945 return processContents(CLONE_CONTENTS, es); |
| 946 } | 946 } |
| 947 | 947 |
| 948 void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& es) | 948 void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& es) |
| 949 { | 949 { |
| 950 RefPtr<Node> newNode = prpNewNode; | 950 RefPtr<Node> newNode = prpNewNode; |
| 951 | 951 |
| 952 if (!m_start.container()) { | 952 if (!m_start.container()) { |
| 953 es.throwDOMException(InvalidStateError); | 953 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("insertNode", "Range", "The range has no container. Perhaps 'detatch()' has b
een invoked on this object?")); |
| 954 return; | 954 return; |
| 955 } | 955 } |
| 956 | 956 |
| 957 if (!newNode) { | 957 if (!newNode) { |
| 958 es.throwDOMException(NotFoundError); | 958 es.throwDOMException(NotFoundError); |
| 959 return; | 959 return; |
| 960 } | 960 } |
| 961 | 961 |
| 962 // HierarchyRequestError: Raised if the container of the start of the Range
is of a type that | 962 // HierarchyRequestError: Raised if the container of the start of the Range
is of a type that |
| 963 // does not allow children of the type of newNode or if newNode is an ancest
or of the container. | 963 // does not allow children of the type of newNode or if newNode is an ancest
or of the container. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1048 return; | 1048 return; |
| 1049 | 1049 |
| 1050 if (collapsed && numNewChildren) | 1050 if (collapsed && numNewChildren) |
| 1051 m_end.set(m_start.container(), startOffset + numNewChildren, lastChi
ld.get()); | 1051 m_end.set(m_start.container(), startOffset + numNewChildren, lastChi
ld.get()); |
| 1052 } | 1052 } |
| 1053 } | 1053 } |
| 1054 | 1054 |
| 1055 String Range::toString(ExceptionState& es) const | 1055 String Range::toString(ExceptionState& es) const |
| 1056 { | 1056 { |
| 1057 if (!m_start.container()) { | 1057 if (!m_start.container()) { |
| 1058 es.throwDOMException(InvalidStateError); | 1058 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("toString", "Range", "The range has no container. Perhaps 'detatch()' has bee
n invoked on this object?")); |
| 1059 return String(); | 1059 return String(); |
| 1060 } | 1060 } |
| 1061 | 1061 |
| 1062 StringBuilder builder; | 1062 StringBuilder builder; |
| 1063 | 1063 |
| 1064 Node* pastLast = pastLastNode(); | 1064 Node* pastLast = pastLastNode(); |
| 1065 for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(n)) { | 1065 for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(n)) { |
| 1066 if (n->nodeType() == Node::TEXT_NODE || n->nodeType() == Node::CDATA_SEC
TION_NODE) { | 1066 if (n->nodeType() == Node::TEXT_NODE || n->nodeType() == Node::CDATA_SEC
TION_NODE) { |
| 1067 String data = toCharacterData(n)->data(); | 1067 String data = toCharacterData(n)->data(); |
| 1068 int length = data.length(); | 1068 int length = data.length(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1088 // We need to update layout, since plainText uses line boxes in the render t
ree. | 1088 // We need to update layout, since plainText uses line boxes in the render t
ree. |
| 1089 // FIXME: As with innerText, we'd like this to work even if there are no ren
der objects. | 1089 // FIXME: As with innerText, we'd like this to work even if there are no ren
der objects. |
| 1090 m_start.container()->document().updateLayout(); | 1090 m_start.container()->document().updateLayout(); |
| 1091 | 1091 |
| 1092 return plainText(this); | 1092 return plainText(this); |
| 1093 } | 1093 } |
| 1094 | 1094 |
| 1095 PassRefPtr<DocumentFragment> Range::createContextualFragment(const String& marku
p, ExceptionState& es) | 1095 PassRefPtr<DocumentFragment> Range::createContextualFragment(const String& marku
p, ExceptionState& es) |
| 1096 { | 1096 { |
| 1097 if (!m_start.container()) { | 1097 if (!m_start.container()) { |
| 1098 es.throwDOMException(InvalidStateError); | 1098 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("createContextualFragment", "Range", "The range has no container. Perhaps 'de
tatch()' has been invoked on this object?")); |
| 1099 return 0; | 1099 return 0; |
| 1100 } | 1100 } |
| 1101 | 1101 |
| 1102 Node* element = m_start.container()->isElementNode() ? m_start.container() :
m_start.container()->parentNode(); | 1102 Node* element = m_start.container()->isElementNode() ? m_start.container() :
m_start.container()->parentNode(); |
| 1103 if (!element || !element->isHTMLElement()) { | 1103 if (!element || !element->isHTMLElement()) { |
| 1104 es.throwDOMException(NotSupportedError); | 1104 es.throwDOMException(NotSupportedError); |
| 1105 return 0; | 1105 return 0; |
| 1106 } | 1106 } |
| 1107 | 1107 |
| 1108 RefPtr<DocumentFragment> fragment = WebCore::createContextualFragment(markup
, toHTMLElement(element), AllowScriptingContentAndDoNotMarkAlreadyStarted, es); | 1108 RefPtr<DocumentFragment> fragment = WebCore::createContextualFragment(markup
, toHTMLElement(element), AllowScriptingContentAndDoNotMarkAlreadyStarted, es); |
| 1109 if (!fragment) | 1109 if (!fragment) |
| 1110 return 0; | 1110 return 0; |
| 1111 | 1111 |
| 1112 return fragment.release(); | 1112 return fragment.release(); |
| 1113 } | 1113 } |
| 1114 | 1114 |
| 1115 | 1115 |
| 1116 void Range::detach(ExceptionState& es) | 1116 void Range::detach(ExceptionState& es) |
| 1117 { | 1117 { |
| 1118 // Check first to see if we've already detached: | 1118 // Check first to see if we've already detached: |
| 1119 if (!m_start.container()) { | 1119 if (!m_start.container()) { |
| 1120 es.throwDOMException(InvalidStateError); | 1120 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("detach", "Range", "The range has no container. Perhaps 'detatch()' has been
invoked on this object?")); |
| 1121 return; | 1121 return; |
| 1122 } | 1122 } |
| 1123 | 1123 |
| 1124 m_ownerDocument->detachRange(this); | 1124 m_ownerDocument->detachRange(this); |
| 1125 | 1125 |
| 1126 m_start.clear(); | 1126 m_start.clear(); |
| 1127 m_end.clear(); | 1127 m_end.clear(); |
| 1128 } | 1128 } |
| 1129 | 1129 |
| 1130 Node* Range::checkNodeWOffset(Node* n, int offset, ExceptionState& es) const | 1130 Node* Range::checkNodeWOffset(Node* n, int offset, ExceptionState& es) const |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1155 Node* childBefore = n->childNode(offset - 1); | 1155 Node* childBefore = n->childNode(offset - 1); |
| 1156 if (!childBefore) | 1156 if (!childBefore) |
| 1157 es.throwDOMException(IndexSizeError); | 1157 es.throwDOMException(IndexSizeError); |
| 1158 return childBefore; | 1158 return childBefore; |
| 1159 } | 1159 } |
| 1160 } | 1160 } |
| 1161 ASSERT_NOT_REACHED(); | 1161 ASSERT_NOT_REACHED(); |
| 1162 return 0; | 1162 return 0; |
| 1163 } | 1163 } |
| 1164 | 1164 |
| 1165 void Range::checkNodeBA(Node* n, ExceptionState& es, const char* methodName) con
st | 1165 void Range::checkNodeBA(Node* n, const String& methodName, ExceptionState& es) c
onst |
| 1166 { | 1166 { |
| 1167 if (!m_start.container()) { | 1167 if (!m_start.container()) { |
| 1168 es.throwDOMException(InvalidStateError); | 1168 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te(methodName, "Range", "The range has no container. Perhaps 'detatch()' has bee
n invoked on this object?")); |
| 1169 return; | 1169 return; |
| 1170 } | 1170 } |
| 1171 | 1171 |
| 1172 if (!n) { | 1172 if (!n) { |
| 1173 es.throwDOMException(NotFoundError); | 1173 es.throwDOMException(NotFoundError); |
| 1174 return; | 1174 return; |
| 1175 } | 1175 } |
| 1176 | 1176 |
| 1177 // InvalidNodeTypeError: Raised if the root container of refNode is not an | 1177 // InvalidNodeTypeError: Raised if the root container of refNode is not an |
| 1178 // Attr, Document, DocumentFragment or ShadowRoot node, or part of a SVG sha
dow DOM tree, | 1178 // Attr, Document, DocumentFragment or ShadowRoot node, or part of a SVG sha
dow DOM tree, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1220 case Node::TEXT_NODE: | 1220 case Node::TEXT_NODE: |
| 1221 case Node::XPATH_NAMESPACE_NODE: | 1221 case Node::XPATH_NAMESPACE_NODE: |
| 1222 es.throwDOMException(InvalidNodeTypeError); | 1222 es.throwDOMException(InvalidNodeTypeError); |
| 1223 return; | 1223 return; |
| 1224 } | 1224 } |
| 1225 } | 1225 } |
| 1226 | 1226 |
| 1227 PassRefPtr<Range> Range::cloneRange(ExceptionState& es) const | 1227 PassRefPtr<Range> Range::cloneRange(ExceptionState& es) const |
| 1228 { | 1228 { |
| 1229 if (!m_start.container()) { | 1229 if (!m_start.container()) { |
| 1230 es.throwDOMException(InvalidStateError); | 1230 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("cloneRange", "Range", "The range has no container. Perhaps 'detatch()' has b
een invoked on this object?")); |
| 1231 return 0; | 1231 return 0; |
| 1232 } | 1232 } |
| 1233 | 1233 |
| 1234 return Range::create(*m_ownerDocument.get(), m_start.container(), m_start.of
fset(), m_end.container(), m_end.offset()); | 1234 return Range::create(*m_ownerDocument.get(), m_start.container(), m_start.of
fset(), m_end.container(), m_end.offset()); |
| 1235 } | 1235 } |
| 1236 | 1236 |
| 1237 void Range::setStartAfter(Node* refNode, ExceptionState& es) | 1237 void Range::setStartAfter(Node* refNode, ExceptionState& es) |
| 1238 { | 1238 { |
| 1239 checkNodeBA(refNode, es, "setStartAfter"); | 1239 checkNodeBA(refNode, "setStartAfter", es); |
| 1240 if (es.hadException()) | 1240 if (es.hadException()) |
| 1241 return; | 1241 return; |
| 1242 | 1242 |
| 1243 setStart(refNode->parentNode(), refNode->nodeIndex() + 1, es); | 1243 setStart(refNode->parentNode(), refNode->nodeIndex() + 1, es); |
| 1244 } | 1244 } |
| 1245 | 1245 |
| 1246 void Range::setEndBefore(Node* refNode, ExceptionState& es) | 1246 void Range::setEndBefore(Node* refNode, ExceptionState& es) |
| 1247 { | 1247 { |
| 1248 checkNodeBA(refNode, es, "setEndBefore"); | 1248 checkNodeBA(refNode, "setEndBefore", es); |
| 1249 if (es.hadException()) | 1249 if (es.hadException()) |
| 1250 return; | 1250 return; |
| 1251 | 1251 |
| 1252 setEnd(refNode->parentNode(), refNode->nodeIndex(), es); | 1252 setEnd(refNode->parentNode(), refNode->nodeIndex(), es); |
| 1253 } | 1253 } |
| 1254 | 1254 |
| 1255 void Range::setEndAfter(Node* refNode, ExceptionState& es) | 1255 void Range::setEndAfter(Node* refNode, ExceptionState& es) |
| 1256 { | 1256 { |
| 1257 checkNodeBA(refNode, es, "setEndAfter"); | 1257 checkNodeBA(refNode, "setEndAfter", es); |
| 1258 if (es.hadException()) | 1258 if (es.hadException()) |
| 1259 return; | 1259 return; |
| 1260 | 1260 |
| 1261 setEnd(refNode->parentNode(), refNode->nodeIndex() + 1, es); | 1261 setEnd(refNode->parentNode(), refNode->nodeIndex() + 1, es); |
| 1262 } | 1262 } |
| 1263 | 1263 |
| 1264 void Range::selectNode(Node* refNode, ExceptionState& es) | 1264 void Range::selectNode(Node* refNode, ExceptionState& es) |
| 1265 { | 1265 { |
| 1266 if (!m_start.container()) { | 1266 if (!m_start.container()) { |
| 1267 es.throwDOMException(InvalidStateError); | 1267 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("selectNode", "Range", "The range has no container. Perhaps 'detatch()' has b
een invoked on this object?")); |
| 1268 return; | 1268 return; |
| 1269 } | 1269 } |
| 1270 | 1270 |
| 1271 if (!refNode) { | 1271 if (!refNode) { |
| 1272 es.throwDOMException(NotFoundError); | 1272 es.throwDOMException(NotFoundError); |
| 1273 return; | 1273 return; |
| 1274 } | 1274 } |
| 1275 | 1275 |
| 1276 if (!refNode->parentNode()) { | 1276 if (!refNode->parentNode()) { |
| 1277 es.throwDOMException(InvalidNodeTypeError, ExceptionMessages::failedToEx
ecute("selectNode", "Range", "the given Node has no parent.")); | 1277 es.throwDOMException(InvalidNodeTypeError, ExceptionMessages::failedToEx
ecute("selectNode", "Range", "the given Node has no parent.")); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1322 if (m_ownerDocument != &refNode->document()) | 1322 if (m_ownerDocument != &refNode->document()) |
| 1323 setDocument(refNode->document()); | 1323 setDocument(refNode->document()); |
| 1324 | 1324 |
| 1325 setStartBefore(refNode); | 1325 setStartBefore(refNode); |
| 1326 setEndAfter(refNode); | 1326 setEndAfter(refNode); |
| 1327 } | 1327 } |
| 1328 | 1328 |
| 1329 void Range::selectNodeContents(Node* refNode, ExceptionState& es) | 1329 void Range::selectNodeContents(Node* refNode, ExceptionState& es) |
| 1330 { | 1330 { |
| 1331 if (!m_start.container()) { | 1331 if (!m_start.container()) { |
| 1332 es.throwDOMException(InvalidStateError); | 1332 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("selectNodeContents", "Range", "The range has no container. Perhaps 'detatch(
)' has been invoked on this object?")); |
| 1333 return; | 1333 return; |
| 1334 } | 1334 } |
| 1335 | 1335 |
| 1336 if (!refNode) { | 1336 if (!refNode) { |
| 1337 es.throwDOMException(NotFoundError); | 1337 es.throwDOMException(NotFoundError); |
| 1338 return; | 1338 return; |
| 1339 } | 1339 } |
| 1340 | 1340 |
| 1341 // InvalidNodeTypeError: Raised if refNode or an ancestor of refNode is an E
ntity, Notation | 1341 // InvalidNodeTypeError: Raised if refNode or an ancestor of refNode is an E
ntity, Notation |
| 1342 // or DocumentType node. | 1342 // or DocumentType node. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1365 | 1365 |
| 1366 m_start.setToStartOfNode(refNode); | 1366 m_start.setToStartOfNode(refNode); |
| 1367 m_end.setToEndOfNode(refNode); | 1367 m_end.setToEndOfNode(refNode); |
| 1368 } | 1368 } |
| 1369 | 1369 |
| 1370 void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& es) | 1370 void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& es) |
| 1371 { | 1371 { |
| 1372 RefPtr<Node> newParent = passNewParent; | 1372 RefPtr<Node> newParent = passNewParent; |
| 1373 | 1373 |
| 1374 if (!m_start.container()) { | 1374 if (!m_start.container()) { |
| 1375 es.throwDOMException(InvalidStateError); | 1375 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te("surroundContents", "Range", "The range has no container. Perhaps 'detatch()'
has been invoked on this object?")); |
| 1376 return; | 1376 return; |
| 1377 } | 1377 } |
| 1378 | 1378 |
| 1379 if (!newParent) { | 1379 if (!newParent) { |
| 1380 es.throwDOMException(NotFoundError); | 1380 es.throwDOMException(NotFoundError); |
| 1381 return; | 1381 return; |
| 1382 } | 1382 } |
| 1383 | 1383 |
| 1384 // InvalidNodeTypeError: Raised if node is an Attr, Entity, DocumentType, No
tation, | 1384 // InvalidNodeTypeError: Raised if node is an Attr, Entity, DocumentType, No
tation, |
| 1385 // Document, or DocumentFragment node. | 1385 // Document, or DocumentFragment node. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1446 if (es.hadException()) | 1446 if (es.hadException()) |
| 1447 return; | 1447 return; |
| 1448 newParent->appendChild(fragment.release(), es); | 1448 newParent->appendChild(fragment.release(), es); |
| 1449 if (es.hadException()) | 1449 if (es.hadException()) |
| 1450 return; | 1450 return; |
| 1451 selectNode(newParent.get(), es); | 1451 selectNode(newParent.get(), es); |
| 1452 } | 1452 } |
| 1453 | 1453 |
| 1454 void Range::setStartBefore(Node* refNode, ExceptionState& es) | 1454 void Range::setStartBefore(Node* refNode, ExceptionState& es) |
| 1455 { | 1455 { |
| 1456 checkNodeBA(refNode, es, "setStartBefore"); | 1456 checkNodeBA(refNode, "setStartBefore", es); |
| 1457 if (es.hadException()) | 1457 if (es.hadException()) |
| 1458 return; | 1458 return; |
| 1459 | 1459 |
| 1460 setStart(refNode->parentNode(), refNode->nodeIndex(), es); | 1460 setStart(refNode->parentNode(), refNode->nodeIndex(), es); |
| 1461 } | 1461 } |
| 1462 | 1462 |
| 1463 void Range::checkDeleteExtract(ExceptionState& es) | 1463 void Range::checkDeleteExtract(const String& methodName, ExceptionState& es) |
| 1464 { | 1464 { |
| 1465 if (!m_start.container()) { | 1465 if (!m_start.container()) { |
| 1466 es.throwDOMException(InvalidStateError); | 1466 es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecu
te(methodName, "Range", "The range has no container. Perhaps 'detatch()' has bee
n invoked on this object?")); |
| 1467 return; | 1467 return; |
| 1468 } | 1468 } |
| 1469 | 1469 |
| 1470 if (!commonAncestorContainer(es) || es.hadException()) | 1470 if (!commonAncestorContainer(es) || es.hadException()) |
| 1471 return; | 1471 return; |
| 1472 | 1472 |
| 1473 Node* pastLast = pastLastNode(); | 1473 Node* pastLast = pastLastNode(); |
| 1474 for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(n)) { | 1474 for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(n)) { |
| 1475 if (n->nodeType() == Node::DOCUMENT_TYPE_NODE) { | 1475 if (n->nodeType() == Node::DOCUMENT_TYPE_NODE) { |
| 1476 es.throwDOMException(HierarchyRequestError); | 1476 es.throwDOMException(HierarchyRequestError); |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 | 1901 |
| 1902 void showTree(const WebCore::Range* range) | 1902 void showTree(const WebCore::Range* range) |
| 1903 { | 1903 { |
| 1904 if (range && range->boundaryPointsValid()) { | 1904 if (range && range->boundaryPointsValid()) { |
| 1905 range->startContainer()->showTreeAndMark(range->startContainer(), "S", r
ange->endContainer(), "E"); | 1905 range->startContainer()->showTreeAndMark(range->startContainer(), "S", r
ange->endContainer(), "E"); |
| 1906 fprintf(stderr, "start offset: %d, end offset: %d\n", range->startOffset
(), range->endOffset()); | 1906 fprintf(stderr, "start offset: %d, end offset: %d\n", range->startOffset
(), range->endOffset()); |
| 1907 } | 1907 } |
| 1908 } | 1908 } |
| 1909 | 1909 |
| 1910 #endif | 1910 #endif |
| OLD | NEW |