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 |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |