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  *
0009  * This library is free software; you can redistribute it and/or
0010  * modify it under the terms of the GNU Library General Public
0011  * License as published by the Free Software Foundation; either
0012  * version 2 of the License, or (at your option) any later version.
0013  *
0014  * This library is distributed in the hope that it will be useful,
0015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0017  * Library General Public License for more details.
0018  *
0019  * You should have received a copy of the GNU Library General Public License
0020  * along with this library; see the file COPYING.LIB.  If not, write to
0021  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0022  * Boston, MA 02110-1301, USA.
0023  *
0024  * This file includes excerpts from the Document Object Model (DOM)
0025  * Level 2 Specification (Candidate Recommendation)
0026  * https://www.w3.org/TR/2000/CR-DOM-Level-2-20000510/
0027  * Copyright © 2000 W3C® (MIT, INRIA, Keio), All Rights Reserved.
0028  *
0029  */
0030 #ifndef _dom2_range_h_
0031 #define _dom2_range_h_
0032 
0033 #include <dom/dom_doc.h>
0034 #include <dom/dom_misc.h>
0035 
0036 namespace DOM
0037 {
0038 
0039 class DocumentFragment;
0040 class Node;
0041 class DOMString;
0042 class DocumentImpl;
0043 class RangeImpl;
0044 
0045 class DOMException;
0046 
0047 // Introduced in DOM Level 2:
0048 class KHTML_EXPORT RangeException
0049 {
0050 public:
0051     RangeException(unsigned short _code)
0052     {
0053         code = _code;
0054     }
0055     RangeException(const RangeException &other)
0056     {
0057         code = other.code;
0058     }
0059 
0060     RangeException &operator = (const RangeException &other)
0061     {
0062         code = other.code;
0063         return *this;
0064     }
0065 
0066     virtual ~RangeException() {}
0067     /**
0068      * An integer indicating the type of error generated.
0069      *
0070      */
0071     enum RangeExceptionCode {
0072         BAD_BOUNDARYPOINTS_ERR         = 1,
0073         INVALID_NODE_TYPE_ERR          = 2,
0074         _EXCEPTION_OFFSET              = 2000,
0075         _EXCEPTION_MAX                 = 2999
0076     };
0077     unsigned short code;
0078 
0079     /// Returns the name of this error
0080     DOMString codeAsString() const;
0081 
0082     /// Returns the name of given DOM error code
0083     static DOMString codeAsString(int rangeCode);
0084 
0085     /** @internal - checks to see whether internal code is a Range one */
0086     static bool isRangeExceptionCode(int exceptioncode);
0087 };
0088 
0089 class KHTML_EXPORT Range
0090 {
0091     friend class DocumentImpl;
0092     friend class Document;
0093     friend class RangeImpl;
0094 public:
0095     Range();
0096     Range(const Document rootContainer);
0097     Range(const Range &other);
0098     Range(const Node startContainer, const long startOffset, const Node endContainer, const long endOffset);
0099 
0100     Range &operator = (const Range &other);
0101 
0102     ~Range();
0103 
0104     /**
0105      * Node within which the range begins
0106      *
0107      */
0108     Node startContainer() const;
0109 
0110     /**
0111      * Offset within the starting node of the range.
0112      *
0113      */
0114     long startOffset() const;
0115 
0116     /**
0117      * Node within which the range ends
0118      *
0119      */
0120     Node endContainer() const;
0121 
0122     /**
0123      * Offset within the ending node of the range.
0124      *
0125      */
0126     long endOffset() const;
0127 
0128     /**
0129      * true if the range is collapsed
0130      *
0131      */
0132     bool collapsed() const;
0133 
0134     /**
0135      * Gets the common ancestor container of the range's two end-points.
0136      * Also sets it.
0137      *
0138      */
0139     // ### BIC make const in the next release
0140     Node commonAncestorContainer();
0141 
0142     /**
0143      * Sets the attributes describing the start of the range.
0144      *
0145      * @param refNode The \c refNode value. This parameter
0146      * must be different from \c null .
0147      *
0148      * @param offset The \c startOffset value.
0149      *
0150      * @return
0151      *
0152      * @exception RangeException
0153      * NULL_NODE_ERR: Raised if \c refNode is \c null .
0154      *
0155      *  INVALID_NODE_TYPE_ERR: Raised if \c refNode or an
0156      * ancestor of \c refNode is an Attr, Entity,
0157      * Notation, or DocumentType node.
0158      *
0159      *  If an offset is out-of-bounds, should it just be fixed up or
0160      * should an exception be raised.
0161      *
0162      */
0163     void setStart(const Node &refNode, long offset);
0164 
0165     /**
0166      * Sets the attributes describing the end of a range.
0167      *
0168      * @param refNode The \c refNode value. This parameter
0169      * must be different from \c null .
0170      *
0171      * @param offset The \c endOffset value.
0172      *
0173      * @return
0174      *
0175      * @exception RangeException
0176      * NULL_NODE_ERR: Raised if \c refNode is \c null .
0177      *
0178      *  INVALID_NODE_TYPE_ERR: Raised if \c refNode or an
0179      * ancestor of \c refNode is an Attr, Entity,
0180      * Notation, or DocumentType node.
0181      *
0182      */
0183     void setEnd(const Node &refNode, long offset);
0184 
0185     /**
0186      * Sets the start position to be before a node
0187      *
0188      * @param refNode Range starts before \c refNode
0189      *
0190      * @return
0191      *
0192      * @exception RangeException
0193      * INVALID_NODE_TYPE_ERR: Raised if an ancestor of \c refNode
0194      * is an Attr, Entity, Notation, or DocumentType node or
0195      * if \c refNode is a Document, DocumentFragment,
0196      * Attr, Entity, or Notation node.
0197      *
0198      */
0199     void setStartBefore(const Node &refNode);
0200 
0201     /**
0202      * Sets the start position to be after a node
0203      *
0204      * @param refNode Range starts after \c refNode
0205      *
0206      * @return
0207      *
0208      * @exception RangeException
0209      * INVALID_NODE_TYPE_ERR: Raised if an ancestor of \c refNode
0210      * is an Attr, Entity, Notation, or DocumentType node or
0211      * if \c refNode is a Document, DocumentFragment,
0212      * Attr, Entity, or Notation node.
0213      *
0214      */
0215     void setStartAfter(const Node &refNode);
0216 
0217     /**
0218      * Sets the end position to be before a node.
0219      *
0220      * @param refNode Range ends before \c refNode
0221      *
0222      * @return
0223      *
0224      * @exception RangeException
0225      * INVALID_NODE_TYPE_ERR: Raised if an ancestor of \c refNode
0226      * is an Attr, Entity, Notation, or DocumentType node or
0227      * if \c refNode is a Document, DocumentFragment,
0228      * Attr, Entity, or Notation node.
0229      *
0230      */
0231     void setEndBefore(const Node &refNode);
0232 
0233     /**
0234      * Sets the end of a range to be after a node
0235      *
0236      * @param refNode Range ends after \c refNode .
0237      *
0238      * @return
0239      *
0240      * @exception RangeException
0241      * INVALID_NODE_TYPE_ERR: Raised if an ancestor of \c refNode
0242      * is an Attr, Entity, Notation or DocumentType node or if
0243      * \c refNode is a Document, DocumentFragment, Attr,
0244      * Entity, or Notation node.
0245      *
0246      */
0247     void setEndAfter(const Node &refNode);
0248 
0249     /**
0250      * Collapse a range onto one of its end-points
0251      *
0252      * @param toStart If true, collapses the Range onto its start; if
0253      * false, collapses it onto its end.
0254      *
0255      * @return
0256      *
0257      */
0258     void collapse(bool toStart);
0259 
0260     /**
0261      * Select a node and its contents
0262      *
0263      * @param refNode The node to select.
0264      *
0265      * @return
0266      *
0267      * @exception RangeException
0268      * INVALID_NODE_TYPE_ERR: Raised if an ancestor of \c refNode
0269      * is an Attr, Entity, Notation or DocumentType node or if
0270      * \c refNode is a Document, DocumentFragment, Attr,
0271      * Entity, or Notation node.
0272      *
0273      */
0274     void selectNode(const Node &refNode);
0275 
0276     /**
0277      * Select the contents within a node
0278      *
0279      * @param refNode Node to select from
0280      *
0281      * @return
0282      *
0283      * @exception RangeException
0284      * INVALID_NODE_TYPE_ERR: Raised if \c refNode or an
0285      * ancestor of \c refNode is an Attr, Entity, Notation
0286      * or DocumentType node.
0287      *
0288      */
0289     void selectNodeContents(const Node &refNode);
0290 
0291     enum CompareHow {
0292         START_TO_START = 0,
0293         START_TO_END = 1,
0294         END_TO_END = 2,
0295         END_TO_START = 3
0296     };
0297 
0298     /**
0299      * Compare the end-points of two ranges in a document.
0300      *
0301      * @param how
0302      *
0303      * @param sourceRange
0304      *
0305      * @return -1, 0 or 1 depending on whether the corresponding
0306      * end-point of the Range is before, equal to, or after the
0307      * corresponding end-point of \c sourceRange .
0308      *
0309      * @exception DOMException
0310      * WRONG_DOCUMENT_ERR: Raised if the two Ranges are not in the
0311      * same document or document fragment.
0312      *
0313      */
0314     short compareBoundaryPoints(CompareHow how, const Range &sourceRange);
0315 
0316     /**
0317      * @internal
0318      * not part of the DOM
0319      *
0320      * Compare the boundary-points of a range.
0321      *
0322      * Return true if the startContainer is before the endContainer,
0323      * or if they are equal.
0324      * Return false if the startContainer is after the endContainer.
0325      *
0326      */
0327     bool boundaryPointsValid();
0328 
0329     /**
0330      * Removes the contents of a range from the containing document or
0331      * document fragment without returning a reference to the removed
0332      * content.
0333      *
0334      * @return
0335      *
0336      * @exception DOMException
0337      * NO_MODIFICATION_ALLOWED_ERR: Raised if any portion of the
0338      * content of the range is read-only or any of the nodes that
0339      * contain any of the content of the range are read-only.
0340      *
0341      */
0342     void deleteContents();
0343 
0344     /**
0345      * Moves the contents of a range from the containing document or
0346      * document fragment to a new DocumentFragment.
0347      *
0348      * @return A DocumentFragment containing the extracted contents.
0349      *
0350      * @exception DOMException
0351      * NO_MODIFICATION_ALLOWED_ERR: Raised if any portion of the
0352      * content of the range is read-only or any of the nodes which
0353      * contain any of the content of the range are read-only.
0354      *
0355      *  HIERARCHY_REQUEST_ERR: Raised if a DocumentType node would be
0356      * extracted into the new DocumentFragment.
0357      *
0358      */
0359     DocumentFragment extractContents();
0360 
0361     /**
0362      * Duplicates the contents of a range
0363      *
0364      * @return A DocumentFragment containing contents equivalent to
0365      * those of this range.
0366      *
0367      * @exception DOMException
0368      * HIERARCHY_REQUEST_ERR: Raised if a DocumentType node would be
0369      * extracted into the new DocumentFragment.
0370      *
0371      */
0372     DocumentFragment cloneContents();
0373 
0374     /**
0375      * Inserts a node into the document or document fragment at the
0376      * start of the range.
0377      *
0378      * @param newNode The node to insert at the start of the range
0379      *
0380      * @return
0381      *
0382      * @exception DOMException
0383      * NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of
0384      * the start of the range is read-only.
0385      *
0386      *  WRONG_DOCUMENT_ERR: Raised if \c newNode and the
0387      * container of the start of the Range were not created from the
0388      * same document.
0389      *
0390      *  HIERARCHY_REQUEST_ERR: Raised if the container of the start of
0391      * the Range is of a type that does not allow children of the type
0392      * of \c newNode or if \c newNode is an
0393      * ancestor of the container .
0394      *
0395      * @exception RangeException
0396      * INVALID_NODE_TYPE_ERR: Raised if \c node is an
0397      * Attr, Entity, Notation, DocumentFragment, or Document node.
0398      *
0399      */
0400     void insertNode(const Node &newNode);
0401 
0402     /**
0403      * Reparents the contents of the range to the given node and
0404      * inserts the node at the position of the start of the range.
0405      *
0406      * @param newParent The node to surround the contents with.
0407      *
0408      * @return
0409      *
0410      * @exception DOMException
0411      * NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of
0412      * either end-point of the range is read-only.
0413      *
0414      *  WRONG_DOCUMENT_ERR: Raised if \c newParent and the
0415      * container of the start of the Range were not created from the
0416      * same document.
0417      *
0418      *  HIERARCHY_REQUEST_ERR: Raised if the container of the start of
0419      * the Range is of a type that does not allow children of the type
0420      * of \c newParent or if \c newParent is
0421      * an ancestor of the container or if \c node would
0422      * end up with a child node of a type not allowed by the type of
0423      * \c node .
0424      *
0425      * @exception RangeException
0426      * BAD_ENDPOINTS_ERR: Raised if the range partially selects a
0427      * non-text node.
0428      *
0429      *  INVALID_NODE_TYPE_ERR: Raised if \c node is an
0430      * Attr, Entity, DocumentType, Notation, Document, or
0431      * DocumentFragment node.
0432      *
0433      */
0434     void surroundContents(const Node &newParent);
0435 
0436     /**
0437      * Produces a new range whose end-points are equal to the
0438      * end-points of the range.
0439      *
0440      * @return The duplicated range.
0441      *
0442      */
0443     Range cloneRange();
0444 
0445     /**
0446      * Returns the contents of a range as a string.
0447      *
0448      * @return The contents of the range.
0449      *
0450      */
0451     DOMString toString();
0452 
0453     /**
0454      * @internal Not part of DOM
0455      */
0456     DOMString toHTML();
0457 
0458     /* Mozilla extension - only works for HTML documents. */
0459     DocumentFragment createContextualFragment(const DOMString &html);
0460 
0461     /**
0462      * Called to indicate that the range is no longer in use and that
0463      * the implementation may relinquish any resources associated with
0464      * this range. Subsequent calls to any methods or attribute getters
0465      * on this range will result in a DOMException being thrown with an
0466      * error code of INVALID_STATE_ERR.
0467      *
0468      */
0469     void detach();
0470 
0471     /**
0472      * not part of the DOM
0473      * true if the range is detached
0474      *
0475      */
0476     bool isDetached() const;
0477 
0478     /**
0479      * @internal
0480      * not part of the DOM
0481      */
0482     RangeImpl *handle() const;
0483     bool isNull() const;
0484     Range(RangeImpl *i);
0485 protected:
0486     RangeImpl *impl;
0487 private:
0488     void throwException(int exceptioncode) const;
0489 };
0490 
0491 } // namespace
0492 
0493 #endif