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 |