fix logic
[personal-kdelibs.git] / khtml / dom / dom2_range.cpp
blob4f898ac597f8451bd73581c5def4d86a013d4184
1 /**
2 * This file is part of the DOM implementation for KDE.
4 * Copyright 1999 Lars Knoll (knoll@kde.org)
5 * Copyright 2000 Gunnstein Lye (gunnstein@netcom.no)
6 * Copyright 2000 Frederik Holljen (frederik.holljen@hig.no)
7 * Copyright 2001 Peter Kelly (pmk@post.com)
8 * Copyright 2003 Apple Computer, Inc.
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
20 * You should have received a copy of the GNU Library General Public License
21 * along with this library; see the file COPYING.LIB. If not, write to
22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
26 #include "dom/dom_exception.h"
27 #include "xml/dom_docimpl.h"
28 #include "xml/dom2_rangeimpl.h"
30 using namespace DOM;
32 Range::Range()
34 // a range can't exist by itself - it must be associated with a document
35 impl = 0;
38 Range::Range(const Document rootContainer)
40 if(rootContainer.handle())
42 impl = new RangeImpl(rootContainer.handle()->docPtr());
43 impl->ref();
45 else
46 impl = 0;
49 Range::Range(const Range &other)
51 impl = other.impl;
52 if (impl) impl->ref();
55 Range::Range(const Node startContainer, const long startOffset, const Node endContainer, const long endOffset)
57 if (startContainer.isNull() || endContainer.isNull()) {
58 throw DOMException(DOMException::NOT_FOUND_ERR);
61 if (!startContainer.handle()->document() ||
62 startContainer.handle()->document() != endContainer.handle()->document()) {
63 throw DOMException(DOMException::WRONG_DOCUMENT_ERR);
66 impl = new RangeImpl(startContainer.handle()->docPtr(),startContainer.handle(),startOffset,endContainer.handle(),endOffset);
67 impl->ref();
70 Range::Range(RangeImpl *i)
72 impl = i;
73 if (impl) impl->ref();
76 Range &Range::operator = (const Range &other)
78 if ( impl != other.impl ) {
79 if (impl) impl->deref();
80 impl = other.impl;
81 if (impl) impl->ref();
83 return *this;
86 Range::~Range()
88 if (impl) impl->deref();
91 Node Range::startContainer() const
93 if (!impl)
94 throw DOMException(DOMException::INVALID_STATE_ERR);
96 int exceptioncode = 0;
97 NodeImpl *r = impl->startContainer(exceptioncode);
98 throwException(exceptioncode);
99 return r;
102 long Range::startOffset() const
104 if (!impl)
105 throw DOMException(DOMException::INVALID_STATE_ERR);
107 int exceptioncode = 0;
108 long r = impl->startOffset(exceptioncode);
109 throwException(exceptioncode);
110 return r;
114 Node Range::endContainer() const
116 if (!impl)
117 throw DOMException(DOMException::INVALID_STATE_ERR);
119 int exceptioncode = 0;
120 NodeImpl *r = impl->endContainer(exceptioncode);
121 throwException(exceptioncode);
122 return r;
125 long Range::endOffset() const
127 if (!impl)
128 throw DOMException(DOMException::INVALID_STATE_ERR);
130 int exceptioncode = 0;
131 long r = impl->endOffset(exceptioncode);
132 throwException(exceptioncode);
133 return r;
136 bool Range::collapsed() const
138 if (!impl)
139 throw DOMException(DOMException::INVALID_STATE_ERR);
141 int exceptioncode = 0;
142 bool r = impl->collapsed(exceptioncode);
143 throwException(exceptioncode);
144 return r;
147 Node Range::commonAncestorContainer()
149 if (!impl)
150 throw DOMException(DOMException::INVALID_STATE_ERR);
152 int exceptioncode = 0;
153 NodeImpl *r = impl->commonAncestorContainer(exceptioncode);
154 throwException(exceptioncode);
155 return r;
158 void Range::setStart( const Node &refNode, long offset )
160 if (!impl)
161 throw DOMException(DOMException::INVALID_STATE_ERR);
163 int exceptioncode = 0;
164 impl->setStart(refNode.handle(),offset,exceptioncode);
165 throwException(exceptioncode);
168 void Range::setEnd( const Node &refNode, long offset )
170 if (!impl)
171 throw DOMException(DOMException::INVALID_STATE_ERR);
173 int exceptioncode = 0;
174 impl->setEnd(refNode.handle(),offset,exceptioncode);
175 throwException(exceptioncode);
178 void Range::setStartBefore( const Node &refNode )
180 if (!impl)
181 throw DOMException(DOMException::INVALID_STATE_ERR);
184 int exceptioncode = 0;
185 impl->setStartBefore(refNode.handle(),exceptioncode);
186 throwException(exceptioncode);
189 void Range::setStartAfter( const Node &refNode )
191 if (!impl)
192 throw DOMException(DOMException::INVALID_STATE_ERR);
194 int exceptioncode = 0;
195 impl->setStartAfter(refNode.handle(),exceptioncode);
196 throwException(exceptioncode);
199 void Range::setEndBefore( const Node &refNode )
201 if (!impl)
202 throw DOMException(DOMException::INVALID_STATE_ERR);
204 int exceptioncode = 0;
205 impl->setEndBefore(refNode.handle(),exceptioncode);
206 throwException(exceptioncode);
209 void Range::setEndAfter( const Node &refNode )
211 if (!impl)
212 throw DOMException(DOMException::INVALID_STATE_ERR);
214 int exceptioncode = 0;
215 impl->setEndAfter(refNode.handle(),exceptioncode);
216 throwException(exceptioncode);
219 void Range::collapse( bool toStart )
221 if (!impl)
222 throw DOMException(DOMException::INVALID_STATE_ERR);
224 int exceptioncode = 0;
225 impl->collapse(toStart,exceptioncode);
226 throwException(exceptioncode);
229 void Range::selectNode( const Node &refNode )
231 if (!impl)
232 throw DOMException(DOMException::INVALID_STATE_ERR);
234 int exceptioncode = 0;
235 impl->selectNode(refNode.handle(),exceptioncode);
236 throwException(exceptioncode);
239 void Range::selectNodeContents( const Node &refNode )
241 if (!impl)
242 throw DOMException(DOMException::INVALID_STATE_ERR);
244 int exceptioncode = 0;
245 impl->selectNodeContents(refNode.handle(),exceptioncode);
246 throwException(exceptioncode);
249 short Range::compareBoundaryPoints( CompareHow how, const Range &sourceRange )
251 if (!impl)
252 throw DOMException(DOMException::INVALID_STATE_ERR);
254 int exceptioncode = 0;
255 short r = impl->compareBoundaryPoints(how,sourceRange.handle(),exceptioncode);
256 throwException(exceptioncode);
257 return r;
260 bool Range::boundaryPointsValid( )
262 if (!impl)
263 throw DOMException(DOMException::INVALID_STATE_ERR);
265 return impl->boundaryPointsValid();
268 void Range::deleteContents( )
270 if (!impl)
271 throw DOMException(DOMException::INVALID_STATE_ERR);
273 int exceptioncode = 0;
274 impl->deleteContents(exceptioncode);
275 throwException(exceptioncode);
278 DocumentFragment Range::extractContents( )
280 if (!impl)
281 throw DOMException(DOMException::INVALID_STATE_ERR);
283 int exceptioncode = 0;
284 DocumentFragmentImpl *r = impl->extractContents(exceptioncode);
285 throwException(exceptioncode);
286 return r;
289 DocumentFragment Range::cloneContents( )
291 if (!impl)
292 throw DOMException(DOMException::INVALID_STATE_ERR);
294 int exceptioncode = 0;
295 DocumentFragmentImpl *r = impl->cloneContents(exceptioncode);
296 throwException(exceptioncode);
297 return r;
300 void Range::insertNode( const Node &newNode )
302 if (!impl)
303 throw DOMException(DOMException::INVALID_STATE_ERR);
305 int exceptioncode = 0;
306 impl->insertNode(newNode.handle(),exceptioncode);
307 throwException(exceptioncode);
310 void Range::surroundContents( const Node &newParent )
312 if (!impl)
313 throw DOMException(DOMException::INVALID_STATE_ERR);
315 int exceptioncode = 0;
316 impl->surroundContents(newParent.handle(),exceptioncode);
317 throwException(exceptioncode);
320 Range Range::cloneRange( )
322 if (!impl)
323 throw DOMException(DOMException::INVALID_STATE_ERR);
325 int exceptioncode = 0;
326 RangeImpl *r = impl->cloneRange(exceptioncode);
327 throwException(exceptioncode);
328 return r;
331 DOMString Range::toString( )
333 if (!impl)
334 throw DOMException(DOMException::INVALID_STATE_ERR);
336 int exceptioncode = 0;
337 DOMString r = impl->toString(exceptioncode);
338 throwException(exceptioncode);
339 return r;
343 DOMString Range::toHTML( )
345 if (!impl)
346 throw DOMException(DOMException::INVALID_STATE_ERR);
347 int exceptioncode = 0;
348 DOMString r = impl->toHTML(exceptioncode);
349 throwException(exceptioncode);
350 return r;
353 DocumentFragment Range::createContextualFragment( const DOMString &html )
355 if (!impl)
356 throw DOMException(DOMException::INVALID_STATE_ERR);
358 int exceptioncode = 0;
359 DocumentFragment r = impl->createContextualFragment(html, exceptioncode);
360 throwException(exceptioncode);
361 return r;
365 void Range::detach( )
367 if (!impl)
368 throw DOMException(DOMException::INVALID_STATE_ERR);
370 int exceptioncode = 0;
371 impl->detach(exceptioncode);
372 throwException(exceptioncode);
375 bool Range::isDetached() const
377 if (!impl)
378 throw DOMException(DOMException::INVALID_STATE_ERR);
380 return impl->isDetached();
383 RangeImpl *Range::handle() const
385 return impl;
388 bool Range::isNull() const
390 return (impl == 0);
393 void Range::throwException(int exceptioncode) const
395 if (!exceptioncode)
396 return;
398 // ### also check for CSS & other exceptions?
399 if (exceptioncode >= RangeException::_EXCEPTION_OFFSET && exceptioncode <= RangeException::_EXCEPTION_MAX)
400 throw RangeException(static_cast<RangeException::RangeExceptionCode>(exceptioncode-RangeException::_EXCEPTION_OFFSET));
401 else
402 throw DOMException(exceptioncode);