File indexing completed on 2024-04-28 15:22:55
0001 /** 0002 * This file is part of the DOM implementation for KDE. 0003 * 0004 * Copyright 1999 Lars Knoll (knoll@kde.org) 0005 * Copyright 2000 Gunnstein Lye (gunnstein@netcom.no) 0006 * Copyright 2000 Frederik Holljen (frederik.holljen@hig.no) 0007 * Copyright 2001 Peter Kelly (pmk@post.com) 0008 * Copyright 2003 Apple Computer, Inc. 0009 * 0010 * This library is free software; you can redistribute it and/or 0011 * modify it under the terms of the GNU Library General Public 0012 * License as published by the Free Software Foundation; either 0013 * version 2 of the License, or (at your option) any later version. 0014 * 0015 * This library is distributed in the hope that it will be useful, 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0018 * Library General Public License for more details. 0019 * 0020 * You should have received a copy of the GNU Library General Public License 0021 * along with this library; see the file COPYING.LIB. If not, write to 0022 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0023 * Boston, MA 02110-1301, USA. 0024 * 0025 */ 0026 #include "dom/dom_exception.h" 0027 #include "xml/dom_docimpl.h" 0028 #include "xml/dom2_rangeimpl.h" 0029 0030 using namespace DOM; 0031 0032 DOMString RangeException::codeAsString() const 0033 { 0034 return codeAsString(code); 0035 } 0036 0037 bool RangeException::isRangeExceptionCode(int exceptioncode) 0038 { 0039 return exceptioncode >= _EXCEPTION_OFFSET && exceptioncode < _EXCEPTION_MAX; 0040 } 0041 0042 DOMString RangeException::codeAsString(int code) 0043 { 0044 switch (code) { 0045 case BAD_BOUNDARYPOINTS_ERR: 0046 return DOMString("BAD_BOUNDARYPOINTS_ERR"); 0047 case INVALID_NODE_TYPE_ERR: 0048 return DOMString("INVALID_NODE_TYPE_ERR"); 0049 default: 0050 return DOMString("(unknown exception code)"); 0051 } 0052 } 0053 0054 Range::Range() 0055 { 0056 // a range can't exist by itself - it must be associated with a document 0057 impl = nullptr; 0058 } 0059 0060 Range::Range(const Document rootContainer) 0061 { 0062 if (rootContainer.handle()) { 0063 impl = new RangeImpl(rootContainer.handle()->docPtr()); 0064 impl->ref(); 0065 } else { 0066 impl = nullptr; 0067 } 0068 } 0069 0070 Range::Range(const Range &other) 0071 { 0072 impl = other.impl; 0073 if (impl) { 0074 impl->ref(); 0075 } 0076 } 0077 0078 Range::Range(const Node startContainer, const long startOffset, const Node endContainer, const long endOffset) 0079 { 0080 if (startContainer.isNull() || endContainer.isNull()) { 0081 throw DOMException(DOMException::NOT_FOUND_ERR); 0082 } 0083 0084 if (!startContainer.handle()->document() || 0085 startContainer.handle()->document() != endContainer.handle()->document()) { 0086 throw DOMException(DOMException::WRONG_DOCUMENT_ERR); 0087 } 0088 0089 impl = new RangeImpl(startContainer.handle()->docPtr(), startContainer.handle(), startOffset, endContainer.handle(), endOffset); 0090 impl->ref(); 0091 } 0092 0093 Range::Range(RangeImpl *i) 0094 { 0095 impl = i; 0096 if (impl) { 0097 impl->ref(); 0098 } 0099 } 0100 0101 Range &Range::operator = (const Range &other) 0102 { 0103 if (impl != other.impl) { 0104 if (impl) { 0105 impl->deref(); 0106 } 0107 impl = other.impl; 0108 if (impl) { 0109 impl->ref(); 0110 } 0111 } 0112 return *this; 0113 } 0114 0115 Range::~Range() 0116 { 0117 if (impl) { 0118 impl->deref(); 0119 } 0120 } 0121 0122 Node Range::startContainer() const 0123 { 0124 if (!impl) { 0125 throw DOMException(DOMException::INVALID_STATE_ERR); 0126 } 0127 0128 int exceptioncode = 0; 0129 NodeImpl *r = impl->startContainer(exceptioncode); 0130 throwException(exceptioncode); 0131 return r; 0132 } 0133 0134 long Range::startOffset() const 0135 { 0136 if (!impl) { 0137 throw DOMException(DOMException::INVALID_STATE_ERR); 0138 } 0139 0140 int exceptioncode = 0; 0141 long r = impl->startOffset(exceptioncode); 0142 throwException(exceptioncode); 0143 return r; 0144 0145 } 0146 0147 Node Range::endContainer() const 0148 { 0149 if (!impl) { 0150 throw DOMException(DOMException::INVALID_STATE_ERR); 0151 } 0152 0153 int exceptioncode = 0; 0154 NodeImpl *r = impl->endContainer(exceptioncode); 0155 throwException(exceptioncode); 0156 return r; 0157 } 0158 0159 long Range::endOffset() const 0160 { 0161 if (!impl) { 0162 throw DOMException(DOMException::INVALID_STATE_ERR); 0163 } 0164 0165 int exceptioncode = 0; 0166 long r = impl->endOffset(exceptioncode); 0167 throwException(exceptioncode); 0168 return r; 0169 } 0170 0171 bool Range::collapsed() const 0172 { 0173 if (!impl) { 0174 throw DOMException(DOMException::INVALID_STATE_ERR); 0175 } 0176 0177 int exceptioncode = 0; 0178 bool r = impl->collapsed(exceptioncode); 0179 throwException(exceptioncode); 0180 return r; 0181 } 0182 0183 Node Range::commonAncestorContainer() 0184 { 0185 if (!impl) { 0186 throw DOMException(DOMException::INVALID_STATE_ERR); 0187 } 0188 0189 int exceptioncode = 0; 0190 NodeImpl *r = impl->commonAncestorContainer(exceptioncode); 0191 throwException(exceptioncode); 0192 return r; 0193 } 0194 0195 void Range::setStart(const Node &refNode, long offset) 0196 { 0197 if (!impl) { 0198 throw DOMException(DOMException::INVALID_STATE_ERR); 0199 } 0200 0201 int exceptioncode = 0; 0202 impl->setStart(refNode.handle(), offset, exceptioncode); 0203 throwException(exceptioncode); 0204 } 0205 0206 void Range::setEnd(const Node &refNode, long offset) 0207 { 0208 if (!impl) { 0209 throw DOMException(DOMException::INVALID_STATE_ERR); 0210 } 0211 0212 int exceptioncode = 0; 0213 impl->setEnd(refNode.handle(), offset, exceptioncode); 0214 throwException(exceptioncode); 0215 } 0216 0217 void Range::setStartBefore(const Node &refNode) 0218 { 0219 if (!impl) { 0220 throw DOMException(DOMException::INVALID_STATE_ERR); 0221 } 0222 0223 int exceptioncode = 0; 0224 impl->setStartBefore(refNode.handle(), exceptioncode); 0225 throwException(exceptioncode); 0226 } 0227 0228 void Range::setStartAfter(const Node &refNode) 0229 { 0230 if (!impl) { 0231 throw DOMException(DOMException::INVALID_STATE_ERR); 0232 } 0233 0234 int exceptioncode = 0; 0235 impl->setStartAfter(refNode.handle(), exceptioncode); 0236 throwException(exceptioncode); 0237 } 0238 0239 void Range::setEndBefore(const Node &refNode) 0240 { 0241 if (!impl) { 0242 throw DOMException(DOMException::INVALID_STATE_ERR); 0243 } 0244 0245 int exceptioncode = 0; 0246 impl->setEndBefore(refNode.handle(), exceptioncode); 0247 throwException(exceptioncode); 0248 } 0249 0250 void Range::setEndAfter(const Node &refNode) 0251 { 0252 if (!impl) { 0253 throw DOMException(DOMException::INVALID_STATE_ERR); 0254 } 0255 0256 int exceptioncode = 0; 0257 impl->setEndAfter(refNode.handle(), exceptioncode); 0258 throwException(exceptioncode); 0259 } 0260 0261 void Range::collapse(bool toStart) 0262 { 0263 if (!impl) { 0264 throw DOMException(DOMException::INVALID_STATE_ERR); 0265 } 0266 0267 int exceptioncode = 0; 0268 impl->collapse(toStart, exceptioncode); 0269 throwException(exceptioncode); 0270 } 0271 0272 void Range::selectNode(const Node &refNode) 0273 { 0274 if (!impl) { 0275 throw DOMException(DOMException::INVALID_STATE_ERR); 0276 } 0277 0278 int exceptioncode = 0; 0279 impl->selectNode(refNode.handle(), exceptioncode); 0280 throwException(exceptioncode); 0281 } 0282 0283 void Range::selectNodeContents(const Node &refNode) 0284 { 0285 if (!impl) { 0286 throw DOMException(DOMException::INVALID_STATE_ERR); 0287 } 0288 0289 int exceptioncode = 0; 0290 impl->selectNodeContents(refNode.handle(), exceptioncode); 0291 throwException(exceptioncode); 0292 } 0293 0294 short Range::compareBoundaryPoints(CompareHow how, const Range &sourceRange) 0295 { 0296 if (!impl) { 0297 throw DOMException(DOMException::INVALID_STATE_ERR); 0298 } 0299 0300 int exceptioncode = 0; 0301 short r = impl->compareBoundaryPoints(how, sourceRange.handle(), exceptioncode); 0302 throwException(exceptioncode); 0303 return r; 0304 } 0305 0306 bool Range::boundaryPointsValid() 0307 { 0308 if (!impl) { 0309 throw DOMException(DOMException::INVALID_STATE_ERR); 0310 } 0311 0312 return impl->boundaryPointsValid(); 0313 } 0314 0315 void Range::deleteContents() 0316 { 0317 if (!impl) { 0318 throw DOMException(DOMException::INVALID_STATE_ERR); 0319 } 0320 0321 int exceptioncode = 0; 0322 impl->deleteContents(exceptioncode); 0323 throwException(exceptioncode); 0324 } 0325 0326 DocumentFragment Range::extractContents() 0327 { 0328 if (!impl) { 0329 throw DOMException(DOMException::INVALID_STATE_ERR); 0330 } 0331 0332 int exceptioncode = 0; 0333 DocumentFragmentImpl *r = impl->extractContents(exceptioncode); 0334 throwException(exceptioncode); 0335 return r; 0336 } 0337 0338 DocumentFragment Range::cloneContents() 0339 { 0340 if (!impl) { 0341 throw DOMException(DOMException::INVALID_STATE_ERR); 0342 } 0343 0344 int exceptioncode = 0; 0345 DocumentFragmentImpl *r = impl->cloneContents(exceptioncode); 0346 throwException(exceptioncode); 0347 return r; 0348 } 0349 0350 void Range::insertNode(const Node &newNode) 0351 { 0352 if (!impl) { 0353 throw DOMException(DOMException::INVALID_STATE_ERR); 0354 } 0355 0356 int exceptioncode = 0; 0357 impl->insertNode(newNode.handle(), exceptioncode); 0358 throwException(exceptioncode); 0359 } 0360 0361 void Range::surroundContents(const Node &newParent) 0362 { 0363 if (!impl) { 0364 throw DOMException(DOMException::INVALID_STATE_ERR); 0365 } 0366 0367 int exceptioncode = 0; 0368 impl->surroundContents(newParent.handle(), exceptioncode); 0369 throwException(exceptioncode); 0370 } 0371 0372 Range Range::cloneRange() 0373 { 0374 if (!impl) { 0375 throw DOMException(DOMException::INVALID_STATE_ERR); 0376 } 0377 0378 int exceptioncode = 0; 0379 RangeImpl *r = impl->cloneRange(exceptioncode); 0380 throwException(exceptioncode); 0381 return r; 0382 } 0383 0384 DOMString Range::toString() 0385 { 0386 if (!impl) { 0387 throw DOMException(DOMException::INVALID_STATE_ERR); 0388 } 0389 0390 int exceptioncode = 0; 0391 DOMString r = impl->toString(exceptioncode); 0392 throwException(exceptioncode); 0393 return r; 0394 0395 } 0396 0397 DOMString Range::toHTML() 0398 { 0399 if (!impl) { 0400 throw DOMException(DOMException::INVALID_STATE_ERR); 0401 } 0402 int exceptioncode = 0; 0403 DOMString r = impl->toHTML(exceptioncode); 0404 throwException(exceptioncode); 0405 return r; 0406 } 0407 0408 DocumentFragment Range::createContextualFragment(const DOMString &html) 0409 { 0410 if (!impl) { 0411 throw DOMException(DOMException::INVALID_STATE_ERR); 0412 } 0413 0414 int exceptioncode = 0; 0415 DocumentFragment r = impl->createContextualFragment(html, exceptioncode); 0416 throwException(exceptioncode); 0417 return r; 0418 } 0419 0420 void Range::detach() 0421 { 0422 if (!impl) { 0423 throw DOMException(DOMException::INVALID_STATE_ERR); 0424 } 0425 0426 int exceptioncode = 0; 0427 impl->detach(exceptioncode); 0428 throwException(exceptioncode); 0429 } 0430 0431 bool Range::isDetached() const 0432 { 0433 if (!impl) { 0434 throw DOMException(DOMException::INVALID_STATE_ERR); 0435 } 0436 0437 return impl->isDetached(); 0438 } 0439 0440 RangeImpl *Range::handle() const 0441 { 0442 return impl; 0443 } 0444 0445 bool Range::isNull() const 0446 { 0447 return (impl == nullptr); 0448 } 0449 0450 void Range::throwException(int exceptioncode) const 0451 { 0452 if (!exceptioncode) { 0453 return; 0454 } 0455 0456 // ### also check for CSS & other exceptions? 0457 if (exceptioncode >= RangeException::_EXCEPTION_OFFSET && exceptioncode <= RangeException::_EXCEPTION_MAX) { 0458 throw RangeException(static_cast<RangeException::RangeExceptionCode>(exceptioncode - RangeException::_EXCEPTION_OFFSET)); 0459 } else { 0460 throw DOMException(exceptioncode); 0461 } 0462 } 0463