tng 2003/01/16 12:12:20
Modified: c/src/xercesc/dom/impl DOMCharacterDataImpl.cpp
DOMCommentImpl.cpp DOMCommentImpl.hpp
DOMProcessingInstructionImpl.cpp
DOMProcessingInstructionImpl.hpp DOMRangeImpl.cpp
DOMRangeImpl.hpp
Log:
DOM Fix: Misc Range related fixes
Revision Changes Path
1.5 +14 -4 xml-xerces/c/src/xercesc/dom/impl/DOMCharacterDataImpl.cpp
Index: DOMCharacterDataImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMCharacterDataImpl.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- DOMCharacterDataImpl.cpp 4 Nov 2002 15:07:34 -0000 1.4
+++ DOMCharacterDataImpl.cpp 16 Jan 2003 20:12:19 -0000 1.5
@@ -251,6 +251,18 @@
if (newLen >= 3999)
delete[] newString;
+
+ if (node->getOwnerDocument() != 0) {
+ Ranges* ranges = ((DOMDocumentImpl *)node->getOwnerDocument())->getRanges();
+ if (ranges != 0) {
+ XMLSize_t sz = ranges->size();
+ if (sz != 0) {
+ for (XMLSize_t i =0; i<sz; i++) {
+ ranges->elementAt(i)->updateRangeForInsertedText(
(DOMNode*)node, offset, datLen);
+ }
+ }
+ }
+ }
}
@@ -271,9 +283,7 @@
void DOMCharacterDataImpl::setData(const DOMNode *node, const XMLCh *arg)
{
- if (castToNodeImpl(node)->isReadOnly())
- throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
- fDataBuf->set(arg);
+ setNodeValue(node, arg);
};
1.12 +41 -1 xml-xerces/c/src/xercesc/dom/impl/DOMCommentImpl.cpp
Index: DOMCommentImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMCommentImpl.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- DOMCommentImpl.cpp 4 Nov 2002 15:07:34 -0000 1.11
+++ DOMCommentImpl.cpp 16 Jan 2003 20:12:19 -0000 1.12
@@ -60,8 +60,10 @@
#include "DOMCommentImpl.hpp"
#include "DOMCharacterDataImpl.hpp"
+#include "DOMStringPool.hpp"
#include "DOMCasts.hpp"
#include "DOMDocumentImpl.hpp"
+#include "DOMRangeImpl.hpp"
#include <xercesc/dom/DOMNode.hpp>
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
@@ -125,6 +127,44 @@
throw DOMException(DOMException::INVALID_ACCESS_ERR,0);
}
}
+
+
+// Non standard extension for the range to work
+DOMComment *DOMCommentImpl::splitText(XMLSize_t offset)
+{
+ if (fNode.isReadOnly())
+ {
+ throw DOMException(
+ DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
+ }
+ XMLSize_t len = fCharacterData.fDataBuf->getLen();
+ if (offset > len || offset < 0)
+ throw DOMException(DOMException::INDEX_SIZE_ERR, 0);
+
+ DOMComment *newText =
+ getOwnerDocument()->createComment(
+ this->substringData(offset, len - offset));
+
+ DOMNode *parent = getParentNode();
+ if (parent != 0)
+ parent->insertBefore(newText, getNextSibling());
+
+ fCharacterData.fDataBuf->chop(offset);
+
+ if (this->getOwnerDocument() != 0) {
+ Ranges* ranges = ((DOMDocumentImpl *)this->getOwnerDocument())->getRanges();
+ if (ranges != 0) {
+ XMLSize_t sz = ranges->size();
+ if (sz != 0) {
+ for (XMLSize_t i =0; i<sz; i++) {
+ ranges->elementAt(i)->updateSplitInfo( this, newText, offset);
+ }
+ }
+ }
+ }
+
+ return newText;
+};
DOMNode* DOMCommentImpl::appendChild(DOMNode *newChild)
{return fNode.appendChild (newChild); };
1.4 +4 -1 xml-xerces/c/src/xercesc/dom/impl/DOMCommentImpl.hpp
Index: DOMCommentImpl.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMCommentImpl.hpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DOMCommentImpl.hpp 4 Nov 2002 15:07:34 -0000 1.3
+++ DOMCommentImpl.hpp 16 Jan 2003 20:12:19 -0000 1.4
@@ -107,6 +107,9 @@
virtual void setData(const XMLCh * arg);
virtual const XMLCh * substringData(XMLSize_t offset, XMLSize_t count) const;
+ // Non standard extension for the range to work
+ DOMComment* splitText(XMLSize_t offset);
+
};
XERCES_CPP_NAMESPACE_END
1.11 +58 -39
xml-xerces/c/src/xercesc/dom/impl/DOMProcessingInstructionImpl.cpp
Index: DOMProcessingInstructionImpl.cpp
===================================================================
RCS file:
/home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMProcessingInstructionImpl.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- DOMProcessingInstructionImpl.cpp 4 Nov 2002 15:07:34 -0000 1.10
+++ DOMProcessingInstructionImpl.cpp 16 Jan 2003 20:12:19 -0000 1.11
@@ -61,6 +61,8 @@
#include "DOMProcessingInstructionImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMNodeImpl.hpp"
+#include "DOMStringPool.hpp"
+#include "DOMRangeImpl.hpp"
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMNode.hpp>
@@ -71,22 +73,20 @@
DOMProcessingInstructionImpl::DOMProcessingInstructionImpl(DOMDocument *ownerDoc,
const XMLCh *targt,
const XMLCh *dat)
- : fNode(ownerDoc), fBaseURI(0)
+ : fNode(ownerDoc), fBaseURI(0), fCharacterData(ownerDoc, dat)
{
fNode.setIsLeafNode(true);
this->fTarget = ((DOMDocumentImpl *)ownerDoc)->cloneString(targt);
- this->fData = ((DOMDocumentImpl *)ownerDoc)->cloneString(dat);
};
DOMProcessingInstructionImpl::DOMProcessingInstructionImpl(
const DOMProcessingInstructionImpl &other,
bool deep)
- : fNode(other.fNode), fChild(other.fChild)
+ : fNode(other.fNode), fChild(other.fChild), fCharacterData(other.fCharacterData)
{
fNode.setIsLeafNode(true);
fTarget = other.fTarget;
- fData = other.fData;
fBaseURI = other.fBaseURI;
};
@@ -115,26 +115,6 @@
};
-const XMLCh * DOMProcessingInstructionImpl::getNodeValue() const
-{
- return fData;
-};
-
-
-void DOMProcessingInstructionImpl::setNodeValue(const XMLCh *value)
-{
- if (fNode.isReadOnly())
- throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
- fData = ((DOMDocumentImpl *)getOwnerDocument())->cloneString(value);
-};
-
-
-const XMLCh * DOMProcessingInstructionImpl::getData() const
-{
- return fData;
-};
-
-
/** A PI's "target" states what processor channel the PI's data
should be directed to. It is defined differently in HTML and XML.
@@ -151,20 +131,6 @@
};
-/**
-* Change the data content of this PI.
-* Note that setNodeValue is aliased to setData
-* @see getData().
-* @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if node is read-only.
-*/
-void DOMProcessingInstructionImpl::setData(const XMLCh *arg)
-{
- if (fNode.isReadOnly())
- throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR,
- 0);
- fData = ((DOMDocumentImpl *)getOwnerDocument())->cloneString(arg);
-};
-
void DOMProcessingInstructionImpl::release()
{
if (fNode.isOwned() && !fNode.isToBeReleased())
@@ -173,6 +139,7 @@
DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
if (doc) {
fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
+ fCharacterData.releaseBuffer();
doc->release(this, DOMDocumentImpl::PROCESSING_INSTRUCTION_OBJECT);
}
else {
@@ -190,6 +157,43 @@
return fBaseURI? fBaseURI : fNode.fOwnerNode->getBaseURI();
}
+// Non standard extension for the range to work
+DOMProcessingInstruction *DOMProcessingInstructionImpl::splitText(XMLSize_t offset)
+{
+ if (fNode.isReadOnly())
+ {
+ throw DOMException(
+ DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
+ }
+ XMLSize_t len = fCharacterData.fDataBuf->getLen();
+ if (offset > len || offset < 0)
+ throw DOMException(DOMException::INDEX_SIZE_ERR, 0);
+
+ DOMProcessingInstruction *newText =
+ getOwnerDocument()->createProcessingInstruction(fTarget,
+ this->substringData(offset, len - offset));
+
+ DOMNode *parent = getParentNode();
+ if (parent != 0)
+ parent->insertBefore(newText, getNextSibling());
+
+ fCharacterData.fDataBuf->chop(offset);
+
+ if (this->getOwnerDocument() != 0) {
+ Ranges* ranges = ((DOMDocumentImpl *)this->getOwnerDocument())->getRanges();
+ if (ranges != 0) {
+ XMLSize_t sz = ranges->size();
+ if (sz != 0) {
+ for (XMLSize_t i =0; i<sz; i++) {
+ ranges->elementAt(i)->updateSplitInfo( this, newText, offset);
+ }
+ }
+ }
+ }
+
+ return newText;
+};
+
//
// Delegation stubs for inherited functions
//
@@ -201,6 +205,7 @@
const XMLCh* DOMProcessingInstructionImpl::getLocalName() const
{return fNode.getLocalName (); };
const XMLCh* DOMProcessingInstructionImpl::getNamespaceURI() const
{return fNode.getNamespaceURI (); };
DOMNode* DOMProcessingInstructionImpl::getNextSibling() const
{return fChild.getNextSibling (); };
+ const XMLCh* DOMProcessingInstructionImpl::getNodeValue() const
{return fCharacterData.getNodeValue (); };
DOMDocument* DOMProcessingInstructionImpl::getOwnerDocument() const
{return fNode.getOwnerDocument (); };
const XMLCh* DOMProcessingInstructionImpl::getPrefix() const
{return fNode.getPrefix (); };
DOMNode* DOMProcessingInstructionImpl::getParentNode() const
{return fChild.getParentNode (this); };
@@ -228,6 +233,20 @@
bool DOMProcessingInstructionImpl::isDefaultNamespace(const
XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); };
const XMLCh* DOMProcessingInstructionImpl::lookupNamespaceURI(const
XMLCh* prefix) const {return fNode.lookupNamespaceURI(prefix); };
DOMNode* DOMProcessingInstructionImpl::getInterface(const XMLCh*
feature) {return fNode.getInterface(feature); };
+
+//
+// Delegation of CharacerData functions.
+//
+
+
+ const XMLCh* DOMProcessingInstructionImpl::getData() const
{return fCharacterData.getData();};
+ void DOMProcessingInstructionImpl::deleteData(XMLSize_t
offset, XMLSize_t count)
+
{fCharacterData.deleteData(this, offset, count);};
+ const XMLCh* DOMProcessingInstructionImpl::substringData(XMLSize_t
offset, XMLSize_t count) const
+
{return fCharacterData.substringData(this, offset, count);};
+ void DOMProcessingInstructionImpl::setData(const XMLCh
*data) {fCharacterData.setData(this, data);};
+ void DOMProcessingInstructionImpl::setNodeValue(const XMLCh
*nodeValue) {fCharacterData.setNodeValue (this, nodeValue); };
+
XERCES_CPP_NAMESPACE_END
1.4 +9 -2
xml-xerces/c/src/xercesc/dom/impl/DOMProcessingInstructionImpl.hpp
Index: DOMProcessingInstructionImpl.hpp
===================================================================
RCS file:
/home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMProcessingInstructionImpl.hpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DOMProcessingInstructionImpl.hpp 4 Nov 2002 15:07:34 -0000 1.3
+++ DOMProcessingInstructionImpl.hpp 16 Jan 2003 20:12:19 -0000 1.4
@@ -72,6 +72,7 @@
#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/dom/DOMProcessingInstruction.hpp>
+#include "DOMCharacterDataImpl.hpp"
#include "DOMNodeImpl.hpp"
#include "DOMChildNode.hpp"
@@ -85,9 +86,10 @@
private:
DOMNodeImpl fNode;
DOMChildNode fChild;
+ // use fCharacterData to store its data so that those character utitlites can
be used
+ DOMCharacterDataImpl fCharacterData;
XMLCh *fTarget;
- XMLCh *fData;
const XMLCh *fBaseURI;
public:
@@ -107,6 +109,11 @@
// NON-DOM: set base uri
virtual void setBaseURI(const XMLCh* baseURI);
+
+ // Non standard extension for the range to work
+ void deleteData(XMLSize_t offset, XMLSize_t count);
+ const XMLCh* substringData(XMLSize_t offset, XMLSize_t count) const;
+ DOMProcessingInstruction* splitText(XMLSize_t offset);
};
XERCES_CPP_NAMESPACE_END
1.8 +382 -123 xml-xerces/c/src/xercesc/dom/impl/DOMRangeImpl.cpp
Index: DOMRangeImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMRangeImpl.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- DOMRangeImpl.cpp 9 Jan 2003 18:41:12 -0000 1.7
+++ DOMRangeImpl.cpp 16 Jan 2003 20:12:19 -0000 1.8
@@ -61,14 +61,18 @@
#include "DOMRangeImpl.hpp"
#include "DOMDocumentImpl.hpp"
#include "DOMDocumentFragmentImpl.hpp"
+#include "DOMCommentImpl.hpp"
+#include "DOMProcessingInstructionImpl.hpp"
#include "DOMCasts.hpp"
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMRangeException.hpp>
#include <xercesc/dom/DOMText.hpp>
+#include <xercesc/dom/DOMProcessingInstruction.hpp>
#include <xercesc/framework/XMLBuffer.hpp>
+#include <xercesc/util/Janitor.hpp>
XERCES_CPP_NAMESPACE_BEGIN
@@ -114,21 +118,45 @@
DOMNode* DOMRangeImpl::getStartContainer() const
{
+ if (fDetached)
+ {
+ throw DOMException(
+ DOMException::INVALID_STATE_ERR, 0);
+ }
+
return fStartContainer;
}
XMLSize_t DOMRangeImpl::getStartOffset() const
{
+ if (fDetached)
+ {
+ throw DOMException(
+ DOMException::INVALID_STATE_ERR, 0);
+ }
+
return fStartOffset;
}
DOMNode* DOMRangeImpl::getEndContainer() const
{
+ if (fDetached)
+ {
+ throw DOMException(
+ DOMException::INVALID_STATE_ERR, 0);
+ }
+
return fEndContainer;
}
XMLSize_t DOMRangeImpl::getEndOffset() const
{
+ if (fDetached)
+ {
+ throw DOMException(
+ DOMException::INVALID_STATE_ERR, 0);
+ }
+
return fEndOffset;
}
@@ -147,7 +175,7 @@
}
//-------------------------------
-// Public getter functions
+// Public setter functions
//-------------------------------
void DOMRangeImpl::setStartContainer(const DOMNode* node)
@@ -203,13 +231,18 @@
fStartContainer = (DOMNode*) refNode;
fStartOffset = offset;
- if ((fDocument != refNode->getOwnerDocument() )
- && (refNode->getOwnerDocument() != 0) )
- {
- fDocument = refNode->getOwnerDocument();
- collapse(true);
+ // error if not the same owner document
+ if (fDocument != refNode->getOwnerDocument()) {
+ if ( refNode != fDocument )
+ throw DOMException(
+ DOMException::WRONG_DOCUMENT_ERR, 0);
}
+ // they may be of same document, but not same root container
+ // collapse if not the same root container
+ if (!commonAncestorOf(refNode, fEndContainer))
+ collapse(true);
+
//compare the start and end boundary point
//collapse if start point is after the end point
if(compareBoundaryPoints(DOMRange::END_TO_START, this) == 1)
@@ -226,13 +259,18 @@
fEndContainer = (DOMNode*) refNode;
fEndOffset = offset;
- if ((fDocument != refNode->getOwnerDocument() )
- && (refNode->getOwnerDocument() != 0) )
- {
- fDocument = refNode->getOwnerDocument();
- collapse(false);
+ // error if not the same owner document
+ if (fDocument != refNode->getOwnerDocument()) {
+ if ( refNode != fDocument )
+ throw DOMException(
+ DOMException::WRONG_DOCUMENT_ERR, 0);
}
+ // they may be of same document, but not same root container
+ // collapse if not the same root container
+ if (!commonAncestorOf(refNode, fStartContainer))
+ collapse(false);
+
//compare the start and end boundary point
//collapse if start point is after the end point
if(compareBoundaryPoints(DOMRange::END_TO_START, this) == 1)
@@ -262,13 +300,18 @@
else
fStartOffset = i-1;
- if ((fDocument != refNode->getOwnerDocument())
- && (refNode->getOwnerDocument() != 0) )
- {
- fDocument = refNode->getOwnerDocument();
- collapse(true);
+ // error if not the same owner document
+ if (fDocument != refNode->getOwnerDocument()) {
+ if ( refNode != fDocument )
+ throw DOMException(
+ DOMException::WRONG_DOCUMENT_ERR, 0);
}
+ // they may be of same document, but not same root container
+ // collapse if not the same root container
+ if (!commonAncestorOf(refNode, fEndContainer))
+ collapse(true);
+
//compare the start and end boundary point
//collapse if start point is after the end point
if(compareBoundaryPoints(DOMRange::END_TO_START, this) == 1)
@@ -296,13 +339,18 @@
fStartOffset = i;
- if ((fDocument != refNode->getOwnerDocument() )
- && (refNode->getOwnerDocument() != 0) )
- {
- fDocument = refNode->getOwnerDocument();
- collapse(true);
+ // error if not the same owner document
+ if (fDocument != refNode->getOwnerDocument()) {
+ if ( refNode != fDocument )
+ throw DOMException(
+ DOMException::WRONG_DOCUMENT_ERR, 0);
}
+ // they may be of same document, but not same root container
+ // collapse if not the same root container
+ if (!commonAncestorOf(refNode, fEndContainer))
+ collapse(true);
+
//compare the start and end boundary point
//collapse if start point is after the end point
if(compareBoundaryPoints(DOMRange::END_TO_START, this) == 1)
@@ -331,13 +379,18 @@
else
fEndOffset = i-1;
- if ((fDocument != refNode->getOwnerDocument() )
- && (refNode->getOwnerDocument() != 0) )
- {
- fDocument = refNode->getOwnerDocument();
- collapse(true);
+ // error if not the same owner document
+ if (fDocument != refNode->getOwnerDocument()) {
+ if ( refNode != fDocument )
+ throw DOMException(
+ DOMException::WRONG_DOCUMENT_ERR, 0);
}
+ // they may be of same document, but not same root container
+ // collapse if not the same root container
+ if (!commonAncestorOf(refNode, fStartContainer))
+ collapse(false);
+
//compare the start and end boundary point
//collapse if start point is after the end point
if(compareBoundaryPoints(DOMRange::END_TO_START, this) == 1)
@@ -366,13 +419,18 @@
else
fEndOffset = i;
- if ((fDocument != refNode->getOwnerDocument() )
- && (refNode->getOwnerDocument() != 0) )
- {
- fDocument = refNode->getOwnerDocument();
- collapse(true);
+ // error if not the same owner document
+ if (fDocument != refNode->getOwnerDocument()) {
+ if ( refNode != fDocument )
+ throw DOMException(
+ DOMException::WRONG_DOCUMENT_ERR, 0);
}
+ // they may be of same document, but not same root container
+ // collapse if not the same root container
+ if (!commonAncestorOf(refNode, fStartContainer))
+ collapse(false);
+
//compare the start and end boundary point
//collapse if start point is after the end point
if(compareBoundaryPoints(DOMRange::END_TO_START, this) == 1)
@@ -429,7 +487,11 @@
DOMRangeException::INVALID_NODE_TYPE_ERR, 0);
}
//First check for the text type node
- if (refNode->getNodeType() == DOMNode::TEXT_NODE)
+ short type = refNode->getNodeType();
+ if((type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
{
//The node itself is the container.
fStartContainer = (DOMNode*) refNode;
@@ -437,7 +499,10 @@
//Select all the contents of the node
fStartOffset = 0;
- fEndOffset = ((DOMText *)refNode)->getLength();
+ if (type == DOMNode::PROCESSING_INSTRUCTION_NODE)
+ fEndOffset =
XMLString::stringLen(((DOMProcessingInstruction*)refNode)->getData());
+ else
+ fEndOffset = ((DOMText *)refNode)->getLength();
return;
}
@@ -465,10 +530,19 @@
fEndContainer = (DOMNode*) node;
fStartOffset = 0;
- if (node->getNodeType() == DOMNode::TEXT_NODE ) {
+ short type = node->getNodeType();
+
+ if((type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE)) {
+
fEndOffset = ((DOMText *)node)->getLength();
return;
}
+ if (type == DOMNode::PROCESSING_INSTRUCTION_NODE) {
+ fEndOffset =
XMLString::stringLen(((DOMProcessingInstruction*)node)->getData());
+ return;
+ }
DOMNode* first = node->getFirstChild();
if (first == 0) {
@@ -510,10 +584,18 @@
DOMNode* realStart = fStartContainer;
DOMNode* realEnd = fEndContainer;
- if (fStartContainer->getNodeType() == DOMNode::TEXT_NODE) {
+ type = fStartContainer->getNodeType();
+ if((type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE)) {
realStart = fStartContainer->getParentNode();
}
- if (fEndContainer->getNodeType() == DOMNode::TEXT_NODE) {
+ type = fEndContainer->getNodeType();
+ if((type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE)) {
realEnd = fEndContainer->getParentNode();
}
@@ -595,16 +677,25 @@
}
}
- // case 4: preorder traversal of context tree.
DOMNode* ancestor = (DOMNode*) commonAncestorOf(pointA, pointB);
- DOMNode* current = ancestor;
- do {
- if (current == pointA) return -1;
- if (current == pointB) return 1;
- current = nextNode(current, true);
+ // case 4: preorder traversal of context tree.
+ if (ancestor) {
+ DOMNode* current = ancestor;
+
+ do {
+ if (current == pointA) return -1;
+ if (current == pointB) return 1;
+ current = nextNode(current, true);
+ }
+ while (current!=0 && current!=ancestor);
+ }
+ else {
+ // case 5: there is no common ancestor of these two points
+ // it means the two Ranges are not in the same "root container"
+ throw DOMException(
+ DOMException::WRONG_DOCUMENT_ERR, 0);
}
- while (current!=0 && current!=ancestor);
return -2; // this should never happen
}
@@ -670,14 +761,24 @@
DOMNode* parent;
DOMNode* next;
- if (fStartContainer->getNodeType() == DOMNode::TEXT_NODE) {
+ type = fStartContainer->getNodeType();
+ if((type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE)) {
//set 'parent' and 'next' here
parent = fStartContainer->getParentNode();
//split the text nodes
- if (fStartOffset > 0)
- ((DOMText*)fStartContainer)->splitText(fStartOffset);
+ if (fStartOffset > 0) {
+ if (type == DOMNode::COMMENT_NODE)
+ ((DOMCommentImpl*)fStartContainer)->splitText(fStartOffset);
+ else if (type == DOMNode::PROCESSING_INSTRUCTION_NODE)
+
((DOMProcessingInstructionImpl*)fStartContainer)->splitText(fStartOffset);
+ else
+ ((DOMText*)fStartContainer)->splitText(fStartOffset);
+ }
//update the new start information later. After inserting the first newNode
if (fStartOffset == 0)
@@ -724,34 +825,33 @@
DOMException::INVALID_STATE_ERR, 0);
}
+ if ((fStartContainer == fEndContainer) && (fEndOffset == fStartOffset))
+ return XMLUni::fgZeroLenString;
+
DOMNode* node = fStartContainer;
DOMNode* stopNode = fEndContainer;
XMLBuffer retStringBuf;
- if ( (fStartContainer->getNodeType() == DOMNode::TEXT_NODE)
- || (fStartContainer->getNodeType() == DOMNode::CDATA_SECTION_NODE) ) {
+ short type = fStartContainer->getNodeType();
+ if((type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE)) {
if (fStartContainer == fEndContainer) {
- if (fEndOffset == fStartOffset) {
- return XMLUni::fgZeroLenString;
- }
- else {
-
- XMLCh* tempString;
- XMLCh temp[4000];
- if ((fEndOffset-fStartOffset) >= 3999)
- tempString = new XMLCh[fEndOffset-fStartOffset+1];
- else
- tempString = temp;
+ XMLCh* tempString;
+ XMLCh temp[4000];
+ if ((fEndOffset-fStartOffset) >= 3999)
+ tempString = new XMLCh[fEndOffset-fStartOffset+1];
+ else
+ tempString = temp;
- XMLString::subString(tempString, fStartContainer->getNodeValue(),
fStartOffset, fEndOffset);
- const XMLCh* retString = ((DOMDocumentImpl
*)fDocument)->getPooledString(tempString);
+ XMLString::subString(tempString, fStartContainer->getNodeValue(),
fStartOffset, fEndOffset);
+ const XMLCh* retString = ((DOMDocumentImpl
*)fDocument)->getPooledString(tempString);
- if ((fEndOffset-fStartOffset) >= 3999)
- delete[] tempString;
-
- return retString;
- }
+ if ((fEndOffset-fStartOffset) >= 3999)
+ delete[] tempString;
+ return retString;
} else {
XMLSize_t length =
XMLString::stringLen(fStartContainer->getNodeValue());
if (length != fStartOffset) {
@@ -786,8 +886,11 @@
}
}
- if ( fEndContainer->getNodeType()!= DOMNode::TEXT_NODE &&
- fEndContainer->getNodeType()!= DOMNode::CDATA_SECTION_NODE ){
+ type = fEndContainer->getNodeType();
+ if((type != DOMNode::TEXT_NODE
+ && type != DOMNode::CDATA_SECTION_NODE
+ && type != DOMNode::COMMENT_NODE
+ && type != DOMNode::PROCESSING_INSTRUCTION_NODE)) {
int i=fEndOffset;
stopNode = fEndContainer->getFirstChild();
while( i>0 && stopNode!=0 ){
@@ -800,15 +903,22 @@
while (node != stopNode) { //look into all kids of the Range
if (node == 0) break;
- if (node->getNodeType() == DOMNode::TEXT_NODE
- || node->getNodeType() == DOMNode::CDATA_SECTION_NODE) {
+ type = node->getNodeType();
+
+ if((type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE)) {
retStringBuf.append(node->getNodeValue());
}
node = nextNode(node, true);
}
- if (fEndContainer->getNodeType() == DOMNode::TEXT_NODE
- || fEndContainer->getNodeType() == DOMNode::CDATA_SECTION_NODE) {
+ type = fEndContainer->getNodeType();
+ if((type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE)) {
if (fEndOffset != 0) {
@@ -931,9 +1041,6 @@
if (fDetached)
throw DOMException(DOMException::INVALID_STATE_ERR, 0);
- if (pointA->getOwnerDocument() != pointB->getOwnerDocument())
- throw DOMException( DOMException::WRONG_DOCUMENT_ERR, 0 );
-
//if the containers are same then it itself is its common ancestor.
if (pointA == pointB)
return pointA;
@@ -942,12 +1049,12 @@
VectorNodes startV(1, false);
DOMNode* node;
- for (node=fStartContainer; node != 0; node=node->getParentNode())
+ for (node=(DOMNode*)pointA; node != 0; node=node->getParentNode())
{
startV.addElement(node);
}
VectorNodes endV(1, false);
- for (node=fEndContainer; node != 0; node=node->getParentNode())
+ for (node=(DOMNode*)pointB; node != 0; node=node->getParentNode())
{
endV.addElement(node);
}
@@ -955,7 +1062,7 @@
int s = startV.size()-1;
int e = endV.size()-1;
- DOMNode* commonAncestor;
+ DOMNode* commonAncestor = 0;
while (s>=0 && e>=0) {
if (startV.elementAt(s) == endV.elementAt(e)) {
@@ -1061,22 +1168,55 @@
return traverseSameContainer( how );
// case 2: Child C of start container is ancestor of end container
- for (DOMNode* node = fStartContainer->getFirstChild(); node != 0;
node=node->getNextSibling()) {
- if (isAncestorOf(node, fEndContainer))
- return traverseCommonStartContainer( node, how );
- }
+ // This can be quickly tested by walking the parent chain of
+ // end container
+ int endContainerDepth = 0;
+ for ( DOMNode* c = fEndContainer, *p = c->getParentNode();
+ p != 0;
+ c = p, p = p->getParentNode())
+ {
+ if (p == fStartContainer)
+ return traverseCommonStartContainer( c, how );
+ ++endContainerDepth;
+ }
// case 3: Child C of end container is ancestor of start container
- for (DOMNode* nd = fEndContainer->getFirstChild(); nd != 0;
nd=nd->getNextSibling()) {
- if (isAncestorOf(nd, fStartContainer))
- return traverseCommonEndContainer( nd, how );
- }
+ // This can be quickly tested by walking the parent chain of A
+ int startContainerDepth = 0;
+ for ( DOMNode* c2 = fStartContainer, *p2 = c2->getParentNode();
+ p2 != 0;
+ c2 = p2, p2 = p2->getParentNode())
+ {
+ if (p2 == fEndContainer)
+ return traverseCommonEndContainer( c2, how );
+ ++startContainerDepth;
+ }
- // case 4: preorder traversal of context tree.
- // There is a common ancestor container. Find the
+ // case 4: There is a common ancestor container. Find the
// ancestor siblings that are children of that container.
- DOMNode* ancestor = (DOMNode*)commonAncestorOf(fStartContainer, fEndContainer);
- return traverseCommonAncestors( ancestor, ancestor, how );
+ int depthDiff = startContainerDepth - endContainerDepth;
+
+ DOMNode* startNode = fStartContainer;
+ while (depthDiff > 0) {
+ startNode = startNode->getParentNode();
+ depthDiff--;
+ }
+
+ DOMNode* endNode = fEndContainer;
+ while (depthDiff < 0) {
+ endNode = endNode->getParentNode();
+ depthDiff++;
+ }
+
+ // ascend the ancestor hierarchy until we have a common parent.
+ for( DOMNode* sp = startNode->getParentNode(), *ep = endNode->getParentNode();
+ sp!=ep;
+ sp = sp->getParentNode(), ep = ep->getParentNode() )
+ {
+ startNode = sp;
+ endNode = ep;
+ }
+ return traverseCommonAncestors( startNode, endNode, how );
}
/**
@@ -1098,7 +1238,11 @@
DOMNode* cloneCurrent = 0;
// Text node needs special case handling
- if ( fStartContainer->getNodeType()== DOMNode::TEXT_NODE )
+ short type = fStartContainer->getNodeType();
+ if((type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
{
cloneCurrent = fStartContainer->cloneNode(false);
if (fEndOffset == fStartOffset) {
@@ -1120,8 +1264,13 @@
}
// set the original text node to its new value
- if ( how != CLONE_CONTENTS )
- ((DOMText*)fStartContainer)->deleteData(fStartOffset,
fEndOffset-fStartOffset);
+ if ( how != CLONE_CONTENTS ) {
+ if(type == DOMNode::PROCESSING_INSTRUCTION_NODE) {
+
((DOMProcessingInstructionImpl*)fStartContainer)->deleteData(fStartOffset,
fEndOffset-fStartOffset);
+ }
+ else
+ ((DOMCharacterData*)fStartContainer)->deleteData(fStartOffset,
fEndOffset-fStartOffset);
+ }
if ( how != DELETE_CONTENTS)
frag->appendChild(cloneCurrent);
}
@@ -1129,7 +1278,7 @@
// Copy nodes between the start/end offsets.
DOMNode* n = getSelectedNode( fStartContainer, fStartOffset );
int cnt = fEndOffset - fStartOffset;
- while( cnt > 0 )
+ while( cnt > 0 && n)
{
DOMNode* sibling = n->getNextSibling();
DOMNode* xferNode = traverseFullySelected( n, how );
@@ -1137,7 +1286,7 @@
frag->appendChild( xferNode );
--cnt;
n = sibling;
- }
+ }
}
// Nothing is partially selected, so collapse to start point
@@ -1443,8 +1592,15 @@
{
if ( isFullySelected )
return traverseFullySelected( n, how );
- if ( n->getNodeType()== DOMNode::TEXT_NODE )
+
+ short type = n->getNodeType();
+
+ if((type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
return traverseTextNode( n, isLeft, how );
+
return traversePartiallySelected( n, how );
}
@@ -1461,11 +1617,6 @@
case CLONE_CONTENTS:
return n->cloneNode( true );
case EXTRACT_CONTENTS:
- if ( n->getNodeType()== DOMNode::DOCUMENT_TYPE_NODE )
- {
- throw DOMException(
- DOMException::HIERARCHY_REQUEST_ERR, 0);
- }
return n;
case DELETE_CONTENTS:
// revisit:
@@ -1505,7 +1656,8 @@
*/
DOMNode* DOMRangeImpl::traverseTextNode( DOMNode*n, bool isLeft, int how )
{
- const XMLCh* txtValue = n->getNodeValue();
+ XMLCh* txtValue = XMLString::replicate(n->getNodeValue());
+ ArrayJanitor<XMLCh> janValue(txtValue);
if ( isLeft )
{
@@ -1629,7 +1781,11 @@
*/
DOMNode* DOMRangeImpl::getSelectedNode( DOMNode*container, int offset )
{
- if ( container->getNodeType() == DOMNode::TEXT_NODE )
+ short type = container->getNodeType();
+ if((type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
return container;
// This case is an important convenience for
@@ -1652,22 +1808,49 @@
XMLSize_t startOffset, XMLSize_t endOffset)
{
if ((start == 0) || (end == 0) ) return;
- //if both start and end are text check and return
- if (start->getNodeType() == DOMNode::TEXT_NODE) {
+ DOMNode*sNode = 0;
+
+ short type = start->getNodeType();
+ if ( type == DOMNode::DOCUMENT_TYPE_NODE )
+ {
+ throw DOMException(
+ DOMException::HIERARCHY_REQUEST_ERR, 0);
+ }
+
+ if((type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
+ {
if (castToNodeImpl(start)->isReadOnly()) {
throw DOMException(
DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
}
+ //if both start and end are text check and return
if (start == end)
return;
+
+ sNode = start;
+ } else {
+ //set the start and end nodes to check
+ sNode = start->getFirstChild();
+ for(XMLSize_t i = 0; i<startOffset; i++)
+ sNode = sNode->getNextSibling();
}
- //set the start and end nodes to check
- DOMNode*sNode = start->getFirstChild();
- for(XMLSize_t i = 0; i<startOffset; i++)
- sNode = sNode->getNextSibling();
DOMNode* eNode;
- if (end->getNodeType() == DOMNode::TEXT_NODE) {
+ type = end->getNodeType();
+ if ( type == DOMNode::DOCUMENT_TYPE_NODE )
+ {
+ throw DOMException(
+ DOMException::HIERARCHY_REQUEST_ERR, 0);
+ }
+
+ if((type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
+ {
eNode = end; //need to check only till this node
}
else { //need to check all the kids that fall before the end offset value
@@ -1685,6 +1868,12 @@
{
for(DOMNode* node=start; node != 0 && node !=end; node=node->getNextSibling())
{
+ if ( node->getNodeType()== DOMNode::DOCUMENT_TYPE_NODE )
+ {
+ throw DOMException(
+ DOMException::HIERARCHY_REQUEST_ERR, 0);
+ }
+
if (castToNodeImpl(node)->isReadOnly()) {
throw DOMException(
DOMException::NO_MODIFICATION_ALLOWED_ERR, 0);
@@ -1713,42 +1902,62 @@
/* This function is called from DOM.
-* The text has already beeen replaced.
+* The text has already been replaced.
* Fix-up any offsets.
*/
void DOMRangeImpl::receiveReplacedText(DOMNode* node)
{
if (node == 0) return;
+ short type = fStartContainer->getNodeType();
if (node == fStartContainer
- && fStartContainer->getNodeType() == DOMNode::TEXT_NODE) {
+ && (type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
+ {
fStartOffset = 0;
}
+ type = fEndContainer->getNodeType();
if (node == fEndContainer
- && fEndContainer->getNodeType() == DOMNode::TEXT_NODE) {
+ && (type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
+ {
fEndOffset = 0;
}
}
/** This function is called from DOM.
-* The text has already beeen inserted.
+* The text has already been deleted.
* Fix-up any offsets.
*/
void DOMRangeImpl::updateRangeForDeletedText(DOMNode* node, XMLSize_t offset, int
count)
{
if (node == 0) return;
+ short type = fStartContainer->getNodeType();
if (node == fStartContainer
- && fStartContainer->getNodeType() == DOMNode::TEXT_NODE) {
+ && (type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
+ {
if (fStartOffset > offset+count) {
fStartOffset = fStartOffset-count;
} else if (fStartOffset > offset) {
fStartOffset = offset;
}
}
+ type = fEndContainer->getNodeType();
if (node == fEndContainer
- && fEndContainer->getNodeType() == DOMNode::TEXT_NODE) {
+ && (type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
+ {
if (fEndOffset > offset+count) {
fEndOffset = fEndOffset-count;
} else if (fEndOffset > offset) {
@@ -1759,6 +1968,40 @@
+/** This function is called from DOM.
+* The text has already beeen inserted.
+* Fix-up any offsets.
+*/
+void DOMRangeImpl::updateRangeForInsertedText(DOMNode* node, XMLSize_t offset, int
count)
+{
+ if (node == 0) return;
+
+ short type = fStartContainer->getNodeType();
+ if (node == fStartContainer
+ && (type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
+ {
+ if (fStartOffset > offset) {
+ fStartOffset = offset;
+ }
+ }
+ type = fEndContainer->getNodeType();
+ if (node == fEndContainer
+ && (type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
+ {
+ if (fEndOffset > offset) {
+ fEndOffset = fEndOffset+count;
+ }
+ }
+}
+
+
+
/** 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.
@@ -1818,18 +2061,34 @@
}
-void DOMRangeImpl::updateSplitInfo(DOMText* oldNode, DOMText* startNode, XMLSize_t
offset)
+void DOMRangeImpl::updateSplitInfo(DOMNode* oldNode, DOMNode* startNode, XMLSize_t
offset)
{
if (startNode == 0) return;
- if (fStartContainer == oldNode && fStartOffset > offset) {
- fStartOffset = fStartOffset - offset;
- fStartContainer = startNode;
+ short type = fStartContainer->getNodeType();
+ if (oldNode == fStartContainer
+ && (type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
+ {
+ if (fStartOffset > offset) {
+ fStartOffset = fStartOffset - offset;
+ fStartContainer = startNode;
+ }
}
- if (fEndContainer == oldNode && fEndOffset > offset) {
+ type = fEndContainer->getNodeType();
+ if (oldNode == fEndContainer
+ && (type == DOMNode::TEXT_NODE
+ || type == DOMNode::CDATA_SECTION_NODE
+ || type == DOMNode::COMMENT_NODE
+ || type == DOMNode::PROCESSING_INSTRUCTION_NODE))
+ {
+ if (fEndOffset > offset) {
fEndContainer = startNode;
- fEndOffset = fEndOffset - offset;
+ fEndOffset = fEndOffset - offset;
+ }
}
}
1.5 +3 -2 xml-xerces/c/src/xercesc/dom/impl/DOMRangeImpl.hpp
Index: DOMRangeImpl.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/impl/DOMRangeImpl.hpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- DOMRangeImpl.hpp 4 Nov 2002 15:07:34 -0000 1.4
+++ DOMRangeImpl.hpp 16 Jan 2003 20:12:19 -0000 1.5
@@ -156,10 +156,11 @@
DOMDocument* getDocument();
// functions to inform all existing valid ranges about a change
- void updateSplitInfo(DOMText* oldNode, DOMText* startNode, XMLSize_t offset);
+ void updateSplitInfo(DOMNode* oldNode, DOMNode* startNode, XMLSize_t offset);
void updateRangeForInsertedNode(DOMNode* node);
void receiveReplacedText(DOMNode* node);
void updateRangeForDeletedText(DOMNode* node, XMLSize_t offset, int count);
+ void updateRangeForInsertedText(DOMNode* node, XMLSize_t offset, int count);
void updateRangeForDeletedNode(DOMNode* node);
private:
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]