| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 #include "wtf/text/StringBuilder.h" | 52 #include "wtf/text/StringBuilder.h" |
| 53 #include <stdio.h> | 53 #include <stdio.h> |
| 54 | 54 |
| 55 namespace WebCore { | 55 namespace WebCore { |
| 56 | 56 |
| 57 using namespace std; | 57 using namespace std; |
| 58 using namespace HTMLNames; | 58 using namespace HTMLNames; |
| 59 | 59 |
| 60 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, rangeCounter, ("Range")); | 60 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, rangeCounter, ("Range")); |
| 61 | 61 |
| 62 inline Range::Range(Document* ownerDocument) | 62 inline Range::Range(Document& ownerDocument) |
| 63 : m_ownerDocument(ownerDocument) | 63 : m_ownerDocument(&ownerDocument) |
| 64 , m_start(m_ownerDocument) | 64 , m_start(m_ownerDocument) |
| 65 , m_end(m_ownerDocument) | 65 , m_end(m_ownerDocument) |
| 66 { | 66 { |
| 67 #ifndef NDEBUG | 67 #ifndef NDEBUG |
| 68 rangeCounter.increment(); | 68 rangeCounter.increment(); |
| 69 #endif | 69 #endif |
| 70 | 70 |
| 71 ScriptWrappable::init(this); | 71 ScriptWrappable::init(this); |
| 72 m_ownerDocument->attachRange(this); | 72 m_ownerDocument->attachRange(this); |
| 73 } | 73 } |
| 74 | 74 |
| 75 PassRefPtr<Range> Range::create(Document* ownerDocument) | 75 PassRefPtr<Range> Range::create(Document& ownerDocument) |
| 76 { | 76 { |
| 77 return adoptRef(new Range(ownerDocument)); | 77 return adoptRef(new Range(ownerDocument)); |
| 78 } | 78 } |
| 79 | 79 |
| 80 inline Range::Range(Document* ownerDocument, Node* startContainer, int startOffs
et, Node* endContainer, int endOffset) | 80 inline Range::Range(Document& ownerDocument, Node* startContainer, int startOffs
et, Node* endContainer, int endOffset) |
| 81 : m_ownerDocument(ownerDocument) | 81 : m_ownerDocument(&ownerDocument) |
| 82 , m_start(m_ownerDocument) | 82 , m_start(m_ownerDocument) |
| 83 , m_end(m_ownerDocument) | 83 , m_end(m_ownerDocument) |
| 84 { | 84 { |
| 85 #ifndef NDEBUG | 85 #ifndef NDEBUG |
| 86 rangeCounter.increment(); | 86 rangeCounter.increment(); |
| 87 #endif | 87 #endif |
| 88 | 88 |
| 89 ScriptWrappable::init(this); | 89 ScriptWrappable::init(this); |
| 90 m_ownerDocument->attachRange(this); | 90 m_ownerDocument->attachRange(this); |
| 91 | 91 |
| 92 // Simply setting the containers and offsets directly would not do any of th
e checking | 92 // Simply setting the containers and offsets directly would not do any of th
e checking |
| 93 // that setStart and setEnd do, so we call those functions. | 93 // that setStart and setEnd do, so we call those functions. |
| 94 setStart(startContainer, startOffset); | 94 setStart(startContainer, startOffset); |
| 95 setEnd(endContainer, endOffset); | 95 setEnd(endContainer, endOffset); |
| 96 } | 96 } |
| 97 | 97 |
| 98 PassRefPtr<Range> Range::create(Document* ownerDocument, Node* startContainer, i
nt startOffset, Node* endContainer, int endOffset) | 98 PassRefPtr<Range> Range::create(Document& ownerDocument, Node* startContainer, i
nt startOffset, Node* endContainer, int endOffset) |
| 99 { | 99 { |
| 100 return adoptRef(new Range(ownerDocument, startContainer, startOffset, endCon
tainer, endOffset)); | 100 return adoptRef(new Range(ownerDocument, startContainer, startOffset, endCon
tainer, endOffset)); |
| 101 } | 101 } |
| 102 | 102 |
| 103 PassRefPtr<Range> Range::create(Document* ownerDocument, const Position& start,
const Position& end) | 103 PassRefPtr<Range> Range::create(Document& ownerDocument, const Position& start,
const Position& end) |
| 104 { | 104 { |
| 105 return adoptRef(new Range(ownerDocument, start.containerNode(), start.comput
eOffsetInContainerNode(), end.containerNode(), end.computeOffsetInContainerNode(
))); | 105 return adoptRef(new Range(ownerDocument, start.containerNode(), start.comput
eOffsetInContainerNode(), end.containerNode(), end.computeOffsetInContainerNode(
))); |
| 106 } | 106 } |
| 107 | 107 |
| 108 Range::~Range() | 108 Range::~Range() |
| 109 { | 109 { |
| 110 // Always detach (even if we've already detached) to fix https://bugs.webkit
.org/show_bug.cgi?id=26044 | 110 // Always detach (even if we've already detached) to fix https://bugs.webkit
.org/show_bug.cgi?id=26044 |
| 111 m_ownerDocument->detachRange(this); | 111 m_ownerDocument->detachRange(this); |
| 112 | 112 |
| 113 #ifndef NDEBUG | 113 #ifndef NDEBUG |
| 114 rangeCounter.decrement(); | 114 rangeCounter.decrement(); |
| 115 #endif | 115 #endif |
| 116 } | 116 } |
| 117 | 117 |
| 118 void Range::setDocument(Document* document) | 118 void Range::setDocument(Document& document) |
| 119 { | 119 { |
| 120 ASSERT(m_ownerDocument != document); | 120 ASSERT(m_ownerDocument != &document); |
| 121 if (m_ownerDocument) | 121 ASSERT(m_ownerDocument); |
| 122 m_ownerDocument->detachRange(this); | 122 m_ownerDocument->detachRange(this); |
| 123 m_ownerDocument = document; | 123 m_ownerDocument = &document; |
| 124 m_start.setToStartOfNode(document); | 124 m_start.setToStartOfNode(&document); |
| 125 m_end.setToStartOfNode(document); | 125 m_end.setToStartOfNode(&document); |
| 126 m_ownerDocument->attachRange(this); | 126 m_ownerDocument->attachRange(this); |
| 127 } | 127 } |
| 128 | 128 |
| 129 Node* Range::startContainer(ExceptionState& es) const | 129 Node* Range::startContainer(ExceptionState& es) const |
| 130 { | 130 { |
| 131 if (!m_start.container()) { | 131 if (!m_start.container()) { |
| 132 es.throwDOMException(InvalidStateError); | 132 es.throwDOMException(InvalidStateError); |
| 133 return 0; | 133 return 0; |
| 134 } | 134 } |
| 135 | 135 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 return; | 216 return; |
| 217 } | 217 } |
| 218 | 218 |
| 219 if (!refNode) { | 219 if (!refNode) { |
| 220 es.throwDOMException(NotFoundError); | 220 es.throwDOMException(NotFoundError); |
| 221 return; | 221 return; |
| 222 } | 222 } |
| 223 | 223 |
| 224 bool didMoveDocument = false; | 224 bool didMoveDocument = false; |
| 225 if (&refNode->document() != m_ownerDocument) { | 225 if (&refNode->document() != m_ownerDocument) { |
| 226 setDocument(&refNode->document()); | 226 setDocument(refNode->document()); |
| 227 didMoveDocument = true; | 227 didMoveDocument = true; |
| 228 } | 228 } |
| 229 | 229 |
| 230 Node* childNode = checkNodeWOffset(refNode.get(), offset, es); | 230 Node* childNode = checkNodeWOffset(refNode.get(), offset, es); |
| 231 if (es.hadException()) | 231 if (es.hadException()) |
| 232 return; | 232 return; |
| 233 | 233 |
| 234 m_start.set(refNode, offset, childNode); | 234 m_start.set(refNode, offset, childNode); |
| 235 | 235 |
| 236 if (didMoveDocument || checkForDifferentRootContainer(m_start, m_end)) | 236 if (didMoveDocument || checkForDifferentRootContainer(m_start, m_end)) |
| 237 collapse(true, es); | 237 collapse(true, es); |
| 238 } | 238 } |
| 239 | 239 |
| 240 void Range::setEnd(PassRefPtr<Node> refNode, int offset, ExceptionState& es) | 240 void Range::setEnd(PassRefPtr<Node> refNode, int offset, ExceptionState& es) |
| 241 { | 241 { |
| 242 if (!m_start.container()) { | 242 if (!m_start.container()) { |
| 243 es.throwDOMException(InvalidStateError); | 243 es.throwDOMException(InvalidStateError); |
| 244 return; | 244 return; |
| 245 } | 245 } |
| 246 | 246 |
| 247 if (!refNode) { | 247 if (!refNode) { |
| 248 es.throwDOMException(NotFoundError); | 248 es.throwDOMException(NotFoundError); |
| 249 return; | 249 return; |
| 250 } | 250 } |
| 251 | 251 |
| 252 bool didMoveDocument = false; | 252 bool didMoveDocument = false; |
| 253 if (&refNode->document() != m_ownerDocument) { | 253 if (&refNode->document() != m_ownerDocument) { |
| 254 setDocument(&refNode->document()); | 254 setDocument(refNode->document()); |
| 255 didMoveDocument = true; | 255 didMoveDocument = true; |
| 256 } | 256 } |
| 257 | 257 |
| 258 Node* childNode = checkNodeWOffset(refNode.get(), offset, es); | 258 Node* childNode = checkNodeWOffset(refNode.get(), offset, es); |
| 259 if (es.hadException()) | 259 if (es.hadException()) |
| 260 return; | 260 return; |
| 261 | 261 |
| 262 m_end.set(refNode, offset, childNode); | 262 m_end.set(refNode, offset, childNode); |
| 263 | 263 |
| 264 if (didMoveDocument || checkForDifferentRootContainer(m_start, m_end)) | 264 if (didMoveDocument || checkForDifferentRootContainer(m_start, m_end)) |
| (...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1222 } | 1222 } |
| 1223 } | 1223 } |
| 1224 | 1224 |
| 1225 PassRefPtr<Range> Range::cloneRange(ExceptionState& es) const | 1225 PassRefPtr<Range> Range::cloneRange(ExceptionState& es) const |
| 1226 { | 1226 { |
| 1227 if (!m_start.container()) { | 1227 if (!m_start.container()) { |
| 1228 es.throwDOMException(InvalidStateError); | 1228 es.throwDOMException(InvalidStateError); |
| 1229 return 0; | 1229 return 0; |
| 1230 } | 1230 } |
| 1231 | 1231 |
| 1232 return Range::create(m_ownerDocument.get(), m_start.container(), m_start.off
set(), m_end.container(), m_end.offset()); | 1232 return Range::create(*m_ownerDocument.get(), m_start.container(), m_start.of
fset(), m_end.container(), m_end.offset()); |
| 1233 } | 1233 } |
| 1234 | 1234 |
| 1235 void Range::setStartAfter(Node* refNode, ExceptionState& es) | 1235 void Range::setStartAfter(Node* refNode, ExceptionState& es) |
| 1236 { | 1236 { |
| 1237 checkNodeBA(refNode, es, "setStartAfter"); | 1237 checkNodeBA(refNode, es, "setStartAfter"); |
| 1238 if (es.hadException()) | 1238 if (es.hadException()) |
| 1239 return; | 1239 return; |
| 1240 | 1240 |
| 1241 setStart(refNode->parentNode(), refNode->nodeIndex() + 1, es); | 1241 setStart(refNode->parentNode(), refNode->nodeIndex() + 1, es); |
| 1242 } | 1242 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1311 case Node::ATTRIBUTE_NODE: | 1311 case Node::ATTRIBUTE_NODE: |
| 1312 case Node::DOCUMENT_FRAGMENT_NODE: | 1312 case Node::DOCUMENT_FRAGMENT_NODE: |
| 1313 case Node::DOCUMENT_NODE: | 1313 case Node::DOCUMENT_NODE: |
| 1314 case Node::ENTITY_NODE: | 1314 case Node::ENTITY_NODE: |
| 1315 case Node::NOTATION_NODE: | 1315 case Node::NOTATION_NODE: |
| 1316 es.throwDOMException(InvalidNodeTypeError); | 1316 es.throwDOMException(InvalidNodeTypeError); |
| 1317 return; | 1317 return; |
| 1318 } | 1318 } |
| 1319 | 1319 |
| 1320 if (m_ownerDocument != &refNode->document()) | 1320 if (m_ownerDocument != &refNode->document()) |
| 1321 setDocument(&refNode->document()); | 1321 setDocument(refNode->document()); |
| 1322 | 1322 |
| 1323 setStartBefore(refNode); | 1323 setStartBefore(refNode); |
| 1324 setEndAfter(refNode); | 1324 setEndAfter(refNode); |
| 1325 } | 1325 } |
| 1326 | 1326 |
| 1327 void Range::selectNodeContents(Node* refNode, ExceptionState& es) | 1327 void Range::selectNodeContents(Node* refNode, ExceptionState& es) |
| 1328 { | 1328 { |
| 1329 if (!m_start.container()) { | 1329 if (!m_start.container()) { |
| 1330 es.throwDOMException(InvalidStateError); | 1330 es.throwDOMException(InvalidStateError); |
| 1331 return; | 1331 return; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1352 break; | 1352 break; |
| 1353 case Node::DOCUMENT_TYPE_NODE: | 1353 case Node::DOCUMENT_TYPE_NODE: |
| 1354 case Node::ENTITY_NODE: | 1354 case Node::ENTITY_NODE: |
| 1355 case Node::NOTATION_NODE: | 1355 case Node::NOTATION_NODE: |
| 1356 es.throwDOMException(InvalidNodeTypeError); | 1356 es.throwDOMException(InvalidNodeTypeError); |
| 1357 return; | 1357 return; |
| 1358 } | 1358 } |
| 1359 } | 1359 } |
| 1360 | 1360 |
| 1361 if (m_ownerDocument != &refNode->document()) | 1361 if (m_ownerDocument != &refNode->document()) |
| 1362 setDocument(&refNode->document()); | 1362 setDocument(refNode->document()); |
| 1363 | 1363 |
| 1364 m_start.setToStartOfNode(refNode); | 1364 m_start.setToStartOfNode(refNode); |
| 1365 m_end.setToEndOfNode(refNode); | 1365 m_end.setToEndOfNode(refNode); |
| 1366 } | 1366 } |
| 1367 | 1367 |
| 1368 void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& es) | 1368 void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& es) |
| 1369 { | 1369 { |
| 1370 RefPtr<Node> newParent = passNewParent; | 1370 RefPtr<Node> newParent = passNewParent; |
| 1371 | 1371 |
| 1372 if (!m_start.container()) { | 1372 if (!m_start.container()) { |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1613 if (a == b) | 1613 if (a == b) |
| 1614 return true; | 1614 return true; |
| 1615 if (!a || !b) | 1615 if (!a || !b) |
| 1616 return false; | 1616 return false; |
| 1617 return a->startPosition() == b->startPosition() && a->endPosition() == b->en
dPosition(); | 1617 return a->startPosition() == b->startPosition() && a->endPosition() == b->en
dPosition(); |
| 1618 } | 1618 } |
| 1619 | 1619 |
| 1620 PassRefPtr<Range> rangeOfContents(Node* node) | 1620 PassRefPtr<Range> rangeOfContents(Node* node) |
| 1621 { | 1621 { |
| 1622 ASSERT(node); | 1622 ASSERT(node); |
| 1623 RefPtr<Range> range = Range::create(&node->document()); | 1623 RefPtr<Range> range = Range::create(node->document()); |
| 1624 range->selectNodeContents(node, IGNORE_EXCEPTION); | 1624 range->selectNodeContents(node, IGNORE_EXCEPTION); |
| 1625 return range.release(); | 1625 return range.release(); |
| 1626 } | 1626 } |
| 1627 | 1627 |
| 1628 int Range::maxStartOffset() const | 1628 int Range::maxStartOffset() const |
| 1629 { | 1629 { |
| 1630 if (!m_start.container()) | 1630 if (!m_start.container()) |
| 1631 return 0; | 1631 return 0; |
| 1632 if (!m_start.container()->offsetInCharacters()) | 1632 if (!m_start.container()->offsetInCharacters()) |
| 1633 return m_start.container()->childNodeCount(); | 1633 return m_start.container()->childNodeCount(); |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1895 | 1895 |
| 1896 void showTree(const WebCore::Range* range) | 1896 void showTree(const WebCore::Range* range) |
| 1897 { | 1897 { |
| 1898 if (range && range->boundaryPointsValid()) { | 1898 if (range && range->boundaryPointsValid()) { |
| 1899 range->startContainer()->showTreeAndMark(range->startContainer(), "S", r
ange->endContainer(), "E"); | 1899 range->startContainer()->showTreeAndMark(range->startContainer(), "S", r
ange->endContainer(), "E"); |
| 1900 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()); |
| 1901 } | 1901 } |
| 1902 } | 1902 } |
| 1903 | 1903 |
| 1904 #endif | 1904 #endif |
| OLD | NEW |