You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by ar...@locus.apache.org on 2000/07/28 03:33:40 UTC
cvs commit: xml-xerces/c/tests/DOM/RangeTest Makefile.in RangeTest.cpp
aruna1 00/07/27 18:33:39
Modified: c/Projects/Win32/VC6/xerces-all xerces-all.dsw
c/Projects/Win32/VC6/xerces-all/XercesLib XercesLib.dsp
c/src/dom CharacterDataImpl.cpp ChildAndParentNode.cpp
CommonParentNode.cpp DOM_Document.cpp
DOM_Document.hpp DOM_DocumentFragment.hpp
DOM_Node.hpp DOM_Text.hpp DocumentFragmentImpl.hpp
DocumentImpl.cpp DocumentImpl.hpp Makefile.in
ParentNode.cpp TextImpl.cpp
c/tests Makefile.in configure.in
Added: c/src/dom DOM_Range.cpp DOM_Range.hpp DOM_RangeException.cpp
DOM_RangeException.hpp RangeImpl.cpp RangeImpl.hpp
c/tests/DOM/RangeTest Makefile.in RangeTest.cpp
Log:
DOM Level 2 Range feature introduced
Revision Changes Path
1.19 +12 -0 xml-xerces/c/Projects/Win32/VC6/xerces-all/xerces-all.dsw
Index: xerces-all.dsw
===================================================================
RCS file: /home/cvs/xml-xerces/c/Projects/Win32/VC6/xerces-all/xerces-all.dsw,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- xerces-all.dsw 2000/06/01 01:31:06 1.18
+++ xerces-all.dsw 2000/07/28 01:33:25 1.19
@@ -165,6 +165,18 @@
###############################################################################
+Project: "RangeTest"=".\RangeTest\RangeTest.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
Project: "Redirect"=".\Redirect\Redirect.dsp" - Package Owner=<4>
Package=<5>
1.39 +24 -0 xml-xerces/c/Projects/Win32/VC6/xerces-all/XercesLib/XercesLib.dsp
Index: XercesLib.dsp
===================================================================
RCS file: /home/cvs/xml-xerces/c/Projects/Win32/VC6/xerces-all/XercesLib/XercesLib.dsp,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -r1.38 -r1.39
--- XercesLib.dsp 2000/07/25 22:41:55 1.38
+++ XercesLib.dsp 2000/07/28 01:33:26 1.39
@@ -1064,6 +1064,22 @@
# End Source File
# Begin Source File
+SOURCE=..\..\..\..\..\src\dom\DOM_Range.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\dom\DOM_Range.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\dom\DOM_RangeException.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\dom\DOM_RangeException.hpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\..\..\src\dom\DOM_Text.cpp
# End Source File
# Begin Source File
@@ -1233,6 +1249,14 @@
# Begin Source File
SOURCE=..\..\..\..\..\src\dom\ProcessingInstructionImpl.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\dom\RangeImpl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\dom\RangeImpl.hpp
# End Source File
# Begin Source File
1.14 +29 -1 xml-xerces/c/src/dom/CharacterDataImpl.cpp
Index: CharacterDataImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/dom/CharacterDataImpl.cpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- CharacterDataImpl.cpp 2000/05/02 19:22:01 1.13
+++ CharacterDataImpl.cpp 2000/07/28 01:33:30 1.14
@@ -55,11 +55,13 @@
*/
/*
- * $Id: CharacterDataImpl.cpp,v 1.13 2000/05/02 19:22:01 aruna1 Exp $
+ * $Id: CharacterDataImpl.cpp,v 1.14 2000/07/28 01:33:30 aruna1 Exp $
*/
#include "CharacterDataImpl.hpp"
#include "DOM_DOMException.hpp"
+#include "RangeImpl.hpp"
+#include "DocumentImpl.hpp"
CharacterDataImpl::CharacterDataImpl(DocumentImpl *ownerDoc,
@@ -92,6 +94,19 @@
throw DOM_DOMException(DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR,
null);
data = value.clone();
+
+ if (this->getOwnerDocument() != null) {
+ typedef RefVectorOf<RangeImpl> RangeImpls;
+ RangeImpls* ranges = this->getOwnerDocument()->getRanges();
+ if (ranges != null) {
+ unsigned int sz = ranges->size();
+ if (sz != 0) {
+ for (unsigned int i =0; i<sz; i++) {
+ ranges->elementAt(i)->receiveReplacedText( this);
+ }
+ }
+ }
+ }
};
@@ -115,6 +130,19 @@
// when parameter values are bad.
//
data.deleteData(offset, count);
+
+ if (this->getOwnerDocument() != null) {
+ typedef RefVectorOf<RangeImpl> RangeImpls;
+ RangeImpls* ranges = this->getOwnerDocument()->getRanges();
+ if (ranges != null) {
+ unsigned int sz = ranges->size();
+ if (sz != 0) {
+ for (unsigned int i =0; i<sz; i++) {
+ ranges->elementAt(i)->updateRangeForDeletedText( (DOM_Node&)*this, offset, count);
+ }
+ }
+ }
+ }
};
1.3 +2 -1 xml-xerces/c/src/dom/ChildAndParentNode.cpp
Index: ChildAndParentNode.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/dom/ChildAndParentNode.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ChildAndParentNode.cpp 2000/06/22 22:19:42 1.2
+++ ChildAndParentNode.cpp 2000/07/28 01:33:30 1.3
@@ -64,7 +64,7 @@
//
/*
- * $Id: ChildAndParentNode.cpp,v 1.2 2000/06/22 22:19:42 aruna1 Exp $
+ * $Id: ChildAndParentNode.cpp,v 1.3 2000/07/28 01:33:30 aruna1 Exp $
*/
/**
@@ -77,6 +77,7 @@
#include "DOM_DOMException.hpp"
#include "TextImpl.hpp"
#include "DocumentImpl.hpp"
+#include "RangeImpl.hpp"
#define THIS_CLASS ChildAndParentNode
#define PARENT_CLASS ChildNode
1.3 +69 -41 xml-xerces/c/src/dom/CommonParentNode.cpp
Index: CommonParentNode.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/dom/CommonParentNode.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- CommonParentNode.cpp 2000/07/13 00:08:39 1.2
+++ CommonParentNode.cpp 2000/07/28 01:33:30 1.3
@@ -55,7 +55,7 @@
*/
/*
- * $Id: CommonParentNode.cpp,v 1.2 2000/07/13 00:08:39 aruna1 Exp $
+ * $Id: CommonParentNode.cpp,v 1.3 2000/07/28 01:33:30 aruna1 Exp $
*/
@@ -270,6 +270,19 @@
}
}
changed();
+
+ if (this->getOwnerDocument() != null) {
+ typedef RefVectorOf<RangeImpl> RangeImpls;
+ RangeImpls* ranges = this->getOwnerDocument()->getRanges();
+ if ( ranges != null) {
+ unsigned int sz = ranges->size();
+ if (sz != 0) {
+ for (unsigned int i =0; i<sz; i++) {
+ ranges->elementAt(i)->updateRangeForInsertedNode(newInternal);
+ }
+ }
+ }
+ }
return newInternal;
};
@@ -287,48 +300,63 @@
{
if (readOnly())
throw DOM_DOMException(
- DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);
-
- if (oldChild != null && oldChild->getParentNode() != this)
- throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null);
-
- ChildNode * oldInternal = (ChildNode *) oldChild;
-
- // Patch tree past oldChild
- ChildNode *prev = oldInternal->previousSibling;
- ChildNode *next = oldInternal->nextSibling;
-
- if (oldInternal != firstChild)
- prev->nextSibling = next;
- else {
- oldInternal->firstChild(false);
- firstChild = next;
- if (next != null) {
- next->firstChild(true);
- }
- }
-
- if (next != null) // oldInternal != lastChild
- next->previousSibling = prev;
- else {
- if (firstChild != null) {
- // store lastChild as previous sibling of first child
- firstChild->previousSibling = prev;
- }
- }
-
- // Remove oldChild's references to tree
- oldInternal->ownerNode = ownerDocument;
- oldInternal->owned(false);
- oldInternal->nextSibling = null;
- oldInternal->previousSibling = null;
+ DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);
+
+ if (oldChild != null && oldChild->getParentNode() != this)
+ throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null);
+
+ //fix other ranges for change before deleting the node
+ if (this->getOwnerDocument() != null ) {
+ typedef RefVectorOf<RangeImpl> RangeImpls;
+ RangeImpls* ranges = this->getOwnerDocument()->getRanges();
+ if (ranges != null) {
+ unsigned int sz = ranges->size();
+ if (sz != 0) {
+ for (unsigned int i =0; i<sz; i++) {
+ if (ranges->elementAt(i) != null)
+ ranges->elementAt(i)->updateRangeForDeletedNode(oldChild);
+ }
+ }
+ }
+ }
+
+ ChildNode * oldInternal = (ChildNode *) oldChild;
+
+ // Patch tree past oldChild
+ ChildNode *prev = oldInternal->previousSibling;
+ ChildNode *next = oldInternal->nextSibling;
+
+ if (oldInternal != firstChild)
+ prev->nextSibling = next;
+ else {
+ oldInternal->firstChild(false);
+ firstChild = next;
+ if (next != null) {
+ next->firstChild(true);
+ }
+ }
+
+ if (next != null) // oldInternal != lastChild
+ next->previousSibling = prev;
+ else {
+ if (firstChild != null) {
+ // store lastChild as previous sibling of first child
+ firstChild->previousSibling = prev;
+ }
+ }
+
+ // Remove oldChild's references to tree
+ oldInternal->ownerNode = ownerDocument;
+ oldInternal->owned(false);
+ oldInternal->nextSibling = null;
+ oldInternal->previousSibling = null;
+
+ changed();
+
+ return oldInternal;
+};
- changed();
- return oldInternal;
-};
-
-
NodeImpl *THIS_CLASS::replaceChild(NodeImpl *newChild, NodeImpl *oldChild)
{
insertBefore(newChild, oldChild);
1.10 +7 -31 xml-xerces/c/src/dom/DOM_Document.cpp
Index: DOM_Document.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/dom/DOM_Document.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- DOM_Document.cpp 2000/05/09 00:22:31 1.9
+++ DOM_Document.cpp 2000/07/28 01:33:30 1.10
@@ -55,43 +55,7 @@
*/
/*
- * $Log: DOM_Document.cpp,v $
- * Revision 1.9 2000/05/09 00:22:31 andyh
- * Memory Cleanup. XMLPlatformUtils::Terminate() deletes all lazily
- * allocated memory; memory leak checking tools will no longer report
- * that leaks exist. (DOM GetElementsByTagID temporarily removed
- * as part of this.)
- *
- * Revision 1.8 2000/04/25 20:29:33 aruna1
- * DOM_XMLDecl type node introduced to get the information of the
- * XML Declaration in a document and store it part of the tree
- *
- * Revision 1.7 2000/03/24 21:26:32 abagchi
- * Added getElementById() from patch submitted by Jeff Lewis
- *
- * Revision 1.6 2000/03/02 19:53:55 roddey
- * This checkin includes many changes done while waiting for the
- * 1.1.0 code to be finished. I can't list them all here, but a list is
- * available elsewhere.
- *
- * Revision 1.5 2000/02/06 07:47:28 rahulj
- * Year 2K copyright swat.
- *
- * Revision 1.4 2000/02/04 01:49:29 aruna1
- * TreeWalker and NodeIterator changes
- *
- * Revision 1.3 2000/01/05 01:16:07 andyh
- * DOM Level 2 core, namespace support added.
- *
- * Revision 1.2 1999/11/23 01:48:14 rahulj
- * Changed 0L to 0. CC under HPUX is happy now.
- *
- * Revision 1.1.1.1 1999/11/09 01:08:50 twl
- * Initial checkin
- *
- * Revision 1.4 1999/11/08 20:44:15 rahul
- * Swat for adding in Product name and CVS comment log variable.
- *
+ * $Id: DOM_Document.cpp,v 1.10 2000/07/28 01:33:30 aruna1 Exp $
*/
@@ -282,4 +246,10 @@
{
return DOM_XMLDecl( ((DocumentImpl *)fImpl)->createXMLDecl(version, encoding, standalone));
}
+
+DOM_Range DOM_Document::createRange()
+{
+ return DOM_Range( ((DocumentImpl *)fImpl)->createRange() );
+}
+
1.13 +15 -45 xml-xerces/c/src/dom/DOM_Document.hpp
Index: DOM_Document.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/dom/DOM_Document.hpp,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- DOM_Document.hpp 2000/04/25 20:29:33 1.12
+++ DOM_Document.hpp 2000/07/28 01:33:30 1.13
@@ -55,55 +55,7 @@
*/
/*
- * $Log: DOM_Document.hpp,v $
- * Revision 1.12 2000/04/25 20:29:33 aruna1
- * DOM_XMLDecl type node introduced to get the information of the
- * XML Declaration in a document and store it part of the tree
- *
- * Revision 1.11 2000/03/24 21:24:50 abagchi
- * Added getElementById() from patch submitted by Jeff Lewis
- *
- * Revision 1.10 2000/03/02 19:53:55 roddey
- * This checkin includes many changes done while waiting for the
- * 1.1.0 code to be finished. I can't list them all here, but a list is
- * available elsewhere.
- *
- * Revision 1.9 2000/02/24 20:11:27 abagchi
- * Swat for removing Log from API docs
- *
- * Revision 1.8 2000/02/17 17:47:24 andyh
- * Update Doc++ API comments
- * NameSpace update to track W3C
- * Changes were made by Chih Hsiang Chou
- *
- * Revision 1.7 2000/02/10 19:41:16 abagchi
- * Added docs for createNodeIterator and createTreeWalker
- *
- * Revision 1.6 2000/02/06 07:47:28 rahulj
- * Year 2K copyright swat.
- *
- * Revision 1.5 2000/02/04 01:49:28 aruna1
- * TreeWalker and NodeIterator changes
- *
- * Revision 1.4 2000/01/22 01:38:29 andyh
- * Remove compiler warnings in DOM impl classes
- *
- * Revision 1.3 2000/01/05 01:16:07 andyh
- * DOM Level 2 core, namespace support added.
- *
- * Revision 1.2 1999/12/21 07:47:06 robweir
- * Patches to support Xalan, where we need to create a
- * "special" DOM with subclassed Nodes.
- *
- * 1. Export the NodeImpl-derived classes
- * 2. Ensure that their constructors have at least protected access
- *
- * Revision 1.1.1.1 1999/11/09 01:08:51 twl
- * Initial checkin
- *
- * Revision 1.4 1999/11/08 20:44:15 rahul
- * Swat for adding in Product name and CVS comment log variable.
- *
+ * $Id: DOM_Document.hpp,v 1.13 2000/07/28 01:33:30 aruna1 Exp $
*/
#ifndef DOM_Document_HEADER_GUARD_
@@ -127,6 +79,7 @@
#include <dom/DOM_NodeIterator.hpp>
#include <dom/DOM_TreeWalker.hpp>
#include <dom/DOM_XMLDecl.hpp>
+#include <dom/DOM_Range.hpp>
class DocumentImpl;
class NodeIteratorImpl;
@@ -460,6 +413,18 @@
const DOMString& encoding,
const DOMString& standalone);
+ /**
+ * To create the range consisting of boundary-points and offset of the
+ * selected contents
+ *
+ * @return The initial state of the Range such that both the boundary-points
+ * are positioned at the beginning of the corresponding DOM_DOcument, before
+ * any content. The range returned can only be used to select content
+ * associated with this document, or with documentFragments and Attrs for
+ * which this document is the ownerdocument
+ */
+ DOM_Range createRange();
+
//@}
/** @name Getter functions */
//@{
@@ -644,6 +609,7 @@
DOM_Document (DocumentImpl *impl);
friend class DOM_Node;
+ friend class DocumentImpl;
friend class NodeIteratorImpl;
friend class DOM_DOMImplementation;
1.6 +3 -23 xml-xerces/c/src/dom/DOM_DocumentFragment.hpp
Index: DOM_DocumentFragment.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/dom/DOM_DocumentFragment.hpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- DOM_DocumentFragment.hpp 2000/03/02 19:53:55 1.5
+++ DOM_DocumentFragment.hpp 2000/07/28 01:33:31 1.6
@@ -55,32 +55,8 @@
*/
/*
- * $Log: DOM_DocumentFragment.hpp,v $
- * Revision 1.5 2000/03/02 19:53:55 roddey
- * This checkin includes many changes done while waiting for the
- * 1.1.0 code to be finished. I can't list them all here, but a list is
- * available elsewhere.
- *
- * Revision 1.4 2000/02/24 20:11:27 abagchi
- * Swat for removing Log from API docs
- *
- * Revision 1.3 2000/02/06 07:47:29 rahulj
- * Year 2K copyright swat.
- *
- * Revision 1.2 1999/12/21 07:47:06 robweir
- * Patches to support Xalan, where we need to create a
- * "special" DOM with subclassed Nodes.
- *
- * 1. Export the NodeImpl-derived classes
- * 2. Ensure that their constructors have at least protected access
- *
- * Revision 1.1.1.1 1999/11/09 01:08:51 twl
- * Initial checkin
- *
- * Revision 1.2 1999/11/08 20:44:16 rahul
- * Swat for adding in Product name and CVS comment log variable.
- *
-*/
+ * $Id: DOM_DocumentFragment.hpp,v 1.6 2000/07/28 01:33:31 aruna1 Exp $
+ */
#ifndef DOM_DocumentFragment_HEADER_GUARD_
#define DOM_DocumentFragment_HEADER_GUARD_
@@ -194,8 +170,7 @@
DOM_DocumentFragment(DocumentFragmentImpl *);
friend class DOM_Document;
-
-
+ friend class RangeImpl;
};
#endif
1.10 +2 -32 xml-xerces/c/src/dom/DOM_Node.hpp
Index: DOM_Node.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/dom/DOM_Node.hpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- DOM_Node.hpp 2000/04/25 20:29:33 1.9
+++ DOM_Node.hpp 2000/07/28 01:33:31 1.10
@@ -55,42 +55,7 @@
*/
/*
- * $Log: DOM_Node.hpp,v $
- * Revision 1.9 2000/04/25 20:29:33 aruna1
- * DOM_XMLDecl type node introduced to get the information of the
- * XML Declaration in a document and store it part of the tree
- *
- * Revision 1.8 2000/04/19 02:26:16 aruna1
- * Full support for DOM_EntityReference, DOM_Entity and DOM_DocumentType introduced
- *
- * Revision 1.7 2000/03/11 02:17:19 chchou
- * Fix bug # 29 to have the spefified flag set correctly for AttrImpl.
- *
- * Revision 1.6 2000/03/02 19:53:56 roddey
- * This checkin includes many changes done while waiting for the
- * 1.1.0 code to be finished. I can't list them all here, but a list is
- * available elsewhere.
- *
- * Revision 1.5 2000/02/24 20:11:28 abagchi
- * Swat for removing Log from API docs
- *
- * Revision 1.4 2000/02/17 17:47:25 andyh
- * Update Doc++ API comments
- * NameSpace update to track W3C
- * Changes were made by Chih Hsiang Chou
- *
- * Revision 1.3 2000/02/06 07:47:30 rahulj
- * Year 2K copyright swat.
- *
- * Revision 1.2 2000/01/05 01:16:07 andyh
- * DOM Level 2 core, namespace support added.
- *
- * Revision 1.1.1.1 1999/11/09 01:08:59 twl
- * Initial checkin
- *
- * Revision 1.4 1999/11/08 20:44:19 rahul
- * Swat for adding in Product name and CVS comment log variable.
- *
+ * $Id: DOM_Node.hpp,v 1.10 2000/07/28 01:33:31 aruna1 Exp $
*/
#ifndef DOM_Node_HEADER_GUARD_
@@ -661,6 +626,7 @@
friend class DOM_NodeList;
friend class DOMParser;
friend class DOM_Entity;
+ friend class RangeImpl;
};
1.8 +4 -0 xml-xerces/c/src/dom/DOM_Text.hpp
Index: DOM_Text.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/dom/DOM_Text.hpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- DOM_Text.hpp 2000/03/24 01:30:50 1.7
+++ DOM_Text.hpp 2000/07/28 01:33:31 1.8
@@ -56,6 +56,9 @@
/*
* $Log: DOM_Text.hpp,v $
+ * Revision 1.8 2000/07/28 01:33:31 aruna1
+ * DOM Level 2 Range feature introduced
+ *
* Revision 1.7 2000/03/24 01:30:50 chchou
* Fix bug #8 to support ignorable whitespace text nodes
*
@@ -211,6 +214,7 @@
DOM_Text(TextImpl *);
friend class DOM_Document;
+ friend class RangeImpl;
1.10 +2 -1 xml-xerces/c/src/dom/DocumentFragmentImpl.hpp
Index: DocumentFragmentImpl.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/dom/DocumentFragmentImpl.hpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- DocumentFragmentImpl.hpp 2000/04/27 02:52:43 1.9
+++ DocumentFragmentImpl.hpp 2000/07/28 01:33:31 1.10
@@ -57,7 +57,7 @@
*/
/*
- * $Id: DocumentFragmentImpl.hpp,v 1.9 2000/04/27 02:52:43 lehors Exp $
+ * $Id: DocumentFragmentImpl.hpp,v 1.10 2000/07/28 01:33:31 aruna1 Exp $
*/
//
@@ -87,6 +87,7 @@
virtual short getNodeType();
virtual bool isDocumentFragmentImpl();
virtual void setNodeValue(const DOMString &);
+
};
#endif
1.30 +53 -12 xml-xerces/c/src/dom/DocumentImpl.cpp
Index: DocumentImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/dom/DocumentImpl.cpp,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- DocumentImpl.cpp 2000/07/19 19:07:50 1.29
+++ DocumentImpl.cpp 2000/07/28 01:33:31 1.30
@@ -55,7 +55,7 @@
*/
/*
- * $Id: DocumentImpl.cpp,v 1.29 2000/07/19 19:07:50 aruna1 Exp $
+ * $Id: DocumentImpl.cpp,v 1.30 2000/07/28 01:33:31 aruna1 Exp $
*/
//
@@ -89,17 +89,20 @@
#include "NodeIDMap.hpp"
#include "DOM_Document.hpp"
#include <util/HashPtr.hpp>
+#include "RangeImpl.hpp"
+#include "DOM_Document.hpp"
DocumentImpl::DocumentImpl()
: ParentNode(this)
{
- docType=null;
- docElement=null;
- namePool = new DStringPool(257);
- iterators = 0L;
+ docType = null;
+ docElement = null;
+ namePool = new DStringPool(257);
+ iterators = 0L;
treeWalkers = 0L;
- fNodeIDMap = 0;
- userData = 0;
+ fNodeIDMap = 0;
+ userData = 0;
+ ranges = 0;
};
@@ -116,11 +119,12 @@
docElement=null;
appendChild(createElementNS(fNamespaceURI, qualifiedName)); //root element
- namePool = new DStringPool(257);
- iterators = 0;
+ namePool = new DStringPool(257);
+ iterators = 0;
treeWalkers = 0;
- fNodeIDMap = 0;
- userData = 0;
+ fNodeIDMap = 0;
+ userData = 0;
+ ranges = 0;
}
void DocumentImpl::setDocumentType(DocumentTypeImpl *doctype)
@@ -158,6 +162,11 @@
// The data in the vector is pointers owned by smart pointers, and will be cleaned up when they go away.
delete treeWalkers;
}
+
+ if (ranges != 0L) {
+ delete ranges;
+ ranges = 0;
+ }
if (userData)
delete userData;
@@ -696,7 +705,39 @@
return new XMLDeclImpl(this, version, encoding, standalone);
}
+RangeImpl* DocumentImpl::createRange()
+{
+
+ RangeImpl* range = new RangeImpl(DOM_Document(this));
+
+ if (ranges == 0L) {
+ ranges = new RangeImpls(1, false);
+ }
+ ranges->addElement(range);
+ return range;
+}
+
+RangeImpls* DocumentImpl::getRanges()
+{
+ return ranges;
+}
+void DocumentImpl::removeRange(RangeImpl* range)
+{
+ if (ranges != null) {
+ unsigned int sz = ranges->size();
+ if (sz !=0) {
+ for (unsigned int i =0; i<sz; i++) {
+ if (ranges->elementAt(i) == range) {
+ ranges->removeElementAt(i);
+ delete range;
+ break;
+ }
+ }
+ }
+ }
+}
+
/** Uses the kidOK lookup table to check whether the proposed
tree structure is legal.
@@ -727,7 +768,7 @@
1 << DOM_Node::CDATA_SECTION_NODE |
1 << DOM_Node::ENTITY_REFERENCE_NODE |
1 << DOM_Node::XML_DECL_NODE;
-
+
kidOK[DOM_Node::ATTRIBUTE_NODE] =
1 << DOM_Node::TEXT_NODE |
1 << DOM_Node::ENTITY_REFERENCE_NODE;
1.20 +10 -1 xml-xerces/c/src/dom/DocumentImpl.hpp
Index: DocumentImpl.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/dom/DocumentImpl.hpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- DocumentImpl.hpp 2000/06/28 17:51:37 1.19
+++ DocumentImpl.hpp 2000/07/28 01:33:31 1.20
@@ -58,7 +58,7 @@
*/
/*
- * $Id: DocumentImpl.hpp,v 1.19 2000/06/28 17:51:37 jpolast Exp $
+ * $Id: DocumentImpl.hpp,v 1.20 2000/07/28 01:33:31 aruna1 Exp $
*/
//
@@ -99,9 +99,11 @@
class DOM_DOMImplementation;
class DOMString;
class NodeIDMap;
+class RangeImpl;
typedef RefVectorOf<NodeIteratorImpl> NodeIterators;
typedef RefVectorOf<TreeWalkerImpl> TreeWalkers;
+typedef RefVectorOf<RangeImpl> RangeImpls;
class CDOM_EXPORT DocumentImpl: public ParentNode {
@@ -120,8 +122,11 @@
NodeIterators *iterators;
TreeWalkers *treeWalkers;
RefHashTableOf<void> *userData;
+ RangeImpls *ranges;
+
friend class NodeIteratorImpl;
friend class TreeWalkerImpl;
+ friend class RangeImpl;
friend class DOMParser;
public:
@@ -164,6 +169,10 @@
virtual XMLDeclImpl* createXMLDecl(const DOMString& version, const DOMString& encoding, const DOMString& standalone);
virtual void* getUserData();
virtual void setUserData(void* value);
+ virtual RangeImpl* createRange();
+ virtual RangeImpls* getRanges(); //non-standard api
+ virtual void removeRange(RangeImpl* range); //non-standard api
+
// helper functions to prevent storing userdata pointers on every node.
virtual void setUserData(NodeImpl* n, void* data);
1.16 +7 -1 xml-xerces/c/src/dom/Makefile.in
Index: Makefile.in
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/dom/Makefile.in,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- Makefile.in 2000/07/05 23:16:11 1.15
+++ Makefile.in 2000/07/28 01:33:32 1.16
@@ -54,7 +54,7 @@
# <http://www.apache.org/>.
#
#
-# $Id: Makefile.in,v 1.15 2000/07/05 23:16:11 jpolast Exp $
+# $Id: Makefile.in,v 1.16 2000/07/28 01:33:32 aruna1 Exp $
#
PLATFORM = @platform@
@@ -97,6 +97,8 @@
DOM_NodeList.hpp \
DOM_Notation.hpp \
DOM_ProcessingInstruction.hpp \
+ DOM_Range.hpp \
+ DOM_RangeException.hpp \
DOM_Text.hpp \
DOM_TreeWalker.hpp \
DOM_XMLDecl.hpp
@@ -131,6 +133,7 @@
NotationImpl.hpp \
ParentNode.hpp \
ProcessingInstructionImpl.hpp \
+ RangeImpl.hpp \
RefCountedImpl.hpp \
TextImpl.hpp \
TreeWalkerImpl.hpp \
@@ -169,6 +172,8 @@
DOM_TreeWalker.$(TO) \
DOM_Notation.$(TO) \
DOM_ProcessingInstruction.$(TO) \
+ DOM_Range.$(TO) \
+ DOM_RangeException.$(TO) \
DOM_Text.$(TO) \
DOM_XMLDecl.$(TO) \
DStringPool.$(TO) \
@@ -191,6 +196,7 @@
NotationImpl.$(TO) \
ParentNode.$(TO) \
ProcessingInstructionImpl.$(TO) \
+ RangeImpl.$(TO) \
RefCountedImpl.$(TO) \
TextImpl.$(TO) \
TreeWalkerImpl.$(TO) \
1.4 +2 -1 xml-xerces/c/src/dom/ParentNode.cpp
Index: ParentNode.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/dom/ParentNode.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ParentNode.cpp 2000/06/22 22:19:43 1.3
+++ ParentNode.cpp 2000/07/28 01:33:32 1.4
@@ -55,13 +55,14 @@
*/
/*
- * $Id: ParentNode.cpp,v 1.3 2000/06/22 22:19:43 aruna1 Exp $
+ * $Id: ParentNode.cpp,v 1.4 2000/07/28 01:33:32 aruna1 Exp $
*/
#include "ParentNode.hpp"
#include "DOM_DOMException.hpp"
#include "DocumentImpl.hpp"
#include "TextImpl.hpp"
+#include "RangeImpl.hpp"
#define THIS_CLASS ParentNode
#define PARENT_CLASS NodeImpl
1.13 +18 -2 xml-xerces/c/src/dom/TextImpl.cpp
Index: TextImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/dom/TextImpl.cpp,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- TextImpl.cpp 2000/05/02 19:22:02 1.12
+++ TextImpl.cpp 2000/07/28 01:33:32 1.13
@@ -55,7 +55,7 @@
*/
/*
- * $Id: TextImpl.cpp,v 1.12 2000/05/02 19:22:02 aruna1 Exp $
+ * $Id: TextImpl.cpp,v 1.13 2000/07/28 01:33:32 aruna1 Exp $
*/
#include "DocumentImpl.hpp"
@@ -64,6 +64,7 @@
#include "TextImpl.hpp"
#include "CharacterDataImpl.hpp"
#include "DStringPool.hpp"
+#include "RangeImpl.hpp"
static DOMString *gText; // will be lazily initialized to point to "#text"
@@ -114,15 +115,30 @@
unsigned int len = data.length();
if (offset >= len)
throw DOM_DOMException(DOM_DOMException::INDEX_SIZE_ERR, null);
-
+
TextImpl *newText =
(TextImpl *) getOwnerDocument()->createTextNode(
data.substringData(offset, data.length() - offset));
+
NodeImpl *parent = getParentNode();
if (parent != null)
parent->insertBefore(newText, getNextSibling());
data = data.substringData(0, offset);
+
+ if (this->getOwnerDocument() != null) {
+ typedef RefVectorOf<RangeImpl> RangeImpls;
+ RangeImpls* ranges = this->getOwnerDocument()->getRanges();
+ if (ranges != null) {
+ unsigned int sz = ranges->size();
+ if (sz != 0) {
+ for (unsigned int i =0; i<sz; i++) {
+ ranges->elementAt(i)->updateSplitInfo( this, newText);
+ }
+ }
+ }
+ }
+
return newText;
};
1.1 xml-xerces/c/src/dom/DOM_Range.cpp
Index: DOM_Range.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Id: DOM_Range.cpp,v 1.1 2000/07/28 01:33:31 aruna1 Exp $
*/
#include <dom/DOM_Range.hpp>
#include "DocumentImpl.hpp"
#include "RangeImpl.hpp"
DOM_Range::DOM_Range()
:fImpl(0)
{
}
DOM_Range::DOM_Range(RangeImpl* impl)
{
fImpl = impl;
RefCountedImpl::addRef(fImpl);
}
DOM_Range::~DOM_Range()
{
RefCountedImpl::removeRef (this->fImpl);
fImpl = 0;
};
DOM_Range & DOM_Range::operator = (const DOM_Range &other)
{
if (this->fImpl != other.fImpl)
{
RefCountedImpl::removeRef(this->fImpl);
this->fImpl = other.fImpl;
RefCountedImpl::addRef(this->fImpl);
}
return *this;
};
DOM_Range & DOM_Range::operator = (const DOM_NullPtr *other)
{
RefCountedImpl::removeRef(this->fImpl);
this->fImpl = 0;
return *this;
};
bool DOM_Range::operator != (const DOM_Range & other) const
{
return this->fImpl != other.fImpl;
};
bool DOM_Range::operator == (const DOM_Range & other) const
{
return this->fImpl == other.fImpl;
};
bool DOM_Range::operator != (const DOM_NullPtr * other) const
{
return this->fImpl != 0;
};
bool DOM_Range::operator == (const DOM_NullPtr * other) const
{
return this->fImpl == 0;
}
//getter functions
DOM_Node& DOM_Range::getStartContainer()
{
return ((RangeImpl *)fImpl)->getStartContainer();
}
unsigned int DOM_Range::getStartOffset()
{
return ((RangeImpl *)fImpl)->getStartOffset();
}
DOM_Node& DOM_Range::getEndContainer()
{
return ((RangeImpl *)fImpl)->getEndContainer();
}
unsigned int DOM_Range::getEndOffset()
{
return ((RangeImpl *)fImpl)->getEndOffset();
}
const DOM_Node& DOM_Range::getCommonAncestorContainer()
{
return ((RangeImpl *)fImpl)->getCommonAncestorContainer();
}
//setter functions
void DOM_Range::setStart(DOM_Node parent, unsigned int offset)
{
this->fImpl->setStart(parent, offset);
}
void DOM_Range::setEnd(DOM_Node parent, unsigned int offset)
{
this->fImpl->setEnd(parent, offset);
}
void DOM_Range::setStartBefore(DOM_Node refNode)
{
this->fImpl->setStartBefore(refNode);
}
void DOM_Range::setStartAfter(DOM_Node refNode)
{
this->fImpl->setStartAfter(refNode);
}
void DOM_Range::setEndBefore(DOM_Node refNode)
{
this->fImpl->setEndBefore(refNode);
}
void DOM_Range::setEndAfter(DOM_Node refNode)
{
this->fImpl->setEndAfter(refNode);
}
//misc functions
void DOM_Range::collapse(bool toStart)
{
this->fImpl->collapse(toStart);
}
bool DOM_Range::getCollapsed()
{
return ((RangeImpl *)fImpl)->getCollapsed();
}
void DOM_Range::selectNode(DOM_Node node)
{
((RangeImpl *)fImpl)->selectNode(node);
}
void DOM_Range::selectNodeContents(DOM_Node node)
{
((RangeImpl *)fImpl)->selectNodeContents(node);
}
//Functions related to comparing ange Boundrary-Points
short DOM_Range::compareBoundaryPoints(CompareHow how, const DOM_Range& range)
{
return ((RangeImpl *)fImpl)->compareBoundaryPoints(how, range.fImpl);
}
void DOM_Range::deleteContents()
{
((RangeImpl *)fImpl)->deleteContents();
}
DOM_DocumentFragment DOM_Range::extractContents()
{
return ((RangeImpl *)fImpl)->extractContents();
}
DOM_DocumentFragment DOM_Range::cloneContents()
{
return ((RangeImpl *)fImpl)->cloneContents();
}
void DOM_Range::insertNode(DOM_Node& node)
{
((RangeImpl *)fImpl)->insertNode(node);
}
//Misc functions
void DOM_Range::surroundContents(DOM_Node node)
{
((RangeImpl *)fImpl)->surroundContents(node);
}
DOM_Range DOM_Range::cloneRange()
{
return DOM_Range( ((RangeImpl *)fImpl)->cloneRange() );
}
DOMString DOM_Range::toString()
{
return ((RangeImpl *)fImpl)->toString();
}
void DOM_Range::detach()
{
((RangeImpl *)fImpl)->detach();
}
1.1 xml-xerces/c/src/dom/DOM_Range.hpp
Index: DOM_Range.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Id: DOM_Range.hpp,v 1.1 2000/07/28 01:33:31 aruna1 Exp $
*/
#ifndef DOM_Range_HEADER_GUARD_
#define DOM_Range_HEADER_GUARD_
#include <util/XercesDefs.hpp>
#include <dom/DOM_Node.hpp>
#include <dom/DOMString.hpp>
#include <dom/DOM_DocumentFragment.hpp>
class RangeImpl;
//class RangeImpl;
class CDOM_EXPORT DOM_Range {
public:
enum CompareHow {
START_TO_START = 0,
START_TO_END = 1,
END_TO_END = 2,
END_TO_START = 3
};
//c'tor & d'tor
DOM_Range();
~DOM_Range();
DOM_Range & operator = (const DOM_Range &other);
DOM_Range & operator = (const DOM_NullPtr *other);
bool operator != (const DOM_Range & other) const;
bool operator == (const DOM_Range & other) const;
bool operator != (const DOM_NullPtr * other) const;
bool operator == (const DOM_NullPtr * other) const;
//getter functions
DOM_Node& getStartContainer();
unsigned int getStartOffset();
DOM_Node& getEndContainer();
unsigned int getEndOffset();
bool getCollapsed();
const DOM_Node& getCommonAncestorContainer();
//setter functions
void setStart(DOM_Node parent, unsigned int offset);
void setEnd(DOM_Node parent, unsigned int offset);
void setStartBefore(DOM_Node refNode);
void setStartAfter(DOM_Node refNode);
void setEndBefore(DOM_Node refNode);
void setEndAfter(DOM_Node refNode);
//misc functions
void collapse(bool toStart);
void selectNode(DOM_Node node);
void selectNodeContents(DOM_Node node);
//Functions related to comparing range Boundrary-Points
short compareBoundaryPoints(CompareHow how, const DOM_Range& range);
void deleteContents();
DOM_DocumentFragment extractContents();
DOM_DocumentFragment cloneContents();
void insertNode(DOM_Node& node);
//Misc functions
void surroundContents(DOM_Node node);
DOM_Range cloneRange();
DOMString toString();
void detach();
protected:
DOM_Range(RangeImpl *);
RangeImpl *fImpl;
friend class DOM_Document;
};
#endif
1.1 xml-xerces/c/src/dom/DOM_RangeException.cpp
Index: DOM_RangeException.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: DOM_RangeException.cpp,v $
* Revision 1.1 2000/07/28 01:33:31 aruna1
* DOM Level 2 Range feature introduced
*
*/
#include "DOM_RangeException.hpp"
DOM_RangeException::DOM_RangeException()
: DOM_DOMException()
{
code = (RangeExceptionCode) 0;
};
DOM_RangeException::DOM_RangeException(RangeExceptionCode exCode, const DOMString &message)
: DOM_DOMException(exCode, message)
{
code = exCode;
};
DOM_RangeException::DOM_RangeException(const DOM_RangeException &other)
: DOM_DOMException(other)
{
code = other.code;
};
DOM_RangeException::~DOM_RangeException()
{
};
1.1 xml-xerces/c/src/dom/DOM_RangeException.hpp
Index: DOM_RangeException.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Log: DOM_RangeException.hpp,v $
* Revision 1.1 2000/07/28 01:33:31 aruna1
* DOM Level 2 Range feature introduced
*
*/
#ifndef DOM_RangeException_HEADER_GUARD_
#define DOM_RangeException_HEADER_GUARD_
#include <dom/DOM_DOMException.hpp>
/**
* Encapsulate range related DOM error or warning. DOM level 2 implementation.
*
* <p> The DOM will create and throw an instance of DOM_RangeException
* when an error condition in range is detected. Exceptions can occur
* when an application directly manipulates the range elements in DOM document
* tree that is produced by the parser.
*
* <p>Unlike the other classes in the C++ DOM API, DOM_RangeException
* is NOT a reference to an underlying implementation class, and
* does not provide automatic memory management. Code that catches
* a DOM Range exception is responsible for deleting it, or otherwise
* arranging for its disposal.
*
*/
class CDOM_EXPORT DOM_RangeException : public DOM_DOMException {
public:
/** @name Enumerators for DOM Range Exceptions */
//@{
enum RangeExceptionCode {
BAD_BOUNDARYPOINTS_ERR = 1,
INVALID_NODE_TYPE_ERR = 2
};
//@}
public:
/** @name Constructors and assignment operator */
//@{
/**
* Default constructor for DOM_RangeException.
*
*/
DOM_RangeException();
/**
* Constructor which takes an error code and a message.
*
* @param code The error code which indicates the exception
* @param message The string containing the error message
*/
DOM_RangeException(RangeExceptionCode code, const DOMString &message);
/**
* Copy constructor.
*
* @param other The object to be copied.
*/
DOM_RangeException(const DOM_RangeException &other);
//@}
/** @name Destructor. */
//@{
/**
* Destructor for DOM_RangeException. Applications are responsible
* for deleting DOM_RangeException objects that they catch after they
* have completed their exception processing.
*
*/
virtual ~DOM_RangeException();
//@}
/** @name Public variables. */
//@{
/**
* A code value, from the set defined by the RangeExceptionCode enum,
* indicating the type of error that occured.
*/
RangeExceptionCode code;
//@}
};
#endif
1.1 xml-xerces/c/src/dom/RangeImpl.cpp
Index: RangeImpl.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Id: RangeImpl.cpp,v 1.1 2000/07/28 01:33:32 aruna1 Exp $
*/
#include "NodeImpl.hpp"
#include "RangeImpl.hpp"
#include "DocumentImpl.hpp"
#include <dom/DOM_DOMException.hpp>
#include <dom/DOM_Document.hpp>
#include <dom/DocumentFragmentImpl.hpp>
#include <dom/DOM_Document.hpp>
#include <util/RefVectorOf.hpp>
#include <dom/DOM_RangeException.hpp>
#include <dom/DOM_DOMException.hpp>
#include <dom/DOM_Text.hpp>
//---------------------
// C'tor and D'tor
//---------------------
RangeImpl::RangeImpl(DOM_Document doc)
: fDocument(doc),
fStartContainer(doc),
fStartOffset(0),
fEndContainer(doc),
fEndOffset(0),
fDetached(false),
fCollapsed(true),
fCommonAncestorContainer(0),
fRemoveChild(0)
{
}
RangeImpl::RangeImpl(const RangeImpl& other)
{
fDocument = other.fDocument;
fStartContainer = other.fStartContainer;
fStartOffset = other.fStartOffset;
fEndContainer = other.fEndContainer;
fEndOffset = other.fEndOffset;
fDetached = other.fDetached;
fCollapsed = other.fCollapsed;
fCommonAncestorContainer = other.fCommonAncestorContainer;
fRemoveChild = other.fRemoveChild;
}
RangeImpl::~RangeImpl()
{
}
void RangeImpl::unreferenced()
{
if (((DocumentImpl*)fDocument.fImpl)->ranges != 0L) {
int sz = ((DocumentImpl*)fDocument.fImpl)->ranges->size();
for (int i=0; i< sz; i++) {
if (((DocumentImpl*)fDocument.fImpl)->ranges->elementAt(i) == this) {
((DocumentImpl*)fDocument.fImpl)->ranges->removeElementAt(i);
break;
}
}
}
delete this;
};
//-------------------------------
// Public getter functions
//-------------------------------
DOM_Node& RangeImpl::getStartContainer()
{
return fStartContainer;
}
unsigned int RangeImpl::getStartOffset()
{
return fStartOffset;
}
DOM_Node& RangeImpl::getEndContainer()
{
return fEndContainer;
}
unsigned int RangeImpl::getEndOffset()
{
return fEndOffset;
}
bool RangeImpl::getCollapsed()
{
if (fDetached)
{
throw DOM_DOMException(
DOM_DOMException::INVALID_STATE_ERR, null);
}
return ((fStartContainer == fEndContainer)
&& (fStartOffset == fEndOffset));
}
//-------------------------------
// Public getter functions
//-------------------------------
void RangeImpl::setStartContainer(const DOM_Node& node)
{
fStartContainer = node;
}
void RangeImpl::setStartOffset(unsigned int offset)
{
fStartOffset = offset;
}
void RangeImpl::setEndContainer(const DOM_Node& node)
{
fEndContainer = node;
}
void RangeImpl::setEndOffset(unsigned int offset)
{
fEndOffset = offset;
}
void RangeImpl::setCommonAncestorContainer(const DOM_Node& node)
{
fCommonAncestorContainer = node;
}
void RangeImpl::setStart(DOM_Node& refNode, unsigned int offset)
{
checkIndex(refNode, offset);
fStartContainer = refNode;
fStartOffset = offset;
if ((fDocument != refNode.getOwnerDocument() )
&& (refNode.getOwnerDocument().fImpl != 0) )
{
fDocument = refNode.getOwnerDocument();
collapse(true);
}
if (fStartOffset >= fEndOffset)
collapse(true); //collapse the range positions to start
else
fCollapsed = false;
}
void RangeImpl::setEnd(DOM_Node& refNode, unsigned int offset)
{
checkIndex(refNode, offset);
fEndContainer = refNode;
fEndOffset = offset;
if ((fDocument != refNode.getOwnerDocument() )
&& (refNode.getOwnerDocument().fImpl != 0) )
{
fDocument = refNode.getOwnerDocument();
collapse(false);
}
if (fEndOffset <= fStartOffset)
collapse(false); //collapse the range positions to end
else
fCollapsed = false;
}
void RangeImpl::setStartBefore(DOM_Node& refNode)
{
validateNode(refNode);
fStartContainer = refNode.getParentNode();
unsigned int i = 0;
for (DOM_Node n = refNode; n!=null; n = n.getPreviousSibling()) {
i++;
}
if (i == 0)
fStartOffset = 0;
else
fStartOffset = i-1;
if ((fDocument != refNode.getOwnerDocument())
&& (refNode.getOwnerDocument().fImpl != 0) )
{
fDocument = refNode.getOwnerDocument();
collapse(true);
}
if (fStartOffset > fEndOffset)
collapse(true); //collapse the range positions to start
else
fCollapsed = false;
}
void RangeImpl::setStartAfter(DOM_Node& refNode)
{
validateNode(refNode);
fStartContainer = refNode.getParentNode();
unsigned int i = 0;
for (DOM_Node n = refNode; n!=null; n = n.getPreviousSibling()) {
i++;
}
fStartOffset = i;
if ((fDocument != refNode.getOwnerDocument() )
&& (refNode.getOwnerDocument().fImpl != 0) )
{
fDocument = refNode.getOwnerDocument();
collapse(true);
}
if (fStartOffset > fEndOffset)
collapse(true); //collapse the range positions to start
else
fCollapsed = false;
}
void RangeImpl::setEndBefore(DOM_Node& refNode)
{
validateNode(refNode);
fEndContainer = refNode.getParentNode();
unsigned int i = 0;
for (DOM_Node n = refNode; n!=null; n = n.getPreviousSibling(), i++);
if (i< 1)
fEndOffset = 0;
else
fEndOffset = i-1;
if ((fDocument != refNode.getOwnerDocument() )
&& (refNode.getOwnerDocument().fImpl != 0) )
{
fDocument = refNode.getOwnerDocument();
collapse(true);
}
if (fEndOffset < fStartOffset)
collapse(false); //collapse the range positions to end
else
fCollapsed = false;
}
void RangeImpl::setEndAfter(DOM_Node& refNode)
{
validateNode(refNode);
fEndContainer = refNode.getParentNode();
unsigned int i = 0;
for (DOM_Node n = refNode; n!=null; n = n.getPreviousSibling(), i++);
if (i ==0)
fEndOffset = 0;
else
fEndOffset = i;
if ((fDocument != refNode.getOwnerDocument() )
&& (refNode.getOwnerDocument().fImpl != 0) )
{
fDocument = refNode.getOwnerDocument();
collapse(true);
}
if (fEndOffset < fStartOffset)
collapse(false); //collapse the range positions to end
else
fCollapsed = false;
}
//-------------------------------
// Public Misc. functions
//-------------------------------
void RangeImpl::detach()
{
fDetached = true;
//nullify nodes
fStartContainer = 0;
fStartOffset = 0;
fEndContainer = 0;
fEndOffset = 0;
fCollapsed = true;
fCommonAncestorContainer = 0;
fRemoveChild = 0;
}
void RangeImpl::collapse(bool toStart)
{
if( fDetached) {
throw DOM_DOMException(
DOM_DOMException::INVALID_STATE_ERR, null);
}
if (toStart) {
fEndContainer = fStartContainer;
fEndOffset = fStartOffset;
} else {
fStartContainer = fEndContainer;
fStartOffset = fEndOffset;
}
fCollapsed = true;
}
void RangeImpl::selectNode(DOM_Node& refNode)
{
validateNode(refNode);
short type = refNode.getNodeType();
if (type == DOM_Node::ATTRIBUTE_NODE
|| type == DOM_Node::ENTITY_NODE
|| type == DOM_Node::NOTATION_NODE
|| type == DOM_Node::DOCUMENT_TYPE_NODE
|| type == DOM_Node::DOCUMENT_FRAGMENT_NODE) {
throw DOM_RangeException(
DOM_RangeException::INVALID_NODE_TYPE_ERR, null);
}
//First check for the text type node
if (type == DOM_Node::TEXT_NODE)
{
//The node itself is the container.
fStartContainer = refNode;
fEndContainer = refNode;
//Select all the contents of the node
fStartOffset = 0;
fEndOffset = ((DOM_Text &)refNode).getLength();
return;
}
DOM_Node parent = refNode.getParentNode();
if (parent != null ) // REVIST: what to do if it IS null?
{
fStartContainer = parent;
fEndContainer = parent;
unsigned int i = 0;
for (DOM_Node n = parent.getFirstChild(); n!=null, n!=refNode; n = n.getNextSibling()) {
i++;
}
fStartOffset = i;
fEndOffset = fStartOffset+1;
}
}
void RangeImpl::selectNodeContents(DOM_Node& node)
{
validateNode(node);
short type = node.getNodeType();
if (type == DOM_Node::ENTITY_NODE
|| type == DOM_Node::NOTATION_NODE
|| type == DOM_Node::DOCUMENT_TYPE_NODE) {
throw DOM_RangeException(
DOM_RangeException::INVALID_NODE_TYPE_ERR, null);
}
fStartContainer = node;
fEndContainer = node;
fStartOffset = 0;
if (node.getNodeType() == DOM_Node::TEXT_NODE ) {
fEndOffset = ((DOM_Text &)node).getLength();
return;
}
DOM_Node first = node.getFirstChild();
if (first == null) {
fEndOffset = 0;
return;
}
unsigned int i = 0;
for (DOM_Node n = first; n!=null; n = n.getNextSibling()) {
i++;
}
fEndOffset = i;
}
void RangeImpl::surroundContents(DOM_Node& newParent)
{
if (newParent==null) return;
//check for elimination criteria
if( fDetached) {
throw DOM_DOMException(
DOM_DOMException::INVALID_STATE_ERR, null);
}
if (newParent.getOwnerDocument() !=fDocument) {
throw DOM_DOMException(
DOM_DOMException::WRONG_DOCUMENT_ERR, null);
}
int type = newParent.getNodeType();
if (type == DOM_Node::ATTRIBUTE_NODE
|| type == DOM_Node::ENTITY_NODE
|| type == DOM_Node::NOTATION_NODE
|| type == DOM_Node::DOCUMENT_TYPE_NODE
|| type == DOM_Node::DOCUMENT_NODE
|| type == DOM_Node::DOCUMENT_FRAGMENT_NODE)
{
throw DOM_RangeException(
DOM_RangeException::INVALID_NODE_TYPE_ERR, null);
}
DOM_Node root = getCommonAncestorContainer();
DOM_Node realStart = fStartContainer;
DOM_Node realEnd = fEndContainer;
if (fStartContainer.getNodeType() == DOM_Node::TEXT_NODE) {
realStart = fStartContainer.getParentNode();
}
if (fEndContainer.getNodeType() == DOM_Node::TEXT_NODE) {
realEnd = fEndContainer.getParentNode();
}
if (realStart != realEnd) {
throw DOM_RangeException(
DOM_RangeException::BAD_BOUNDARYPOINTS_ERR, null);
}
DOM_DocumentFragment frag = extractContents();
insertNode(newParent);
newParent.appendChild(frag);
selectNode(newParent);
}
short RangeImpl::compareBoundaryPoints(DOM_Range::CompareHow how, RangeImpl* srcRange)
{
if (fDocument != srcRange->fDocument) {
throw DOM_DOMException(
DOM_DOMException::WRONG_DOCUMENT_ERR, null);
}
if( fDetached) {
throw DOM_DOMException(
DOM_DOMException::INVALID_STATE_ERR, null);
}
DOM_Node pointA, pointB;
int offsetA, offsetB;
switch (how)
{
case (DOM_Range::START_TO_START) :
pointA = srcRange->getStartContainer();
pointB = fStartContainer;
offsetA = srcRange->getStartOffset();
offsetB = fStartOffset;
break;
case (DOM_Range::START_TO_END) :
pointA = srcRange->getStartContainer();
pointB = fEndContainer;
offsetA = srcRange->getStartOffset();
offsetB = fEndOffset;
break;
case (DOM_Range::END_TO_START) :
pointA = srcRange->getEndContainer();
pointB = fStartContainer;
offsetA = srcRange->getEndOffset();
offsetB = fStartOffset;
break;
case (DOM_Range::END_TO_END) :
pointA = srcRange->getEndContainer();
pointB = fEndContainer;
offsetA = srcRange->getEndOffset();
offsetB = fEndOffset;
break;
}
// case 1: same container
if (pointA == pointB) {
if (offsetA < offsetB) return -1; //A before B
if (offsetA == offsetB) return 0; //A equal to B
return 1; // A after B
}
// case 2: Child C of container A is ancestor of B
for (DOM_Node node = pointA.getFirstChild(); node != null; node=node.getNextSibling()) {
if (isAncestorOf(node, pointB)) {
int index = indexOf(node, pointA);
if (offsetA <= index) return -1;
return 1;
}
}
// case 3: Child C of container B is ancestor of A
for (DOM_Node nd = pointB.getFirstChild(); nd != null; nd=nd.getNextSibling()) {
if (isAncestorOf(nd, pointA)) {
int index = indexOf(nd, pointB);
if (index < offsetB ) return -1;
return 1; //B strictly before A
}
}
// case 4: preorder traversal of context tree.
DOM_Node ancestor = commonAncestorOf(pointA, pointB);
DOM_Node current = ancestor;
do {
if (current == pointA) return -1;
if (current == pointB) return 1;
current = nextNode(current, true);
}
while (current!=null && current!=ancestor);
return -2; // this should never happen
}
void RangeImpl:: deleteContents()
{
if ((fStartContainer == null) || (fEndContainer == null) ) return;
checkReadOnly(fStartContainer, fEndContainer, fStartOffset, fEndOffset);
if( fDetached) {
throw DOM_DOMException(
DOM_DOMException::INVALID_STATE_ERR, null);
}
DOM_Node current = fStartContainer;
// if same container, simplify case
if (fStartContainer == fEndContainer) {
if (fStartOffset == fEndOffset) { // already collapsed
return;
}
if (fStartOffset > fEndOffset)
throw DOM_RangeException(DOM_RangeException::BAD_BOUNDARYPOINTS_ERR, null);
if (fStartContainer.getNodeType() == DOM_Node::TEXT_NODE) {
DOMString value = fStartContainer.getNodeValue();
unsigned int realStart = fStartOffset;
unsigned int realEnd = fEndOffset;
if (fStartOffset > value.length()) realStart = value.length()-1;
if (fEndOffset > value.length()) realEnd = value.length()-1;
((DOM_Text &)fStartContainer).deleteData(realStart, realEnd-realStart);
} else {
current = fStartContainer.getFirstChild();
unsigned int i = 0;
//move till the start offset
for(i = 0; i < fStartOffset && current != null; i++) {
current=current.getNextSibling();
}
//delete all children after the start offset to end offset
for(i = 0; i < (fEndOffset-fStartOffset) && (current != null); i++) {
DOM_Node newCurrent = current.getNextSibling();
removeChild(fStartContainer, current);
current = newCurrent;
}
}
collapse(true);
return;
}
//The case of partial selections and when start container is not the same as end one
bool deleteCurrent = false;
// initialize current for startContainer.
if (current.getNodeType() == DOM_Node::TEXT_NODE) {
((DOM_Text &)current).deleteData(fStartOffset, current.getNodeValue().length()-fStartOffset);
} else {
current = current.getFirstChild();
for (unsigned int i = 0 ; i < fStartOffset && current != null; i++){
current = current.getNextSibling();
}
if (current == null) {
current = fStartContainer;
} else if (current != fStartContainer)
deleteCurrent = true;
}
DOM_Node parent = null;
DOM_Node next;
DOM_Node partialNode = null;
int partialInt = START;
DOM_Node startRoot = null;
DOM_Node root = getCommonAncestorContainer();
// traverse up from the startContainer...
// current starts as the node to delete;
while (current != root && current != null) {
parent = current.getParentNode();
if (parent == root) {
if (startRoot == null)
startRoot = current;
} else {
if (partialNode == null) {
partialNode = parent;
partialInt = AFTER;
}
}
if (parent != root) {
next = current.getNextSibling();
DOM_Node nextnext;
while (next != null) {
nextnext = next.getNextSibling();
removeChild(parent, next);
next = nextnext;
}
}
if (deleteCurrent) {
removeChild(parent, current);
deleteCurrent = false;
}
current = parent;
}
DOM_Node endRoot = null;
// initialize current for endContainer.
current = fEndContainer;
if (current.getNodeType() == DOM_Node::TEXT_NODE) {
((DOM_Text &)current).deleteData(0, fEndOffset);
} else {
if (fEndOffset == 0) { // "before"
current = fEndContainer;
}
else {
current = current.getFirstChild();
for(unsigned int i = 1; i < fEndOffset && current != null; i++) {
current=current.getNextSibling();
}
if (current==null) { // REVIST: index-out-of-range what to do?
current = fEndContainer.getLastChild();
} else
if (current != fStartContainer) {
deleteCurrent = true;
}
}
}
// traverse up from the endContainer...
while (current != root && current != null) {
parent = current.getParentNode();
if (parent == root) {
if (endRoot == null)
endRoot = current;
} else {
if (partialNode==null) {
partialNode = parent;
partialInt = BEFORE;
}
}
if (parent != root && parent != null) {
next = current.getPreviousSibling();
DOM_Node nextnext;
while (next != null) {
nextnext = next.getPreviousSibling();
removeChild(parent, next);
next = nextnext;
}
}
if (deleteCurrent) {
removeChild(parent, current);
deleteCurrent = false;
}
current = parent;
}
//if (endRoot == null || startRoot == null) return; //REVIST
current = endRoot.getPreviousSibling();
DOM_Node prev = null;
while (current != null && current != startRoot ) {
prev = current.getPreviousSibling();
parent = current.getParentNode();
if (parent != null) {
removeChild(parent, current);
}
current = prev;
}
if (partialNode == null) {
collapse(true);
} else if (partialInt == AFTER) {
setStartAfter(partialNode);
setEndAfter(partialNode);
} else if (partialInt == BEFORE) {
setStartBefore(partialNode);
setEndBefore(partialNode);
}
}
DOM_DocumentFragment RangeImpl::extractContents()
{
return traverseContents(EXTRACT_CONTENTS);
}
DOM_DocumentFragment RangeImpl::cloneContents()
{
return traverseContents(CLONE_CONTENTS);
}
void RangeImpl::insertNode(DOM_Node& newNode)
{
if (newNode == null) return; //don't have to do anything
if (fStartContainer.getParentNode().fImpl->readOnly()) {
throw DOM_DOMException(
DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);
}
if (fDocument != newNode.getOwnerDocument()) {
throw DOM_DOMException(
DOM_DOMException::WRONG_DOCUMENT_ERR, null);
}
// Prevent cycles in the tree.
//isKidOK() is not checked here as its taken care by insertBefore() function
if (isAncestorOf( newNode, fStartContainer)) {
throw DOM_DOMException(
DOM_DOMException::HIERARCHY_REQUEST_ERR, null);
}
if( fDetached) {
throw DOM_DOMException(
DOM_DOMException::INVALID_STATE_ERR, null);
}
int type = newNode.getNodeType();
if (type == DOM_Node::ATTRIBUTE_NODE
|| type == DOM_Node::ENTITY_NODE
|| type == DOM_Node::NOTATION_NODE
|| type == DOM_Node::DOCUMENT_NODE
|| type == DOM_Node::DOCUMENT_FRAGMENT_NODE)
{
throw DOM_RangeException(
DOM_RangeException::INVALID_NODE_TYPE_ERR, null);
}
DOM_Node parent;
DOM_Node next;
if (fStartContainer.getNodeType() == DOM_Node::TEXT_NODE) {
//set 'parent' and 'next' here
parent = fStartContainer.getParentNode();
//split the text nodes
if (fStartOffset > 0)
((DOM_Text &)fStartContainer).splitText(fStartOffset);
//update the new start information later. After inserting the first newNode
if (fStartOffset == 0)
next = fStartContainer;
else
next = fStartContainer.getNextSibling();
} // end of text handling
else {
parent = fStartContainer;
next = fStartContainer.getFirstChild();
for(unsigned int i = 0; (i < fStartOffset) && (next != null); i++) {
next=next.getNextSibling();
}
}
if (parent != null) {
if (next != null)
parent.insertBefore(newNode, next);
else
parent.appendChild(newNode);
}
}
RangeImpl* RangeImpl::cloneRange()
{
if( fDetached) {
throw DOM_DOMException(
DOM_DOMException::INVALID_STATE_ERR, null);
}
RangeImpl* range = ((DocumentImpl*)fDocument.fImpl)->createRange();
range->setStart(fStartContainer, fStartOffset);
range->setEnd(fEndContainer, fEndOffset);
return range;
}
DOMString RangeImpl::toString()
{
if( fDetached) {
throw DOM_DOMException(
DOM_DOMException::INVALID_STATE_ERR, null);
}
DOM_Node node = fStartContainer;
DOMString tempString;
if ( (fStartContainer.getNodeType() == DOM_Node::TEXT_NODE)
|| (fStartContainer.getNodeType() == DOM_Node::CDATA_SECTION_NODE) ) {
if (fStartContainer == fEndContainer) {
tempString.appendData(fStartContainer.getNodeValue().substringData(fStartOffset, fEndOffset));
return tempString;
} else {
int length = fStartContainer.getNodeValue().length();
tempString.appendData(fStartContainer.getNodeValue().substringData(fStartOffset, length - fStartOffset));
}
}else if (node == fEndContainer){
DOM_Node anode = node.getFirstChild();
unsigned int i = 0;
for ( ;i<fStartOffset; i++)
anode = anode.getNextSibling();
for( ; ( i<fEndOffset || anode!=null); anode = anode.getNextSibling(), i++) {
if( (anode.getNodeType() == DOM_Node::TEXT_NODE)
|| (anode.getNodeType() == DOM_Node::CDATA_SECTION_NODE)) {
tempString.appendData(anode.getNodeValue());
}
}
return tempString;
}
DOM_Node root = getCommonAncestorContainer();
while (node != fEndContainer) {
node = nextNode(node, true);
if ((node == null) || (node == fEndContainer)) break;
if (node.getNodeType() == DOM_Node::TEXT_NODE
|| node.getNodeType() == DOM_Node::CDATA_SECTION_NODE
) {
tempString.appendData(node.getNodeValue());
}
}
if (fEndContainer.getNodeType() == DOM_Node::TEXT_NODE
|| fEndContainer.getNodeType() == DOM_Node::CDATA_SECTION_NODE) {
tempString.appendData(fEndContainer.getNodeValue().substringData(0,fEndOffset));
}
return tempString;
}
DOM_Document RangeImpl::getDocument()
{
return fDocument;
}
const DOM_Node& RangeImpl::getCommonAncestorContainer()
{
return fCommonAncestorContainer = commonAncestorOf(fStartContainer, fEndContainer);
}
//---------------------
//private functions
//---------------------
bool RangeImpl::isValidAncestorType(DOM_Node& node)
{
for (DOM_Node aNode = node; aNode!=null; aNode = aNode.getParentNode()) {
short type = aNode.getNodeType();
if ( type == DOM_Node::ENTITY_NODE
|| type == DOM_Node::NOTATION_NODE
|| type == DOM_Node::DOCUMENT_TYPE_NODE)
return false;
}
return true;
}
bool RangeImpl::isAncestorOf(const DOM_Node& a, const DOM_Node& b) {
for (DOM_Node node=b; node != null; node=node.getParentNode()) {
if (node == a) return true;
}
return false;
}
unsigned short RangeImpl::indexOf(const DOM_Node& child, const DOM_Node& parent)
{
unsigned short i = 0;
if (child.getParentNode() != parent) return -1;
for(DOM_Node node = child; node!= null; node=node.getPreviousSibling()) {
i++;
}
return i;
}
void RangeImpl::validateNode(DOM_Node& node)
{
if( fDetached) {
throw DOM_DOMException(
DOM_DOMException::INVALID_STATE_ERR, null);
}
if ( !isValidAncestorType(node)) {
throw DOM_RangeException(
DOM_RangeException::INVALID_NODE_TYPE_ERR, null);
}
}
DOM_Node RangeImpl::commonAncestorOf(DOM_Node& pointA, DOM_Node& pointB)
{
if (fDetached)
throw DOM_DOMException(DOM_DOMException::INVALID_STATE_ERR, null);
if (pointA.getOwnerDocument() != pointB.getOwnerDocument())
throw DOM_DOMException( DOM_DOMException::WRONG_DOCUMENT_ERR, null );
//if the containers are same then it itself is its common ancestor.
if (pointA == pointB)
return pointA;
typedef RefVectorOf<NodeImpl> VectorNodes;
VectorNodes* startV= new VectorNodes(1, false);
DOM_Node node;
for (node=fStartContainer; node != null; node=node.getParentNode())
{
startV->addElement(node.fImpl);
}
VectorNodes* endV = new VectorNodes(1, false);
for (node=fEndContainer; node != null; node=node.getParentNode())
{
endV->addElement(node.fImpl);
}
int s = startV->size()-1;
int e = endV->size()-1;
NodeImpl* commonAncestor;
while (s>=0 && e>=0) {
if (startV->elementAt(s) == endV->elementAt(e)) {
commonAncestor = startV->elementAt(s);
}
else break;
--s;
--e;
}
delete startV;
delete endV;
return DOM_Node(commonAncestor);
}
void RangeImpl::checkIndex(DOM_Node& node, unsigned int offset)
{
validateNode(node);
if (offset < 0) {
throw DOM_DOMException( DOM_DOMException::INDEX_SIZE_ERR, null );
}
short type = node.getNodeType();
if((type == DOM_Node::TEXT_NODE
|| type == DOM_Node::CDATA_SECTION_NODE
|| type == DOM_Node::COMMENT_NODE
|| type == DOM_Node::PROCESSING_INSTRUCTION_NODE)) {
if (offset > node.getNodeValue().length())
throw DOM_DOMException( DOM_DOMException::INDEX_SIZE_ERR, null );
else return;
}
DOM_Node child = node.getFirstChild();
unsigned int i = 0;
for (; child != null; i++) {
child = child.getNextSibling();
}
if (i < offset) {
throw DOM_DOMException( DOM_DOMException::INDEX_SIZE_ERR, null );
}
}
DOM_Node RangeImpl::nextNode(const DOM_Node& node, bool visitChildren) {
if (node == null) return null;
DOM_Node result;
if (visitChildren) {
result = node.getFirstChild();
if (result != null) {
return result;
}
}
// if hasSibling, return sibling
result = node.getNextSibling();
if (result != null) {
return result;
}
// return parent's 1st sibling.
DOM_Node parent = node.getParentNode();
while ( (parent != null) && (parent != fDocument) )
{
result = parent.getNextSibling();
if (result != null) {
return result;
} else {
parent = parent.getParentNode();
if (parent == fEndContainer) return parent;
}
}
// end of list, return null
return null;
}
/** This is the master traversal function which is used by
* both extractContents and cloneContents().
*/
DOM_DocumentFragment RangeImpl::traverseContents(TraversalType trvType)
{
if (fDetached)
throw DOM_DOMException(DOM_DOMException::INVALID_STATE_ERR, null);
if (fStartContainer == null || fEndContainer == null) {
return DOM_DocumentFragment(); // REVIST: Throw exception?
}
DOM_DocumentFragment frag = fDocument.createDocumentFragment() ;
DOM_Node current = fStartContainer;
DOM_Node cloneCurrent = null;
DOM_Node cloneParent = null;
DOM_Node partialNode = null;
int partialInt = START;
// if same container, simplify case
if (fStartContainer == fEndContainer) {
if (fStartOffset == fEndOffset) { // eg collapsed
return frag; // REVIST: what is correct re spec?
}
if (fStartContainer.getNodeType() == DOM_Node::TEXT_NODE) {
cloneCurrent = fStartContainer.cloneNode(false);
cloneCurrent.setNodeValue(
cloneCurrent.getNodeValue().substringData(fStartOffset, fEndOffset));
if (trvType == EXTRACT_CONTENTS) {
((DOM_Text &)current).deleteData(fStartOffset, fEndOffset-fStartOffset);
}
frag.appendChild(cloneCurrent);
} else {
current = current.getFirstChild();
unsigned int i = 0;
for(i = 0; i < fStartOffset && current != null; i++) {
current=current.getNextSibling();
}
unsigned int n = fEndOffset-fStartOffset;
for(i = 0; i < n && current != null ;i++) {
DOM_Node newCurrent=current.getNextSibling();
if (trvType == CLONE_CONTENTS) {
cloneCurrent = current.cloneNode(true);
frag.appendChild(cloneCurrent);
} else
if (trvType == EXTRACT_CONTENTS) {
frag.appendChild(current);
}
current = newCurrent;
}
}
if (trvType == EXTRACT_CONTENTS ) {
collapse(true);
}
return frag;
}
//***** END SIMPLE CASE ****
DOM_Node root = getCommonAncestorContainer();
DOM_Node parent = null;
// go up the start tree...
current = fStartContainer;
bool endAtRoot = false;
//REVIST: Always clone TEXT_NODE's?
if (current.getNodeType() == DOM_Node::TEXT_NODE) {
cloneCurrent = current.cloneNode(false);
cloneCurrent.setNodeValue(
((DOM_Text&)cloneCurrent).getNodeValue().substringData(fStartOffset, current.getNodeValue().length() - fStartOffset));
if (trvType == EXTRACT_CONTENTS) {
((DOM_Text&)current).deleteData(fStartOffset, current.getNodeValue().length()-fStartOffset);
}
} else {
current = current.getFirstChild();
for(unsigned int i = 0; i < fStartOffset && current != null; i++) {
current=current.getNextSibling();
}
// current is now at the offset.
if (current==null) { //"after"
current = fStartContainer;
}
if (trvType == CLONE_CONTENTS) {
cloneCurrent = current.cloneNode(true);
} else if (trvType == EXTRACT_CONTENTS ) {
cloneCurrent = current;
}
}
DOM_Node startRoot = null;
DOM_Node endRoot = null;
parent = null;
if (root == fEndContainer) {
if (fStartContainer.getParentNode() == fEndContainer) {
//a unique situation when start and end are partial under the same pass
DOM_Node endNode = fEndContainer.getFirstChild();
for (unsigned int i = 0;
i <= fEndOffset-2;
i++, endNode = endNode.getNextSibling());
if (cloneParent == null)
cloneParent = root.cloneNode(false);
cloneParent.appendChild(cloneCurrent); //clone the node from above
for (current= current.getNextSibling();
current != null, current != endNode.getNextSibling();
current=current.getNextSibling()) {
if (trvType == CLONE_CONTENTS) {
cloneCurrent = current.cloneNode(true);
cloneParent.appendChild(cloneCurrent);
} else if (trvType == EXTRACT_CONTENTS) {
cloneParent.appendChild(current);
}
}
if (trvType == EXTRACT_CONTENTS) {
collapse(true);
}
frag.appendChild(cloneParent);
return frag;
}
}
// going up in a direct line from boundary point
// through parents to the common ancestor,
// all these nodes are partially selected, and must
// be cloned.
while (current != root) {
parent = current.getParentNode();
if (parent == root) {
cloneParent = frag;
startRoot = current;
} else {
//check if (parent == null) case too
cloneParent = parent.cloneNode(false);
if (partialNode==null && parent != root) {
partialNode = parent;
partialInt = AFTER;
}
}
// The children to the "right" of the "ancestor hierarchy"
// are "fully-selected".
DOM_Node next = null;
//increment to the next sibling BEFORE doing the appendChild
current = current.getNextSibling();
//do this appendChild after the increment above.
cloneParent.appendChild(cloneCurrent);
while (current != null) {
next = current.getNextSibling();
if (current != null && parent != root) {
if (trvType == CLONE_CONTENTS) {
cloneCurrent = current.cloneNode(true);
cloneParent.appendChild(cloneCurrent);
} else
if (trvType == EXTRACT_CONTENTS) {
cloneParent.appendChild(current);
}
}
current = next;
}
current = parent;
cloneCurrent = cloneParent;
}
// go up the end tree...
current = fEndContainer;
if (current.getNodeType() == DOM_Node::TEXT_NODE) {
cloneCurrent = current.cloneNode(false);
cloneCurrent.setNodeValue(
(cloneCurrent.getNodeValue()).substringData(0,fEndOffset));
if (trvType == EXTRACT_CONTENTS) {
((DOM_Text&)current).deleteData(0, fEndOffset);
}
} else {
if (fEndOffset == 0) { // "before"
current = fEndContainer;
}
else {
current = current.getFirstChild();
for(unsigned int i = 1; i < fEndOffset && current != null; i++) {
current=current.getNextSibling();
}
if (current==null) { // REVIST: index-out-of-range what to do?
current = fEndContainer.getLastChild();
}
}
if (trvType == CLONE_CONTENTS) {
cloneCurrent = current.cloneNode(true);
} else
if (trvType == EXTRACT_CONTENTS ) {
cloneCurrent = current;
}
}
while (current != root && current != null) {
parent = current.getParentNode();
if (parent == root) {
cloneParent = frag;
endRoot = current;
} else {
cloneParent = parent.cloneNode(false);
if (partialNode==null && parent != root) {
partialNode = parent;
partialInt = BEFORE;
}
}
DOM_Node holdCurrent = current;
current = parent.getFirstChild();
cloneParent.appendChild(cloneCurrent);
DOM_Node next = null;
while (current != holdCurrent && current != null) {
next = current.getNextSibling();
// The leftmost children are fully-selected
// and are removed, and appended, not cloned.
if (current != null && parent != root) {
if (trvType == CLONE_CONTENTS) {
cloneCurrent = current.cloneNode(true);
cloneParent.appendChild(cloneCurrent);
} else
if (trvType == EXTRACT_CONTENTS) {
//cloneCurrent = current;
cloneParent.appendChild(current);
}
}
current = next;
}
current = parent;
cloneCurrent = cloneParent;
}
// traverse the "fully-selected" middle...
DOM_Node clonedPrevious = frag.getLastChild();
current = endRoot.getPreviousSibling();
DOM_Node prev = null;
while (current != startRoot && current != null) {
prev = current.getPreviousSibling();
if (trvType == CLONE_CONTENTS) {
cloneCurrent = current.cloneNode(true);
} else
if (trvType == EXTRACT_CONTENTS) {
cloneCurrent = current;
}
frag.insertBefore(cloneCurrent, clonedPrevious);
current = prev;
clonedPrevious = cloneCurrent;
}
// collapse the range...
if (trvType == EXTRACT_CONTENTS ) {
if (partialNode == null) {
collapse(true);
} else
if (partialInt == AFTER) {
setStartAfter(partialNode);
setEndAfter(partialNode);
}
else if (partialInt == BEFORE) {
setStartBefore(partialNode);
setEndBefore(partialNode);
}
}
return frag;
}
void RangeImpl::checkReadOnly(DOM_Node& start, DOM_Node& end,
unsigned int startOffset, unsigned int endOffset)
{
if ((start == null) || (end == null) ) return;
//if both start and end are text check and return
if (start.getNodeType() == DOM_Node::TEXT_NODE) {
if (start.fImpl->readOnly()) {
throw DOM_DOMException(
DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);
}
if (start == end)
return;
}
//set the start and end nodes to check
DOM_Node sNode = start.getFirstChild();
for(unsigned int i = 0; i<startOffset; i++)
sNode = sNode.getNextSibling();
DOM_Node eNode;
if (end.getNodeType() == DOM_Node::TEXT_NODE) {
eNode = end; //need to check only till this node
}
else { //need to check all the kids that fall before the end offset value
eNode = end.getFirstChild();
for (unsigned int i = 0; i<endOffset-1; i++)
eNode = eNode.getNextSibling();
}
//recursivly search if any node is readonly
recurseTreeAndCheck(sNode, eNode);
}
void RangeImpl::recurseTreeAndCheck(DOM_Node& start, DOM_Node& end)
{
for(DOM_Node node=start; node != null, node !=end; node=node.getNextSibling())
{
if (node.fImpl->readOnly()) {
throw DOM_DOMException(
DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR, null);
}
if (node.hasChildNodes()) {
node = node.getFirstChild();
recurseTreeAndCheck(node, end);
}
}
}
DOM_Node RangeImpl::removeChild(DOM_Node& parent, DOM_Node& child)
{
fRemoveChild = child; //only a precaution measure not to update this range data before removal
DOM_Node n = parent.removeChild(child);
fRemoveChild = null;
return n;
}
//
// Mutation functions
//
/* This function is called from DOM.
* The text has already beeen replaced.
* Fix-up any offsets.
*/
void RangeImpl::receiveReplacedText(NodeImpl* node)
{
if (node == null) return;
DOM_Node anode(node);
if (anode == fStartContainer
&& fStartContainer.getNodeType() == DOM_Node::TEXT_NODE) {
fStartOffset = 0;
}
if (anode == fEndContainer
&& fEndContainer.getNodeType() == DOM_Node::TEXT_NODE) {
fEndOffset = 0;
}
}
/** This function is called from DOM.
* The text has already beeen inserted.
* Fix-up any offsets.
*/
void RangeImpl::updateRangeForDeletedText(DOM_Node& node, unsigned int offset, int count)
{
if (node == null) return;
if (node == fStartContainer
&& fStartContainer.getNodeType() == DOM_Node::TEXT_NODE) {
if (fStartOffset > offset+count) {
fStartOffset = fStartOffset-count;
} else if (fStartOffset > offset) {
fStartOffset = offset;
}
}
if (node == fEndContainer
&& fEndContainer.getNodeType() == DOM_Node::TEXT_NODE) {
if (fEndOffset > offset+count) {
fEndOffset = fEndOffset-count;
} else if (fEndOffset > offset) {
fEndOffset = offset;
}
}
}
/** This function must be called by the DOM _BEFORE_
* a node is deleted, because at that time it is
* connected in the DOM tree, which we depend on.
*/
void RangeImpl::updateRangeForDeletedNode(NodeImpl* node)
{
if (node == null) return;
if (fRemoveChild == node) return;
DOM_Node tNode(node);
if (node->getParentNode() == fStartContainer.fImpl) {
unsigned short index = indexOf(tNode, fStartContainer);
if ( fStartOffset > index) {
fStartOffset--;
}
}
if (node->getParentNode() == fEndContainer.fImpl) {
unsigned short index = indexOf(tNode, fEndContainer);
if ( fEndOffset < index) {
fEndOffset--;
}
}
if (node->getParentNode() != fStartContainer.fImpl
&& node->getParentNode() != fEndContainer.fImpl) {
if (isAncestorOf(node, fStartContainer)) {
if (( node->getParentNode()->getNodeType() == DOM_Node::DOCUMENT_FRAGMENT_NODE) )
return; //if the node's up in the heirarchy and its parent is doc-frag ignore
DOM_Node tpNode(node->getParentNode());
setStartContainer( tpNode );
fStartOffset = indexOf( tNode, tpNode)-1;
}
if (isAncestorOf(node, fEndContainer)) {
if (( node->getParentNode()->getNodeType() == DOM_Node::DOCUMENT_FRAGMENT_NODE))
return;
DOM_Node tpNode(node->getParentNode());
setEndContainer( tpNode );
fEndOffset = indexOf( tNode, tpNode)-1;
}
}
}
void RangeImpl::updateRangeForInsertedNode(NodeImpl* node) {
if (node == null) return;
if (node->getParentNode() == fStartContainer.fImpl) {
unsigned int index = indexOf(DOM_Node(node), fStartContainer) -1;
if (index < fStartOffset) {
fStartOffset++;
}
}
if (node->getParentNode() == fEndContainer.fImpl) {
unsigned int index = indexOf(DOM_Node(node), fEndContainer);
//if index is equal then the text is inserted before the end of
//range so should get included in the range
if (index <= fEndOffset) {
fEndOffset++;
}
}
}
void RangeImpl::updateSplitInfo(TextImpl* oldNode, TextImpl* startNode)
{
if (startNode == null) return;
DOM_Text oldText(oldNode);
DOM_Text newText(startNode);
unsigned int oldStartOffset;
if (fStartContainer == oldText) {
oldStartOffset = fStartOffset;
fStartContainer = newText;
fStartOffset = 0;
if (fEndContainer == oldText) {
fEndContainer = newText;
fEndOffset = fEndOffset - oldStartOffset;
}
}
}
1.1 xml-xerces/c/src/dom/RangeImpl.hpp
Index: RangeImpl.hpp
===================================================================
#ifndef RangeImpl_HEADER_GUARD_
#define RangeImpl_HEADER_GUARD_
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/*
* $Id: RangeImpl.hpp,v 1.1 2000/07/28 01:33:32 aruna1 Exp $
*/
#include "DOM_Node.hpp"
#include "RefCountedImpl.hpp"
#include "DOM_Range.hpp"
#include "DOM_Text.hpp"
#include "DOM_Document.hpp"
#include <util/RefVectorOf.hpp>
typedef RefVectorOf<RangeImpl> Ranges;
class CDOM_EXPORT RangeImpl : public RefCountedImpl {
public:
//c'tor
RangeImpl(DOM_Document doc);
RangeImpl(const RangeImpl& other);
//d'tor
~RangeImpl();
//referencing related functions
virtual void unreferenced();
//getter functions
DOM_Node& getStartContainer();
unsigned int getStartOffset();
DOM_Node& getEndContainer();
unsigned int getEndOffset();
void collapse(bool toStart);
bool getCollapsed();
void setStartBefore(DOM_Node& node);
void setStartAfter(DOM_Node& node);
void setEndBefore(DOM_Node& node);
void setEndAfter(DOM_Node& node);
void setStart(DOM_Node& node, unsigned int offset);
void setEnd(DOM_Node& node, unsigned int offset);
void selectNode(DOM_Node& node);
void selectNodeContents(DOM_Node& node);
short compareBoundaryPoints(DOM_Range::CompareHow how, RangeImpl* range);
void detach();
void deleteContents();
RangeImpl* cloneRange();
DOMString toString();
DOM_Document getDocument();
void surroundContents(DOM_Node& node);
DOM_DocumentFragment extractContents();
DOM_DocumentFragment cloneContents();
void insertNode(DOM_Node& newNode);
const DOM_Node& getCommonAncestorContainer();
// functions to inform all existing valid ranges about a change
void updateSplitInfo(TextImpl* oldNode, TextImpl* startNode);
void updateRangeForInsertedNode(NodeImpl* node);
void receiveReplacedText(NodeImpl* node);
void updateRangeForDeletedText(DOM_Node& node, unsigned int offset, int count);
void updateRangeForDeletedNode(NodeImpl* node);
private:
enum TraversalType {
EXTRACT_CONTENTS = 1,
CLONE_CONTENTS = 2
};
enum TraversePoint {
BEFORE = -1,
START = 0,
AFTER = 1
};
//setter functions
void setStartContainer(const DOM_Node& node);
void setStartOffset(unsigned int offset) ;
void setEndContainer(const DOM_Node& node);
void setEndOffset(unsigned int offset) ;
void setCommonAncestorContainer(const DOM_Node& node) ;
//misc functions
void validateNode(DOM_Node& node);
bool isValidAncestorType(DOM_Node& node);
void checkIndex(DOM_Node& node, unsigned int offset);
static bool isAncestorOf(const DOM_Node& a, const DOM_Node& b);
unsigned short indexOf(const DOM_Node& child, const DOM_Node& parent);
DOM_Node commonAncestorOf(DOM_Node& pointA, DOM_Node& pointB);
DOM_Node nextNode(const DOM_Node& node, bool visitChildren);
DOM_DocumentFragment traverseContents(TraversalType type);
void checkReadOnly(DOM_Node& start, DOM_Node& end,
unsigned int starOffset, unsigned int endOffset);
void recurseTreeAndCheck(DOM_Node& start, DOM_Node& end);
DOM_Node removeChild(DOM_Node& parent, DOM_Node& child);
//private data
DOM_Node fStartContainer;
unsigned int fStartOffset;
DOM_Node fEndContainer;
unsigned int fEndOffset;
bool fCollapsed;
DOM_Node fCommonAncestorContainer;
DOM_Document fDocument;
bool fDetached;
DOM_Node fRemoveChild;
};
#endif
1.8 +9 -26 xml-xerces/c/tests/Makefile.in
Index: Makefile.in
===================================================================
RCS file: /home/cvs/xml-xerces/c/tests/Makefile.in,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Makefile.in 2000/05/15 20:46:10 1.7
+++ Makefile.in 2000/07/28 01:33:39 1.8
@@ -54,35 +54,8 @@
# <http://www.apache.org/>.
#
#
-# $Log: Makefile.in,v $
-# Revision 1.7 2000/05/15 20:46:10 aruna1
-# Unix related changes in for NodeIDMap
+# $Id: Makefile.in,v 1.8 2000/07/28 01:33:39 aruna1 Exp $
#
-# Revision 1.6 2000/02/29 02:19:11 rahulj
-# No more compilation errors under HPUX 11.0. We do not build
-# DOMMemTest as it crashes the aCC compiler.
-#
-# Revision 1.5 2000/02/26 07:20:17 rahulj
-# - The threading tests now work on HPUX.
-# - Under HPUX 10.20 we do no build DOMMemTest and DOMTest.
-# It crashes the compiler.
-# - One could not write more worse makefiles than what exists for the
-# tests. Hopefully, I will get bugged enough to fix them oneday.
-#
-# Revision 1.4 2000/02/18 22:51:39 abagchi
-# Added Traversal
-#
-# Revision 1.3 2000/02/17 20:18:20 abagchi
-# Added Encoding Test
-#
-# Revision 1.2 2000/02/06 07:48:34 rahulj
-# Year 2K copyright swat.
-#
-# Revision 1.1 2000/01/31 22:21:53 aruna1
-# initial checkin
-#
-#
-#
DOMIDTest_DIR=DOM/DOMIDTest
DOMMemTest_DIR=DOM/DOMMemTest
@@ -90,6 +63,7 @@
Traversal_DIR=DOM/Traversal
ThreadTest_DIR=ThreadTest
EncodingTest_DIR=EncodingTest
+DOMRange_DIR=DOM/RangeTest
LIB_DIR=${XERCESCROOT}/lib
@@ -107,7 +81,7 @@
all: domtest threadtest encodingtest traversal
endif
else
- all: domidtest dommemtest domtest threadtest encodingtest traversal
+ all: domidtest dommemtest domtest threadtest encodingtest traversal rangetest
endif
domidtest:
@@ -134,6 +108,10 @@
@echo Building "Traversal"
cd $(Traversal_DIR) ; $(MAKE) $(MAKE_FLAGS) ; cd ..
+rangetest:
+ @echo Building "Range"
+ cd $(DOMRange_DIR) ; $(MAKE) $(MAKE_FLAGS) ; cd ..
+
clean:
cd $(DOMIDTest_DIR) && $(MAKE) $@ && cd ..
cd $(DOMMemTest_DIR) && $(MAKE) $@ && cd ..
@@ -141,6 +119,7 @@
cd $(ThreadTest_DIR) && $(MAKE) $@ && cd ..
cd $(EncodingTest_DIR) && $(MAKE) $@ && cd ..
cd $(Traversal_DIR) && $(MAKE) $@ && cd ..
+ cd $(DOMRange_DIR) && $(MAKE) $@ && cd ..
distclean:
cd $(DOMIDTest_DIR) && $(MAKE) $@ && cd ..
@@ -149,6 +128,7 @@
cd $(ThreadTest_DIR) && $(MAKE) $@ && cd ..
cd $(EncodingTest_DIR) && $(MAKE) $@ && cd ..
cd $(Traversal_DIR) && $(MAKE) $@ && cd ..
+ cd $(DOMRange_DIR) && $(MAKE) $@ && cd ..
rm -f Makefile config.cache config.log config.status
rm -f *~ core
1.9 +2 -1 xml-xerces/c/tests/configure.in
Index: configure.in
===================================================================
RCS file: /home/cvs/xml-xerces/c/tests/configure.in,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- configure.in 2000/06/03 00:01:07 1.8
+++ configure.in 2000/07/28 01:33:39 1.9
@@ -1,4 +1,4 @@
-# $Id: configure.in,v 1.8 2000/06/03 00:01:07 aruna1 Exp $
+# $Id: configure.in,v 1.9 2000/07/28 01:33:39 aruna1 Exp $
#
#
@@ -72,6 +72,7 @@
DOM/DOMMemTest/Makefile \
DOM/Traversal/Makefile \
EncodingTest/Makefile \
+DOM/RangeTest/Makefile \
ThreadTest/Makefile])
echo
1.1 xml-xerces/c/tests/DOM/RangeTest/Makefile.in
Index: Makefile.in
===================================================================
#
# The Apache Software License, Version 1.1
#
# Copyright (c) 1999-2000 The Apache Software Foundation. All rights
# reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. The end-user documentation included with the redistribution,
# if any, must include the following acknowledgment:
# "This product includes software developed by the
# Apache Software Foundation (http://www.apache.org/)."
# Alternately, this acknowledgment may appear in the software itself,
# if and wherever such third-party acknowledgments normally appear.
#
# 4. The names "Xerces" and "Apache Software Foundation" must
# not be used to endorse or promote products derived from this
# software without prior written permission. For written
# permission, please contact apache\@apache.org.
#
# 5. Products derived from this software may not be called "Apache",
# nor may "Apache" appear in their name, without prior written
# permission of the Apache Software Foundation.
#
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
# ====================================================================
#
# This software consists of voluntary contributions made by many
# individuals on behalf of the Apache Software Foundation, and was
# originally based on software copyright (c) 1999, International
# Business Machines, Inc., http://www.ibm.com . For more information
# on the Apache Software Foundation, please see
# <http://www.apache.org/>.
#
#
# $Id: Makefile.in,v 1.1 2000/07/28 01:33:39 aruna1 Exp $
#
#
###################################################################
# IMPORTANT NOTE #
###################################################################
# If you are going to do the OS390BATCH build, make sure you have #
# the OS390BATCH environment variable set. #
# #
# export OS390BATCH=1 #
# #
###################################################################
PLATFORM = @platform@
COMPILER = @compiler@
CXXFLAGS = @cxxflags@
CFLAGS = @cflags@
PREFIX = @prefix@
OSVER = @osver@
LIBS = @libs@
CC = @compiler@
include ../../../version.incl
include ../../Makefile.incl
APP_NAME=RangeTest
APP_DIR=DOM/RangeTest
OUTDIR= ${XERCESCROOT}/tests/${APP_DIR}
EXEC= ${XERCESCROOT}/bin
OBJS= ${OUTDIR}/RangeTest.o
SRC= ${XERCESCROOT}/tests/${APP_DIR}
HEADER_FILES=
INCLUDE = ${INCLUDES}
## OS390BATCH
ifeq (${OS390BATCH},1)
BATCH_TARGET= "//'${LOADMOD}(${APP_NAME})'"
all: makedir ${BATCH_TARGET}
else
all: makedir ${EXEC}/${APP_NAME}
endif
makedir:
-mkdir -p $(OUTDIR)
${EXEC}/${APP_NAME}: ${OBJS}
${LINK} ${PLATFORM_LIB_LINK_OPTIONS} ${OBJS} -o $@ ${LIBRARY_SEARCH_PATHS} ${LIBRARY_NAMES} ${EXTRA_LINK_OPTIONS}
${BATCH_TARGET}: ${OBJS}
${LINK} ${PLATFORM_LIB_LINK_OPTIONS} ${OBJS} -o $@ ${LIBRARY_SEARCH_PATHS} ${LIBRARY_NAMES} ${EXTRA_LINK_OPTIONS}
$(OUTDIR)/RangeTest.o: ${SRC}/RangeTest.cpp ${HEADER_FILES}
${CC} ${CMP} $(INCLUDE) -o $(OUTDIR)/RangeTest.o ${SRC}/RangeTest.cpp
clean:
rm -f ${OBJS} ${EXEC}/${APP_NAME}
distclean: clean
rm -f Makefile
1.1 xml-xerces/c/tests/DOM/RangeTest/RangeTest.cpp
Index: RangeTest.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache\@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation, and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com . For more information
* on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/**
* $Id: RangeTest.cpp,v 1.1 2000/07/28 01:33:39 aruna1 Exp $
*/
/** This RangeTest tests all of the cases delineated as examples
* in the DOM Level 2 Range specification, and a few others.
* <p>These do not by any means completely test the API and
* corner cases.
*/
#include <stdio.h>
#include <string.h>
#include <dom/DOM.hpp>
#include <dom/DomMemDebug.hpp>
#include <parsers/DOMParser.hpp>
#include <util/PlatformUtils.hpp>
#include <util/XMLException.hpp>
#include <util/XMLString.hpp>
#include <dom/DOM_Range.hpp>
#include <dom/DOM_XMLDecl.hpp>
#include <framework/MemBufInputSource.hpp>
#define TASSERT(c) tassert((c), __FILE__, __LINE__)
void tassert(bool c, char *file, int line)
{
if (!c)
printf("Failure. Line %d, file %s\n", line, file);
};
#define TESTPROLOG entryMemState = DomMemDebug();
#define TESTEPILOG exitMemState = DomMemDebug(); \
if (entryMemState != exitMemState) { \
printf(" Memory leak at line %d, file %s: ", __LINE__, __FILE__); \
exitMemState.printDifference(entryMemState); \
}
#define EXCEPTION_TEST(operation, expected_exception) \
{ \
try { \
operation; \
printf(" Error: no exception thrown at line %d\n", __LINE__); \
} \
catch (DOM_DOMException &e) { \
if (e.code != expected_exception) \
printf(" Wrong exception code: %d at line %d\n", e.code, __LINE__); \
} \
catch (...) { \
printf(" Wrong exception thrown at line %d\n", __LINE__); \
} \
}
int main()
{
DomMemDebug entryMemState, exitMemState;
try {
XMLPlatformUtils::Initialize();
}
catch (const XMLException& toCatch) {
char *pMessage = XMLString::transcode(toCatch.getMessage());
fprintf(stderr, "Error during XMLPlatformUtils::Initialize(). \n"
" Message is: %s\n", pMessage);
delete [] pMessage;
return -1;
}
/*
Range tests include testing of
createRange
setStart, setStartBefore. setStartAfter,
setEnd, setEndBefore. setEndAfter
getStartContainer, getStartOffset
getEndContainer, getEndOffset
getCommonAncestorContainer
selectNode
selectNodeContents
insertNode
deleteContents
collapse
getCollapsed
surroundContents
compareBoundaryPoints
cloneRange
cloneContents
extractContents
toString
detach
*/
{
{
DOM_Document doc = DOM_Document::createDocument();
//Creating a root element
DOM_Element root = doc.createElement("Body");
doc.appendChild(root);
//Creating the siblings of root
DOM_Element E11 = doc.createElement("H1");
root.appendChild(E11);
DOM_Element E12 = doc.createElement("P");
root.appendChild(E12);
//Attaching texts to siblings
DOM_Text textNode1 = doc.createTextNode("Title");
E11.appendChild(textNode1);
DOM_Text textNode11 = doc.createTextNode("AnotherText");
E11.appendChild(textNode11);
DOM_Text textNode2 = doc.createTextNode("Blah xyz");
E12.appendChild(textNode2);
DOM_Text E210 = doc.createTextNode("insertedText");
}
TESTPROLOG;
{
//DOM Tree and some usable node creation
DOM_Document doc = DOM_Document::createDocument();
//Creating a root element
DOM_Element root = doc.createElement("Body");
doc.appendChild(root);
//Creating the siblings of root
DOM_Element E11 = doc.createElement("H1");
root.appendChild(E11);
DOM_Element E12 = doc.createElement("P");
root.appendChild(E12);
//Attaching texts to siblings
DOM_Text textNode1 = doc.createTextNode("Title");
E11.appendChild(textNode1);
DOM_Text textNode11 = doc.createTextNode("AnotherText");
E11.appendChild(textNode11);
DOM_Text textNode2 = doc.createTextNode("Blah xyz");
E12.appendChild(textNode2);
//experimental nodes
DOM_Element E120 = doc.createElement("Element1");
DOM_Element E121 = doc.createElement("Element2");
DOM_Element E122 = doc.createElement("Element3");
DOM_Element E311 = doc.createElement("SurroundNode1");
DOM_Text E210 = doc.createTextNode("insertedText");
DOM_Node rt = doc.getDocumentElement();
DOM_Range range = doc.createRange();
//Tests start here
// Initial dom tree looks like :
// <Body><H1>Title</H1><P>Blah xyz</P>
//i.e., Body
// _____________|______________
// | |
// H1 P
// | |
// "Title" "Blah xyz"
//test for start and end settings of a range
range.setStart(rt.getFirstChild(), 0);
TASSERT(range.getStartContainer() == rt.getFirstChild() );
TASSERT(range.getStartOffset() == 0);
range.setEnd(rt.getFirstChild(), 1);
TASSERT(range.getEndContainer() == rt.getFirstChild() );
TASSERT(range.getEndOffset() == 1);
DOM_Node node = range.getCommonAncestorContainer();
TASSERT(range.getCommonAncestorContainer() == rt.getFirstChild());
//selection related test
range.selectNode(rt.getLastChild());
TASSERT(range.getStartContainer() == rt);
TASSERT(range.getStartOffset() == 1);
TASSERT(range.getEndContainer() == rt);
TASSERT(range.getEndOffset() == 2);
//insertion related tests
range.insertNode(E120);
//only end offset moves and new node gets into range as being inserted at boundary point
TASSERT(range.getStartContainer() == rt);
TASSERT(range.getStartOffset() == 1);
TASSERT(range.getEndContainer() == rt);
TASSERT(range.getEndOffset() == 3);
range.insertNode(E121);
//only end offset moves and new node gets into range as being inserted at boundary point
TASSERT(range.getStartContainer() == rt);
TASSERT(range.getStartOffset() == 1);
TASSERT(range.getEndContainer() == rt);
TASSERT(range.getEndOffset() == 4);
rt.insertBefore(E122, rt.getFirstChild());
//both offsets move as new node is not part of the range
TASSERT(range.getStartContainer() == rt);
TASSERT(range.getStartOffset() == 2);
TASSERT(range.getEndContainer() == rt);
TASSERT(range.getEndOffset() == 5);
//changing selection
range.selectNode(rt.getLastChild().getPreviousSibling());
TASSERT(range.getStartContainer() == rt);
TASSERT(range.getStartOffset() == 3);
TASSERT(range.getEndContainer() == rt);
TASSERT(range.getEndOffset() == 4);
//deleting related tests
range.deleteContents();
TASSERT(rt.getLastChild().getPreviousSibling() == E121);
range.setStart(rt.getFirstChild().getNextSibling().getFirstChild(), 2);
TASSERT(range.getStartContainer() == rt.getFirstChild().getNextSibling().getFirstChild());
TASSERT(range.getStartOffset() == 2);
range.setEnd(rt.getFirstChild().getNextSibling().getFirstChild(), 4);
TASSERT(range.getEndContainer() == rt.getFirstChild().getNextSibling().getFirstChild());
TASSERT(range.getEndOffset() == 4);
//inserting text between a text node
range.insertNode(E210);
//only end offset moves and new node gets into range as being inserted at boundary point
TASSERT(range.getStartContainer() == rt.getFirstChild().getNextSibling().getLastChild().getPreviousSibling());
TASSERT(range.getStartOffset() == 0);
TASSERT(range.getEndContainer() == rt.getFirstChild().getNextSibling().getLastChild().getPreviousSibling());
TASSERT(range.getEndOffset() == 2);
//inserting element node before the selcted text node
range.insertNode(E120);
//only end offset moves and new node gets into range as being inserted at boundary point
TASSERT(range.getStartContainer() == rt.getFirstChild().getNextSibling().getLastChild().getPreviousSibling());
TASSERT(range.getStartOffset() == 0);
TASSERT(range.getEndContainer() == rt.getFirstChild().getNextSibling().getLastChild().getPreviousSibling());
TASSERT(range.getEndOffset() == 2);
//checking the text replacment
range.getStartContainer().setNodeValue("ReplacedText");
//collapsed
TASSERT(range.getCollapsed() == true);
//the offsets are set to 0
TASSERT(range.getStartOffset() == 0);
TASSERT(range.getEndOffset() == 0);
//changing the selection. Preparing for 'surround'
range.setStart(range.getStartContainer().getParentNode(), 2);
range.setEnd(range.getStartContainer(), 5);
range.surroundContents(E311);
//testing cloning
DOM_Range aRange = range.cloneRange();
TASSERT(aRange.getStartContainer() == range.getStartContainer());
TASSERT(aRange.getEndContainer() == range.getEndContainer());
TASSERT(aRange.getStartOffset() == 2);
TASSERT(aRange.getEndOffset() == 3);
//changing the new ranges start
aRange.setStart(aRange.getStartContainer().getFirstChild(), 1);
//comparing the ranges
short compVal = range.compareBoundaryPoints(DOM_Range::END_TO_END, aRange);
TASSERT(compVal == 0);
compVal = range.compareBoundaryPoints(DOM_Range::START_TO_START, aRange);
TASSERT(compVal == -1);
compVal = range.compareBoundaryPoints(DOM_Range::START_TO_END, aRange);
TASSERT(compVal == -1);
compVal = range.compareBoundaryPoints(DOM_Range::END_TO_START, aRange);
TASSERT(compVal == 1);
//testing collapse
//not collapsed
TASSERT(range.getCollapsed() == false);
TASSERT(range.getStartOffset() == 2);
TASSERT(range.getEndOffset() == 3);
//selectNodeContents
range.selectNodeContents(rt.getLastChild().getFirstChild());
TASSERT(range.getStartContainer() == rt.getLastChild().getFirstChild());
TASSERT(range.getEndContainer() == rt.getLastChild().getFirstChild());
TASSERT(range.getStartOffset() == 0);
TASSERT(range.getEndOffset() == 8);
//testing collapse
range.collapse(true); //collapse to start
TASSERT(range.getCollapsed() == true);
TASSERT(range.getStartOffset() == 0);
TASSERT(range.getEndOffset() == 0);
TASSERT(aRange.getEndOffset() == 3); //other range is unaffected
// DOM Tree now looks like this
// <Body>
// |---------|----------|--------------|
// Element3 H1 Element2 P
// | |
// |------|-----------| "Blah xyz"
// "Ti" "insertedText" SurroundNode
// |
// |--------|---------------|
// Element1 "ReplacedText "AnotherText"
// range has H1 as start and end container and 2 as start and end offset. in collapsed state
// aRange has "Ti" as start with 1 as start offset, H1 as end and 3 as end offset
DOM_DocumentFragment docFrag = aRange.cloneContents();
TASSERT( docFrag != 0);
range.selectNode(rt.getFirstChild());
TASSERT(range.getStartContainer() == rt);
//Testing toString()
const char* str = aRange.toString().transcode();
char* str2 = "iinsertedTextReplacedTextAnotherText";
TASSERT(*str == *str2);
//start and end before and after tests
range.setStartBefore(rt.getFirstChild());
TASSERT(range.getStartOffset() == 0);
range.setEndBefore(rt.getFirstChild());
TASSERT(range.getEndOffset() == 0);
range.setStartAfter(rt.getLastChild());
TASSERT(range.getStartOffset() == 4);
range.setStartAfter(rt.getFirstChild());
TASSERT(range.getStartOffset() == 1);
range.setEndBefore(rt.getLastChild());
TASSERT(range.getEndOffset() == 3);
range.setEndAfter(rt.getLastChild());
TASSERT(range.getEndOffset() == 4);
//testing extract()
DOM_DocumentFragment frag2 = range.extractContents();
TASSERT( frag2 != 0);
//detaching the other range
aRange.detach();
range.detach();
}
TESTEPILOG;
} //creating the dom tree and tests
//
// Print Final allocation stats for full test
//
DomMemDebug().print();
// And call the termination method
XMLPlatformUtils::Terminate();
return 0;
};