Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: Source/core/dom/Range.cpp

Issue 23964014: Improve exception messages for detached Range objects. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebaseline. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/dom/Range.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/dom/Range.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698