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

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

Issue 23404003: Make Range methods to work with detached node (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: 2013-08-27T11:16:22 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
11 * License as published by the Free Software Foundation; either 11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version. 12 * version 2 of the License, or (at your option) any later version.
13 * 13 *
14 * This library is distributed in the hope that it will be useful, 14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details. 17 * Library General Public License for more details.
18 * 18 *
19 * You should have received a copy of the GNU Library General Public License 19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to 20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA. 22 * Boston, MA 02110-1301, USA.
23 */ 23 */
24 24
25 #include "config.h" 25 #include "config.h"
26 #include "core/dom/Range.h" 26 #include "core/dom/Range.h"
27 27
28 #include "bindings/v8/ExceptionMessages.h"
28 #include "bindings/v8/ExceptionState.h" 29 #include "bindings/v8/ExceptionState.h"
29 #include "bindings/v8/ExceptionStatePlaceholder.h" 30 #include "bindings/v8/ExceptionStatePlaceholder.h"
30 #include "core/dom/ClientRect.h" 31 #include "core/dom/ClientRect.h"
31 #include "core/dom/ClientRectList.h" 32 #include "core/dom/ClientRectList.h"
32 #include "core/dom/DocumentFragment.h" 33 #include "core/dom/DocumentFragment.h"
33 #include "core/dom/ExceptionCode.h" 34 #include "core/dom/ExceptionCode.h"
34 #include "core/dom/Node.h" 35 #include "core/dom/Node.h"
35 #include "core/dom/NodeTraversal.h" 36 #include "core/dom/NodeTraversal.h"
36 #include "core/dom/NodeWithIndex.h" 37 #include "core/dom/NodeWithIndex.h"
37 #include "core/dom/ProcessingInstruction.h" 38 #include "core/dom/ProcessingInstruction.h"
(...skipping 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 Node* childBefore = n->childNode(offset - 1); 1153 Node* childBefore = n->childNode(offset - 1);
1153 if (!childBefore) 1154 if (!childBefore)
1154 es.throwDOMException(IndexSizeError); 1155 es.throwDOMException(IndexSizeError);
1155 return childBefore; 1156 return childBefore;
1156 } 1157 }
1157 } 1158 }
1158 ASSERT_NOT_REACHED(); 1159 ASSERT_NOT_REACHED();
1159 return 0; 1160 return 0;
1160 } 1161 }
1161 1162
1162 void Range::checkNodeBA(Node* n, ExceptionState& es) const 1163 void Range::checkNodeBA(Node* n, ExceptionState& es, const char* methodName) con st
1163 { 1164 {
1165 if (!m_start.container()) {
1166 es.throwDOMException(InvalidStateError);
1167 return;
1168 }
1169
1170 if (!n) {
1171 es.throwDOMException(NotFoundError);
1172 return;
1173 }
1174
1164 // InvalidNodeTypeError: Raised if the root container of refNode is not an 1175 // InvalidNodeTypeError: Raised if the root container of refNode is not an
1165 // Attr, Document, DocumentFragment or ShadowRoot node, or part of a SVG sha dow DOM tree, 1176 // Attr, Document, DocumentFragment or ShadowRoot node, or part of a SVG sha dow DOM tree,
1166 // or if refNode is a Document, DocumentFragment, ShadowRoot, Attr, Entity, or Notation node. 1177 // or if refNode is a Document, DocumentFragment, ShadowRoot, Attr, Entity, or Notation node.
1167 1178
1179 if (!n->parentNode()) {
1180 es.throwDOMException(InvalidNodeTypeError, ExceptionMessages::failedToEx ecute(methodName, "Range", "the given Node has no parent."));
1181 return;
1182 }
1183
1168 switch (n->nodeType()) { 1184 switch (n->nodeType()) {
1169 case Node::ATTRIBUTE_NODE: 1185 case Node::ATTRIBUTE_NODE:
1170 case Node::DOCUMENT_FRAGMENT_NODE: 1186 case Node::DOCUMENT_FRAGMENT_NODE:
1171 case Node::DOCUMENT_NODE: 1187 case Node::DOCUMENT_NODE:
1172 case Node::ENTITY_NODE: 1188 case Node::ENTITY_NODE:
1173 case Node::NOTATION_NODE: 1189 case Node::NOTATION_NODE:
1174 es.throwDOMException(InvalidNodeTypeError); 1190 es.throwDOMException(InvalidNodeTypeError);
1175 return; 1191 return;
1176 case Node::CDATA_SECTION_NODE: 1192 case Node::CDATA_SECTION_NODE:
1177 case Node::COMMENT_NODE: 1193 case Node::COMMENT_NODE:
1178 case Node::DOCUMENT_TYPE_NODE: 1194 case Node::DOCUMENT_TYPE_NODE:
1179 case Node::ELEMENT_NODE: 1195 case Node::ELEMENT_NODE:
1180 case Node::PROCESSING_INSTRUCTION_NODE: 1196 case Node::PROCESSING_INSTRUCTION_NODE:
1181 case Node::TEXT_NODE: 1197 case Node::TEXT_NODE:
1182 case Node::XPATH_NAMESPACE_NODE: 1198 case Node::XPATH_NAMESPACE_NODE:
1183 break; 1199 break;
1184 } 1200 }
1185 1201
1186 Node* root = n; 1202 Node* root = n;
1187 while (ContainerNode* parent = root->parentNode()) 1203 while (ContainerNode* parent = root->parentNode())
1188 root = parent; 1204 root = parent;
1189 1205
1190 switch (root->nodeType()) { 1206 switch (root->nodeType()) {
1191 case Node::ATTRIBUTE_NODE: 1207 case Node::ATTRIBUTE_NODE:
1192 case Node::DOCUMENT_NODE: 1208 case Node::DOCUMENT_NODE:
1193 case Node::DOCUMENT_FRAGMENT_NODE: 1209 case Node::DOCUMENT_FRAGMENT_NODE:
1210 case Node::ELEMENT_NODE:
1194 break; 1211 break;
1195 case Node::CDATA_SECTION_NODE: 1212 case Node::CDATA_SECTION_NODE:
1196 case Node::COMMENT_NODE: 1213 case Node::COMMENT_NODE:
1197 case Node::DOCUMENT_TYPE_NODE: 1214 case Node::DOCUMENT_TYPE_NODE:
1198 case Node::ELEMENT_NODE:
1199 case Node::ENTITY_NODE: 1215 case Node::ENTITY_NODE:
1200 case Node::NOTATION_NODE: 1216 case Node::NOTATION_NODE:
1201 case Node::PROCESSING_INSTRUCTION_NODE: 1217 case Node::PROCESSING_INSTRUCTION_NODE:
1202 case Node::TEXT_NODE: 1218 case Node::TEXT_NODE:
1203 case Node::XPATH_NAMESPACE_NODE: 1219 case Node::XPATH_NAMESPACE_NODE:
1204 es.throwDOMException(InvalidNodeTypeError); 1220 es.throwDOMException(InvalidNodeTypeError);
1205 return; 1221 return;
1206 } 1222 }
1207 } 1223 }
1208 1224
1209 PassRefPtr<Range> Range::cloneRange(ExceptionState& es) const 1225 PassRefPtr<Range> Range::cloneRange(ExceptionState& es) const
1210 { 1226 {
1211 if (!m_start.container()) { 1227 if (!m_start.container()) {
1212 es.throwDOMException(InvalidStateError); 1228 es.throwDOMException(InvalidStateError);
1213 return 0; 1229 return 0;
1214 } 1230 }
1215 1231
1216 return Range::create(m_ownerDocument, m_start.container(), m_start.offset(), m_end.container(), m_end.offset()); 1232 return Range::create(m_ownerDocument, m_start.container(), m_start.offset(), m_end.container(), m_end.offset());
1217 } 1233 }
1218 1234
1219 void Range::setStartAfter(Node* refNode, ExceptionState& es) 1235 void Range::setStartAfter(Node* refNode, ExceptionState& es)
1220 { 1236 {
1221 if (!m_start.container()) { 1237 checkNodeBA(refNode, es, "setStartAfter");
1222 es.throwDOMException(InvalidStateError);
1223 return;
1224 }
1225
1226 if (!refNode) {
1227 es.throwDOMException(NotFoundError);
1228 return;
1229 }
1230
1231 checkNodeBA(refNode, es);
1232 if (es.hadException()) 1238 if (es.hadException())
1233 return; 1239 return;
1234 1240
1235 setStart(refNode->parentNode(), refNode->nodeIndex() + 1, es); 1241 setStart(refNode->parentNode(), refNode->nodeIndex() + 1, es);
1236 } 1242 }
1237 1243
1238 void Range::setEndBefore(Node* refNode, ExceptionState& es) 1244 void Range::setEndBefore(Node* refNode, ExceptionState& es)
1239 { 1245 {
1240 if (!m_start.container()) { 1246 checkNodeBA(refNode, es, "setEndBefore");
1241 es.throwDOMException(InvalidStateError);
1242 return;
1243 }
1244
1245 if (!refNode) {
1246 es.throwDOMException(NotFoundError);
1247 return;
1248 }
1249
1250 checkNodeBA(refNode, es);
1251 if (es.hadException()) 1247 if (es.hadException())
1252 return; 1248 return;
1253 1249
1254 setEnd(refNode->parentNode(), refNode->nodeIndex(), es); 1250 setEnd(refNode->parentNode(), refNode->nodeIndex(), es);
1255 } 1251 }
1256 1252
1257 void Range::setEndAfter(Node* refNode, ExceptionState& es) 1253 void Range::setEndAfter(Node* refNode, ExceptionState& es)
1258 { 1254 {
1259 if (!m_start.container()) { 1255 checkNodeBA(refNode, es, "setEndAfter");
1260 es.throwDOMException(InvalidStateError);
1261 return;
1262 }
1263
1264 if (!refNode) {
1265 es.throwDOMException(NotFoundError);
1266 return;
1267 }
1268
1269 checkNodeBA(refNode, es);
1270 if (es.hadException()) 1256 if (es.hadException())
1271 return; 1257 return;
1272 1258
1273 setEnd(refNode->parentNode(), refNode->nodeIndex() + 1, es); 1259 setEnd(refNode->parentNode(), refNode->nodeIndex() + 1, es);
1274 } 1260 }
1275 1261
1276 void Range::selectNode(Node* refNode, ExceptionState& es) 1262 void Range::selectNode(Node* refNode, ExceptionState& es)
1277 { 1263 {
1278 if (!m_start.container()) { 1264 if (!m_start.container()) {
1279 es.throwDOMException(InvalidStateError); 1265 es.throwDOMException(InvalidStateError);
1280 return; 1266 return;
1281 } 1267 }
1282 1268
1283 if (!refNode) { 1269 if (!refNode) {
1284 es.throwDOMException(NotFoundError); 1270 es.throwDOMException(NotFoundError);
1285 return; 1271 return;
1286 } 1272 }
1287 1273
1274 if (!refNode->parentNode()) {
1275 es.throwDOMException(InvalidNodeTypeError, ExceptionMessages::failedToEx ecute("selectNode", "Range", "the given Node has no parent."));
1276 return;
1277 }
1278
1288 // InvalidNodeTypeError: Raised if an ancestor of refNode is an Entity, Nota tion or 1279 // InvalidNodeTypeError: Raised if an ancestor of refNode is an Entity, Nota tion or
1289 // DocumentType node or if refNode is a Document, DocumentFragment, ShadowRo ot, Attr, Entity, or Notation 1280 // DocumentType node or if refNode is a Document, DocumentFragment, ShadowRo ot, Attr, Entity, or Notation
1290 // node. 1281 // node.
1291 for (ContainerNode* anc = refNode->parentNode(); anc; anc = anc->parentNode( )) { 1282 for (ContainerNode* anc = refNode->parentNode(); anc; anc = anc->parentNode( )) {
1292 switch (anc->nodeType()) { 1283 switch (anc->nodeType()) {
1293 case Node::ATTRIBUTE_NODE: 1284 case Node::ATTRIBUTE_NODE:
1294 case Node::CDATA_SECTION_NODE: 1285 case Node::CDATA_SECTION_NODE:
1295 case Node::COMMENT_NODE: 1286 case Node::COMMENT_NODE:
1296 case Node::DOCUMENT_FRAGMENT_NODE: 1287 case Node::DOCUMENT_FRAGMENT_NODE:
1297 case Node::DOCUMENT_NODE: 1288 case Node::DOCUMENT_NODE:
(...skipping 24 matching lines...) Expand all
1322 case Node::DOCUMENT_NODE: 1313 case Node::DOCUMENT_NODE:
1323 case Node::ENTITY_NODE: 1314 case Node::ENTITY_NODE:
1324 case Node::NOTATION_NODE: 1315 case Node::NOTATION_NODE:
1325 es.throwDOMException(InvalidNodeTypeError); 1316 es.throwDOMException(InvalidNodeTypeError);
1326 return; 1317 return;
1327 } 1318 }
1328 1319
1329 if (m_ownerDocument != refNode->document()) 1320 if (m_ownerDocument != refNode->document())
1330 setDocument(refNode->document()); 1321 setDocument(refNode->document());
1331 1322
1332 setStartBefore(refNode, es); 1323 setStartBefore(refNode);
1333 if (es.hadException()) 1324 setEndAfter(refNode);
1334 return;
1335 setEndAfter(refNode, es);
1336 } 1325 }
1337 1326
1338 void Range::selectNodeContents(Node* refNode, ExceptionState& es) 1327 void Range::selectNodeContents(Node* refNode, ExceptionState& es)
1339 { 1328 {
1340 if (!m_start.container()) { 1329 if (!m_start.container()) {
1341 es.throwDOMException(InvalidStateError); 1330 es.throwDOMException(InvalidStateError);
1342 return; 1331 return;
1343 } 1332 }
1344 1333
1345 if (!refNode) { 1334 if (!refNode) {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1455 if (es.hadException()) 1444 if (es.hadException())
1456 return; 1445 return;
1457 newParent->appendChild(fragment.release(), es); 1446 newParent->appendChild(fragment.release(), es);
1458 if (es.hadException()) 1447 if (es.hadException())
1459 return; 1448 return;
1460 selectNode(newParent.get(), es); 1449 selectNode(newParent.get(), es);
1461 } 1450 }
1462 1451
1463 void Range::setStartBefore(Node* refNode, ExceptionState& es) 1452 void Range::setStartBefore(Node* refNode, ExceptionState& es)
1464 { 1453 {
1465 if (!m_start.container()) { 1454 checkNodeBA(refNode, es, "setStartBefore");
1466 es.throwDOMException(InvalidStateError);
1467 return;
1468 }
1469
1470 if (!refNode) {
1471 es.throwDOMException(NotFoundError);
1472 return;
1473 }
1474
1475 checkNodeBA(refNode, es);
1476 if (es.hadException()) 1455 if (es.hadException())
1477 return; 1456 return;
1478 1457
1479 setStart(refNode->parentNode(), refNode->nodeIndex(), es); 1458 setStart(refNode->parentNode(), refNode->nodeIndex(), es);
1480 } 1459 }
1481 1460
1482 void Range::checkDeleteExtract(ExceptionState& es) 1461 void Range::checkDeleteExtract(ExceptionState& es)
1483 { 1462 {
1484 if (!m_start.container()) { 1463 if (!m_start.container()) {
1485 es.throwDOMException(InvalidStateError); 1464 es.throwDOMException(InvalidStateError);
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
1916 1895
1917 void showTree(const WebCore::Range* range) 1896 void showTree(const WebCore::Range* range)
1918 { 1897 {
1919 if (range && range->boundaryPointsValid()) { 1898 if (range && range->boundaryPointsValid()) {
1920 range->startContainer()->showTreeAndMark(range->startContainer(), "S", r ange->endContainer(), "E"); 1899 range->startContainer()->showTreeAndMark(range->startContainer(), "S", r ange->endContainer(), "E");
1921 fprintf(stderr, "start offset: %d, end offset: %d\n", range->startOffset (), range->endOffset()); 1900 fprintf(stderr, "start offset: %d, end offset: %d\n", range->startOffset (), range->endOffset());
1922 } 1901 }
1923 } 1902 }
1924 1903
1925 #endif 1904 #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