From: <bi...@us...> - 2009-06-18 23:03:32
|
Revision: 4818 http://oorexx.svn.sourceforge.net/oorexx/?rev=4818&view=rev Author: bigrixx Date: 2009-06-18 23:03:29 +0000 (Thu, 18 Jun 2009) Log Message: ----------- split into multiple files for easier editting Modified Paths: -------------- incubator/orxutils/xml/xmldom.cls Added Paths: ----------- incubator/orxutils/xml/attr.cls incubator/orxutils/xml/attributemap.cls incubator/orxutils/xml/cdatasection.cls incubator/orxutils/xml/characterdata.cls incubator/orxutils/xml/childnode.cls incubator/orxutils/xml/comment.cls incubator/orxutils/xml/coredocument.cls incubator/orxutils/xml/deepnodelist.cls incubator/orxutils/xml/domerrors.cls incubator/orxutils/xml/element.cls incubator/orxutils/xml/entity.cls incubator/orxutils/xml/entityreference.cls incubator/orxutils/xml/namednodemap.cls incubator/orxutils/xml/node.cls incubator/orxutils/xml/nodelist.cls incubator/orxutils/xml/notation.cls incubator/orxutils/xml/parentnode.cls incubator/orxutils/xml/processinginstruction.cls incubator/orxutils/xml/text.cls Added: incubator/orxutils/xml/attr.cls =================================================================== --- incubator/orxutils/xml/attr.cls (rev 0) +++ incubator/orxutils/xml/attr.cls 2009-06-18 23:03:29 UTC (rev 4818) @@ -0,0 +1,529 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: Attr */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +::class "Attr" subclass Node +::init + expose value name textNode namespaceURI localName type + value = .nil + type = .nil + textNode = .nil + namespaceURI = .nil + localName = .nil + if arg() == 2 then do + use strict arg ownerDocument, name + self~init:super(ownerDoc) + end + else if arg() == 3 then do + use strict arg ownerDoc, namespaceURI, nodeName + self~init:super(ownerDoc) + self~setName(nodeName) + end + else do + use strict arg ownerDoc, namespaceURI, nodeName, localName + self~init:super(ownerDoc) + end + self~init:super(ownerDocument) + self~isSpecified = .false + self~hasStringValue = .true + +::method setName private + expose namespaceURI localName + use arg qname + -- null string is the same as not there + if namspaceURI == "" then do + namespaceURI = .nil + end + + colon1 = qname~pos(":") + colon2 = qname~lastPos(":") + -- no prefix + if colon1 == 0 then do + -- local name and qualified name are the same + localName = qname + end + else do + parse var qname localName (colon1) (colon2 + 1) localName + end + +-- support for the Document renameNode method +::method rename + expose nodeName namespaceURI + use strict arg uri, name = .nil + if name == .nil then do + nodeName = uri + end + else do + nodeName = name + namespaceURI = uri + self~setName(name) + end + +-- override for default method +::attribute namespaceURI GET +-- get the prefix from the node name +::attribute prefix GET + expose nodeName + index = nodeName~pos(":") + if index > 0 then do + return nodeName~substr(1, index - 1) + end + else do + return .nil + end + +::attribute prefix SET + expose nodeName localName + use strict arg prefix + + -- we're either adding or replacing the prefix + if prefix \= "" then do + nodeName = prefix":"localName + end + -- or removing it entirely + else do + nodeName = localName + end + +::attribute localName GET + +::attribute ownerDocument SET private + expose value + use strict arg doc + forward class(super) continue + if \self~hasStringValue then do + child = value + do while child \= .nil + child~ownerDocument = doc + child = child~nextSibling + end + end + +::attribute idAttribute SET + use strict arg value + self~isIdAttribute = value + +::method isId + use strict arg + return self~isIdAttribute + +::method cloneNode + expose value + use strict arg deep = .false + + newNode = self~cloneNode:super(deep) + + if \self~hasStringValue then do + close~value = .nil + child = value + do while child \= .nil + newNode~appendChild(child~cloneNode(.true)) + child = child~nextSibling + end + end + + newNode~isSpecified = .true + return newNode + +::attribute nodeType GET + use strict arg + return .Node~ATTRIBUTE_NODE + +::attribute nodeName GET + expose name + use strict arg + return name + +::attribute nodeValue SET + forward message("VALUE=") +::attribute nodeValue GET + forward message("VALUE") + + +::attribute typeName GET + expose type + use strict arg + if type \= .nil then do + if type~isA(.String) then do + return type + end + else do + return type~typeName + end + end + else do + return .nil + end + +::attribute typeNamespace GET + expose type + use strict arg + if type \= .nil then do + if \type~isA(.String) then do + return type~namespace + end + else do + return "http://www.w3.org/TR/REC-xml"; + end + end + return .nil + +::method isDerivedFrom + expose type + use strict arg typeNamespace, typeName, derivationMethod + if type \= .nil, \type~isA(.String) then do + return type~isDOMDerivedFrom(typeNamespace, typeName, derivationMethod) + end + return .false + +-- set/retrieve type directly +::attribute type +::attribute typeNamespace GET + expose typeName + use strict arg + if typeName \= .nil then do + return "http://www.w3.org/TR/REC-xml" + end + else do + return .nil + end + +::attribute schemaTypeInfo + use strict arg + -- we provide all of our own type information directly + return this + +::attribute name GET + +::attribute value SET + expose value textNode + use strict arg newValue + + self~ownerElement + oldvalue = "" + + -- we might need to process an old value if it's a serious of text nodes + if value \= .nil then do + if self~ownerDocument~mutationEvents then do + if self~hasMutationEvents then do + -- if we have a string value and we need to + -- broadcast mutation events, then we need to + -- convert this into a text node for the event + if self~hasStringValue then do + oldValue = value + if textNode == .nil then do + textNode = self~ownerDocument~createTextNode(value) + end + else do + textNode~data = value + end + -- set the value to be a text node rather than a string + value = textNode + textNode~ownerNode = this + textNode~isOwned = .true + self~removeChild(textNode, true) + end + else do + oldValue = self~value + do while value \= .nil + self~removeChild(value, .true) + end + end + end + end + else do + if self~hasStringValue then do + oldValue = value + end + else do + -- discard any text children + oldValue = self~value + firstChild = value + firstChild ownerNode = self~ownerDocument + end + -- remove the existing value + value = .nil + end + end + + self~isSpecified = .true + if self~ownerDocument~mutationEvents then do + self~insertBefore(self~ownerDocument~createTextNode(newValue), .nil, .true) + self~hasStringValue = .false + self~ownerDocument~modifiedAttrValue(this, oldvalue) + end + else do + value = newValue + self~changed() + end + + if self~isIdAttribute & self~ownderElement \= .nil then do + self~ownerDocument~putIdentifier(newvalue, ownerElement) + end + +::attribute value GET + expose value + use strict arg + -- no set value is a null string + if value == .nil then do + return "" + end + -- if already a string, then set it directly + if value~isA(.String) then do + return value + end + + -- this is a potential chain of child nodes + firstChild = value + + if firstChild~nodeType == .Node~ENTITY_REFERENCE_NODE then do + data = firstChild~entryRefValue + end + else do + data = firstChild~nodeValue + end + -- no data at this point, return a null string + if data == .nil then do + return "" + end + + node = firstChild~nextSibling + -- if the only child node, we're done + if node == .nil then do + return data + end + + buffer = .mutableBuffer~new(data) + + do while node \= .nil + if firstChild~nodeType == .Node~ENTITY_REFERENCE_NODE then do + data = firstChild~entryRefValue + if data \= .nil then do + buffer~append(data) + end + end + else do + buffer~append(firstChild~nodeValue) + end + node = node~nextSibling + end + + return buffer~string + +::attribute element GET + use strict arg + + if self~isOwned then do + return self~ownerNode + end + else do + return .nil + end + +::attribute ownerElement GET + forward message("ELEMENT") + +::attribute specified GET + forward name("ISSPECIFIED") +::attribute specified SET + forward name("ISSPECIFIED=") + +::method hasChildNodes + expose value + use strict arg + return value \= .nil + +::method childNodes + -- we handle the node list methods directly + use strict arg + return self + +::method firstChild + expose value + use strict arg + self~makeChildNode + return value + +::method lastChild + expose value + use strict arg + + self~makeChildNode + + child = value + previous = .nil + + do while child \= .nil + previous = child + child = child~nextSibling + end + + return previous + +::method insertBefore + expose value + use strict arg newChild, refChild, replace = .false + + -- if this is a fragment, transfer each of the + -- children from the fragment to ourselves + if newChild~nodeType == .Node~DOCUMENT_FRAGMENT_MODE then do + do while newChild~hasChildNodes + self~insertBefore(newChild~firstChild, refChild) + end + return newChild + end + -- already here? This is a little silly, but the event model + -- requires us to remove it and the reinsert + if newChild == refChild then do + refChild = refChild~nextSibling + self~removeChild(newChild) + self~insertBefore(newChild, refChild) + return newChild + end + -- ensure if we just have a string value that it is converted into a text + -- node + self~makeChildNode + + self~ownerDocument~insertingNode(this, replace) + -- detach from any existing parent node + oldParent = newChild~parentNode + + if oldParent \= .nil then do + oldParent~removeChild(newNode) + end + + newNode~ownerNode = this + newNode~isOwned = .true + + firstChild = value + -- no existing value, this case is easy + if firstChild == .nil then do + value = newChild + end + else do + -- append operation? + if refNode == .nil then do + lastChild = self~lastChild + lastChild~nextSibling = newNode + newNode~previousSibling = lastChild + end + -- normal insertion + else do + if refChild == firstChild then do + newNode~nextSibling = firstChild + firstChild~previousSibling = newNode + newNode~previousSibling = .nil + value = newNode + end + else do + previous = refNode~previousSibling + newNode~nextSibling = refNode + previous~nextSibling = newNode + refNode~previousSibling = newNode + newNode~previousSibling = previous + end + end + end + + -- record the change + self~changed + + self~ownerDocument~insertedNode(this, newNode, replace) + + return newChild + +::method removeChild + expose value + use strict arg oldChild, replace = .false + + if value~isA(.string) then do + return .nil + end + + self~ownerDocument~removingNode(this, oldNode, replace) + + -- removing the first? + if oldNode == value then do + value = oldNode~nextSibling + if value \= .nil then do + value~previousSibling = .nil + end + end + else do + previous = oldNode~previousSibling + next = oldNode~nextSibling + previous~nextSibling = next + if next \= .nil then do + next~previousSibling = previous + end + end + + oldNode~ownerNode = self~ownerDocument + oldNode~isOwned = .false + oldNode~nextSibling = .nil + oldNode~previousSibling = .nil + + self~changed + + ownerDocument~removedNode(this, replace) + + return oldNode + +::method replaceChild + use strict arg newChild, oldChild + + self~makeChildNode + self~ownerDocument~replacingNode(self) + self~insertBefore(newChild, oldChild, .true) + if newChild \= oldChild then do + self~removeChild(oldChild, true) + end + + self~ownerDocument~repacingNode(self) + return oldChild + +-- NodeList methods +::attribute length GET + expose value + use strict arg + + if value~isA(.string) then do + return 1 + end + + child = value + length = 0 + do while child \= .nil + length += 1 + child = child~nextSibling + end + + return length + +::method item + expose value + use strict arg index + + if value~isA(.String) then do + if index \= 0 then do + return .nil + end + self~makeChildNode + return value + end + else do + if index < 0 then do + return .nil + end + node = value + do i = 0 to index while node \= .nil + node = node~nextSibling + end + return node + end + +::method isDerivedFrom + use strict arg typeNamespace, typeName, derivationMethod + return .false Property changes on: incubator/orxutils/xml/attr.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/attributemap.cls =================================================================== --- incubator/orxutils/xml/attributemap.cls (rev 0) +++ incubator/orxutils/xml/attributemap.cls 2009-06-18 23:03:29 UTC (rev 4818) @@ -0,0 +1,170 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: AttributeMap -- an implementation of NamedNodeMap that can deal */ +/* with member ownership issues */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +::class "AttributeMap" subclass NamedNodeMap +::method init + expose hasDefaults + use strict arg ownerNode, defaults = . nil + + self~init:super(ownerNode) + hasDefaults = .false + -- if we have a defaults set, clone it and if we really added + -- something, marks us as having defaults + if defaults \= .nil then do + self~cloneContent(defaults) + if self~attributes \= .nil then do + hasDefaults = .true + end + end + +::method setNamedItem + use strict arg attribute + -- replaceing an attribute with itself does nothing + if attribute~isOwned then do + return attribute + end + + attribute~ownerNode = self~ownerNode + attribute~isOwned = .true + + index = self~findNamePoint(attribute~nodeName, 0) + attributes = self~attributes + previous = .nil + if index \= .nil then do + previous = attributes[i] + attributes[i] = attribute + previous~ownerNode = self~ownerNode~ownerDocument + previous~isOwned = .false + previous~isSpecified = .true + end + else do + if attributes = .nil then do + attributes = .list~new + self~attributes = attributes + end + attributes~append(attribute) + end + + self~ownerNode~ownerDocument~setAttrNode(attribute, previous) + return previous + +::method setNamedItemNS + use strict arg attribute + -- replaceing an attribute with itself does nothing + if attribute~isOwned then do + return attribute + end + + attribute~ownerNode = self~ownerNode + attribute~isOwned = .true + + index = self~findNamePointNS(attribute~namespaceURI, attribute~nodeName) + attributes = self~attributes + previous = .nil + if index \= .nil then do + previous = attributes[i] + attributes[i] = attribute + previous~ownerNode = self~ownerNode~ownerDocument + previous~isOwned = .false + previous~isSpecified = .true + end + else do + if attributes = .nil then do + attributes = .list~new + self~attributes = attributes + end + attributes~append(attribute) + end + + self~ownerNode~ownerDocument~setAttrNode(attribute, previous) + return previous + +::method removeNamedItem + use strict arg name + + index = self~findNamePoint(name) + if index == .nil then do + return .nil + end + + return self~remove(self~attributes[index], index, true) + +::method removeNamedItemNS + use strict arg namespaceURI, name + + index = self~findNamePointNS(namspaceURI, name) + if index == .nil then do + return .nil + end + + return self~remove(self~attributes[index], index, true) + +::method remove private + use strict arg attr, index, addDefault = .false + + ownerDocument = self~ownerNode~ownderDocument + name = attr~nodeName + if attr~isIdAttribue then do + ownerDocument~removeIdentifier(attr~value) + end + + attributes = self~attributes + + setdefault = .false + -- do we have default attributes that we might need to revert to? + if self~hasDefaults & addDefault then do + defaults = ownerNode~defaultAttributes + if defaults \= .nil then do + defaultAttr = defaults~getNamedItem(name) + if defaultAttr \= .nil then do + newAttr = defaultAttr~cloneNode(.true) + -- the namespace uri comes from the deleted node, + -- not the default source value if the default + -- does not have a local name + if newAttr~localName \== .nil then do + newAttr~namespaceURI = attr~namespaceURI + end + newAttr~ownerNode = ownerNode + newAttr~isOwned = true + -- mark this as a default value + newAttr~isSpecified = false + attributes[index] = newAttr + setdefault = .true + -- if this is the id attribute, make sure the document knows + -- about this mapping + if attr~isIdAttribute then do + ownerDocument~putIdentifier(newAttr~nodeValue, ownerNode) + end + end + end + end + -- if we didn't end up setting a default, remove the node + if \setDefault then do + attributes~remove(index) + end + -- detach from usage + attr~ownerNode = .nil + attr~isOwned = .false + attr~isSpecified = .true + attr~isIdAttribute = false + + -- notify the document + ownerDocument~removedAttrNode(attr, ownerNode, name) + return attr + +::method cloneContent + use strict arg source + srcnodes = source~attributes + if srcnodes \= .nil then do + self~attributes = .List~new + do node over srcnodes + newNode = node~cloneNode(true) + newNode~ownerNode = self~ownerNode + newNode~isOwned = .true + self~attributes~append(newNode) + end + end Property changes on: incubator/orxutils/xml/attributemap.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/cdatasection.cls =================================================================== --- incubator/orxutils/xml/cdatasection.cls (rev 0) +++ incubator/orxutils/xml/cdatasection.cls 2009-06-18 23:03:29 UTC (rev 4818) @@ -0,0 +1,14 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: CDATASection */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +::class "CDATASection" subclass Text PUBLIC +::attribute nodeType GET + use strict arg + return .Node~CDATA_SECTION_NODE + +::attribute nodeName GET + use strict arg + return "#cdata-section" Property changes on: incubator/orxutils/xml/cdatasection.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/characterdata.cls =================================================================== --- incubator/orxutils/xml/characterdata.cls (rev 0) +++ incubator/orxutils/xml/characterdata.cls 2009-06-18 23:03:29 UTC (rev 4818) @@ -0,0 +1,100 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: CharacterData -- base class for all nodes that carry character data */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +::class "CharacterData" subclass ChildNode +::method init + expose data + use strict arg ownerDocument, data + self~init:super(ownerDocument) + +::attribute childNodes GET + use strict arg + -- always returns an empty node list + return .NodeList~new + +::attribute nodeValue GET + expose data + use strict arg + return data + +::attribute nodeValue SET + expose data + use strict arg value, replace = .false + + oldValue = data + self~ownerDocument~modifyingCharacterData(self, replace) + + data = value + + self~ownerDocument~modifiedCharacterData(self, oldValue, value, replace) + +::attribute data GET +::attribute length GET + expose data + use strict arg + return data~length + +::method appendData + expose data + use strict arg newData + if newData == .nil then do + return + end + + self~setNodeValue(data||newData) + +::method deleteData + expose data + use strict arg offset, count, replace = .false + + tailLength = max(data~length - count - offset, 0) + if offset >= data~length then do + newData = data + end + else do + newData = data~delstr(offset + 1, count) + end + -- set the node value to the adjusted version + self~nodeValue = newData + + self~ownerDocument~deletedText(self, offset, count) + +::method insertData + expose data + use strict arg offset, newData, replace = .false + + if offset >= data~length then do + newValue = data + end + else do + newValue = date~insert(newData, offset +1) + end + + self~ownerDocument~deletedText(self, offset, data~length) + +::method replaceData + expose data + use strict arg offset, count, newData + + oldvalue = data + + self~ownerDocument~replacingData(self) + + -- this needs to be done as multiple operations to get all of the + -- events broadcast + self~deleteData(offset, count, .true) + self~insertData(offset, newData, .true) + + self~ownerDocument~replacedCharacterData(self, oldvalue, data) + +::method setData + forward message("NODEVALUE=") + +::method substringData + expose data + use strict arg offset, count + + return data~substring(offset + 1, count) Property changes on: incubator/orxutils/xml/characterdata.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/childnode.cls =================================================================== --- incubator/orxutils/xml/childnode.cls (rev 0) +++ incubator/orxutils/xml/childnode.cls 2009-06-18 23:03:29 UTC (rev 4818) @@ -0,0 +1,39 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: ChildNode base type for nodes that can be children of other nodes */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +::class "ChildNode" subclass Node +::method init + expose previousSibling nextSibling + forward class(super) continue + + previousSibling = .nil + nextSibling = .nil + + +::method cloneNode + use strict arg deep = .false + + newNode = self~init:super(deep) + // detach the new instance from the context + newNode~previousSibling = .nil + newNode~nextSibling = .nil + newNode~isFirstChild = .false + + return newNode + +::attribute parentNode GET + if self~isOwned then do + return self~ownerNode + end + else do + return .nil + end + +::attribute nextSibling GET +::attribute nextSibling SET PRIVATE + +::attribute previousSibling GET +::attribute previousSibling SET PRIVATE Property changes on: incubator/orxutils/xml/childnode.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/comment.cls =================================================================== --- incubator/orxutils/xml/comment.cls (rev 0) +++ incubator/orxutils/xml/comment.cls 2009-06-18 23:03:29 UTC (rev 4818) @@ -0,0 +1,14 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: Comment -- a comment node */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +::class "Comment" subclass CharacterData PUBLIC +::attribute nodeType GET + use strict arg + return .Node~COMMENT_NODE + +::attribute nodeName get + use strict arg + return "#comment" Property changes on: incubator/orxutils/xml/comment.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/coredocument.cls =================================================================== --- incubator/orxutils/xml/coredocument.cls (rev 0) +++ incubator/orxutils/xml/coredocument.cls 2009-06-18 23:03:29 UTC (rev 4818) @@ -0,0 +1,609 @@ + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: CoreDocument */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +::class "CoreDocument" subclass ParentNode +::method init + expose docType docElement encoding actualEncoding version standalone documentURI - + userdata identifiers domNormalizer configuration xpathEvaluator changes - + allowGrammerAccess errorChecking documentNumber nodeCounter nodeTable + use strict arg docType = .nil, grammarAccess = .false + self~init:super(.nil) + self~ownerDocument = self + + docElement = .nil + encoding = .nil + actualEncoding = .nil + version = .nil + standalone = .false + documentURI = .false + userData = .nil + identifiers = .nil + domNormalizer = .nil + configuration = .nil + xpathEvaluator = .nil + changes = 0 + errorChecking = .true + documentNumber = 0 + nodeCounter = 0 + nodeTable = .nil + + -- if we have a document type, this gets appended as our first child + if docType \= .nil then do + docType~ownerDocument = self + appendChild(docType) + end + +::attribute ownerDocument GET + use strict arg + -- documents don't have an owner + return .nil + +::attribute nodeType GET + use strict arg + return .Node~DOCUMENT_NODE + +::attirbute nodeName GET + use strict arg + return "#document" + +::method cloneNode + use strict arg deep = .false + newDoc = .CoreDocument~new + self~cloneDocument(newDoc, deep) + return newDoc + +::method cloneDocument private + expose identifers, firstChild + use arg newDoc, deep + + if deep then do + reversedIdentifers = .nil + if identifiers \= .nil then do + reversedIdentifiers = .directory~new + -- create the table using the inverse look up logic + sup = identifiers~supplier + do while sup~available + reversedIdentifiers[sup~item] = sup~index + end + end + + -- now copy each of the children into the new document + child = firstChild + do while child \= .nil + newDoc~appendChild(newDoc~importDocNode(child, .true, .true, reversedIdentifers)) + end + end + + newDoc~allowGrammarAccess = self~allowGrammarAccess + newDoc~errorChecking = self~errorChecking + +::method insertBefore + expose docElement docType + use strict arg newChild, refChild + + type = newChild~nodeType + -- if this is a DocumentType node, then make ourselves the owner + if newChild~ownerDocument == .nil & newChild~isA(.DocumentType) then do + newChild~ownerDocument = self + end + -- do a normal insert + self~insertBefore:super(newChild, refChild) + -- we only have two types of children, so cache each of + -- type types + if type == .Node~ELEMENT_NODE then do + docElement = newChild + end + else if type == .Node~DOCUMENT_TYPE_NODE then do + docType = newChild + end + return newChild + +::method removeChild + expose docElement docType + use strict arg oldChild + + self~removeChild:super(oldChild) + + type = oldChild~ELEMENT_NODE + + if type = .Node~ELEMENT_TYPE then do + docElement = .nil + end + else if type = .Node~DOCUMENT_TYPE_NODE do + docType = .nil + end + return oldChild + +::method replaceChild + expose docElement docType + use strict arg newChild, oldChild + + -- if this is a DocumentType node, then make ourselves the owner + if newChild~ownerDocument == .nil & newChild~isA(.DocumentType) then do + newChild~ownerDocument = self + end + + self~replaceChild:super(newChild, oldChild) + + type = oldChild~ELEMENT_NODE + + if type = .Node~ELEMENT_TYPE then do + docElement = .newChild + end + else if type = .Node~DOCUMENT_TYPE_NODE do + docType = .newChild + end + return oldChild + +::attribute textContent GET + use strict arg + return .nil + +::attribute textContent SET + use strict arg value + -- this is a NOP + +::method getFeature + expose xpathEvaluator + use strict arg feature, version = .nil + + anyVersion = version == .nil | version == "" + + if feature~caselessEquals("+XPath") & (anyVersion | version == "3.0") then do + if xpathEvaluator == .nil then do + xpathEvaluator = .XPathEvaluator~new(self) + end + return xpathEvaluator + end + + return self~getFeature:super(feature, version) + +-- Document factory methods + +::method createAttribute + use strict arg name + return .Attr~new(self, name) + +::method createAttributeNS + if arg() == 2 then do + use strict arg namespaceURI, qualifiedName + return .Attr~new(self, namespaceURI, qualifiedName) + end + else do + use strict arg namespaceURI, qualifiedName, localName + return .Attr~new(self, namespaceURI, qualifiedName, localName) + end + +::method createCDATASection + use strict arg data + return .CDATASection~new(self, data) + +::method createComment + use strict arg data + return .Comment~new(self, data) + +::method createDocumentFragment + use strict arg + return .DocumentFragment~new(self) + +::method createElement + use strict arg tagname + return .Element~new(self, tagname) + +::method createElementNS + if arg() == 2 then do + use strict arg namespaceURI, qualifiedName + return .Element~new(self, namespaceURI, qualifiedName) + end + else do + use strict arg namespaceURI, qualifiedName, localName + return .Element~new(self, namespaceURI, qualifiedName, localName) + end + +::method createEntityReference + use strict arg name + return .EntityReference~new(self, name) + +::method createProcessingInstruction + use strict arg target, data + return .ProcessingInstruction~new(self, target, data) + +::method createTextNode + use strict arg data + return .Text~new(self, data) + +::attribute docType GET +::attribute documentElement GET + expose docElement + use strict arg + return docElement + +::method getElementsByTagName + use strict arg tagName + return .DeepNodeList~new(self, tagname) + +::method getElementsByTagNameNS + use strict arg namespaceURI, localName + return .DeepNodeList~new(self, namespaceURI, localName) + +::method getImplementation + use strict arg + + return .DomImplementation~getDOMImplementation + +::attribute errorChecking +::attribute strictErrorChecking + +::attribute inputEncoding +::attribute xmlEncoding + +::attribute documentURI + +::method createDocumentType + use strict arg qualifiedName, publicID, systemID + + return .DocumentType~new(self, qualifiedName, publicID, systemID) + +::method createEntity + use strict arg name + return .Entity~new(self, name) + +::method createNotation + use strict arg name + return .Notation~new(self, name) + +::method importNode + use strict arg source, deep = .false + return self~importDocNode(source, deep, .false, .nil) + +::method importDocNode private + expose identifiers + use strict arg source, deep, cloningDoc, reversedIdentifiers + + newNode = .nil + type = source~nodeType + select + when type == .Node~ELEMENT_NODE then do + if source~localName == .nil then do + newElement = self~createElement(source~nodeName) + end + else do + newElement = self~createElementNS(source~namespaceURI, source~nodeName) + end + -- we need to copy the attributes for the element here...other + -- children are handled below + sourceAttrs = source~attributes + if sourceAttrs \= .nil then do + do attr over sourceAttrs + if attr~isSpecified | cloningDoc then do + -- if we're just importing, ignore the default attributes. + newAttr = self~importNode(attr, .true, cloningDoc, reversedIdentifiers) + if attr~localName == .nil then do + newElement~setAttributeNode(newAttr) + end + else do + newElement~setAttributeNodeNS(newAttr) + end + end + end + end + -- have a reversed identifer table? We need to check if + -- the element has an identifier and fix this up + if reversedIdentifiers \= .nil then do + elementId = reversedIdentifers[source] + if elementId \= .nil then do + if identifiers == .nil then do + identifers = .table~new + end + identifiers[elementId] = newElement + end + end + newNode = newElement + end + when type == .Node~ATTRIBUTE_NODE then do + if source~localName == .nil then do + newNode = self~createAttribute(source~nodeName) + end + else do + newNode = self~createAttributeNS(source~namespaceURI, source~nodeName) + end + -- we'll do a deep copy, unless this can be avoided in the simple + -- cases + deep = .true + -- if we have a string value, we can just copy that and + -- avoid doing the deep copy + if attr~hasStringValue then do + newNode~value = attr~value + deep = .false + end + end + when type == .Node~TEXT_NODE then do + newNode = self~createTextNode(source~nodeValue) + end + when type == .Node~CDATA_SECTION_NODE then do + newNode = self~createCDATASection(source~nodeValue) + end + when type == .Node~ENTITY_REFERENCE_NODE then do + newNode = self~createEntityReference(source~nodeName) + -- createEntityReference copies the subtree, so + -- disable the deep copy operation + deep = .false + end + when type == .Node~ENTITY_NODE then do + newNode = self~createEntity(source~nodeName) + newNode~publicId = source~publicId + newNode~systemId = source~systemId + newNode~notationName = source~notationName + -- the children need to be copied also...to do this, + -- we need to make the entity writeable + newNode = readOnly = .false + end + when type == .Node~PROCESSING_INSTRUCTION_NODE then do + newNode = self~createProcessingInstruction(source~nodeName, source~nodeValue) + end + when type == .Node~COMMENT_NODE then do + newNode = self~createComment(source~nodeValue) + end + when type == .Node~DOCUMENT_TYPE_NODE then do + newNode = self~createDocumentType(source~nodeName, source~publicId, source~systemId) + newNode~internalSubset = source~internalSubset + sourceMap = source~entities + newMap = newNode~entities + -- copy all of the entities, if thee are any + if sourceMap \= .nil then do + do item over sourceMap + newMap~setNamedItem(self~importNode(item, .true, .true, reversedIdentifers) + end + end + sourceMap = source~notations + newMap = newNode~notations + -- copy all of the notations, if thee are any + if sourceMap \= .nil then do + do item over sourceMap + newMap~setNamedItem(self~importNode(item, .true, .true, reversedIdentifers) + end + end + end + when type == .Node~DOCUMENT_FRAGMENT_NODE then do + newNode = self~createDocumentFragment + end + when type == .Node~NOTATION_NODE then do + newNode = self~createNotation(source~nodeName) + newNode~publicId = source~publicId + newNode~systemId = source~systemId + end + when type == .Node~DOCUMENT_NODE then do + .DomErrors~raiseError(.DomErrors~NOT_SUPPORTED_ERR) + end + otherwise do + .DomErrors~raiseError(.DomErrors~NOT_SUPPORTED_ERR) + end + end + + -- do we need to copy the child nodes too? + if deep then do + child = source~firstChild + do while child \= .nil + newNode~appendChild(self~importNode(child, .true, cloningDoc, reversedIdentifiers) + end + end + + if newNode~nodeType == .Node~ENTITY_NODE then do + newNode~readOnly = .true + end + return newNode + +::method adoptNode + expose docType + use strict arg source + + if source == .nil then do + return .nil + end + + type = source~nodeType + + select + when type == .Node~ATTRIBUTE_NODE then do + -- detach from the owner if this is owned + if source~ownerDocument \= .nil then do + source~ownerElement~removeAttributeNode(source) + end + -- this is now specified, since it's no longer + -- derived from a default associated with an element + source~specified = .true + -- change the owner + source~ownerDocument = self + end + when type == .Node~ENTITY_NODE | type == .Node~NOTATION_NODE then do + .DomErrors~raiseError(.DomErrors~NO_MODIFICATION_ALLOWED_ERR) + end + when type == .Node~DOCUMENT_NODE | type == .Node~DOCUMENT_TYPE_NODE then do + .DomErrors~raiseError(.DomErrors~NOT_SUPPORTED_ERR) + end + when type == .Node~ENTITY_REFERENCE_NODE then do + parent = source~parentNode + if parent \= .nil then do + parent~removeChild(source) + end + -- remove the replacement value + child = source~firstChild + do while child \= .nil + source~removeChild(child) + child = source~firstChild + end + + source~ownerDocument = self + if docType \= .nil then do + entities = docType~entities + entityNode = entities~getNamedItem(source~nodeName) + if entityNode \= .nil then do + child = entityNode~firstChild + do while child \= .nil + newChild = child~cloneNode(.true) + source~appendChild(newChild) + child = child~nextSibling + end + end + end + end + when type == .Node~ELEMENT_NODE then do + parent = source~parentNode + if parent \= .nil then do + parent~removeChild(source) + end + source~ownerDocument = self + end + otherwise do + parent = source~parentNode + if parent \= .nil then do + parent~removeChild(source) + end + source~ownerDocument = self + end + end + -- return the adopted node + return source + +::method getElementById + use strict arg id + + return self~getIdentifer(id) + +::method getIdentifier + expose identifers + use strict arg id + if identifers == .nil then do + return .nil + end + + element = identifers[id] + if element \= .nil then do + parent = element~parentNode + do while parent \= .nil + if parent == self then do + return element + end + parent = parent~parentNode + end + end + + return .nil + +::method clearIdentifiers private + expose identifers + if identifers \= .nil then do + identifiers~empty + end + +::method putIdentifier + expose identifiers + use strict arg name, element + + if element == .nil then do + self~removeIdentifier(name) + end + else do + if identifiers == .nil then do + identifiers = .directory~new + end + identifers[name] = element + end + +::method removeIdentifier + expose identifiers + use strict arg name + if identifiers == .nil then do + return + end + + identifers~remove(name) + +::method identifiers + if identifiers == .nil then do + identifiers = .directory~new + end + + return identifers~allIndexes + +::method copy + use strict arg + newDoc = self~copy:super() + + newDoc~docType = .nil + newDoc~docElement = .nil + return newDoc + +::method changed + expose changes + changes += 1 + +::method addEventListener + use strict arg node, type, listener, useCapture + -- this is a nop + +::method removeEventListener + use strict arg node, type, listener, useCapture + +::method copyEventListeners + use strict arg source, target + +::method dispatchEvent + use strict arg node, event + +::method replacedText + use strict arg node + +::method deletedText + use strict arg node, offset, count + +::method insertedText + use strict arg node, offset, count + +::method modifyingCharacterData + use strict arg node, replace + +::method modifiedCharacterData + use strict arg node, oldValue, value, replace + +::method insertingNode + use strict arg node, replace + +::method insertedNode + use strict arg node, newInternal, replace + +::method removingNode + use strict arg node, oldChild, replace + +::method removedNode + use strict arg node, replace + +::method replacingNode + use strict arg node + +::method replacedNode + use strict arg node + +::method replacingData + use strict arg node + +::method replacedCharacterData + use strict arg node, oldValue, value + +::method modifiedAttrValue + use strict arg attr, oldValud + +::method setAttrNode + use strict arg attr, previous + +::method removedAttrNode + use strict arg attr, oldOwner, name + +::method renamedAttrNode + use strict arg oldAttr, newAttr + +::method renamedElement + use strict arg oldElement, newElement Property changes on: incubator/orxutils/xml/coredocument.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/deepnodelist.cls =================================================================== --- incubator/orxutils/xml/deepnodelist.cls (rev 0) +++ incubator/orxutils/xml/deepnodelist.cls 2009-06-18 23:03:29 UTC (rev 4818) @@ -0,0 +1,162 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: DeepNodeList */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + + +::class DeepNodeList subclass NodeList +::method init + expose rootNode tagName changes nodes nsName + + use strict arg rootNode, tagName, nsName = .nil + nodes = .Array~new + changes = 0 + +-- lazy search for the matching nodes. This only fills in the cache +-- as far as the last valid requested position +::method item + expose rootNode changes nodes + use strict arg index + -- if the tree has changed, we need to restart this + if rootNode~changes \= changes then do + nodes = .array~new + changes = rootNode~changes + end + + currentSize = nodes~items + if index < currentSize then do + return nodes[index + 1] + end + else do + // we need to continue the traversal from the last node added + if currentSize == 0 then do + thisNode = rootNode + end + else do + thisNode = nodes[currentSize] + end + -- keep adding up to the one we're looking for + + do while index > currentSize + thisNode = self~nexMatchingElementAfter(thisNode) + if thisNode \= .nil then do + nodes~append(thisNode) + currentSize += currentSize + end + else do + // no more nodes available + leave + end + end + -- this is either the one we want or .nil + return thisNode + end + +::attribute length GET + expose nodes + use strict arg + -- this forces everything to be initialized + item(999999999) + return nodes~items + +::attribute makearray + expose nodes + use strict arg + -- this forces everything to be initialized + item(999999999) + return nodes~copy + +::method nextMatchingElementAfter private + expose rootNode tagName nsName + use arg current + + do while current \= nil + -- go down to the first child if it has one + if current~hasChildNodes then do + current = current~firstChild + end + -- no children and we're at the rootnode, so we + -- don't go up or to any siblings + else if current == rootNode do + return .nil + end + -- now try for a sibling of our current position + next = current~nextSibling + -- if we found one, then this is our next candidate + if next \= .nil then do + current = next + end + else do + next = .nil + -- now we step "up and to the right" for as many attempts as needed + -- or utnil we pop back to the root node + do while current \= rootNode + current = current~parentNode + next = current~nextSibling + if next \= .nil then do + leave + end + end + -- this is either a good node, or .nil + current = next + end + -- we have a candidate node, now make sure it matches what we're looking for + if current \= rootNode, current \= .nil, current~nodeType == .Node~ELEMENT_NODE then do + -- no namespace checking? We'll take any element node if the name is + -- "*" or it matches directly + if nsName == .nil then do + if tagName == "*" | current~tagName == tagName then do + return current + end + end + -- namespace qualified (which might also be "*") + else do + -- wildcard match on the tagname, so just check the namespace name + if tagName == "*" then do + -- wildcards on both, this is easy + if nsName == "*" then do + return current + end + else do + -- null string is a non-specific namepace request, which + -- matches only if the element does not have a namespace + if nsName == "" & current~namespaceURI == .nil then do + return current + end + -- requires an exact namespace match + else if nsName == current~namespaceURI + return current + end + end + end + -- non-wild card on the name + else do + -- if we have a name match, then see if the namespace + -- name also matches + if current~localName == tagName then do + -- ok, the local name matches, the ns rules are the + -- same as above + if nsName == "*" then do + return current + end + else do + -- null string is a non-specific namepace request, which + -- matches only if the element does not have a namespace + if nsName == "" & current~namespaceURI == .nil then do + return current + end + -- requires an exact namespace match + else if nsName == current~namespaceURI + return current + end + end + end + end + end + end + -- if we get here, we had a candidate, but it was not a match + -- just continue the tree walk + end + -- nothing found + return .nil Property changes on: incubator/orxutils/xml/deepnodelist.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/domerrors.cls =================================================================== --- incubator/orxutils/xml/domerrors.cls (rev 0) +++ incubator/orxutils/xml/domerrors.cls 2009-06-18 23:03:29 UTC (rev 4818) @@ -0,0 +1,25 @@ +::class DOMErrors +::constant HIERARCHY_REQUEST_ERR "An attempt was made to insert a node where it is not permitted." +::constant INDEX_SIZE_ERR "The index or size is negative, or greater than the allowed value." +::constant INUSE_ATTRIBUTE_ERR "An attempt is made to add an attribute that is already in use elsewhere." +::constant INVALID_ACCESS_ERR "A parameter or an operation is not supported by the underlying object." +::constant INVALID_CHARACTER_ERR "An invalid or illegal XML character is specified." +::constant INVALID_MODIFICATION_ERR "An attempt is made to modify the type of the underlying object." +::constant INVALID_STATE_ERR "An attempt is made to use an object that is not, or is no longer, usable." +::constant NAMESPACE_ERR "An attempt is made to create or change an object in a way which is incorrect with regard to namespaces." +::constant NOT_FOUND_ERR "An attempt is made to reference a node in a context where it does not exist." +::constant NOT_SUPPORTED_ERR "The implementation does not support the requested type of object or operation." +::constant NO_DATA_ALLOWED_ERR "Data is specified for a node which does not support data." +::constant NO_MODIFICATION_ALLOWED_ERR "An attempt is made to modify an object where modifications are not allowed." +::constant SYNTAX_ERR "An invalid or illegal string is specified." +::constant VALIDATION_ERR "A call to a method such as insertBefore or removeChild would make the Node invalid with respect to document grammar." +::constant WRONG_DOCUMENT_ERR "A node is used in a different document than the one that created it." +::constant TYPE_MISMATCH_ERR "The value type for this parameter name is incompatible with the expected value type." + +::constant BAD_BOUNDARYPOINTS_ERR "The boundary-points of a Range do not meet specific requirements." +::constant INVALID_NODE_TYPE_ERR "The container of a boundary-point of a Range is being set to either a node of an invalid type or a node with an ancestor of an invalid type." + +::method raiseError class + use arg message + + raise syntax 98.900 array(message) -- just raise this as a user execution error Property changes on: incubator/orxutils/xml/domerrors.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/element.cls =================================================================== --- incubator/orxutils/xml/element.cls (rev 0) +++ incubator/orxutils/xml/element.cls 2009-06-18 23:03:29 UTC (rev 4818) @@ -0,0 +1,577 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: Element */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +::class "Element" subclass ParentNode public +::method init + expose nodeName attributes namespaceURI localName type + attributes = .nil + namespaceURI = .nil + localName = .nil + type = .nil + + if arg() == 2 then do + use strict arg ownerDoc, nodeName + self~init:super(ownerDoc) + end + else if arg() == 3 then do + use strict arg ownerDoc, namespaceURI, nodeName + self~init:super(ownerDoc) + self~setName(nodeName) + end + else do + use strict arg ownerDoc, namespaceURI, nodeName, localName + self~init:super(ownerDoc) + end + +::method setName private + expose namespaceURI localName + use arg qname + -- null string is the same as not there + if namspaceURI == "" then do + namespaceURI = .nil + end + + colon1 = qname~pos(":") + colon2 = qname~lastPos(":") + -- no prefix + if colon1 == 0 then do + -- local name and qualified name are the same + localName = qname + end + else do + parse var qname localName (colon1) (colon2 + 1) localName + end + +-- support for the Document renameNode method +::method rename + expose nodeName namespaceURI + use strict arg uri, name = .nil + if name == .nil then do + nodeName = uri + end + else do + nodeName = name + namespaceURI = uri + self~setName(name) + end + +-- override for default method +::attribute namespaceURI GET +-- get the prefix from the node name +::attribute prefix GET + expose nodeName + index = nodeName~pos(":") + if index > 0 then do + return nodeName~substr(1, index - 1) + end + else do + return .nil + end + +::attribute prefix SET + expose nodeName localName + use strict arg prefix + + -- we're either adding or replacing the prefix + if prefix \= "" then do + nodeName = prefix":"localName + end + -- or removing it entirely + else do + nodeName = localName + end + +::attribute localName GET + +::attribute nodeType GET + return .node~ELEMENT_NODE + +::attribute nodeName GET + +::attribute attributes GET + expose attributes + use strict arg + + if attributes == .nil then do + attributes = .AttributeMap~new(this, .nil) + end + + return attributes + +::attribute attributes SET private + +::method cloneNode + expose attributes + use strict arg deep = .false + newNode = self~cloneNode(deep) + + -- the attributes are always copied regardless of the deep flag + if attributes \= .nil then do + newNode~attributes = attributes~cloneMap(newNode) + end + + return newNode + +::attribute baseURI GET + use strict arg + return .nil + +::attribute ownerDocument SET private + expose attributes + use strict arg doc + + forward class(super) continue + -- also set this for all of the attributes + if attributes \= .nil then do + attributes~ownderDocument = doc + end + + +::method getAttribute + expose attributes + + use strict arg name + if attributes == .nil then do + return "" + end + + attr = attributes~getNamedItem(name) + if attr == .nil then do + return "" + end + else do + return attr~value + end + + +::method getAttributeNode + expose attributes + + use strict arg name + if attributes == .nil then do + return .nil + end + + return attributes~getNamedItem(name) + +::method getElementsByTagName + use strict arg tagname + // this version does a lazy search + return .DeepNodeList~new(this, tagname) + +::remove attributeNode + expose attributes + + use strict arg attr + + if attributes \= .nil then do + attributes~removeItem(attr) + end + +-- this is the same as the nodename for an element +::attribute tagname GET + expose nodeName + return nodeName + +::method removeAttribute + expose attributes + ust strict arg name + + if attrbutes \= .nil then do + attributes~removeNamedItem(name) + end + +::method removeAttributeNode + expose attributes + ust strict arg oldAttr + + if attrbutes \= .nil then do + attributes~removItem(oldAttr, .true) + end + +::method setAttribute + expose attributes + + use strict arg name, value + + attr = self~getAttributeName(name) + if newAttr == .nil then do + newAttr = getOwnerDocument().createAttribute(name) + + if attributes =- .nil then do + attributes = .AttributeMap~new(this) + end + + newAttr~nodeValue = value + attributes~setNamedItem(newAttr) + end + else do + newAttr~nodeValue = value + end + +::method setAttributeNode + expose attributes + + use strict arg newAttr + + if attributes == .nil then do + attributes = .AttributeMap~new(this) + end + + return attributes~setNamedItem(newAttr) + + +::method getAttributeNS + expose attributes + use strict arg namespaceURI, localName + + if attributes == .nil then do + return "" + end + + attr = attributes~getNamedItemNS(namespaceURI, localName) + if attr == .nil then do + return "" + end + else do + return attr~value + end + + +::method setAttributeNS + espose attributes + use strict arg namespaceURI, qualifiedName, value + + index = qualifiedName~pos(":") + if pos > 0 then do + parse var qualifiedName prefix ":" localName + end + else do + prefix = .nil + localName = qualifiedName + end + + newAttr = getAttributeNodeNS(namespaceURI, localName) + if newAttr == .nil then do + newAttr = self~getOwnerDocument ~createAttributeNS(namespaceURI, qualifiedName) + + if attributes == .nil then do + attributes = .AttributeMap~new(this) + end + + newAttr~nodeValue = value + attributes~setNameItemNS(newAttr) + end + else do + newAttr~name = qualifiedName + newAttr~nodeValue = value + end + +::method removeAttributeNS + expose attributes + use strict arg namespaceURI, localName + + if attributes == .nil then do + return + end + + attributes~removeNamedItemNS(namespaceURI, localName) + +::method getAttributeNodeNS + expose attributes + use strict arg namespaceURI, localName + + if attributes == .nil then do + return + end + + return attributes~getNamedItemNS(namespaceURI, localName) + +::method setAttributeNodeNS + expose attributes... [truncated message content] |
From: <bi...@us...> - 2009-06-23 00:09:37
|
Revision: 4835 http://oorexx.svn.sourceforge.net/oorexx/?rev=4835&view=rev Author: bigrixx Date: 2009-06-23 00:09:36 +0000 (Tue, 23 Jun 2009) Log Message: ----------- more dom work Modified Paths: -------------- incubator/orxutils/xml/coredocument.cls Added Paths: ----------- incubator/orxutils/xml/document.cls incubator/orxutils/xml/nodefilter.cls incubator/orxutils/xml/nodeiterator.cls incubator/orxutils/xml/treewalker.cls Modified: incubator/orxutils/xml/coredocument.cls =================================================================== --- incubator/orxutils/xml/coredocument.cls 2009-06-22 19:36:41 UTC (rev 4834) +++ incubator/orxutils/xml/coredocument.cls 2009-06-23 00:09:36 UTC (rev 4835) @@ -1,4 +1,3 @@ - /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Class: CoreDocument */ Added: incubator/orxutils/xml/document.cls =================================================================== --- incubator/orxutils/xml/document.cls (rev 0) +++ incubator/orxutils/xml/document.cls 2009-06-23 00:09:36 UTC (rev 4835) @@ -0,0 +1,38 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: Document */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +::class "Document" subclass Document +::method init + expose iterators ranges eventListeners + use arg doctype = .nil, grammarAccess = .false + + self~init:super(doctype, grammarAccess) + iterators = .nil + ranges = .nil + eventListeners = .nil + +::method cloneNode + use strict arg deep = .false + + newDoc = .Document~new + self~cloneDocument(newDoc, deep) + return newDoc + +::method implementation + -- this is a singleton + return .DOMImplementation~implementation + +::method createNodeIterator + expose iterators + use strict arg root, whatToShow, filter, entityReferenceExpansion = .true + + iterator = .NodeIterator~new(self, root, whatToShow, filter, entityReferenceExpansion) + + if iterators = .nil then do + iterators = .list~new + end + + iterators~append(iterator) + return iterator Property changes on: incubator/orxutils/xml/document.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/nodefilter.cls =================================================================== --- incubator/orxutils/xml/nodefilter.cls (rev 0) +++ incubator/orxutils/xml/nodefilter.cls 2009-06-23 00:09:36 UTC (rev 4835) @@ -0,0 +1,34 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: NodeFilter */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +::class "NodeIterator" mixinclass Object +-- constants returned by acceptNode +::constant FILTER_ACCEPT 1 +::constant FILTER_REJECT 2 +::constant FILTER_SKIP 3 + +-- whatToShow values +::constant SHOW_ALL -1 +::constant SHOW_ELEMENT 1 +::constant SHOW_ATTRIBUTE 2 +::constant SHOW_TEXT 4 +::constant SHOW_CDATA_SECTION 8 +::constant SHOW_ENTITY_REFERENCE 16 +::constant SHOW_ENTITY 32 +::constant SHOW_PROCESSING_INSTRUCTION 64 +::constant SHOW_COMMENT 128 +::constant SHOW_DOCUMENT 256 +::constant SHOW_DOCUMENT_TYPE 512 +::constant SHOW_DOCUMENT_FRAGMENT 1024 +::constant SHOW_NOTATION 2048 + +-- use to filter the individual nodes +::method acceptNode + use strict arg node + -- default implementation accepts everything + return self~FILTER_ACCEPT + + + Property changes on: incubator/orxutils/xml/nodefilter.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/nodeiterator.cls =================================================================== --- incubator/orxutils/xml/nodeiterator.cls (rev 0) +++ incubator/orxutils/xml/nodeiterator.cls 2009-06-23 00:09:36 UTC (rev 4835) @@ -0,0 +1,236 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: NodeIterator */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +::class "NodeIterator" +::method init + expose document root currentNode whatToShowFlags whatToShow nodeFilter entityReferenceExpansion forward + use strict arg document, root, whatToShow = (.NodeFilter~SHOW_ALL), nodeFilter = .nil, entityReferenceExpansion = .false + + if whatToShow == .NodeFilter~SHOW_ALL then do + flagValues = "11111111111" -- we'll set all flags to true + end + else do + -- convert this to a binary string, then pad out to 11 digits for the + -- mapping + flagValues = whatToShow~d2x~x2b~right(11, 0) + end + + whatToShowFlags = .directory~new + parse var flagValues whatToShowFlags[.Node~ELEMENT] +1 - + whatToShowFlags[.Node~ATTRIBUTE] +1 - + whatToShowFlags[.Node~TEXT] +1 - + whatToShowFlags[.Node~CDATA_SECTION] +1 - + whatToShowFlags[.Node~ENTITY_REFERENCE] +1 - + whatToShowFlags[.Node~ENTITY] +1 - + whatToShowFlags[.Node~PROCESSING_INSTRUCTION] +1 - + whatToShowFlags[.Node~COMMENT] +1 - + whatToShowFlags[.Node~DOCUMENT] +1 - + whatToShowFlags[.Node~DOCUMENT_TYPE] +1 - + whatToShowFlags[.Node~DOCUMENT_FRAGMENT] +1 - + whatToShowFlags[.Node~NOTATION] +1 + + forward = .true -- we start iterating in a forward direction + +::attribute root GET +::attribute whatToShow GET +::attribute filter GET +::attribute expandEntityReferences GET + +::method nextNode + expose root currentNode forward + use strictArg + + if root == .nil then do + return .nil + end + + nextNode = currentNode + + do forever + -- if we're backing up, repeat the current node + if \forward & nextNode \= .nil then do + nextNode = currentNode + end + else do + if \entityReferenceExpansion, nextNode \= .nil, nextNode~nodeType == .Node~ENTITY_REFERENCE_NODE then do + nextNode = self~nextNode(nextNode, .false) + end + else do + nextNode = self~nextNode(nextNode, .true) + end + end + forward = .true + -- did not find a next node, return .nil + if nextNode = .nil then do + return .nil + end + + -- now try the filters + if self~acceptNode(nextNode) then do + -- if the filter says this one is ok, then set the iteration + -- position and return + currentNode = nextNode + return currentNode + end + -- keep looping until we find something good + end + + return .nil -- no acceptable nodes found + +::method previousNode + expose root currentNode forward + use strictArg + + if root == .nil | currentNode = .nil then do + return .nil + end + + previousNode = currentNode + + do forever + if forward & previousNode \= .nil then do + previousNode = currentNode + end + else do + previousNode = self~previousNode(previousNode) + end + + -- this is going backwards + forward = .false + + if previousNode = .nil then do + return .nil + end + + if self~acceptNode(previousNode) then do + currentNode = previousNode + return currentNode + end + end + + return .nil + +::method acceptNode private + expose nodeFilter whatToShowFlags + use arg node + + if nodeFilter == .nil then do + return whatToShowFlags[node~nodeType] + end + else do + return whatToShowFlags[node~nodeType] & nodeFilter~acceptNode(node) == .NodeFilter~FILTER_ACCEPT + end + +::method locateNextNode private + expose root + use strict arg node, visitChildren + + if node == .nil then do + return .nil + end + + if visitChildren then do + if node~hasChildNodes then do + return node~firstChild + end + end + + -- back to the root? We're done + if node == root then do + return .nil + end + + -- use the next sibling if it exists + result = node~nextSibling + if result \= .nil then do + return result + end + + -- go up to the parent + parent = node~parentNode + do while parent \= .nil & parent \= root + result = parent~nextSibling + if result \= .nil then do + return result + end + parent = parent~parentNode + end + -- end of the nodes, return .nil + return .nil + +::method locatePreviousNode private + expose root entityReferenceExpansion + use strict arg node + + -- back to the root? We're done + if node == root then do + return .nil + end + + -- use the next sibling if it exists + result = node~previousSibling + if result == .nil then do + -- if no previous sibling, then step up to the parent + return node~parentNode + end + + -- if the sibling has children, drill down to the last last child + if result~hasChildNodes & \(\entityReferenceExpansion & result~nodeType == .Node~ENTITY_REFERENCE_NODE) then do + do while result~hasChildNodes + result = result~lastChild + end + end + + return result + +::method removeNode + expose forward currentNode + use strict arg node + if node = .nil then do + return + end + + delete = self~matchNodeOrParent(node) + + if forward then do + currentNode = self~locatePreviousNode(deleted) + end + else do + next = self~locateNextNode(deleted, .false) + if next \= .nil then do + currentNode = next + end + else do + currentNode = self~locatedPreviousNode(deleted) + forward = .true + end + end + +::method matchNodeOrParent private + expose currentNode root + use strict arg node + + if currentNode == .nil then do + return .nil + end + + target = currentNode + do while target \= root + if node == target then do + return target + end + target = target~parentNode + end + + return .nil + +::method detach + expose root currentNode document + + root = .nil + currentNode = .nil + document~removeNodeIterator(self) + document = .nil + Property changes on: incubator/orxutils/xml/nodeiterator.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/treewalker.cls =================================================================== --- incubator/orxutils/xml/treewalker.cls (rev 0) +++ incubator/orxutils/xml/treewalker.cls 2009-06-23 00:09:36 UTC (rev 4835) @@ -0,0 +1,329 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: TreeWalker */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +::class "TreeWalker" +::method init + expose currentNode root whatToShow nodeFilter entityReferenceExpansion whatToShowFlags + use strict arg root, self~whatToShow, nodeFilter, entityReferenceExpansion + + currentNode = root + +::attribute root GET +::attribute filter GET +::attribute expandEntityReferences GET +::attribute currentNode +::attribute whatToShow GET +::attribute whatToShow SET + expose whatToShow whatToShowFlags + use strict arg whatToShow + + if whatToShow == .NodeFilter~SHOW_ALL then do + flagValues = "11111111111" -- we'll set all flags to true + end + else do + -- convert this to a binary string, then pad out to 11 digits for the + -- mapping + flagValues = whatToShow~d2x~x2b~right(11, 0) + end + + whatToShowFlags = .directory~new + parse var flagValues whatToShowFlags[.Node~ELEMENT] +1 - + whatToShowFlags[.Node~ATTRIBUTE] +1 - + whatToShowFlags[.Node~TEXT] +1 - + whatToShowFlags[.Node~CDATA_SECTION] +1 - + whatToShowFlags[.Node~ENTITY_REFERENCE] +1 - + whatToShowFlags[.Node~ENTITY] +1 - + whatToShowFlags[.Node~PROCESSING_INSTRUCTION] +1 - + whatToShowFlags[.Node~COMMENT] +1 - + whatToShowFlags[.Node~DOCUMENT] +1 - + whatToShowFlags[.Node~DOCUMENT_TYPE] +1 - + whatToShowFlags[.Node~DOCUMENT_FRAGMENT] +1 - + whatToShowFlags[.Node~NOTATION] +1 + +::attribute parentNode GET + expose currentNode + if currentNode = .nil then do + return .nil + end + +::method lastChild + expose currentNode + use strict arg + + if currentNode == .nil then do + return .nil + end + + node = self~getLastChild(currentNode) + if node \= .nil then do + currentNode = node + end + + return node + +::method previousSibling + expose currentNode + use strict arg + + node = self~getPreviousSibline(currentNode) + if node \= .nil then do + currentNode = node + end + + return node + +::method nextSibling + expose currentNode + use strict arg + + node = self~getNextSibling(currentNode) + if node \= .nil then do + currentNode = node + end + + return node + +::method previousNode + expose currentNode + use strict arg + + if currentNode == .nil then do + return .nil + end + + node = self~getPreviousSibling(currentNode) + if node == .nil then do + node = self~getParentNode(currentNode) + if result \= .nil then do + currentNode = node + return node + end + return .nil + end + + lastChild = self~getLastChild(node) + previos = lastChild + + do while lastChild \= .nil + previous = lastChild + lastChild = self~getLastChild(previous) + end + + lastChild = previous + + if lastChild \= . nil then do + currentNode = lastChild + return lastChild + end + + if node \= .nil then do + currentNode = node + return currentNode + end + + return .nil + +::method nextNode + expose currentNode + use strict arg + + if currentNode == .nil then do + return .nil + end + + node = self~getFirstChild(currentNode) + + if node \= .nil then do + currentNode = node + return node + end + + node = self~getNextSibling(currentNode) + + if node \= .nil then do + currentNode = node + return node + end + + parent = self~getParentNode(currentNode) + do while parent \= .nil + node = self~getNextSibling(parent) + if node \= .nil then do + currentNode = node + return node + end + + parent = self~getParentNode(parent) + end + + return .nil + +::method getParentNode private + expose currentNode + if node == .nil | node == root then do + return .nil + end + + newNode = node~parentNode + if newNode == .nil then do + return .nil + end + + if self~acceptNode(newNode) == .NodeFilter~FILTER_ACCEPT then do + return newNode + end + + -- if skipped or rejected, try for another parent + return self~getParentNode(newNode) + +::method getNextSibling private + expose root + use strict arg node, startNode = root + + if node == .nil | node == startNode then do + return .nil + end + + newNode = node~nextSibling + if newNode == .nil then do + newNode = node~parentNode + if newNode = .nil | newNode == startNode then do + return .nil + end + + if self~acceptNode(newNode) == .NodeFilter~FILTER_SKIP then do + return self~getNextSibling(newNode, startNode) + end + + return .nil + end + + accept = self~acceptNode(newNode) + if accept == .NodeFilter~FILTER_ACCEPT then do + return newNode + end + else if accept == .NodeFilter~FILTER_SKIP then do + child = self~getFirstChild(newNode) + if child == .nil then do + return self~getNextSibling(newNode, startNode) + end + return child + end + else do + return self~getNextSibling(newNode, startNode) + end + +::method getPreviousSibling private + expose root + use strict arg node, startNode = root + + if node == .nil | node == startNode then do + return .nil + end + + newNode = node~previousSibling + if newNode == .nil then do + newNode = node~parentNode + if newNode == .nil | newNode == startNode then do + return .nil + end + + if self~acceptNode(newNode) == .NodeFilter~FILTER_SKIP then do + return self~getPreviousSibling(newNode, startNode) + end + return .nil + end + + accept = self~acceptNode(newNode) + if accept == .NodeFilter~FILTER_ACCEPT then do + return newNode + end + else if accept == .NodeFilter~FILTER_SKIP then do + child = self~getLastChild(newNode) + if child == .nil then do + return self~getPreviousSibling(newNode, startNode) + end + return child + end + else do + return self~getPreviousSibling(newNode, startNode) + end + +::method getFirstChild private + expose entityReferenceExpansion + use strict arg node + + if entityReferenceExpansion & node~nodeType == .Node~ENTITY_REFERENCE_NODE then do + return .nil + end + + newNode = node~firstChild + if newNode == .nil then do + return .nil + end + + accept = self~acceptNode(newNode) + if accept == .NodeFilter~FILTER_ACCEPT then do + return newNode + end + else if accept == .NodeFilter~FILTER_SKIP & newNode~hasChildNodes then do + child = self~getFirstChild(newNode) + if child == .nil then do + return self~getNextSibling(newNode, node) + end + end + else do + return self~getNextSibling(newNode, node) + end + +::method getLastChild private + expose entityReferenceExpansion + use strict arg node + + if entityReferenceExpansion & node~nodeType == .Node~ENTITY_REFERENCE_NODE then do + return .nil + end + + newNode = self~lastChild + if newNode == .nil then do + return .nil + end + + accept = self~acceptNode(newNode) + if accept == .NodeFilter~FILTER_ACCEPT then do + return newNode + end + else if accept == .NodeFilter~FILTER_SKIP & newNode~hasChildNodes then do + child = self~getLastChild(newNode) + if child == .nil then do + return self~getPreviousSibling(newNode, node) + end + end + else do + return self~getPreviousSibling(newNode, node) + end + +::method acceptNode private + expose nodeFilter whatToShowFlags + use strict arg node + + if nodeFilter == .nil then do + if whatToShowFlags[node~nodeType] then do + return .NodeFilter~FILTER_ACCEPT + end + else do + return .NodeFilter~FILTER_SKIP + end + end + else do + if whatToShowFlags[node~nodeType] then do + return nodeFilter~accept(node) + end + else do + return .NodeFilter~FILTER_SKIP + end + end + Property changes on: incubator/orxutils/xml/treewalker.cls ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2009-06-29 23:51:43
|
Revision: 4857 http://oorexx.svn.sourceforge.net/oorexx/?rev=4857&view=rev Author: bigrixx Date: 2009-06-29 23:50:37 +0000 (Mon, 29 Jun 2009) Log Message: ----------- More DOM work Modified Paths: -------------- incubator/orxutils/xml/document.cls Added Paths: ----------- incubator/orxutils/xml/range.cls Modified: incubator/orxutils/xml/document.cls =================================================================== --- incubator/orxutils/xml/document.cls 2009-06-29 18:32:05 UTC (rev 4856) +++ incubator/orxutils/xml/document.cls 2009-06-29 23:50:37 UTC (rev 4857) @@ -36,3 +36,17 @@ iterators~append(iterator) return iterator + +::method createTreeWalker + use strict arg root, whatToShow, filter, entityReferenceExpansion = .true + return .TreeWalker~new(root, whatToShow, filter, entityReferenceExpansion) + +::method removeNodeIterator + expose iterators + use strict arg nodeIterator + + if nodeIterator == .nil | iterators == .nil then do + return + end + + iterators~remove(iterator) Added: incubator/orxutils/xml/range.cls =================================================================== --- incubator/orxutils/xml/range.cls (rev 0) +++ incubator/orxutils/xml/range.cls 2009-06-29 23:50:37 UTC (rev 4857) @@ -0,0 +1,1188 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: Range */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +::class "Range" +::constant START_TO_START 0 +::constant START_TO_END 1 +::constant END_TO_END 2 +::constant END_TO_START 3 +::constant EXTRACT_CONTENTS 1 +::constant CLONE_CONTENTS 2 +::constant DELETE_CONTENTS 3 + +::method init + expose document startContainer endContainer startOffset endOffset - + insertNode deleteNode splitNode insertedFromRange + use strict arg document + startContainer = document + endContainer = document + startOffset = 0 + endOffset = 0 + insertNode = .nil + deleteNode = .nil + splitNode = .nil + insertedFromRange = .false + +::attribute startContainer GET +::attribute startOffset GET +::attribute endContainer GET +::attribute endOffset GET +::attribute collapsed GET + expose startContainer endContainer startOffset endOffset + use strict arg + return startContainer == endContainer & startOffset = endOffset + +::attribute commonAncestorContainer + expose startContainer + startV = .array~new + node = startContainer + do while node \= .nil + startV~append(node) + node = node~parentNode + end + + endV = .array~new + + node = endContainer + do while node \= .nil + endV~append(node) + node = node~parentNode + end + + -- this will give all of the common elements, + -- retaining the order. The last one is the + -- element we want + common = startV~intersection(endV) + return common[common~last] + +::method setStart + expose startContainer startOffset endContainer endOffset + use strict arg refNode, offset + + self~checkIndex(refNode, offset) + startContainer = refNode + startOffset = offset + + if self~commonAncestorContainer == .nil | - + (startContainer == endContainer & endOffset < startOffset) then do + self~collapse(.true) + end + +::method setEnd + expose startContainer startOffset endContainer endOffset + use strict arg refNode, offset + + self~checkIndex(refNode, offset) + endContainer = refNode + endOffset = offset + + if self~commonAncestorContainer == .nil | - + (startContainer == endContainer & endOffset < startOffset) then do + self~collapse(.false) + end + + +::method setStartBefore + expose startContainer startOffset endContainer endOffset + use strict arg refNode + + startContainer = refNode~parentNode + i = 0 + node = refNode + do while node \= .nil + i += 1 + node = node~previousSibling + end + + startOffset = i - 1 + + -- now collapse this, if necessary + if self~commonAncestorContainer == .nil | - + (startContainer == endContainer & endOffset < startOffset) then do + self~collapse(.true) + end + + +::method setStartAfter + expose startContainer startOffset endContainer endOffset + use strict arg refNode + + startContainer = refNode~parentNode + i = 0 + node = refNode + do while node \= .nil + i += 1 + node = node~previousSibling + end + + startOffset = i + + -- now collapse this, if necessary + if self~commonAncestorContainer == .nil | - + (startContainer == endContainer & endOffset < startOffset) then do + self~collapse(.true) + end + + +::method setStartAfter + expose startContainer startOffset endContainer endOffset + use strict arg refNode + + endContainer = refNode~parentNode + i = 0 + node = refNode + do while node \= .nil + i += 1 + node = node~previousSibling + end + + endOffset = i - 1 + + -- now collapse this, if necessary + if self~commonAncestorContainer == .nil | - + (startContainer == endContainer & endOffset < startOffset) then do + self~collapse(.false) + end + + +::method setEndAfter + expose startContainer startOffset endContainer endOffset + use strict arg refNode + + endContainer = refNode~parentNode + i = 0 + node = refNode + do while node \= .nil + i += 1 + node = node~previousSibling + end + + endOffset = i + + -- now collapse this, if necessary + if self~commonAncestorContainer == .nil | - + (startContainer == endContainer & endOffset < startOffset) then do + self~collapse(.false) + end + + +::method collapse + expose startContainer startOffset endContainer endOffset + use strict arg toStart + + if toStart then do + endContainer = startContainer + endOffset = startOffset + end + else do + startContainer = endContainer + startOffset = endOffset + end + +::method selectNode + expose startContainer startOffset endContainer endOffset + use strict arg refnode + + parent = refNode~parentNode + if parent == .nil then do + startContainer = parent + endContainer = parent + i = 0 + node = refNode + do while node \= .nil + node = previousSibling + i += 1 + end + startOffet = i - 1 + endOffset = i + end + +::method selectNodeContents + expose startContainer startOffset endContainer endOffset + use strict arg refnode + + startContainer = refNode + startOffset = 0 + endContainer = refNode + endOffset = 0 + first = refNode~firstChild + do while first \= .nil + endOffset += 1 + first = first~nextSibling + end + +::method compareBoundaryPoints + expose startContainer startOffset endContainer endOffset + use strict arg how, sourceRange + + select + when how == .Range~START_TO_START then do + endPointA = sourceRange~startContainer + endPointB = startContainer + offsetA = sourceRange~startOffset + offsetB = startOffset + end + when how == .Range~START_TO_END then do + endPointA = sourceRange~startContainer + endPointB = endContainer + offsetA = sourceRange~startOffset + offsetB = endOffset + end + when how == .Range~END_TO_START then do + endPointA = sourceRange~endContainer + endPointB = startContainer + offsetA = sourceRange~endOffset + offsetB = startOffset + end + when how == .Range~END_TO_END then do + endPointA = sourceRange~endContainer + endPointB = endContainer + offsetA = sourceRange~endOffset + offsetB = endOffset + end + end + + -- The DOM Spec outlines four cases that need to be tested + -- to compare two range boundary points: + -- case 1: same container + -- case 2: Child C of container A is ancestor of B + -- case 3: Child C of container B is ancestor of A + -- case 4: preorder traversal of context tree. + + -- case 1: same container + if endPointA == endPointB then do + -- returns 0, 1, or -1 + return (offsetB - offsetA)~sign + end + + -- case 2: Child C of container A is ancestor of B + current = endPointB + parent = current~parentNode + do while parent \= .nil + if parent == endPointA then do + if offsetA <= self~indexOf(current, endPointA) then do + return 1 + end + else do + return -1 + end + end + current = parent + parent = parent~parentNode + end + + -- case 3: Child C of container B is ancestor of A + current = endPointA + parent = current~parentNode + do while parent \= .nil + if parent == endPointB then do + if self~indexOf(current, endPointB) < offsetB then do + return 1 + end + else do + return -1 + end + end + current = parent + parent = parent~parentNode + end + + -- case 4: preorder traversal of context tree. + depthDiff = 0 + node = endPointA + do while node \= .nil + depthDiff += 1 + node = node~parentNode + end + + node = endPointB + do while node \= .nil + depthDiff -= 1 + node = node~parentNode + end + + do while depthDiff > 0 + endPointA = endPointA~parentNode + depthDiff -= 1 + end + + do while depthDiff < 0 + endPointB = endPointB~parentNode + depthDiff += 1 + end + + parentA = endPointA~parentNode + parentB = endPointB~parentNode + do while parentA \= parentB + endPointA = parentA + endPointB = parentB + parentA = parentA~parentNode + parentB = parentB~parentNode + end + + node = endPointA~nextSibling + do while node \= .nil + if node == endPointB then do + return 1 + end + node = node~nextSibling + end + + return -1 + +::method deleteContents + use strict arg + self~traverseContents(self~DELETE_CONTENTS) + +::method extractContents + use strict arg + return self~traverseContents(self~EXTRACT_CONTENTS) + +::method cloneContents + use strict arg + return self~traverseContents(self~CLONE_CONTENTS) + +::insertNode + expose startContainer startOffset endContainer endOffset insertedFromRange + use strict arg newNode + if newNode == .nil then do + return + end + + type = newNode~nodeType + currentChildren = 0 + insertedFromRange = .true + + if startContainer == .Node~TEXT_NODE then do + parent = startContainer~parentNode + currentChildren = parent~childNodes~length + cloneCurrent = startContainer~cloneNode(.false) + cloneCurrent~nodeValue = cloneCurrent~nodeValue~substr(startOffset + 1) + startContainer~nodeValue = startContainer~nodeValue(1, startOffset) + next = startContainer~nextSibling + if next \= .nil then do + if parent \= .nil then do + parent~insertBefore(newNode, next) + paretn~insertBefore(cloneNode, next) + end + end + else do + if parent \= .nil then do + parent~appendChild(newNode) + parent~appendChild(cloneCurrent) + end + end + -- update the ranges + if endContainer == startContainer then do + endContainer = cloneCurrent + endOffset -= startOffset + end + else if endContainer == parent do + endOffset += parent~childNodes~length - currentChildren + end + + self~signalSplitdata(startContainer, cloneCurrent, startOffset) + end + else do + if endContainer == startContainer then do + currentChildren = endContainer~childNodes~length + end + current = startContainer~firstChild + do i = 1 to startOffset while current \= .nil + current = current~nextSibling + end + if current \= .nil then do + startContainer~insertBefore(newNode, current) + end + else do + startContainer~appendChild(newNode) + end + if endContainer = startContainer & endOffset \= 0 then do + endOffset += endContainer~childNodes~length - currentNodes + end + end + insertedFromRange = .false + +::method surroundContents + expose startContainer startOffset endContainer endOffset + use strict arg newParent + + if newParent == .nil then do + return + end + + type = newParent~nodeType + realStart = startContainer + realEnd = endContainer + + if startContainer~nodeType == .Node~TEXT_NODE then do + realStart = startContainer~parentNode + end + + if endContainer~nodeType == .Node~TEXT_NODE then do + realEnd = endContainer~parentNode + end + + if realStart != realEnd then do + DomErrors~raiseError(.DomErrors~BAD_BOUNDARY_POINTS_ERR) + end + + frag = self~extractContents() + self~insertNode(newParent) + newParent~appendChild(frag) + self~selectNode(newParent) + +::method cloneRange + expose document startContainer startOffset endContainer endOffset + + range = document~createRange + range~setStart(startContainer, startOffset) + range~setEnd(endContainer, endOffset) + return range + +::method string + expose startContainer startOffset endContainer endOffset + + node = startContainer + stopNode = endContainer + + buffer = .mutablebuffer~new + if startContainer~nodeType == .Node~TEXT_NODE | startContainer~nodeType == .Node~CDATA_SECTION_NODE then do + if startContainer == endContainter then do + return startContainer~nodeValue~substr(startOffset + 1, endOffset - startOffset) + end + buffer~append(startContainer~nodeValue~substr(startOffset + 1)) + end + else do + node = node~firstChild + if startOffset > 0 then do + counter = 0 + do while counter < startOffset, node \= .nil + node = node~nextSibling + counter += 1 + end + end + if nod == .nil then do + node = self~nextNode(startContainer, .false) + end + end + + if endContainer~nodeType \= .Node~TEXT_NODE & endContainer~nodeType \= .Node~CDATA_SECTION_NODE then do + counter = endOffset + stopNode = endContainer~firstChild + do while counter > 0, stopNode \= .nil + counter -= 1 + stopNode = stopNode~nextSibling + end + + if stopNode == .nil then do + stopNode = self~nextNode(endContainer, .false) + end + end + + do while node \= stopNode, node \= .nil + if node~nodeType == .Node~TEXT_NODE | node~nodeType == .Node~CDATA_SECTION_NODE then do + buffer~append(node~nodeValue) + end + node = self~nextNode(node, .true) + end + + if endContainer~nodeType == .Node~TEXT_NODE | endContainer~nodeType == .Node~CDATA_SECTION_NODE then do + buffer~append(endContainer~nodeValue~substr(1, endOffset)) + end + + return buffer~string + +::detach + expose document + use strict arg + document~removeRange(self) + document = .nil + +::method signalSplitData + expose splitNode document + use strict arg node, newNode, offset + + splitNode = node + document~splitData(node, newNode, offset) + splitNode = .nil + +::method receiveSplitData + expose startContainer startOffset endContainer endOffset splitNode + use strict arg node, newNode, offset + + if node == .nil | newNode == .nil | splitNode == node then do + return + end + + if node == startContainer & startContainer~nodeType == .Node~TEXT_NODE then do + if startOffset > offset then do + startOffset = startOffset - offset + startContainer = newNode + end + end + + if node == endContainer & endContainer~nodeType == .Node~TEXT_NODE then do + if endtOffset > offset then do + endOffset = endOffset - offset + endContainer = newNode + end + end + +::method deleteData + expose deleteNode + use strict arg node, offset, count + + deleteNode = node + node~deleteData(offset, count) + deleteNode = .nil + +::method receiveDeletedText + expose startContainer startOffset endContainer endOffset deleteNode + use strict arg node, offset, count + + if node == .nil | deleteNode == node then do + return + end + + if node == startContainer then do + if startOffset > offset + count then do + startOffset = offset + (startOffset - (offset + count)) + end + else if startOffset > offset then do + startOffset = offset + end + end + if node == endContainer then do + if endOffset > offset + count then do + endOffset = offset + (endOffset - (offset + count)) + end + else if endOffset > offset then do + endOffset = offset + end + end + +::method insertData + expose insertNode + use strict arg node, index, insert + + insertNode = node + node~insertData(index, insert) + insertNode = .nil + +::method receiveInsertedText + expose startContainer startOffset endContainer endOffset insertNode + use strict arg node, index, len + + if node == .nil | deleteNode == node then do + return + end + + if node == startContainer then do + if index < startContainer then do + startOffset += len + end + end + if node == endContainer then do + if index < endOffset then do + endOffset += len + end + end + +::method receiveReplacedText + expose startContainer startOffset endContainer endOffset + use strict arg node + + if node == .nil then do + return + end + + if node == startContainer then do + startOffset = 0 + end + + if node == endContainer then do + endOffset = 0 + end + +::method insertedNodeFromDOM + expose startContainer startOffset endContainer endOffset insertNode insertedFromRange + use strict arg node + + if node == .nil | insertNode == node | insertedFromRange then do + return + end + + parent = node~parentNode + + if parent == startContainer then do + index = self~indexOf(node, startContainer) + if index < startOffset then do + startOffset += 1 + end + end + + if parent == endContainer then do + index = self~indexOf(node, endContainer) + if index < endOffset then do + endOffset += 1 + end + end + + +::method removeChild private + expose removeChild + use strict arg parent, child + removeChild = child + result parent~removeChild(child) + removeChild = .nil + return result + + +::method removeNode + expose startContainer startOffset endContainer endOffset removeChild + use strict arg node + + if node == .nil | removeChild == node then do + return + end + + parent = node~parentNode + if parent == startContainer then do + index = self~indexOf(node, startContainer) + if index < startOffset then do + startOffset -= 1 + end + end + + if parent == endContainer then do + index = self~indexOf(node, endContainer) + if index < endOffset then do + endOffset-- + end + end + + if parent \= startContainer | parent \= endContainer then do + if self~isAncestorOf(node, startContainer) then do + startContainer = parent + startOffset = self~indexOf(node, parent) + end + if self~isAncestorOf(node, endContainer) then do + endContainer = parent + endOffset = self~indexOf(node, parent) + end + end + + +-- utility functions +::method traverseContents private + expose startContainer startOffset endContainer endOffset + use strict arg now + + if startContainer == .nil | endContainer = .nil then do + return .nil + end + + -- Case 1: same container + if startContainer == endContainer then do + return self~traverseSameContainer(how) + end + + -- Case 2: Child C if start container is ancestor of end container. + -- this can be quickly tested by walking the parent chain of the end + -- container + endContainerDepth = 0 + node = endContainer + parent = node~parentNode + do while parent \= .nil + if p == startContainer then do + return self~traverseCommonStartContainer(node, how) + end + node = parent + parent = p~parentNode + endContainerDepth++ + end + + -- case 3: Child C of container B is ancestor of A + -- This can be quickly tested by walking the parent chain of A + endContainerDepth = 0 + node = startContainer + parent = node~parentNode + do while parent \= .nil + if p == endContainer then do + return self~traverseCommonEndContainer(node, how) + end + node = parent + parent = p~parentNode + endContainerDepth++ + end + + -- case 4: There is a common ancestor container. Find the + -- ancestor siblings that are children of that container. + + depthDiff = startContainerDept - endContainerDepth + startNode = startContainer + + do while depthDiff > 0 + startNode = startNode~parentNode + depthDiff -= 1 + end + + endNode = endContainer + + do while depthDiff < 0 + endNode = endNode~parentNode + depthDiff += 1 + end + + sp = startNode~parentNode + ep = endNode~parentNode + + do while sp \= ep + startNode = sp + endNode = sp + + sp = sp~parentNode + ep = ep~parentNode + end + return self~traverseCommonAncestors(startNode, endNode, how) + +::method traverseSameContainer private + expose document startContainer startOffset endContainer endOffset + use strict arg how + + fragment = .nil + + if how == self~DELETE_CONTENTS then do + fragment = document~createDocumentFragment + end + + nodeType = startContainer~nodeType + if nodeType == .Node~TEXT_NODe | nodeType == .Node~CDATA_SECTION_NODE | nodeType == .Node~COMMENT_NODE | nodeType == .Node~PROCESSING_INSTRUCTION_NODE then do + test = startContainer~nodeValue + sub = s~substr(startOffset + 1, endOffset - startOffset) + + if how \= self~CLONE_CONTENTS then do + startContainer~deleteData(startOffset, endOffset - startOffset) + self~collapse(.true) + end + + if how == self~DELETE_CONTENTS then do + return .nil + end + if nodeType == .Node~TEXT_NODE then do + fragment~appendChild(document~createTestNode(sub)) + end + else if nodeType == .Node~CDATA_SECTION_NODE then do + fragment~appendChild(document~createCDATASection(sub)) + end + else if nodeType == .Node~COMMENT_NODE then do + fragment~appendChild(document~createComment(sub)) + end + else do -- .Node~PROCESSING_INSTRUCTION_NODE + fragment~appendChild(document~createProcessingInstruction(startContainer~nodeName, sub)) + end + return fragment + end + + -- copy nodes between start/end offsets + node = self~getSelectedNode(startContainer, startOffset) + count = endOffset - startOffset + + do count + sibling = node~nextSibling + xferNode = self~traverseFullySelected(node, how) + if fragment \= .nil then do + fragment~appendChild(xferNode) + end + node = sibling + end + + if now \= self~CLONE_CONTENTS then do + self~collapse(.true) + end + + return fragment + +::method traverseCommonStartContainer private + expose document startContainer startOffset endContainer endOffset + use strict arg endAncestor, how + + fragment = .nil + + if how == self~DELETE_CONTENTS then do + fragment = document~createDocumentFragment + end + + node = self~traverseRightBoundary(endAncestor, how) + if fragment \= .nil then do + fragment~appendChild(node) + end + + endIndex = self~indexOf(endAncestor, startContainer) + count = endIndex - startOffset + + if count <= 0 then do + if how \= self~CLONE_CONTENTS then do + self~setEndBefore(endAncestor) + self~collapse(.false) + end + return fragment + end + + node = endAncestor~previousSibling + do count + sibling = node~previousSibling + xferNode = self~traverseFullySelected(node, how) + if fragment \= .nil then do + fragment~insertBefore(xferNode, fragment~firstChild) + end + node = sibling + end + + if how \= self~CLONE_CONTENTS then do + self~setEndBefore(endAncestor) + self~collapse(.false) + end + return fragment + +::method traverseCommonEndContainer private + expose document startContainer endContainer + use strict arg startAncestor, how + + fragment = .nil + + if how == self~DELETE_CONTENTS then do + fragment = document~createDocumentFragment + end + + node = self~traverseLeftBoundary(endAncestor, how) + if fragment \= .nil then do + fragment~appendChild(node) + end + + startIndex = self~indexOf(startAncestor, endContainer) + 1 + count = endOffset - startIndex + node = startAncestor~nextSibling + + do count + sibling = node~nextSibling + xferNode = self~traverseFullySelected(node, how) + if fragment \= .nil then do + fragment~appendChild(xferNode) + end + node = sibling + end + + if how \= self~CLONE_CONTENTS then do + self~setStartAfter(startAncestor) + self~collapse(.true) + end + return fragment + +::method traverseCommonAncestors private + expose document startContainer endContainer + use strict arg startAncestor, endAncestor, how + + fragment = .nil + + if how == self~DELETE_CONTENTS then do + fragment = document~createDocumentFragment + end + + node = self~traverseLeftBoundary(endAncestor, how) + if fragment \= .nil then do + fragment~appendChild(node) + end + + commonParent = startAncestor~parentNode + startOffset = self~indexOf(startAncestor, commonParent) + 1 + endOffset = self~indexOf(endAncestor, commonParent) + + count = endOffset - startOffset + sibling = startAncestor~nextSibling + + do count + nextSibling = sibling~nextSibling + node = self~traverseFullySelected(sibling, now) + if fragment \= .nil then do + fragment~appendChild(node) + end + sibling = nextSibling + end + + node = self~traverseRightBoundary(endAncestor, how) + if fragment \= .nil then do + fragment~appendChild(node) + end + + if how \= self~CLONE_CONTENTS then do + self~setStartAfter(startAncestor) + self~collapse(.true) + end + return fragment + +::method traverseRightBoundary private + expose document startContainer startOffset endContainer endOffset + use strict arg root, how + + next = self~getSelectedNode(endContainer, endOffset - 1) + isFullySelected = next \= endContainer + + if next == root then do + return self~traverseNode(next, isFullySelected, .false, now) + end + + parent = next~parentNode + clonedParent = self~traverseNode(parent, .false, .false, how) + + do while parent \= .nil + do while next \= .nil + prevSibling = next~previousSibling + clonedChild = self~traverseNode(next, isFullySelected, .false, how) + if how \= self~DELETE_CONTENTS then do + clonedParent~insertBefore(clonedChild, clonedParent~firstChild) + end + isFullySelected = .true + next = prevSibling + end + if parent == root then do + return clonedParent + end + + next = parent~previousSibling + parent = parent~parentNode + node clonedGrandParent = self~traverseNode(parent, .false, .false, how) + if how \= self~DELETE_CONTENTS then do + clonedGrandParent~appendChild(clonedParent) + end + clonedParent = clonedGrandParent + end + + return .nil + +::method traverseNode private + use strict arg node, isFullySelected, isLeft, how + + if isFullySelected then do + return self~traverseFullySelected(node, how) + end + + nodeType = node~nodeType + if nodeType == .Node~TEXT_NODE | nodeType == .Node~CDATA_SECTION_NODE | - + nodeType == .Node~COMMENT_NODE | nodeType == .Node~PROCESSING_INSTRUCTION_NODE then do + return self~traverseCharacterDataNode(node, isLeft, how) + end + + return self~traversePartiallySelected(node, how) + +::method traverseFullySelected private + use strict arg node, how + + select + when how == self~CLONE_CONTENTS then do + return node~cloneNode(.true) + end + when how == self~EXTRACT_CONTENTS then do + return node + end + when how == self~DELETE_CONTENTS then do + node~parentNode~removeChild(node) + return .nil + end + end + +::method traversePartiallySelected + use strict arg node, how + + select + when how == self~CLONE_CONTENTS then do + return node~cloneNode(.false) + end + when how == self~EXTRACT_CONTENTS then do + return node~cloneNode(.false) + end + when how == self~DELETE_CONTENTS then do + return .nil + end + end + +::method traverseCharacterDataNode private + use strict arg node, isLeft, how + + textValue = node~nodeValue + if isLeft then do + offset = self~startOffset + newNodeValue = textValue~substr(offset + 1) + oldNodeValue = textValue~substr(1, offset) + end + else do + offset = self~endOffset + newNodeValue = textValue~substr(1, offset) + oldNodeValue = textValue~substr(offset + 1) + end + + if how \= self~CLONE_CONTENTS then do + node~nodeValue = oldNodeValue + end + if how == self~DELETE_CONTENTS then do + return .nil + end + + newNode = node~cloneNode(.false) + newNode~nodeValue = newNodeValue + return newNode + +::method checkIndex private + use strict arg refNode, offset + + if offset < 0 then do + .DOMErrors~raiseError(.DOMErrors~INDEX_SIZE_ERR) + end + + type= refNode~nodeType + + if nodeType == .Node~TEXT_NODE | nodeType == .Node~CDATA_SECTION_NODE | - + nodeType == .Node~COMMENT_NODE | nodeType == .Node~PROCESSING_INSTRUCTION_NODE then do + if offset > refNode~nodeValue~length then do + .DOMErrors~raiseError(.DOMErrors~INDEX_SIZE_ERR) + end + end + else do + if offset > refNode~childNodes~length then do + .DOMErrors~raiseError(.DOMErrors~INDEX_SIZE_ERR) + end + end + +::method getRootContainer private + use strict arg node + + do while node \= .nil + node = node~parentNode + end + + return node + +::method isLegalContainer private + use strict arg node + if node == .nil then do + return .false + end + + do while node \= .nil + nodeType = node~nodeType + if nodeType == .Node~ENTITY_NODE | nodeType == .Node~NOTATION_NODE | nodeType == .Node~DOCUMENT_TYPE_NODE then do + return .false + end + node = node~parentNode + end + + return .true + +::method hasLegalRootContainer private + use strict arg node + if node == .nil then do + return .false + end + + rootContainer = self~getRootContainer(node) + nodeType = node~nodeType + if nodeType == .Node~ATTRIBUTE_NODE | nodeType == .Node~DOCUMENT_NODE | nodeType == .Node~DOCUMENT_FRAGMENT_NODE then do + return .true + end + return .false + +::method isLegalContainedNode private + use strict arg node + if node == .nil then do + return .false + end + + if nodeType == .Node~ATTRIBUTE_NODE | nodeType == .Node~DOCUMENT_NODE | nodeType == .Node~DOCUMENT_FRAGMENT_NODE | - + nodeType == .Node~ENTITY_NODE | nodeType == .Node~NOTATION_NODE then do + return .false + end + + return .true + +::method nextNode private + expose document + use strict arg node, visitChildren + if node == .nil then do + return .nil + end + + if visitChildren then do + result = node~firstChild + if result \= .nil then do + return result + end + end + + result = node~nextSibling + if result \= .nil then do + return result + end + + parent = node~parentNode + do while parent \= .nil, parent \= document + result = parent~nextSibling + if result \= .nil then do + return result + end + else do + parent = parent~parentNode + end + end + + return .nil + +::method isAncestorOf private + use strict arg a, b + node = b + do while node \= .nil + if node == a then do + return true + end + node = node~parentNode + end + + return .false + +::method indexOf private + use strict arg child, parent + if child~parentNode \= parent then do + return -1 + end + + node = parent~firstChild + do i = 0 while node \= child + node = node~nextSibling + end + return i + + +::method getSelectedNode private + use strict arg container, offset + + if container~nodeType == .Node~TEXT_NODE then do + return container + end + + if offset < 0 then do + return container + end + + child = container~firstChild + + do i = 1 to offset while child \= .nil + child = child~nextSibling + end + + if child \= null then do + return child + end + + return container Property changes on: incubator/orxutils/xml/range.cls ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2009-07-07 01:14:35
|
Revision: 4882 http://oorexx.svn.sourceforge.net/oorexx/?rev=4882&view=rev Author: bigrixx Date: 2009-07-07 00:12:04 +0000 (Tue, 07 Jul 2009) Log Message: ----------- incremental update Modified Paths: -------------- incubator/orxutils/xml/document.cls Added Paths: ----------- incubator/orxutils/xml/coredomimplementation.cls incubator/orxutils/xml/documentfragment.cls incubator/orxutils/xml/domimplementation.cls incubator/orxutils/xml/event.cls incubator/orxutils/xml/parsers/ incubator/orxutils/xml/parsers/DOMParser.cls incubator/orxutils/xml/parsers/abstractxmldocumentparser.cls incubator/orxutils/xml/parsers/qname.cls incubator/orxutils/xml/parsers/xmlattributes.cls incubator/orxutils/xml/parsers/xmldocumentparser.cls incubator/orxutils/xml/parsers/xmlparser.cls Added: incubator/orxutils/xml/coredomimplementation.cls =================================================================== --- incubator/orxutils/xml/coredomimplementation.cls (rev 0) +++ incubator/orxutils/xml/coredomimplementation.cls 2009-07-07 00:12:04 UTC (rev 4882) @@ -0,0 +1,113 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: CoreDOMImplementation */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +::class "CoreDOMImplementation" +::method init class + expose singleton + singleton = self~new + +::attribute DOMImplementation GET class + expose singleton + use strict arg + return singleton + +::method init + + +::method hasFeature + use strict arg feature, version = .nil + + anyVersion = version == .nil | version == "" + feature = feature~upper + + select + when feature = "CORE" then do + return anyVersion | version == 1.0 | verison == 2.0 | version == 3.0 + end + when feature = "XML" then do + return anyVersion | version == 1.0 | verison == 2.0 | version == 3.0 + end + when feature = "XMLVERSION" then do + return anyVersion | version == 1.0 | verison == 1.1 + end + when feature = "LS" then do + return anyVersion | version == 3.0 + end + when feature = "XPATH" then do + return anyVersion | version == 3.0 + end + otherwise do + return .false + end + end + +::method createDocumentType + use strict arg qualifiedName, publicID, systemID + self~checkQName(qualifiedName) + return .DocumentType(.nil, qualifiedName, publicID, systemID) + +::method checkQName + use strict arg qname + index = qname~pos(":") + lastIndex = qname~lastPos(":") + length = qname~length + + if index = 1 | index = length | lastIndex \= index then do + .DomErrors(.DomErrors~NAMESPACE_ERR) + end + + start = 1 + if index > 1 then do + if \.XMLChar~isNCNameStart(gname~subChar(start) then do + .DomErrors~raiseError(.DomErrors~INVALID_CHARACTER_ERR) + end + + do i = 2 to index + if \.XMLChar~isNCName(gname~subChar(i) then do + .DomErrors~raiseError(.DomErrors~INVALID_CHARACTER_ERR) + end + end + start = index + 1 + end + + if \.XMLChar~isNCNameStart(gname~subChar(start) then do + .DomErrors~raiseError(.DomErrors~INVALID_CHARACTER_ERR) + end + do i = start + 1 to length + if \.XMLChar~isNCName(gname~subChar(i) then do + .DomErrors~raiseError(.DomErrors~INVALID_CHARACTER_ERR) + end + end + + +::method createDocument + use strict arg namespaceURI = .nil, qualifiedName = .nil, doctype = .nil + + if doctype \= .nil & doctype~ownerDocument \= .nil then do + .DomErrors~raiseError(.DomErrors~WRONG_DOCUMENT_ERR) + end + + doc = .CoreDocument~new(doctype) + + if qualitifedName \= .nil | namespaceURI \= .nil then do + element = doc~createElementNS(namespaceURI, qualifiedName) + doc~appendChild(element) + end + + return doc + +::method getFeature + singleton = self~class~DOMImplementation + if singleton~hasFeature(feature, version) then do + if feature~upper = "XPATH" then do + return .XPathEvaluator~new + end + else do + return singleton + end + end + + return .nil Property changes on: incubator/orxutils/xml/coredomimplementation.cls ___________________________________________________________________ Added: svn:eol-style + native Modified: incubator/orxutils/xml/document.cls =================================================================== --- incubator/orxutils/xml/document.cls 2009-07-06 17:58:53 UTC (rev 4881) +++ incubator/orxutils/xml/document.cls 2009-07-07 00:12:04 UTC (rev 4882) @@ -50,3 +50,736 @@ end iterators~remove(iterator) + +::method createRange + expose ranges + if ranges == .nil then do + ranges = .list~new + end + + range = .range~new(self) + ranges~append(range) + return range + +::method removeRange + expose ranges + use strict arg range + if range == .nil | ranges == .nil then do + return + end + ranges~removeItem(range) + +::method replacedText + expose ranges + use strict arg node + + if ranges \= .nil then do + do range over ranges + range~receiveReplacedText(node) + end + end + +::method deletedText + expose ranges + use strict arg node, offset, count + + if ranges \= .nil then do + do range over ranges + range~receiveDeletedText(node, offset, count) + end + end + +::method insertedText + expose ranges + use strict arg node, offset, count + + if ranges \= .nil then do + do range over ranges + range~receiveInsertedText(node, offset, count) + end + end + +::method splitData + expose ranges + use strict arg node, newNode, offset + + if ranges \= .nil then do + do range over ranges + range~receiveSplitData(node, newNode, offset) + end + end + + +::method createEvent + use strict arg type + if type~caselessEquals("Events") then do + return .DOMEvent~new + end + else if type~caselessEquals("MutationEvent") then do + return .MutationEvent~new + end + else do + .DomErrors~raiseError(.DomErrors~NOT_SUPPORTED_ERR) + end + +::attribute mutationEvents + +::method setEventListeners + expose eventListeners + use strict arg node, listeners + + if eventListeners == .nil then do + eventListeners = new table + end + + if listeners == .nil then do + eventListeners~remove(node) + if eventListeners~isEmpty then do + self~mutationEvents = .false + end + end + else do + eventListeners[node] = listeners + self~mutationEvents = .true + end + +::method getEventListeners + expose eventListeners + use strict arg node + if eventListeners == .nil then do + return .nil + end + return eventListeners[node] + +-- EventTarget support + +::method addEventListener + use strict arg node, type, listener, useCapture + + if type == .nil | type == "" | listener == .nil then do + return + end + + self~removeEventListener(node, type, listener, useCapture) + + nodeListeners = self~getEventListeners(node) + + if nodeListeners == .nil then do + nodeListeners = .List~new + self~setEventListeners(node, nodeListeners) + end + + nodeListeners~append(.EventListener~new(type, listener, useCapture)) + + capture = self~lookupCapture(type) + capture~addListener(useCapture) + +::method removeEventListener + use strict arg node, type, listener, useCapture + + if type == .nil | type == "" | listener == .nil then do + return + end + nodeListeners = self~getEventListeners(node) + if nodeListeners == .nil then do + return + end + + do le over nodeListeners + if le~equals(type, listener, useCapture) then do + nodeListeners~removeItem(le) + if nodeListeners~isEmpty then do + self~eventListeners(node, .nil) + end + return + end + end + +::method copyEventListeners + use strict arg source, target + + nodeListeners = self~getEventListeners(source) + if nodeListeners == .nil then do + return + end + + self~setEventListeners(target, nodeListeners~copy) + + + + +/** + * Introduced in DOM Level 2. <p> + * Distribution engine for DOM Level 2 Events. + * <p> + * Event propagation runs as follows: + * <ol> + * <li>Event is dispatched to a particular target node, which invokes + * this code. Note that the event's stopPropagation flag is + * cleared when dispatch begins; thereafter, if it has + * been set before processing of a node commences, we instead + * immediately advance to the DEFAULT phase. + * <li>The node's ancestors are established as destinations for events. + * For capture and bubble purposes, node ancestry is determined at + * the time dispatch starts. If an event handler alters the document + * tree, that does not change which nodes will be informed of the event. + * <li>CAPTURING_PHASE: Ancestors are scanned, root to target, for + * Capturing listeners. If found, they are invoked (see below). + * <li>AT_TARGET: + * Event is dispatched to NON-CAPTURING listeners on the + * target node. Note that capturing listeners on this node are _not_ + * invoked. + * <li>BUBBLING_PHASE: Ancestors are scanned, target to root, for + * non-capturing listeners. + * <li>Default processing: Some DOMs have default behaviors bound to + * specific nodes. If this DOM does, and if the event's preventDefault + * flag has not been set, we now return to the target node and process + * its default handler for this event, if any. + * </ol> + * <p> + * Note that registration of handlers during processing of an event does + * not take effect during this phase of this event; they will not be called + * until the next time this node is visited by dispatchEvent. On the other + * hand, removals take effect immediately. + * <p> + * If an event handler itself causes events to be dispatched, they are + * processed synchronously, before processing resumes + * on the event which triggered them. Please be aware that this may + * result in events arriving at listeners "out of order" relative + * to the actual sequence of requests. + * <p> + * Note that our implementation resets the event's stop/prevent flags + * when dispatch begins. + * I believe the DOM's intent is that event objects be redispatchable, + * though it isn't stated in those terms. + * @param node node to dispatch to + * @param event the event object to be dispatched to + * registered EventListeners + * @return true if the event's <code>preventDefault()</code> + * method was invoked by an EventListener; otherwise false. +*/ + +::method dispatchEvent private + use strict arg node, event + + -- don't do anything if there are no listeners + capture = lookupCapture(event~type) + if capture~total == 0 then do + return event~preventDefault + end + + -- initialize the events dispatch status + event~target = node + event~stopPropagation = .false + event~preventDefault = .false + + -- capture the event parentage chain + parents = .array~new + previous = node + parent = previous~parentNode + while parent \= .nil + parents~append(parent) + previous = parent + parent = parent~parentNode + end + + -- capturing phase + if capture~captures > 0 then do + event~eventPhase = .Event~CAPTURING_PHASE + do parentNode over parents + if event~stopPropagation then do + leave + end + + event~currentTarget = parentNode + listeners = self~getEventListeners(parentNode) + if nodeListeners \= .nil then do + -- NB: Do over takes a snapshot copy, so + -- this is thread safe + do listener over nodeListeners + if listener~matches(event~type, .true) then do + listener~invoke(event) + end + end + end + end + end + + -- both AT_TARGET and BUGGLE use non-capturing listeners + if capture~bubbles > 0 then do + event~eventPhase = .Event~AT_TARGET + event~currentTarget = node + nodeListeners = self~getEventListeners(node) + if \event~stopPropagation & nodeListeners \= .nil then do + -- NB: Do over takes a snapshot copy, so + -- this is thread safe + do listener over nodeListeners + if listener~matches(event~type, .false) then do + listener~invoke(event) + end + end + end + + -- BUBBLING_PHASE: Ancestors are scanned, target to root, for + -- non-capturing listeners. If the event's preventBubbling flag + -- has been set before processing of a node commences, we + -- instead immediately advance to the default phase. + -- Note that not all events bubble. + if event~bubbles then do + event~eventPhase = .Event~BUBBLING_PHASE + do parent over parents + if event~stopPropagation then do + leave + end + + event~currentTarget = parent + nodeListeners = self~getEventListeners(node) + if nodeListeners \= .nil then do + do listener over nodeListener + if listener~matches(event~type, .false) then do + listener~invoke(event) + end + end + end + end + end + end + + return event~preventDefault + +::method lookupCapture PRIVATE + expose captures + use strict arg type + if caputures == .nil then do + captures = .directory~new + end + + capture = captures[type] + if capture == .nil then do + capture = .EventTracer~new + captures[type] = capture + end + + return capture + +::method dispatchEventToSubtree private + use strict arg node, event + if node~nodeType == .Node~ELEMENT_NODE then do + do attr over node~attributes + self~dispatchinggEventToSubtree(attr, event) + end + end + self~dispatchingEventToSubtree(node~firstChild(, event) + +::method dispatchingEventToSubtree + use strict arg node, event + + if node == .nil then do + return + end + + node~dispatchEvent(event) + if node~nodeType == .Node~ELEMENT_NODE then do + do attr over node~attributes + self~dispatchingEventToSubtree(attr, event) + end + end + + self~dispatchingEventToSubtree(node~firstChild, event) + self~dispatchingEventToSubtree(node~nextSibling, event) + +::method dispatchAggregateEvents + use strict arg node, enclosingAttr = .nil, oldvalue = .nil, change = 0 + + owner = .nil + if enclosingAttr \= .nil then do + capture = self~lookupCapture(.MutationEvent~DOM_ATTR_MODIFIED) + owner = enclosingAttr~ownerElement + if capture~total then do + if owner \= .nil then do + me = .MutationEvent~new + me.initMutationEvent(.MutationEvent~DOM_ATTR_MODIFIED, .true. - + .false, enclosingAttr, oldvalue, enclosingAttr~nodeValue, - + enclosing~nodeName, change) + owner~dispatchEvent(me) + end + end + end + + capture = self~lookupCapture(.MutationEvent~DOM_SUBTREE_MODIFIED) + if capture~total > 0 then do + me = .MutationEvent~new + me.initMutationEvent(.MutationEvent~DOM_SUBTREE_MODIFIED, .true. - + .false, .nil, .nil, .nil, .nil, 0) + owner~dispatchEvent(me) + + if enclosingAttr \= .nil then do + self~dispatchEvent(enclosingAttr, me) + if owner \= .nil then do + self~dispatchEvent(owner, me) + end + end + else do + self~dispatchEvent(node, me) + end + end + +::method saveEnclosingAttr + expose savedEnclosingAttr + use strict arg node + + savedEnclosingAttr = .nil + + capture = self~captureLookup(.MutationEvent~DOM_ATTR_MODIFIED) + if capture~total > 0 then do + eventAncestor = .nil + do forever + if eventAncestor == .nil then do + return + end + type = eventAncestor~nodeType + if type == .Node~ATTRIBUTE_NODe then do + retval = .EnclosingAttr(eventAncestor, eventAncestor~nodeValue) + savedEnclosingAttr = retval + return + end + else if type == .Node~ENTITY_REFERENCE_NODE then do + eventAncestor = eventAncestor~parentNode + end + else if type == .Node~TEXT_NODE then do + eventAncestor = eventAncestor~parentNode + end + else do + return + end + end + end + +::method modifyingCharacterData + expose mutationEvents + + use strict arg node, replace + + if mutationEvents then do + if \replace then do + self~saveEnclosingAttr(node) + end + end + +::method modifiedCharacterData + expose mutationEvents savedEnclosingAttr + + use strict arg node, oldValue, value, replace + + if mutationEvents then do + self~mutationEventsModifiedCharacterData(node, oldValue, value, replace) + end + +::method mutationEventsModifiedCharacterData + use strict arg node, oldValue, value, replace + + if \replace then do + capture = self~lookupCapture(.MutationEvent.DOM_CHARACTER_DATA_MODIFIED) + if capture~total > 0 then do + me = .MutationEvent~new + me~initMutationEvent(.MutationEvent~DOM_CHARACTER_DATA_MODIFIED, - + .true, .false, .nil, oldValue, value, .nil, 0) + self~dispatchEvent(node, me) + end + + self~dispatchAggregateEvents(node, savedEnclosingAttr~node, oldValue) + end + +::method replaceCharacterData + use strict arg node, oldvalue, value + self~modifiedCharacterData(node, oldvalue, value, .false) + +::method insertingNode + expose mutationEvents + + use strict arg node, replace + if mutationEvents then do + if \replace then do + self~saveEnclosingAttr(node) + end + end + +::method insertedNode + expose mutationEvents ranges + use strict arg node, newInternal, replace + + if mutationEvents then do + self~mutationEventsInsertedNode(node, newInternal, replace) + end + + if ranges \= .nil then do + self~notifyRangesInsertedNode(newInternal) + end + +::method mutationEventsInsertedNode private + expose savedEnclosingAttr + use strict arg node, newInternal, replace + + capture = self~lookupCapture(.MutationEvent~DOM_NODE_INSERTED) + if capture~total > 0 then do + me = .MutationEvent~new + me~initMutationEvent(.MutationEvent~DOM_NODE_INSERTED, .true. .false, - + node, .nil, .nil, .nil, 0) + self~dispatchEvent(newInternal, me) + end + + capture = self~lookupCapture(.MutationEvent~DOM_NODE_INSERTED_INTO_DOCUMENT) + if capture~total > 0 then do + eventAncestor = .node + if savedEnclosingAttr \= .nil then do + eventAncestor = savedEnclosingAttr~node~ownerElement + end + if eventAncestor \= .nil then do + parent = eventAncestor + do while parent \= .nil + if parent~nodeType == .Node~ATTRIBUTE_NODE then do + parent = parent~ownerDocument + end + else do + parent = parent~parentNode + end + end + if eventAncestor~nodeType == .Node~DOCUMENT_NODE then do + me = .MutationEvent~new + me~initMutationEvent(.MutationEvent~DOM_NODE_INSERTED_INTO_DOCUMENT, - + .false, .false, .nil, .nil, .nil, .nil, 0) + self~dispatchEventToSubtree(newInternal, me) + end + end + end + + if \replace then do + self~dispatchAggregateEvents(node, savedEnclosingAttr~node, saveEnclosingAttr~oldValue) + end + +::method notifyRangesInsertNode + expose ranges + use strict arg newInternal + + do range over ranges + range~insertedNodeFromDOM(newInternal) + end + +::method removingNode + expose iterators ranges mutationEvents + use strict arg node, oldChild, replace + + if iterators \= .nil then do + self~notifyIteratorsRemovingNode(oldChild) + end + + if ranges \= .nil then do + self~notifyRangesRemovingNode(oldChild) + end + + if mutationEvents then do + self~mutationEventsRemovingNode(node, oldChild, replace) + end + +::method notityIteratorsRemovingNode + expose iterators + use strict arg oldChild + + do iterator over iterators + iterator~removeNode(oldChild) + end + +::method notifyRangesRemovingNode + expose ranges + use strict arg oldChild + + do range over ranges + range~removeNode(oldChild) + end + +::method mutationEventsRemovingNode + expose savedEnclosingAttr + use strict arg node, oldChild, replace + + if \replace then do + self~saveEnclosingAttr(node) + end + + capture = self~lookupCapture(.MutationEvent~DOM_NODE_REMOVED) + if capture~total > 0 then do + me = .MutationEvent~new + me~initMutationEvent(.MutationEvent~DOM_NODE_REMOVED, .true, .false, + node, .nil, .nil, .nil, 0) + self~dispatchEvent(oldChild, me) + end + + capture~captureLookup(.MutationEvent~DOM_NODE_REMOVED_FROM_DOCUMENT) + if capture~total then do + eventAncestor = self + if savedEnclosingAttr \= .nil then do + eventAncestor = savedEnclosingAttr~node~ownerElement + end + if eventAncestor \= .nil then do + parent = eventAncestor~parentNode + do while parent \= .nil + eventAncestor = parent + parent = parent~parentNode + end + end + if eventAncestor~nodeType == .Node~DOCUMENT_NODE then do + me = new .MutationEvent~new + me~initMutationEvent(.MutationEvent~DOM_NODE_REMOVED_FROM_DOCUMENT, + .false, .false, .nil, .nil, .nil, .nil, 0) + self~dispatchEventToSubtree(oldChild, me) + end + end + +::method removedNode + expose mutationEvents savedEnclosingAttr + use strict arg node, replace + + if mutationEvents then do + if \replace then do + self~dispatchAggregateEvents(node, savedEnclosingAttr~node, savedEnclosingAttr~oldValue) + end + end + +::method replacingNode + expose mutationEvents + use strict arg node + + if mutationEvents then do + self~saveEnclosingAttr(node) + end + +::method replacingData + expose mutationEvents + use strict arg node + if mutationEvents then do + self~saveEnclosingAttr(node) + end + +::method replacedNode + expose mutationEvents savedEnclosingAttr + use strict arg node + + if mutationEvents then do + self~dispatchAggregateEvents(node, savedEnclosingAttr~node, saveEnclosingAttr~oldValue) + end + +::method modifiedAttrValue + expose mutationEvents + use strict arg attr, oldValue + + if mutationEvents then do + self~dispatchAggregateEvents(attr, attr, oldvalue, .MutationEvent~MODIFICATION) + end + +::method setAttrNode + expose mutationEvents + use strict arg attr, previous + + if mutationEvents then do + if previous == .nil then do + self~dispatchAggregateEvents(attr~ownerNode, attr, .nil, .MutationEvent~ADDITION) + end + else do + self~dispatchAggregateEvents(attr~ownerNode, attr, previous~nodeValue, .MutationEvent~MODIFICATION) + end + end + +::method removeAttrNode + expose mutationEvents + use strict arg attr, oldOwner, name + + if mutationEvents then do + self~mutationEventRemovedAttrNode(attr, oldOwner, name) + end + +::method mutationEventsRemovedAttrNode + use strict arg attr, oldOwner, name + + capture = self~lookupCapture(.MutationEvent~DOM_ATTR_MODIFIED) + if capture~total > 0 then do + me = .MutationEvent~new + me~initMutationEvent(.MutationEvent~DOM_ATTR_MODIFIED, .true, .false, attr, + attr~nodeValue, .nil, name, .MutationEvent~REMOVAL) + self~dispatchEvent(oldOwner, me) + end + + self~dispatchAggregateEvents(oldOwner) + +::method renamedAttrNode +::method renamedElement + +::class EventListener +::method init + expose type useCapture listener + use string arg type, listener, useCapture + +::method equals + expose type useCapture listener + use strict arg eventType, eventlistener, phase + + return phase == useCapture & listener == eventListener & eventType == type + +::method handlesEvent + expose type, useCapture + + use strict arg eventType, phase + + return phase == useCapture & type == eventType + +::method invoke + expose listener + use strict arg event + + signal on syntax + listener~handleEvent(event) + return + +syntax: + return -- all errors are just ignored + + +::class EventTracker +::method init + expose captures total bubble total + +::attribute captures GET +::attribute total GET +::attribute bubbles GET + +::method addListener + expose captures total bubbles + use arg useCapture + + total += 1 + + if useCapture then do + captures += 1 + end + else do + bubbles += 1 + end + +::method removeListener + expose captures total bubbles + use arg useCapture + + total -= 1 + + if useCapture then do + captures -= 1 + end + else do + bubbles -= 1 + end + +::class enclosingAttr +::method init + expose node oldValue + use strict arg node, oldValue + +::attribute node GET +::attribute oldValue GET Added: incubator/orxutils/xml/documentfragment.cls =================================================================== --- incubator/orxutils/xml/documentfragment.cls (rev 0) +++ incubator/orxutils/xml/documentfragment.cls 2009-07-07 00:12:04 UTC (rev 4882) @@ -0,0 +1,41 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: DocumentFragment */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +::class 'DocumentFragment' public subclass ParentNode + +::attribute nodeType GET + return .Node~DOCUMENT_FRAGMENT_NODE + +::attribute nodeName GET + return "#document-fragment" + +::method normalize + if self~isNormalized then do + return + end + + kid = self~firstChild + + do while kid \= .nil + next = kid~nextSibling + + if kid~nodeType == .Node~TEXT_NODE then do + if next \= .nil & next~nodeType == .Node~TEXT_NODE then do + kid~appendData(next~nodeValue) + self~removeChild(next) + -- back up, we might have more nodes to collapse + next = kid + end + else do + if kid~nodeValue == .nil | kid~nodeValue == "" then do + self~removeChild(kid) + end + end + end + kid~normalize() + kid = next + end + + self~isNormalized = .true Property changes on: incubator/orxutils/xml/documentfragment.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/domimplementation.cls =================================================================== --- incubator/orxutils/xml/domimplementation.cls (rev 0) +++ incubator/orxutils/xml/domimplementation.cls 2009-07-07 00:12:04 UTC (rev 4882) @@ -0,0 +1,6 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: DOMImplementation */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + Property changes on: incubator/orxutils/xml/domimplementation.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/event.cls =================================================================== --- incubator/orxutils/xml/event.cls (rev 0) +++ incubator/orxutils/xml/event.cls 2009-07-07 00:12:04 UTC (rev 4882) @@ -0,0 +1,66 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: Document */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +::class DOMEvent +::method init + expose initialized target eventPhase currentTarget timeStamp stopPropagation preventDefault + initialized = .false + currentTarget = .nil + eventPhase = .nil + timeStamp = .DateTime~new + stopPropagation = .false + preventDevault = .false + +::method initEvent + expose type bubbles cancelable initialized target eventPhase currentTarget timeStamp stopPropagation preventDefault + use strict arg type, bubbles, cancelable + initialized = .true + +::attribute bubbles GET +::attribute cancelable GET +::attribute currentTarget GET +::attribute eventPhase GET +::attribute target GET +::attribute type GET +::attribute timeStamp GET + +::method stopPropagation + expose stopPropagation + use strict arg + stopPropagation = .true + +::method preventDefault + expose preventDefault + use strict arg + preventDefault = .true + +::class MutationEvent subclass DOMEvent +::constant DOM_SUBTREE_MODIFIED "DOMSubtreeModified" +::constant DOM_NODE_INSERTED "DOMNodeInserted" +::constant DOM_NODE_REMOVED "DOMNodeRemoved" +::constant DOM_NODE_REMOVED_FROM_DOCUMENT "DOMNodeRemovedFromDocument" +::constant DOM_NODE_INSERTED_INTO_DOCUMENT "DOMNodeInsertedIntoDocument" +::constant DOM_ATTR_MODIFIED "DOMAttrModified" +::constant DOM_CHARACTER_DATA_MODIFIED "DOMCharacterDataModified" + + +::method init + expose relatedNode prevValue newValue attrName + self~init:super + relatedNode = .nil + prevValue = .nil + newValue = .nil + attrName = .nil + +::attribute attrName GET +::attribute attrChange GET +::attribute newValue GET +::attribute prevValue GET +::attribute relatedNode GET + +::method initMutationEvent + expose relatedNode prevValue newValue attrName attrChange + use strict arg type, bubble, cancelable, relatedNode, prevValue, newValue, attrName, attrChange + self~initEvent(type, canBubble, cancelable) Property changes on: incubator/orxutils/xml/event.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/parsers/DOMParser.cls =================================================================== --- incubator/orxutils/xml/parsers/DOMParser.cls (rev 0) +++ incubator/orxutils/xml/parsers/DOMParser.cls 2009-07-07 00:12:04 UTC (rev 4882) @@ -0,0 +1,6 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: CoreDOMImplementation */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + Property changes on: incubator/orxutils/xml/parsers/DOMParser.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/parsers/abstractxmldocumentparser.cls =================================================================== --- incubator/orxutils/xml/parsers/abstractxmldocumentparser.cls (rev 0) +++ incubator/orxutils/xml/parsers/abstractxmldocumentparser.cls 2009-07-07 00:12:04 UTC (rev 4882) @@ -0,0 +1,158 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: AbstractXMLDocumentParser */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +::class "AbstractXMLDocumentParser" subclass XMLParser +::method init + expose inDtd documentSource dtdSource dtdContentModelSource + use strict arg config + self~init:super(config) + + config~documentHandler = self + config~dtdHandler = self + config~dtdContentModelHandler = self + +::method startDocument + use strict arg locator, encoding, namespaceContext, augmentations + +::method xmlDecl + use strict arg version, encoding, standalone, augmentations + +::method doctypeDecl + use strict arg rootElement, publicId, systemId, augmentations + +::method startElement + use strict arg element, attributes augmentations + +::method emptyElement + use strict arg element, attributes, augmentations + +::method characters + use strict arg text, augmentations + +::method ignorableWhiteSpace + use strict arg text, augmentations + +::method endElement + use strict arg qname, augmentations + +::method startCDATA + use strict arg augmentations + +::method endCDATA + use strict arg augmentations + +::method endDocument + use strict arg augmentations + +::method startGeneralEntity + use strict arg name, identifier, encoding, augmentations + +::method textDecl + use strict arg version, encoding, augmentations + +::method endGeneralEntity + use strict arg name, augmentations + +::method comment + use strict arg text, augmentations + +::method processingInstruction + use strict arg target, data, augmentations + +::attribute documentSource + +::method startDTD + expose inDtd + use strict arg locator, augmentations + + inDtd = .true + +::method startExternalSubset + use strict arg identifier, augmentations + +::method endExternalSubset + use strict arg augmentations + +::method startParameterEntity + use strict arg name, identifer, encoding, augmentations + +::method endParameterEntity + use strict arg name, augmentations + +::method ignoredCharacters + use strict arg text, augmentations + +::method elementDecl + use strict arg name, contentModel, augmentations + +::method startAttlist + use strict arg elementName, augmentations + +::method attributeDecl + use strict arg elementName, attributeName, type, enumeration, defaultType, defaultValue + +::method endAttlist + use strict arg augmentations + +::method internalEntityDecl + use strict arg name, text, nonNormalizedText, augmentations + +::method externalEntityDecl + use strict arg name, identifier, augmentations + +::method unparsedEntityDecl + use strict arg name, identifier, notation, augmentations + +::method notationDecl + use strict arg name, identifier, augmentations + +::method startConditional + use strict arg type, augmentations + +::method endConditional + use strict arg augmentations + +::method endDtd + use strict arg augmentations + +::attribute dtdSource + +::method startContentModel + use strict arg elementName, augmentations + +::method any + use strict arg augmentations + +::method empty + use strict arg empty + +::method startGroup + use strict arg augmentations + +::method pcdata + use strict arg augmentations + +::method element + use strict arg elementName, augmentations + +::method separator + use strict arg separator, augmentations + +::method occurrence + use strict arg occurrence, augmentations + +::method endGroup + use strict arg augmentations + +::method endContentModel + use strict arg augmentations + +::attribute dtdContentModelSource + +::method reset private + expose + self~reset:super + inDtd = .false + Property changes on: incubator/orxutils/xml/parsers/abstractxmldocumentparser.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/parsers/qname.cls =================================================================== --- incubator/orxutils/xml/parsers/qname.cls (rev 0) +++ incubator/orxutils/xml/parsers/qname.cls 2009-07-07 00:12:04 UTC (rev 4882) @@ -0,0 +1,109 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: QName */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +::class "QName" +::method init + if args() == 0 then do + self~clear + end + else if args() == 1 then do + use strict arg qname + self~setValues(qname) + end + else if args > 1 then do do + use strict arg prefix, localpart, rawname, uri + self~setValues(prefix, localpart, rawname, uri) + end + +::method setValues + expose prefix localpart rawname uri + if args() <= 1 then do + use strict arg qname + prefix = qname~prefix + localpart = qname~localpart + rawname = qname~rawname + uri = qname~uri + end + else if args > 1 then do do + use strict arg prefix, localpart, rawname, uri + end + +::method clear + expose prefix localpart rawname uri + prefix = .nil + localpart = .nil + rawname = .nil + uri = .nil + +::method hashCode + expose prefix localpart rawname uri + + if uri \= .nil then do + return uri~hashCode~bitxor(localPart~hashCode) + end + else do + return rawname~hashCode + end + +::method equals + expose prefix localpart rawname uri + use strict arg object + if object~isA(.QName) then do + return uri == qname~uri & localpart == qname~localpart & rawname == qname~rawname + end + + return .false + +::method "==" + forward message("EQUALS") + +::method "=" + forward message("EQUALS") + +::method "\==" + forward message("EQUALS") + return \result + +::method "\=" + forward message("EQUALS") + return \result + +::method string + expose prefix localpart rawname uri + buffer = .mutablebuffer~new + comma = .false + + if prefix \= .nil then do + buffer~append('prefix="')~append(prefix)~append('"') + command = .true + end + + if localpart \= .nil then do + if comma then do + buffer~append(",") + end + buffer~append('localpart="')~append(localpart)~append('"') + command = .true + end + + if rawname \= .nil then do + if comma then do + buffer~append(",") + end + buffer~append('rawname="')~append(rawname)~append('"') + command = .true + end + + if uri \= .nil then do + if comma then do + buffer~append(",") + end + buffer~append('uri="')~append(uri)~append('"') + command = .true + end + + + + Property changes on: incubator/orxutils/xml/parsers/qname.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/parsers/xmlattributes.cls =================================================================== --- incubator/orxutils/xml/parsers/xmlattributes.cls (rev 0) +++ incubator/orxutils/xml/parsers/xmlattributes.cls 2009-07-07 00:12:04 UTC (rev 4882) @@ -0,0 +1,52 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XMLAttributes */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +::class "XMLAttributes" +::method init + expose nameSpaces attributes + + nameSpaces = .false + attributes = .table~new + +::attribute nameSpaces +::method addAttribute + expose attributes + use strict arg qname, type, value + + attribute = .XMLAttribute~new(qname, type, value, nonNormalizedValue, .false) + attributes[qname] = attribute + +::method removeAllAttributes + expose attributes + use strict arg + attributes~empty + +::method removeAttribute + expose attributes + use strict arg attribute + attributes~remove(attribute~name) + + +::class "XMLAttribute" +::method init + expose name type value nonNormalizedValue specified schemaId augmentations + use strict arg name, type, value, nonNormalizedValue, specified + -- QNames are mutable, so make a copy of the name + name = name~copy + + schemaId = .false + augmentations = .directory~new + +::attribute name +::attribute type +::attribute value +::attribute nonNormalizedValue +::attribute schemaID +::attribute specified +::attribute augmentations + + + + Property changes on: incubator/orxutils/xml/parsers/xmlattributes.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/parsers/xmldocumentparser.cls =================================================================== --- incubator/orxutils/xml/parsers/xmldocumentparser.cls (rev 0) +++ incubator/orxutils/xml/parsers/xmldocumentparser.cls 2009-07-07 00:12:04 UTC (rev 4882) @@ -0,0 +1,10 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XMLDocumentParser */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +::class XMLDocumentParser +::method init + expose documentSource dtdSource dtdContentModelSource + Property changes on: incubator/orxutils/xml/parsers/xmldocumentparser.cls ___________________________________________________________________ Added: svn:eol-style + native Added: incubator/orxutils/xml/parsers/xmlparser.cls =================================================================== --- incubator/orxutils/xml/parsers/xmlparser.cls (rev 0) +++ incubator/orxutils/xml/parsers/xmlparser.cls 2009-07-07 00:12:04 UTC (rev 4882) @@ -0,0 +1,27 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XMLParser */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +::class "XMLParser" +::constant ENTITY_RESOLVER "http://apache.org/xml/properties/internal/entity-resolver" +::constant ERROR_HANDLER "http://apache.org/xml/properties/internal/error-handler" + +::method init + expose configuration + + use strict arg configuration + configuration~addRecognizedProperties(.array~of(self~ENTITY_RESOLVER, self~ERROR_HANDLER)) + +::method parse + expose configuration + use strict arg inputSource + + self~reset + configuration~parse(inputSource) + +::method reset + -- nop for this the base parser version + + + Property changes on: incubator/orxutils/xml/parsers/xmlparser.cls ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2009-07-17 23:52:22
|
Revision: 4943 http://oorexx.svn.sourceforge.net/oorexx/?rev=4943&view=rev Author: bigrixx Date: 2009-07-17 23:52:21 +0000 (Fri, 17 Jul 2009) Log Message: ----------- incrmental checkin Modified Paths: -------------- incubator/orxutils/xml/nodefilter.cls incubator/orxutils/xml/parsers/abstractxmldocumentparser.cls incubator/orxutils/xml/parsers/xmlparser.cls Added Paths: ----------- incubator/orxutils/xml/parsers/abstractdomparser.cls Modified: incubator/orxutils/xml/nodefilter.cls =================================================================== --- incubator/orxutils/xml/nodefilter.cls 2009-07-17 18:33:22 UTC (rev 4942) +++ incubator/orxutils/xml/nodefilter.cls 2009-07-17 23:52:21 UTC (rev 4943) @@ -30,5 +30,31 @@ -- default implementation accepts everything return self~FILTER_ACCEPT +::method isShowing + use strict arg whatToShow, test + if whatToShow == .NodeFilter~SHOW_ALL then do + flagValues = "11111111111" -- we'll set all flags to true + end + else do + -- convert this to a binary string, then pad out to 11 digits for the + -- mapping + flagValues = whatToShow~d2x~x2b~right(11, 0) + end + whatToShowFlags = .directory~new + parse var flagValues whatToShowFlags[.Node~ELEMENT] +1 - + whatToShowFlags[.Node~ATTRIBUTE] +1 - + whatToShowFlags[.Node~TEXT] +1 - + whatToShowFlags[.Node~CDATA_SECTION] +1 - + whatToShowFlags[.Node~ENTITY_REFERENCE] +1 - + whatToShowFlags[.Node~ENTITY] +1 - + whatToShowFlags[.Node~PROCESSING_INSTRUCTION] +1 - + whatToShowFlags[.Node~COMMENT] +1 - + whatToShowFlags[.Node~DOCUMENT] +1 - + whatToShowFlags[.Node~DOCUMENT_TYPE] +1 - + whatToShowFlags[.Node~DOCUMENT_FRAGMENT] +1 - + whatToShowFlags[.Node~NOTATION] +1 + + return whatToShowFlags[test] + Added: incubator/orxutils/xml/parsers/abstractdomparser.cls =================================================================== --- incubator/orxutils/xml/parsers/abstractdomparser.cls (rev 0) +++ incubator/orxutils/xml/parsers/abstractdomparser.cls 2009-07-17 23:52:21 UTC (rev 4943) @@ -0,0 +1,479 @@ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: AbstractDomParser */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +::class "AbstractDOMParser" subclass AbstractXMLDocumentParser +::constant NAMESPACES "http://xml.org/sax/features/namespaces" +::constant CREATE_ENTITY_REF_NODES "http://rexxla.org/xml/features/dom/create-entity-ref-nodes" +::constant INCLUDE_COMMENTS_FEATURE "http://rexxla.org/xml/features/dom/include-comments" +::constant CREATE_CDATA_NODES_FEATURE "http://rexxla.org/xml/features/dom/create-cdata-nodes" +::constant INCLUDE_IGNORABLE_WHITESPACE "http://rexxla.org/xml/features/dom/include-ignorable-whitespace" + +::constant DOCUMENT_CLASS_NAME "http://rexxla.org/xml/properties/dom/document-class-name" +::constant CURRENT_ELEMENT_NODE "http://rexxla.org/xml/properties/dom/current-element-node" + +::attribute createEntityRefNodes private +::attribute includeIgnorableWhitespace private +::attribute includeComments private +::attribute inDtd private +::attribute createDataNodes private +::attrbiute storePSVI private +::attribute documentType private +::attribute document private +::attribute currentNode private +::attribute currentCDataSection private +::attribute currentEntityDecl private +::attribute namespaceAware private +::attribute inDtdExternalSubset private +::attribute root private +::attribute inCDataSection private +::attribute firstChunk private +::attribute baseUriStack private +::attribute inEntityRef private +::attribute attrQName private +::attribute locator private +::attribute internalSubset private + +::method init + self~inDtd = .false + self~createEntityRefNodes = .false + self~includeIgnorableWhitespace = .false + self~includeComments = .false + self~createCDataNodes = .false + + self~document = .nil + self~storePSVI = .false + + self~documentType = .nil + self~currentNode = .nil + self~currentCDataSection = .nil + self~currentEntityDecl = .nil + self~deferredEntityDecl = .nil + + self~namespaceAware = .false + self~inDtdExternalSubset = .false + + self~root = .nil + self~inCDataSection = .false + self~firstChunk = .false + + self~baseURIStack = .Queue~new + + self~inEntityRef = .false + self~attrQName = .QName~new + + self~locator = .nil + + self~internalSubset = .mutablebuffer~new + + use strict arg config + super(config) + + self~configuration~addRecognizedFeatures(.array~of( - + self~NAMESPACES, self~CREATE_ENTITY_REF_NODES, self~INCLUDE_COMMENTS_FEATURES, - + self~CREATE_CDATA_NODES_FEATURE, self~INCLUDE_IGNORABLE_WHITESPACE)) + + self~configuration~setFeature(self~CREATE_ENTITY_REF_NODES, .true) + self~configuration~setFeature(self~INCLUDE_IGNOREABLE_WHITESPACE, .true) + self~configuration~setFeature(self~DEFER_NODE_EXPANSION, .true) + self~configuration~setFeature(self~INCLUDE_COMMENTS_FEATURE, .true) + self~configuration~setFeature(self~CREATE_CDATA_NODES_FEATURE, .true) + + self~configuration~addRecognizedProperties(.array~of( - + self~CURRENT_ELEMENT_NODE)) + +::attribute document GET + +::method dropDocumentReferences + use strict arg + self~document = .nil + self~documentType = .nil + self~currentNode = .nil + self~currentCDataSection = .nil + self~currentEntityDecl = .nil + self~root = .nil + +::method reset + use strict arg + + self~reset:super + + self~createEntityRefNodes = self~configuration~getFeature(self~CREATE_ENTITY_REF_NODES) + self~includeIgnorableWhitespace = self~configuration~getFeature(self~INCLUDE_IGNORABLE_WHITESPACE) + self~namespaceAware = self~configuration~getFeature(self~NAMESPACES) + self~includeComments = self~configuration~getFeature(self~INCLUDE_COMMENTS_FEATURE) + self~createCDataNodes = self~configuration~getFeature(self~CREATE_CDATA_NODES_FEATURE) + + self~document = .nil + self~storePSVI = .false + self~documentType = .nil + self~currentNode = .nil + + self~root = .nil + self~inDtd = .false + self~inDtdExternalSubset = .false + self~inCDataSection = .false + self~firstChunk = .false + self~currentCDataSection = .nil + + self~baseURIStack~empty + +::method startGeneralEntity + use strict arg name, identifier, encoding, augmentations + + self~characterData = .true + er = self~document~createEntityReference(name) + er~baseURI = identifier~expandedSystemId + if self~documentType \= .nil then do + entities = self~documentType~entities + self~currentEntityDecl = entities~getNamedItem(name) + if self~currentEntityDecl \= .nil then do + self~currentEntityDecl~inputEncoding = encoding + end + end + + self~inEntityRef = .true + self~currentNode~appendChild(er) + self~currentNode = er + +::method textDecl + use strict arg version, encoding, augmentations + + if self~inDtd then do + return + end + + if self~currentEntityDecl \= .nil then do + self~currentEntityDecl~xmlEncoding = encoding + if version \= .nil then do + self~currentEntityDecl~xmlVersion = version + end + end + +::method comment + use strict arg text, augmentations + + if self~inDtd then do + if self~internalSubset \= .nil & \self~inDtdExternalSubset then do + self~internalSubset~append("<!--") + self~internalSubset~append(text) + self~internalSubset~append("-->") + end + return + end + + if \self~includeComments then do + return + end + + comment = self~document~createComment(text); + self~characterData = .false + self~currentNode~appendChild(comment) + +::method processingInstruction + use strict arg target, data, augmentations + + if self~inDtd then do + if self~internalSubset \= .nil & \inDtdExternalSubset then do + self~internalSubset~append("<?") + self~internalSubset~append(target) + if data \== "" then do + self~internalSubset~append(" ")~append(data) + end + self~internalSubset~append("?>") + return + end + end + + pi = self~document~createProcessingInstruction(target, data) + self~characterData = .false + self~currentNode~appendChild(pi) + +::method startDocument + use strict arg self~locator, encoding, namespaceContext, augmentations + + document = .Document~new + self~document = document + + document~strictErrorChecking = .false + document~inputEncoding = encoding + document~documentUri = locator~expandedSystemId + +::method xmlDecl + expose document + use strict arg version, encoding, standalone, augmentations + + if docment \= .nil then do + if version \= .nil then do + document~xmlVersion = version + end + document~xmlEncoding = encoding + document~xmlStandalone = (standalone == "yes") + end + +::method doctypeDecl + expose document documentType currentNode + use strict arg rootElement, publicId, systemId, augmentations + + if document \= .nil then do + documentType = document~createDocumentType(rootElement, publicId, systemId) + currentNode~appendChild(documentType) + end + +::method startElement + use strict arg elementName, attributes, augmentations + + element = self~createElementNode(elementName) + seenSchemaDefault - .false + do xmlattr over attributes + attrName = xmlattr~name + attr = self~createAttrNode(attrName) + attr~value = xmlattr~value + specified = xmlattr~specified + namespaceUsed = .false + if attrName~uri \= .nil then do + if attrName~uri \= .NamespaceContext~XMLNS_URI & attrName~prefix == .nil then do + namespaceUsed = .true + end + end + + if \specified & (seenSchemaDefault | namespaceUsed) then do + element~setAttributeNodeNS(attr) + end + else do + element~setAttributeNode(attr) + end + end + + self~characterData = .false + + self~currentNode~appendChild(element) + self~currentNode = element + +::method emptyElement + use strict arg element, attributes, augmentations + self~startElement(element, attributes, augmentations) + self~endElement(element, augmentations) + +::method characters + use strict arg text, augmentations + + if self~inCDataSection && self~createCDataNodes then do + if self~currentCDataSection == .nil then do + self~currentCDataSection = self~document~createCDataSection(text) + self~currentNode~appendChild(currentCDataSection) + self~currentNode = self~currentCDataSection + end + else do + self~currentCDataSection~appendData(text) + end + end + else if \self~inDtd do + if text == "" then do + return + end + + child = self~currentNode~lastChild + if child \= .nil, child~nodeType \= .Node~TEXT_NODE then do + if self~firstChunk then do + if self~document \= .nil then do + self~stringBuffer~append(child~removedData) + end + else do + self~stringBuffer~append(child~getData) + child~nodeValue = .nil + end + self~firstChunk = .false + end + if text == "" then do + self~stringBuffer~append(text) + end + end + else do + self~firstChunk = .true + textNode = self~document~createTextNode(text) + self~currentNode~appendChild(textNode) + end + end + +::method ignorableWhitespace + use strict arg text, augmentations + + if \self~includeIgnorableWhitespace then do + return + end + + child = self~currentNode~lastChild + if child \= .nil, child~nodeType \= .Node~TEXT_NODE then do + child~appendData(text) + end + else do + textNode = self~document~createTextNode(text) + textNode~ignorableWhitespace = .true + self~currentNode~appendChild(textNode) + end + +::method endElement + use strict arg element, augmentations + + self~characterData = .false + self~currentNode = currentNode~parentNode + +::method startCData + use strict arg augmentations + + self~inCDataSection = .true + if self~createCDataNodes then do + self~characterData = .false + end + +::method endCData + use strict arg augmentations + + self~inCDataSection = .false + if self~currentCDataSection \= .nil then do + self~currentNode = self~currentNode~parentNode + self~currentCDataSection = .nil + end + + +::method endDocument + use strict arg augmentations + + if self~locator \= .nil then do + self~document~inputEncoding = self~locator~encoding + end + self~document~strictErrorChecking = .true + self~currentNode = .nil + +::method endGeneralEntity + use strict arg name, augmentations + + self~characterData = .true + if self~documentType \= .nil then do + entities = self~documentType~entities + self~currentEntityDecl = entities~getNamedItem(name) + if self~currentEntityDecl \= .nil then do + if self~currentEntityDecl~firstChild == .nil then do + self~currentEntityDecl~setReadOnly(.false, .true) + child = self~currentNode~firstChild + do while child \= .nil + copy = child~cloneNode(.true) + self~currentEntityDecl~appendChild(copy) + child = child~nextSibling + end + self~currentEntityDecl~setReadOnly(.true, .true) + end + self~currentEntityDecl = .nil + end + end + + self~inEntityRef = .false + + if \self~createEntityRefNodes then do + children = self~currentNode~childNodes + parent = self~currentNode~parentNode + if children~length > 0 then do + node = self~currentNode~previousSibling + if node \= .nil, node~nodeType == .Node~TEXT_NODE, child~nodeType == .Node~TEXT_NODE then do + node~appendData(child~nodeValue) + self~currentNode~removeChild(child) + end + else do + node = parent~insertBefore(child, self~currentNode) + self~handleBaseURI(node) + end + + do child over children + node = parent~insertBefore(child, self~currentNode) + self~handleBaseURI(node) + end + end + end + parent~removeChild(self~currentNode) + self~currentNode = parent + +::method handleBaseURI private + use strict arg node + + nodeType = node~nodeType + if nodeType == .Node~ELEMENT_NODE then do + if self~namespaceAware then do + if node~getAttributeNodeNS("http://www.w3.org/XML/1998/namespace","base") \= .nil then do + return + end + end + else if node~attributeNode("xml:base") \= .nil then do + return + end + baseURI = self~currentNode~baseURI + if baseURI \= .nil & baseURI \= self~document~documentURI then do + if self~namespaceAware then do + node~setAttributeNS("http://www.w3.org/XML/1998/namespace","base", baseURI) + end + else do + node~setAttribute("xml:base", baseURI) + end + end + end + else if nodeType == .Node~PROCESSING_INSTRUCTION_NODE do + baseURI = self~currentNode~baseURI + if baseURI \= .nil then do + self~handleError("pi-base-uri-not-preserved", baseURI, .DOMError~SEVERITY_WARNING) + end + end + +::method handleError private + expose errorHandler + if errorHandler == .nil then do + return + end + + use strict arg type, relatedData, severity + + errorHandler~errorHandler~handleError(new DOMError(type, baseURI, severity) + +::method startDtd + use strict arg locator, augmentations + + self~inDtd = .true + if locator \= .nil then do + self~baseURIStack~push(locator~baseSystemId) + end + + self~internalSubset = .mutablebuffer~new + +::method endDtd + use strict arg augmentations + + self~inDtd = .false + if \self~baseUriStack~isEmpty then do + self~baseUriStack~pop + end + + if self~internalSubset \= .nil & self~internalSubset~length > 0 then do + self~document~internalSubset = self~internalSubset + end + +::method startConditional + use strict arg type, augmentations + +::method endConditional + use strict arg augmentations + +::method startExternalSubset + use strict arg identifer, augmentations + + self~baseUriStack~push(identifer~baseSystemId) + self~inDtdExternalSubet = .true + +::method endExternalSubset + use strict arg augmentations + + self~inDtdExternalSubset = .false + self~baseUriStack~pop + + + Property changes on: incubator/orxutils/xml/parsers/abstractdomparser.cls ___________________________________________________________________ Added: svn:eol-style + native Modified: incubator/orxutils/xml/parsers/abstractxmldocumentparser.cls =================================================================== --- incubator/orxutils/xml/parsers/abstractxmldocumentparser.cls 2009-07-17 18:33:22 UTC (rev 4942) +++ incubator/orxutils/xml/parsers/abstractxmldocumentparser.cls 2009-07-17 23:52:21 UTC (rev 4943) @@ -4,6 +4,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ ::class "AbstractXMLDocumentParser" subclass XMLParser + ::method init expose inDtd documentSource dtdSource dtdContentModelSource use strict arg config Modified: incubator/orxutils/xml/parsers/xmlparser.cls =================================================================== --- incubator/orxutils/xml/parsers/xmlparser.cls 2009-07-17 18:33:22 UTC (rev 4942) +++ incubator/orxutils/xml/parsers/xmlparser.cls 2009-07-17 23:52:21 UTC (rev 4943) @@ -7,6 +7,8 @@ ::constant ENTITY_RESOLVER "http://apache.org/xml/properties/internal/entity-resolver" ::constant ERROR_HANDLER "http://apache.org/xml/properties/internal/error-handler" +::attribute configuration private + ::method init expose configuration This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-16 00:22:35
|
Revision: 7901 http://oorexx.svn.sourceforge.net/oorexx/?rev=7901&view=rev Author: bigrixx Date: 2012-06-16 00:22:25 +0000 (Sat, 16 Jun 2012) Log Message: ----------- merge individual dom classes into master package and fix syntax errors Modified Paths: -------------- incubator/orxutils/xml/domerrors.cls incubator/orxutils/xml/event.cls incubator/orxutils/xml/nodefilter.cls incubator/orxutils/xml/xmldom.cls Modified: incubator/orxutils/xml/domerrors.cls =================================================================== --- incubator/orxutils/xml/domerrors.cls 2012-06-15 02:52:37 UTC (rev 7900) +++ incubator/orxutils/xml/domerrors.cls 2012-06-16 00:22:25 UTC (rev 7901) @@ -23,3 +23,5 @@ use arg message raise syntax 98.900 array(message) -- just raise this as a user execution error + + Modified: incubator/orxutils/xml/event.cls =================================================================== --- incubator/orxutils/xml/event.cls 2012-06-15 02:52:37 UTC (rev 7900) +++ incubator/orxutils/xml/event.cls 2012-06-16 00:22:25 UTC (rev 7901) @@ -1,6 +1,6 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: Document */ +/* Class: DOMEvent */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ ::class DOMEvent Modified: incubator/orxutils/xml/nodefilter.cls =================================================================== --- incubator/orxutils/xml/nodefilter.cls 2012-06-15 02:52:37 UTC (rev 7900) +++ incubator/orxutils/xml/nodefilter.cls 2012-06-16 00:22:25 UTC (rev 7901) @@ -3,7 +3,7 @@ /* Class: NodeFilter */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "NodeIterator" mixinclass Object +::class "NodeFilter" mixinclass Object -- constants returned by acceptNode ::constant FILTER_ACCEPT 1 ::constant FILTER_REJECT 2 Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-15 02:52:37 UTC (rev 7900) +++ incubator/orxutils/xml/xmldom.cls 2012-06-16 00:22:25 UTC (rev 7901) @@ -97,12 +97,11 @@ use strict arg feature, version = (.nil) if version = .nil then do featureset over ver if featureset[feature] <> .nil then return .true - end - end + end else do featureset = self~feature[version] if featureset <> .nil, featureset[feature] <> .nil then return .true - end + end return .false @@ -174,769 +173,3431 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: DocumentFragment */ +/* Class: DeepNodeList */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class DocumentFragment subclass Node public +::class DeepNodeList subclass NodeList +::method init + expose rootNode tagName changes nodes nsName -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/* Class: DocumentFragment */ -/* Private methods */ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ + use strict arg rootNode, tagName, nsName = .nil + nodes = .Array~new + changes = 0 +-- lazy search for the matching nodes. This only fills in the cache +-- as far as the last valid requested position +::method item + expose rootNode changes nodes + use strict arg index + -- if the tree has changed, we need to restart this + if rootNode~changes \= changes then do + nodes = .array~new + changes = rootNode~changes + end -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/* Class: DocumentFragment */ -/* Public methods */ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ + currentSize = nodes~items + if index < currentSize then do + return nodes[index + 1] + end + else do + -- we need to continue the traversal from the last node added + if currentSize == 0 then do + thisNode = rootNode + end + else do + thisNode = nodes[currentSize] + end + -- keep adding up to the one we're looking for + do while index > currentSize + thisNode = self~nexMatchingElementAfter(thisNode) + if thisNode \= .nil then do + nodes~append(thisNode) + currentSize += currentSize + end + else do + -- no more nodes available + leave + end + end + -- this is either the one we want or .nil + return thisNode + end -/*----------------------------------------------------------------------------*/ -/* Method: init */ -/* Description: instance initialization. */ -/*----------------------------------------------------------------------------*/ +::attribute length GET + expose nodes + use strict arg + -- this forces everything to be initialized + self~item(999999999) + return nodes~items -::method init +::method makearray + expose nodes use strict arg - self~nodeType = 11 + -- this forces everything to be initialized + self~item(999999999) + return nodes~copy +::method nextMatchingElementAfter private + expose rootNode tagName nsName + use arg current + do while current \= nil + -- go down to the first child if it has one + if current~hasChildNodes then do + current = current~firstChild + end + -- no children and we're at the rootnode, so we + -- don't go up or to any siblings + else if current == rootNode then do + return .nil + end + -- now try for a sibling of our current position + next = current~nextSibling + -- if we found one, then this is our next candidate + if next \= .nil then do + current = next + end + else do + next = .nil + -- now we step "up and to the right" for as many attempts as needed + -- or utnil we pop back to the root node + do while current \= rootNode + current = current~parentNode + next = current~nextSibling + if next \= .nil then do + leave + end + end + -- this is either a good node, or .nil + current = next + end + -- we have a candidate node, now make sure it matches what we're looking for + if current \= rootNode, current \= .nil, current~nodeType == .Node~ELEMENT_NODE then do + -- no namespace checking? We'll take any element node if the name is + -- "*" or it matches directly + if nsName == .nil then do + if tagName == "*" | current~tagName == tagName then do + return current + end + end + -- namespace qualified (which might also be "*") + else do + -- wildcard match on the tagname, so just check the namespace name + if tagName == "*" then do + -- wildcards on both, this is easy + if nsName == "*" then do + return current + end + else do + -- null string is a non-specific namepace request, which + -- matches only if the element does not have a namespace + if nsName == "" & current~namespaceURI == .nil then do + return current + end + -- requires an exact namespace match + else if nsName == current~namespaceURI then do + return current + end + end + end + -- non-wild card on the name + else do + -- if we have a name match, then see if the namespace + -- name also matches + if current~localName == tagName then do + -- ok, the local name matches, the ns rules are the + -- same as above + if nsName == "*" then do + return current + end + else do + -- null string is a non-specific namepace request, which + -- matches only if the element does not have a namespace + if nsName == "" & current~namespaceURI == .nil then do + return current + end + -- requires an exact namespace match + else if nsName == current~namespaceURI then do + return current + end + end + end + end + end + end + -- if we get here, we had a candidate, but it was not a match + -- just continue the tree walk + end + -- nothing found + return .nil + + /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: Document */ +/* Class: NamedNodeMap */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class 'Document' subclass Node public +::class 'NamedNodeMap' public +::method init + expose ownerNode attributes + use strict arg ownerNode + attributes = .nil /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: Document */ +/* Class: NamedNodeMap */ /* Private methods */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ +::method findNamePoint private + expose attributes + use arg name -/*----------------------------------------------------------------------------*/ -/* Method: doctype= */ -/* Description: set the document type. */ -/*----------------------------------------------------------------------------*/ + if attributes == .nil then do + return .nil + end -::attribute doctype GET + s = attributes~supplier + do while s~available + attr = s~item + if attr~nodeName == name then do + return s~index + end + end -/*----------------------------------------------------------------------------*/ -/* Method: implementation */ -/* Description: set the document implementation. */ -/*----------------------------------------------------------------------------*/ + return .nil -::attribute implementation GET +::method findNamePointNS private + expose attributes + use arg name, namespace + + if attributes == .nil then do + return .nil + end + + s = attributes~supplier + do while s~available + attr = s~item + if namespace == .nil then do + if attr~namespaceURI == .nil & name == attr~localName then do + return s~index + end + + if attr~localName == .nil & name == attr~nodeName then do + return s~index + end + end + else do + if attr~namespaceURI == namespace & attr~localName == name then do + return s~index + end + end + end + + return .nil + + /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: Document */ +/* Class: NamedNodeMap */ /* Public methods */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Method: init */ -/* Description: instance initialization. */ +/* Method: getNamedItem */ +/* Description: get a named item. */ /*----------------------------------------------------------------------------*/ -::method init - expose doctype implementation - self~nodeType = 9 - doctype = .nil - implementation = DOMImplementation~new +::method getNamedItem + expose attributes + use strict arg name + if attributes == .nil then do + return .nil + end + do attribute over attributes + if attribute~name == name then do + return attribute + end + end + return .nil + + /*----------------------------------------------------------------------------*/ -/* Method: documentElement */ -/* Description: return the root element of the document. */ +/* Method: getNamedItemNS */ +/* Description: get a named item by namespace */ /*----------------------------------------------------------------------------*/ -::method documentElement - return self~children[0] +::method getNamedItemNS + expose attributes + use strict arg name, namespace + if attributes == .nil then do + return .nil + end -/*----------------------------------------------------------------------------*/ -/* Method: createElement */ -/* Description: create an element node. */ -/*----------------------------------------------------------------------------*/ + do attribute over attributes + if attribute~name == name & attribute~namespaceURI == namespace then do + return attribute + end + end + return .nil -::method createElement - use strict arg tagname - return .Element~new(tagname) /*----------------------------------------------------------------------------*/ -/* Method: createElementNS */ -/* Description: create an element node. */ +/* Method: setNamedItem */ +/* Description: set a named item. */ /*----------------------------------------------------------------------------*/ -::method createElementNS - use strict arg uri, qname - -- TODO finish this - return .Element~new(tagname) +::method setNamedItem + expose attributes + use strict arg node + index = self~findNamePoint(node~nodeName) + previous = .nil -/*----------------------------------------------------------------------------*/ -/* Method: createDocumentFragment */ -/* Description: create a document fragment node. */ -/*----------------------------------------------------------------------------*/ + if index \= .nil then do + previous = attributes[index] + attributes[index] = node + end + else do + if attributes == .nil then do + attributes = .list~new + end + attributes~append(node) + end -::method createDocumentFragment - use strict arg - return .DocumentFragment~new + return previous /*----------------------------------------------------------------------------*/ -/* Method: createTextNode */ -/* Description: create a text node. */ +/* Method: setNamedItemNS */ +/* Description: set a named item. */ /*----------------------------------------------------------------------------*/ -::method createTextNode - use strict arg data - return .Text~new(data) +::method setNamedItemNS + expose attributes + use strict arg node + index = self~findNamePointNS(node~localName, node~namespaceURI) + previous = .nil -/*----------------------------------------------------------------------------*/ -/* Method: createComment */ -/* Description: create a comment node. */ -/*----------------------------------------------------------------------------*/ + if index \= .nil then do + previous = attributes[index] + attributes[index] = node + end + else do + -- we try again just based on the nodeName + index = self~findNamePoint(node~nodeName) + if index > .nil then do + previous = attributes[index] + attributes[index] = node + end + else do + if attributes == .nil then do + attributes = .list~new + end + attributes~append(node) + end + end -::method createComment - use strict arg data - return .Comment~new(data) + return previous /*----------------------------------------------------------------------------*/ -/* Method: createCDATASect */ -/* Description: create a CDATA section node. */ +/* Method: removeNamedItem */ +/* Description: remove a named item. */ /*----------------------------------------------------------------------------*/ -::method createCDATASect - use strict arg data - return .CDATASection~new(data) +::method removeNamedItem + expose attributes + use strict arg name + index = self~findNamePoint(name) + previous = .nil + if index \= .nil then do + previous = attributes[index] + attributes~remove(index) + end + return previous + + /*----------------------------------------------------------------------------*/ -/* Method: createProcessingInstruction */ -/* Description: create a processing instruction node. */ +/* Method: removeNamedItemNS */ +/* Description: remove a named item. */ /*----------------------------------------------------------------------------*/ -::method createProcessingInstruction - use strict arg target, data - return .ProcessingInstruction~new(target, data) +::method removeNamedItemNS + expose attributes + use strict arg namespace, name + index = self~findNamePointNS(name, namespace) + previous = .nil + if index \= .nil then do + previous = attributes[index] + attributes~remove(index) + end + return previous + /*----------------------------------------------------------------------------*/ -/* Method: createAttribute */ -/* Description: create an attribute node. */ +/* Method: cloneMap */ +/* Description: perform a deep copy of this map object */ /*----------------------------------------------------------------------------*/ +::method cloneMap + expose attributes + use strict arg owner + newMap = .NamedNodeMap(owner) + newMap~cloneContent(attributes) -::method createAttribute - use strict arg name - return .Attr~new(name) +/*----------------------------------------------------------------------------*/ +/* Method: cloneContent */ +/* Description: initialize the content from another map */ +/*----------------------------------------------------------------------------*/ +::method cloneContent + expose attributes + use arg source + if source \= .nil then do + attributes = .list~new + do attr over source + attributes~append(attr~cloneNode(.true)) + end + end /*----------------------------------------------------------------------------*/ -/* Method: createAttributeNS */ -/* Description: create an attribute node. */ +/* Method: item */ +/* Description: return the named item. */ /*----------------------------------------------------------------------------*/ -::method createAttributeNS - use strict arg uri, qname - -- TODO This needs finishing - return .Attr~new(name) +::method item + expose attributes + use strict arg position + if attributes == .nil then do + return .nil + end + else do + return attributes~makearray[position + 1] + end /*----------------------------------------------------------------------------*/ -/* Method: createEntityReference */ -/* Description: create an entity reference node. */ +/* Method: length */ +/* Description: return the number of named items. */ /*----------------------------------------------------------------------------*/ -::method createEntityReference - use strict arg name - return .EntityReference~new(name) +::method length + expose attributes + use strict arg + if attributes \== .nil then do + return attributes~items + end + else do + return 0; + end +::method makearray + expose attributes + use strict arg + return attributes~makearray -- make sure this is a copy -/*----------------------------------------------------------------------------*/ -/* Method: getElementsByName */ -/* Description: create a list of all element with the specified name. */ -/*----------------------------------------------------------------------------*/ +::method "[]" + forward message("ITEM") -::method getElementsByName - use arg tagname - temp = .NodeList~new - -- TODO: lots to do here, see the spec - return temp +::attribute attributes PRIVATE /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: Attr */ +/* Class: AttributeMap -- an implementation of NamedNodeMap that can deal */ +/* with member ownership issues */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class Attr subclass Node public +::class "AttributeMap" subclass NamedNodeMap +::method init + expose hasDefaults + use strict arg ownerNode, defaults = . nil + self~init:super(ownerNode) + hasDefaults = .false + -- if we have a defaults set, clone it and if we really added + -- something, marks us as having defaults + if defaults \= .nil then do + self~cloneContent(defaults) + if self~attributes \= .nil then do + hasDefaults = .true + end + end -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/* Class: Attr */ -/* Private methods */ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ +::method setNamedItem + use strict arg attribute + -- replaceing an attribute with itself does nothing + if attribute~isOwned then do + return attribute + end + attribute~ownerNode = self~ownerNode + attribute~isOwned = .true -/*----------------------------------------------------------------------------*/ -/* Method: specified= */ -/* Description: only the set method is private */ -/*----------------------------------------------------------------------------*/ + index = self~findNamePoint(attribute~nodeName, 0) + attributes = self~attributes + previous = .nil + if index \= .nil then do + previous = attributes[i] + attributes[i] = attribute + previous~ownerNode = self~ownerNode~ownerDocument + previous~isOwned = .false + previous~isSpecified = .true + end + else do + if attributes = .nil then do + attributes = .list~new + self~attributes = attributes + end + attributes~append(attribute) + end -::attribute specified private set + self~ownerNode~ownerDocument~setAttrNode(attribute, previous) + return previous +::method setNamedItemNS + use strict arg attribute + -- replaceing an attribute with itself does nothing + if attribute~isOwned then do + return attribute + end + + attribute~ownerNode = self~ownerNode + attribute~isOwned = .true + + index = self~findNamePointNS(attribute~namespaceURI, attribute~nodeName) + attributes = self~attributes + previous = .nil + if index \= .nil then do + previous = attributes[i] + attributes[i] = attribute + previous~ownerNode = self~ownerNode~ownerDocument + previous~isOwned = .false + previous~isSpecified = .true + end + else do + if attributes = .nil then do + attributes = .list~new + self~attributes = attributes + end + attributes~append(attribute) + end + + self~ownerNode~ownerDocument~setAttrNode(attribute, previous) + return previous + +::method removeNamedItem + use strict arg name + + index = self~findNamePoint(name) + if index == .nil then do + return .nil + end + + return self~remove(self~attributes[index], index, true) + +::method removeNamedItemNS + use strict arg namespaceURI, name + + index = self~findNamePointNS(namspaceURI, name) + if index == .nil then do + return .nil + end + + return self~remove(self~attributes[index], index, true) + +::method remove private + use strict arg attr, index, addDefault = .false + + ownerDocument = self~ownerNode~ownderDocument + name = attr~nodeName + if attr~isIdAttribue then do + ownerDocument~removeIdentifier(attr~value) + end + + attributes = self~attributes + + setdefault = .false + -- do we have default attributes that we might need to revert to? + if self~hasDefaults & addDefault then do + defaults = ownerNode~defaultAttributes + if defaults \= .nil then do + defaultAttr = defaults~getNamedItem(name) + if defaultAttr \= .nil then do + newAttr = defaultAttr~cloneNode(.true) + -- the namespace uri comes from the deleted node, + -- not the default source value if the default + -- does not have a local name + if newAttr~localName \== .nil then do + newAttr~namespaceURI = attr~namespaceURI + end + newAttr~ownerNode = ownerNode + newAttr~isOwned = true + -- mark this as a default value + newAttr~isSpecified = false + attributes[index] = newAttr + setdefault = .true + -- if this is the id attribute, make sure the document knows + -- about this mapping + if attr~isIdAttribute then do + ownerDocument~putIdentifier(newAttr~nodeValue, ownerNode) + end + end + end + end + -- if we didn't end up setting a default, remove the node + if \setDefault then do + attributes~remove(index) + end + -- detach from usage + attr~ownerNode = .nil + attr~isOwned = .false + attr~isSpecified = .true + attr~isIdAttribute = false + + -- notify the document + ownerDocument~removedAttrNode(attr, ownerNode, name) + return attr + +::method cloneContent + use strict arg source + srcnodes = source~attributes + if srcnodes \= .nil then do + self~attributes = .List~new + do node over srcnodes + newNode = node~cloneNode(true) + newNode~ownerNode = self~ownerNode + newNode~isOwned = .true + self~attributes~append(newNode) + end + end + + /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: Attr */ -/* Public methods */ +/* Class: Node */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ +::CLASS 'Node' public +::CONSTANT ELEMENT_NODE 1 +::CONSTANT ATTRIBUTE_NODE 2 +::CONSTANT TEXT_NODE 3 +::CONSTANT CDATA_SECTION_NODE 4 +::CONSTANT ENTITY_REFERENCE_NODE 5 +::CONSTANT ENTITY_NODE 6 +::CONSTANT PROCESSING_INSTRUCTION_NODE 7 +::CONSTANT COMMENT_NODE 8 +::CONSTANT DOCUMENT_NODE 9 +::CONSTANT DOCUMENT_TYPE_NODE 10 +::CONSTANT DOCUMENT_FRAGMENT_NODE 11 +::CONSTANT NOTATION_NODE 12 +-- initialize a counter to give new nodes a unique id +::METHOD init class + expose ctr + ctr = 0 + +-- get the next id for new nodes +::METHOD getId class private + expose ctr + ctr += 1 + return ctr + + /*----------------------------------------------------------------------------*/ /* Method: init */ /* Description: instance initialization. */ /*----------------------------------------------------------------------------*/ -::method init - use strict arg name - self~nodeName = name - self~nodeType = 2 - self~nodeValue = '' - self~specified = .false +::METHOD init + expose ownerNode childNodes nodeId + use strict arg ownerNode + nodeId = self~class~getId + childNodes = .NodeList~new + self~owned = .false -- unowned until we are added as a child + self~readonly = .false -- newly created nodes can be altered + self~firstChild = .false -- not attached yet, so can't be first -/*----------------------------------------------------------------------------*/ -/* Method: name */ -/* Description: return the node name. */ -/*----------------------------------------------------------------------------*/ +::ATTRIBUTE nodeName GET +-- superclasses overrid +::ATTRIBUTE nodeValue GET + return .nil +::ATTRIBUTE nodeValue SET + return -- default behavior is to do nothing...superclasses override this +::ATTRIBUTE nodeType GET +-- superclasses override +::ATTRIBUTE parentNode GET + return .nil +::ATTRIBUTE childNodes GET + use strict arg + -- the nodes implement the NodeList methods directly, so + -- all we need to do is return ourself + return self +-- superclasses override +::ATTRIBUTE firstChild GET + return .nil +-- superclasses override +::ATTRIBUTE lastChild GET + return .nil +-- superclasses override +::ATTRIBUTE previousSibling GET + return .nil +-- superclasses override +::ATTRIBUTE nextSibling GET + return .nil +-- superclasses override +::ATTRIBUTE attributes GET + return .nil -::attribute name get +::METHOD hasAttributes use strict arg - return self~nodeName + return .false +::ATTRIBUTE ownerDocument GET + expose ownerDocument ownerNode -/*----------------------------------------------------------------------------*/ -/* Method: specified */ -/* Description: return the specified indicator. */ -/*----------------------------------------------------------------------------*/ + -- if we're a child node, then ask our owner for the information + if self~owned then do + return ownerNode~ownerDocument + end + else do + -- return the owner directly + return ownerNode + end -::attribute specified get +::ATTRIBUTE ownerDocument SET PRIVATE + expose ownerNode -/*----------------------------------------------------------------------------*/ -/* Method: value */ -/* Description: return the node value. */ -/*----------------------------------------------------------------------------*/ + use strict arg doc + if \self~owned then do + ownerNode = doc + end -::attribute value get +::ATTRIBUTE namespaceURI GET use strict arg - return self~nodeValue + return .nil +::ATTRIBUTE prefix GET + use strict arg + return .nil +::ATTRIBUTE prefix SET + -- this is an error by default + .DomErrors~raiseError(.DomErrors~NAMESPACE_ERR) +::ATTRIBUTE localName GET + use strict arg + return .nil +::ATTRIBUTE baseURI GET + use strict arg + return .nil +-- private attributes used for the implementation +::ATTRIBUTE owned PRIVATE +::ATTRIBUTE readonly PRIVATE +::ATTRIBUTE isFirstChild PRIVATE -/*----------------------------------------------------------------------------*/ -/* Method: value= */ -/* Description: set the node value. */ -/*----------------------------------------------------------------------------*/ +-- default implementations designed to be overridden +::METHOD hasChildNodes + use strict arg + return .false; -::attribute value set - use arg newval - self~nodeValue = newval - self~specified = .true +-- base cloning method +::METHOD cloneNode + use strict arg deep = .false + -- make a copy of ourselves + newNode = self~copy + -- neither owned or readonly + newNode~owned = .false + newNode~readOnly = .false + return newNode + +::METHOD isSupported + use strict arg feature, version + return .false + +::METHOD insertBefore + use strict arg newChild, refChild + -- not implemented in the base node + .DomErrors~raiseError(.DomErrors~Hierarchy_request_err) + +::METHOD replaceChild + use strict arg newChild, oldChild + -- not implemented in the base node + .DomErrors~raiseError(.DomErrors~Hierarchy_request_err) + +::METHOD removeChild + use strict arg oldChild + -- not implemented in the base node + .DomErrors~raiseError(.DomErrors~Not_found_err) + +::METHOD appendChild + use strict arg newChild + return self~insertBefore(newChild, .nil) + +::METHOD compareDocumentPosition + use strict arg other + raise syntax 93.963 -- not supported + +::ATTRIBUTE textContent GET + forward message("NODEVALUE") + +::ATTRIBUTE textContent SET + forward message("NODEVALUE=") + +::METHOD isSameNode + use strict arg other + return self~identityHash = other~identityHash + +::METHOD lookupPrefix + use strict arg uri + raise syntax 93.963 -- not supported + +::METHOD isDefaultNamespace + use strict arg uri + raise syntax 93.963 -- not supported + +::METHOD lookupNamespaceURI + use strict arg prefix + raise syntax 93.963 -- not supported + +::METHOD isEqualNode + use strict arg other + + if self == other then do + return .true + end + + if self~nodetype != other~nodetype then do + return .false + end + + if self~nodename != other~nodename then do + return .false + end + + if self~localname != other~localname then do + return .false + end + + if self~namespaceURI != other~namespaceURI then do + return .false + end + + if self~prefix != other~prefix then do + return .false + end + + if self~nodevalue != other~nodevalue then do + return .false + end + +::METHOD getFeature + use strict arg feature, version + return .nil + +::METHOD setUserData + use strict arg key, date, handler + raise syntax 93.963 -- not supported + +::METHOD getUserData + use strict arg key + raise syntax 93.963 -- not supported + + /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: Element */ +/* Class: Node */ +/* Private methods */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class 'Element' subclass Node public +::attribute ctr class private +::attribute id private +-- methods of NodeList that the node implements directly. superclasses will +-- implement this more full + /*----------------------------------------------------------------------------*/ +/* Method: item */ +/* Description: get a list item. */ /*----------------------------------------------------------------------------*/ -/* Class: Element */ -/* Private methods */ + +::method item + use strict arg index + -- always returns .nil + return .nil + /*----------------------------------------------------------------------------*/ +/* Method: length */ +/* Description: get the number of items in the list. */ /*----------------------------------------------------------------------------*/ +::method length + use strict arg + -- always returns 0 + return 0 +::method makearray + use strict arg + -- just an empty array + return .array~new(0) +::method "[]" + return message("ITEM") + /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: Element */ -/* Public methods */ +/* Class: ChildNode base type for nodes that can be children of other nodes */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ +::class "ChildNode" subclass Node +::method init + expose previousSibling nextSibling + forward class(super) continue + previousSibling = .nil + nextSibling = .nil + + +::method cloneNode + use strict arg deep = .false + + newNode = self~init:super(deep) + -- detach the new instance from the context + newNode~previousSibling = .nil + newNode~nextSibling = .nil + newNode~isFirstChild = .false + + return newNode + +::attribute parentNode GET + if self~isOwned then do + return self~ownerNode + end + else do + return .nil + end + +::attribute nextSibling GET +::attribute nextSibling SET PRIVATE + +::attribute previousSibling GET +::attribute previousSibling SET PRIVATE + + /*----------------------------------------------------------------------------*/ -/* Method: init */ -/* Description: instance initialization. */ /*----------------------------------------------------------------------------*/ +/* Class: ParentNode base type for nodes that can be parents of other nodes */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +::class "ParentNode" subclass ChildNode ::method init - use strict arg tagname - self~nodeName = tagname - self~nodeType = 1 - self~nodeValue = .nil - self~attr = .NamedNodeList~new + expose firstChild lastChild ownerDocument childNodes + forward class(super) continue -/*----------------------------------------------------------------------------*/ -/* Method: tagname */ -/* Description: return the node name. */ -/*----------------------------------------------------------------------------*/ + -- set this explicitly + use strict arg ownerDocument + self~clearChildNodes -::attribute tagname get +::method clearChildren private + expose firstChild lastChild childNodes + firstChild = .nil + lastChild = .nil + childNodes = 0 + +::method cloneNode + expose firstChild + use strict arg deep = .false + + newNode = self~cloneNode:super(deep) + newNode~clearChildNodes + -- if this is a deep copy, then we need to clone all of the children too + if deep then do + child = firstChild + do while child \= .nil + newNode~appendNode(child~cloneNode(.true)) + child = child.nextSibling + end + end + return newNode + +::attribute ownerDocument GET +::attribute ownerDocument SET private + expose ownerDocument firstChild + use strict arg doc + -- we need to set this at the higher levels too + self~"OWNERDOCUMENT":super(doc) + -- set this in each of the children too + child = firstChild + do while child \= .nil + child~ownerDocument = doc + child = child.nextSibling + end + +::method hasChildren + expose firstChild use strict arg - return self~nodeName + return firstChild \= .nil +::attribute firstChild GET +::attribute lastChild GET -/*----------------------------------------------------------------------------*/ -/* Method: getAttribute */ -/* Description: return the specified attribute value. */ -/*----------------------------------------------------------------------------*/ +::method insertBefore + expose firstChild lastChild ownerDocument childNodes + use arg newChild, refChild, replace = .false -::method getAttribute - use strict arg name - return self~attributes[name]~nodeValue + -- this case is really a no-op, but we need to go through the steps + -- in case we need to signal events. + if newChild == refChild then do + refChild = refChild~nextSibling + self~removeChild(newChild) + self~insertBefore(newChild, refChild) + return newChild + end + -- inform the owner that this is happening + ownerDocment~insertingNode(this, replace) -/*----------------------------------------------------------------------------*/ -/* Method: setAttribute */ -/* Description: set a specified attribute. */ -/*----------------------------------------------------------------------------*/ + -- make sure we've detached this node from any previous + -- parent node. + oldParent = newChild~parentNode + if oldParent \= .nil then do + oldParent~removeChild(newChild) + end -::method setAttribute - use strict arg name, value - self~attributes[name]~nodeValue = value + -- set the new owner + newChild~ownerNode = self + newChild~isOwned = .true -/*----------------------------------------------------------------------------*/ -/* Method: removeAttribute */ -/* Description: remove an attribute value. */ -/*----------------------------------------------------------------------------*/ + -- Now detach before and after -::method removeAttribute - use strict arg name - self~attributes[name]~nodeValue = '' + -- first added child is easy + if firstChild == .nil then do + firstChild = newChild + lastChild = newChild + end + -- .nil is an append + else if refChild == .nil then do + lastChild~nextSibling = newChild + newChild~previousSibling = lastChild + newChild~nextSibling = .nil + lastChild = newChild + end + -- normal insertion + else do + -- insertion at the beginning, need to adjust + if refChild == firstChild then do + newChild~firstSibling = firstChild + newChild~previousSibling = .nil + firstChild~previousSibling = newChild + firstChild = newChild + end + -- insertion in the middle + else do + previousNode = refNode~previousSibling + previousNode~nextSibling = newChild + newChild~previousSibling = previousNode + newChild~nextSibling = refNode + refNode~previousSibling = newChild + end + end + -- bump the count of nodes + childNodes += 1 -/*----------------------------------------------------------------------------*/ -/* Method: getAttributeNode */ -/* Description: get an attribute node. */ -/*----------------------------------------------------------------------------*/ + -- broadcast a change event + self~changed + -- inform the document of this update + ownerDocument~insertedNode(self, newChild, replace) + return newChild -::method getAttributeNode - use strict arg name - return self~attributes[name] +::method removeChild + expose firstChild lastChild ownerDocument childNodes + use strict arg oldChild, replace = .false + ownerDocument~removingNode(self, oldChild, replace) -/*----------------------------------------------------------------------------*/ -/* Method: setAttributeNode */ -/* Description: set an attribute node. */ -/*----------------------------------------------------------------------------*/ + -- removing the first child + if oldChild == firstChild then do + firstChild = firstChild~nextSibling + firstChild~previousSibling = .nil + -- if this was the only child, then clear out everything + if lastChild == oldChild then do + lastChild = .nil + end + end + else do + previous = oldChild~previousSibling + next = oldChild~nextSibling + previous~nextSibling = next + -- this could be the last child, so we might have to update that + if next == .nil then do + lastChild = previous + end + else do + -- close up the chaing + next~previousSibling = previous + end + end -::method setAttributeNode - use strict arg newAttr - self~attributes[newAttr~nodeName] = newAttr - return newAttr + childNodes -= 1 + oldChild~ownerNode = ownerDocument + oldChild~isOwned = .false + oldChild~nextSibling = .nil + oldChild~previousSibling = .nil -/*----------------------------------------------------------------------------*/ -/* Method: removeAttributeNode */ -/* Description: set an attribute node. */ -/*----------------------------------------------------------------------------*/ + -- note the change update + self~changed -::method removeAttributeNode - use strict arg oldAttr - self~attributes~remove(oldAttr~nodeName) - return oldAttr + ownerDocument~removeNode(self, replace) + return oldChild +::method replaceChild + expose ownerDocument + use strict arg newChild, oldChild -/*----------------------------------------------------------------------------*/ -/* Method: getElementsByTagName */ -/* Description: get a list of elements by tag name. */ -/*----------------------------------------------------------------------------*/ + self~insertBefore(newChild, oldChild, .true) + if newChild !== oldChild then do + removeChild(oldChild, true) + end -::method getElementsByTagName - use strict arg name - return self~getElementsByName(name) + ownerDocument.replacedNode(this) + return oldChild +::method textContent + use strict arg -/*----------------------------------------------------------------------------*/ -/* Method: normalize */ -/* Description: normalize the subtree. */ -/*----------------------------------------------------------------------------*/ + child = self~firstChild + if child \== .nil then do + next = child~nextSibling + if next == .nil then do + if self~hasTextContent(child) then do + return child~textContent + end + else do + return "" + end + end + else do + buffer = .mutablebuffer~new + buildTextContent(buffer) + return buffer~string + end + end + return "" -::method normalize +::method buildTextContent private + use arg buffer + child = self~firstChild + do while child \= .nil + if self~hasTextContent(child) then do + child~buildTextContext(buffer) + end + child = child~nextSibling + end + +::method hasTextContext private + use arg child + type = child~nodeType + if type \= .Node~COMMENT_NODE && - + child \= .Node~PROCESSING_INSTRUCTION_NODE && - + child \= .Node~TEXT_NODE then do + return .false + end + + return \child~isIgnorableWhilespace + +::attribute textContent SET + use strict arg text + child = self~firstChild + do while child \= .nil + self~removeChild(child) + end + + -- create a text node and append + if text \= .nil, text \== "" then do + self~appendChild(self~ownerDocument~createTextNode(text)) + end + +-- overrides for the NodeList methods +::attribute length GET + expose childNodes use strict arg - -- TODO: a lot of work to do here, see the spec - return + return childNodes +::attribute item GET + expose firstNode childNodes + use strict arg index -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/* Class: Text */ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ + if index < 0 || index >= childNodes then do + return .nil + end + child = firstChild + do while index > 0 + child = child~nextSibling + index -= 1 + end -::class Text subclass Node public + return child +::method makearray + expose firstNode childNodes + use strict arg -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/* Class: Text */ -/* Private methods */ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ + result = .array~new(childNodes) + child = firstChild + do while child \= .nil + result~append(child) + child = child~nextSibling + end + return result + /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: Text */ -/* Public methods */ +/* Class: DocumentFragment */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ +::class 'DocumentFragment' public subclass ParentNode +::attribute nodeType GET + return .Node~DOCUMENT_FRAGMENT_NODE -/*----------------------------------------------------------------------------*/ -/* Method: init */ -/* Description: instance initialization. */ -/*----------------------------------------------------------------------------*/ +::attribute nodeName GET + return "#document-fragment" -::method init - use strict arg data - self~nodeName = '#text' - self~nodeType = 3 - self~nodeValue = data +::method normalize + if self~isNormalized then do + return + end + kid = self~firstChild -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/* Class: Comment */ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ + do while kid \= .nil + next = kid~nextSibling -::class Comment subclass Node public + if kid~nodeType == .Node~TEXT_NODE then do + if next \= .nil & next~nodeType == .Node~TEXT_NODE then do + kid~appendData(next~nodeValue) + self~removeChild(next) + -- back up, we might have more nodes to collapse + next = kid + end + else do + if kid~nodeValue == .nil | kid~nodeValue == "" then do + self~removeChild(kid) + end + end + end + kid~normalize() + kid = next + end + self~isNormalized = .true /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: Comment */ -/* Private methods */ +/* Class: Document */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ +::class "Document" subclass Node +::method init + expose iterators ranges eventListeners + use arg doctype = .nil, grammarAccess = .false + self~init:super(doctype, grammarAccess) + iterators = .nil + ranges = .nil + eventListeners = .nil -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/* Class: Comment */ -/* Public methods */ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ +::method cloneNode + use strict arg deep = .false + newDoc = .Document~new + self~cloneDocument(newDoc, deep) + return newDoc -/*----------------------------------------------------------------------------*/ -/* Method: init */ -/* Description: instance initialization. */ -/*----------------------------------------------------------------------------*/ +::method implementation + -- this is a singleton + return .DOMImplementation~implementation -::method init - use strict arg data - self~nodeName = '#comment' - self~nodeType = 8 - self~nodeValue = data +::method createNodeIterator + expose iterators + use strict arg root, whatToShow, filter, entityReferenceExpansion = .true -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/* Class: CDATASection */ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ + iterator = .NodeIterator~new(self, root, whatToShow, filter, entityReferenceExpansion) -::class CDATASection subclass Node public + if iterators = .nil then do + iterators = .list~new + end + iterators~append(iterator) + return iterator -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/* Class: CDATASection */ -/* Private methods */ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ +::method createTreeWalker + use strict arg root, whatToShow, filter, entityReferenceExpansion = .true + return .TreeWalker~new(root, whatToShow, filter, entityReferenceExpansion) +::method removeNodeIterator + expose iterators + use strict arg nodeIterator -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/* Class: CDATASection */ -/* Public methods */ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ + if nodeIterator == .nil | iterators == .nil then do + return + end + iterators~remove(iterator) -/*----------------------------------------------------------------------------*/ -/* Method: init */ -/* Description: instance initialization. */ -/*----------------------------------------------------------------------------*/ +::method createRange + expose ranges + if ranges == .nil then do + ranges = .list~new + end + range = .range~new(self) + ranges~append(range) + return range + +::method removeRange + expose ranges + use strict arg range + if range == .nil | ranges == .nil then do + return + end + ranges~removeItem(range) + +::method replacedText + expose ranges + use strict arg node + + if rang... [truncated message content] |
From: <bi...@us...> - 2012-06-16 22:58:33
|
Revision: 7907 http://oorexx.svn.sourceforge.net/oorexx/?rev=7907&view=rev Author: bigrixx Date: 2012-06-16 22:58:26 +0000 (Sat, 16 Jun 2012) Log Message: ----------- some more cleanup and a tiny start on unit tests Modified Paths: -------------- incubator/orxutils/xml/xmldom.cls Added Paths: ----------- incubator/orxutils/xml/element.testgroup Added: incubator/orxutils/xml/element.testgroup =================================================================== --- incubator/orxutils/xml/element.testgroup (rev 0) +++ incubator/orxutils/xml/element.testgroup 2012-06-16 22:58:26 UTC (rev 7907) @@ -0,0 +1,64 @@ +#!/usr/bin/rexx +/* + SVN Revision: $Rev: 3371 $ + Change Date: $Date: 2008-09-21 00:33:29 -0400 (Sun, 21 Sep 2008) $ +*/ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2005-2010 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 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. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS 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 COPYRIGHT */ +/* OWNER OR 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. */ +/* */ +/*----------------------------------------------------------------------------*/ + parse source . . fileSpec; + + group = .TestGroup~new(fileSpec) + group~add(.element.testGroup) + + if group~isAutomatedTest then return group + + testResult = group~suite~execute~~print + +return testResult +-- End of entry point. + +::requires "ooTest.frm" -- load the ooRexxUnit classes +::requires "xmldom.cls" + +::class "element.testGroup" subclass ooTestCase public + +::method testBaseElement + dom = .DomImplementation~implementation + doc = dom~createDocument + + element = doc~createElement("FOO") + Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-16 18:44:08 UTC (rev 7906) +++ incubator/orxutils/xml/xmldom.cls 2012-06-16 22:58:26 UTC (rev 7907) @@ -48,65 +48,8 @@ /* */ /*----------------------------------------------------------------------------*/ - - /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: DOMImplementation */ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ - -::class DOMImplementation public - - -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/* Class: DOMImplementation */ -/* Private methods */ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ - -::attribute ver get private - -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/* Class: DOMImplementation */ -/* Public methods */ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ - - -/*----------------------------------------------------------------------------*/ -/* Method: init */ -/* Description: instance initialization. */ -/*----------------------------------------------------------------------------*/ - -::method init - expose ver - use strict arg - ver = .directory~new - ver['1.0'] = .directory~new - -/*----------------------------------------------------------------------------*/ -/* Method: hasFeature */ -/* Description: return boolean indicator for a specified feature. */ -/*----------------------------------------------------------------------------*/ - -::method hasFeature - expose ver - use strict arg feature, version = (.nil) - if version = .nil then do featureset over ver - if featureset[feature] <> .nil then return .true - end - else do - featureset = self~feature[version] - if featureset <> .nil, featureset[feature] <> .nil then return .true - end - return .false - - -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ /* Class: NodeList */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ @@ -178,7 +121,7 @@ /*----------------------------------------------------------------------------*/ -::class DeepNodeList subclass NodeList +::class DeepNodeList subclass NodeList public ::method init expose rootNode tagName changes nodes nsName @@ -625,7 +568,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "AttributeMap" subclass NamedNodeMap +::class "AttributeMap" subclass NamedNodeMap public ::method init expose hasDefaults use strict arg ownerNode, defaults = . nil @@ -829,12 +772,12 @@ ::METHOD init expose ownerNode childNodes nodeId - use strict arg ownerNode + use strict arg ownerNode = .nil nodeId = self~class~getId childNodes = .NodeList~new self~owned = .false -- unowned until we are added as a child self~readonly = .false -- newly created nodes can be altered - self~firstChild = .false -- not attached yet, so can't be first + self~isFirstChild = .false -- not the first child until added to something. ::ATTRIBUTE nodeName GET -- superclasses overrid @@ -851,7 +794,6 @@ -- the nodes implement the NodeList methods directly, so -- all we need to do is return ourself return self --- superclasses override ::ATTRIBUTE firstChild GET return .nil -- superclasses override @@ -859,10 +801,8 @@ return .nil -- superclasses override ::ATTRIBUTE previousSibling GET - return .nil -- superclasses override ::ATTRIBUTE nextSibling GET - return .nil -- superclasses override ::ATTRIBUTE attributes GET return .nil @@ -1068,7 +1008,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "ChildNode" subclass Node +::class "ChildNode" subclass Node public ::method init expose previousSibling nextSibling forward class(super) continue @@ -1109,14 +1049,14 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "ParentNode" subclass ChildNode +::class "ParentNode" subclass ChildNode public ::method init expose firstChild lastChild ownerDocument childNodes forward class(super) continue -- set this explicitly - use strict arg ownerDocument - self~clearChildNodes + use strict arg ownerDocument = .nil + self~clearChildren ::method clearChildren private expose firstChild lastChild childNodes @@ -1175,7 +1115,7 @@ end -- inform the owner that this is happening - ownerDocment~insertingNode(this, replace) + ownerDocument~insertingNode(this, replace) -- make sure we've detached this node from any previous -- parent node. @@ -1420,12 +1360,12 @@ /* Class: Document */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "Document" subclass Node +::class "Document" subclass ParentNode public ::method init - expose iterators ranges eventListeners + expose iterators ranges eventListeners grammarAccess doctype use arg doctype = .nil, grammarAccess = .false - self~init:super(doctype, grammarAccess) + self~init:super iterators = .nil ranges = .nil eventListeners = .nil @@ -2129,7 +2069,7 @@ ::method renamedAttrNode ::method renamedElement -::class EventListener +::class EventListener public ::method init expose type useCapture listener use strict arg type, listener, useCapture @@ -2159,7 +2099,7 @@ return -- all errors are just ignored -::class EventTracker +::class EventTracker public ::method init expose captures total bubble total @@ -2193,7 +2133,7 @@ bubbles -= 1 end -::class enclosingAttr +::class enclosingAttr public ::method init expose node oldValue use strict arg node, oldValue @@ -2207,7 +2147,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "Attr" subclass Node +::class "Attr" subclass Node public ::method init expose value name textNode namespaceURI localName type value = .nil @@ -2740,7 +2680,9 @@ else if arg() == 3 then do use strict arg ownerDoc, namespaceURI, nodeName self~init:super(ownerDoc) - self~setName(nodeName) + if nodeName \= .nil then do + self~setName(nodeName) + end end else do use strict arg ownerDoc, namespaceURI, nodeName, localName @@ -3296,7 +3238,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "CharacterData" subclass ChildNode +::class "CharacterData" subclass ChildNode public ::method init expose data use strict arg ownerDocument, data @@ -3398,7 +3340,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class Text subclass CharacterData +::class Text subclass CharacterData public ::attribute nodeType GET use strict arg @@ -3738,7 +3680,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "EntityReference" subclass ParentNode +::class "EntityReference" subclass ParentNode public ::method init expose name baseURI use strict arg ownerDoc, name @@ -3826,23 +3768,24 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: CoreDOMImplementation */ +/* Class: DOMImplementation */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "CoreDOMImplementation" +::class "DOMImplementation" public ::method init class expose singleton - singleton = self~new + singleton = .nil -::attribute DOMImplementation GET class +::attribute implementation GET class expose singleton use strict arg + if singleton == .nil then do + singleton = .DOMImplementation~new + end + return singleton -::method init - - ::method hasFeature use strict arg feature, version = .nil @@ -3908,17 +3851,17 @@ end end - +-- create a document node ::method createDocument use strict arg namespaceURI = .nil, qualifiedName = .nil, doctype = .nil - if doctype \= .nil & doctype~ownerDocument \= .nil then do + if doctype \= .nil, doctype~ownerDocument \= .nil then do .DomErrors~raiseError(.DomErrors~WRONG_DOCUMENT_ERR) end doc = .CoreDocument~new(doctype) - if qualitifedName \= .nil | namespaceURI \= .nil then do + if qualifiedName \= .nil | namespaceURI \= .nil then do element = doc~createElementNS(namespaceURI, qualifiedName) doc~appendChild(element) end @@ -3939,7 +3882,7 @@ return .nil -::class DOMErrors +::class DOMErrors public ::constant HIERARCHY_REQUEST_ERR "An attempt was made to insert a node where it is not permitted." ::constant INDEX_SIZE_ERR "The index or size is negative, or greater than the allowed value." ::constant INUSE_ATTRIBUTE_ERR "An attempt is made to add an attribute that is already in use elsewhere." @@ -3971,7 +3914,7 @@ /* Class: DOMEvent */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class DOMEvent +::class DOMEvent public ::method init expose initialized target eventPhase currentTarget timeStamp stopPropagation preventDefault initialized = .false @@ -4004,7 +3947,7 @@ use strict arg preventDefault = .true -::class MutationEvent subclass DOMEvent +::class MutationEvent subclass DOMEvent public ::constant DOM_SUBTREE_MODIFIED "DOMSubtreeModified" ::constant DOM_NODE_INSERTED "DOMNodeInserted" ::constant DOM_NODE_REMOVED "DOMNodeRemoved" @@ -4039,7 +3982,7 @@ /* Class: NodeFilter */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "NodeFilter" mixinclass Object +::class "NodeFilter" mixinclass Object public -- constants returned by acceptNode ::constant FILTER_ACCEPT 1 ::constant FILTER_REJECT 2 @@ -4100,7 +4043,7 @@ /* Class: NodeIterator */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "NodeIterator" +::class "NodeIterator" public ::method init expose document root currentNode whatToShowFlags whatToShow nodeFilter entityReferenceExpansion forward use strict arg document, root, whatToShow = (.NodeFilter~SHOW_ALL), nodeFilter = .nil, entityReferenceExpansion = .false @@ -4336,7 +4279,7 @@ /* Class: Range */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "Range" +::class "Range" public ::constant START_TO_START 0 ::constant START_TO_END 1 ::constant END_TO_END 2 @@ -5506,7 +5449,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "TreeWalker" +::class "TreeWalker" public ::method init expose currentNode root whatToShow nodeFilter entityReferenceExpansion whatToShowFlags use strict arg root, self~whatToShow, nodeFilter, entityReferenceExpansion @@ -5829,3 +5772,611 @@ end end +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: CoreDocument */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +::class "CoreDocument" subclass Document public +::method init + expose docType docElement encoding actualEncoding version standalone documentURI - + userdata identifiers domNormalizer configuration xpathEvaluator changes - + allowGrammerAccess errorChecking documentNumber nodeCounter nodeTable + use strict arg docType = .nil, grammarAccess = .false + self~init:super(.nil) + self~ownerDocument = self + + docElement = .nil + encoding = .nil + actualEncoding = .nil + version = .nil + standalone = .false + documentURI = .false + userData = .nil + identifiers = .nil + domNormalizer = .nil + configuration = .nil + xpathEvaluator = .nil + changes = 0 + errorChecking = .true + documentNumber = 0 + nodeCounter = 0 + nodeTable = .nil + + -- if we have a document type, this gets appended as our first child + if docType \= .nil then do + docType~ownerDocument = self + appendChild(docType) + end + +::attribute ownerDocument GET + use strict arg + -- documents don't have an owner + return .nil + +::attribute nodeType GET + use strict arg + return .Node~DOCUMENT_NODE + +::attribute nodeName GET + use strict arg + return "#document" + +::method cloneNode + use strict arg deep = .false + newDoc = .CoreDocument~new + self~cloneDocument(newDoc, deep) + return newDoc + +::method cloneDocument private + expose identifers firstChild + use arg newDoc, deep + + if deep then do + reversedIdentifers = .nil + if identifiers \= .nil then do + reversedIdentifiers = .directory~new + -- create the table using the inverse look up logic + sup = identifiers~supplier + do while sup~available + reversedIdentifiers[sup~item] = sup~index + end + end + + -- now copy each of the children into the new document + child = firstChild + do while child \= .nil + newDoc~appendChild(newDoc~importDocNode(child, .true, .true, reversedIdentifers)) + end + end + + newDoc~allowGrammarAccess = self~allowGrammarAccess + newDoc~errorChecking = self~errorChecking + +::method insertBefore + expose docElement docType + use strict arg newChild, refChild + + type = newChild~nodeType + -- if this is a DocumentType node, then make ourselves the owner + if newChild~ownerDocument == .nil & newChild~isA(.DocumentType) then do + newChild~ownerDocument = self + end + -- do a normal insert + self~insertBefore:super(newChild, refChild) + -- we only have two types of children, so cache each of + -- type types + if type == .Node~ELEMENT_NODE then do + docElement = newChild + end + else if type == .Node~DOCUMENT_TYPE_NODE then do + docType = newChild + end + return newChild + +::method removeChild + expose docElement docType + use strict arg oldChild + + self~removeChild:super(oldChild) + + type = oldChild~ELEMENT_NODE + + if type = .Node~ELEMENT_TYPE then do + docElement = .nil + end + else if type = .Node~DOCUMENT_TYPE_NODE then do + docType = .nil + end + return oldChild + +::method replaceChild + expose docElement docType + use strict arg newChild, oldChild + + -- if this is a DocumentType node, then make ourselves the owner + if newChild~ownerDocument == .nil & newChild~isA(.DocumentType) then do + newChild~ownerDocument = self + end + + self~replaceChild:super(newChild, oldChild) + + type = oldChild~ELEMENT_NODE + + if type = .Node~ELEMENT_TYPE then do + docElement = .newChild + end + else if type = .Node~DOCUMENT_TYPE_NODE then do + docType = .newChild + end + return oldChild + +::attribute textContent GET + use strict arg + return .nil + +::attribute textContent SET + use strict arg value + -- this is a NOP + +::method getFeature + expose xpathEvaluator + use strict arg feature, version = .nil + + anyVersion = version == .nil | version == "" + + if feature~caselessEquals("+XPath") & (anyVersion | version == "3.0") then do + if xpathEvaluator == .nil then do + xpathEvaluator = .XPathEvaluator~new(self) + end + return xpathEvaluator + end + + return self~getFeature:super(feature, version) + +-- Document factory methods + +::method createAttribute + use strict arg name + return .Attr~new(self, name) + +::method createAttributeNS + if arg() == 2 then do + use strict arg namespaceURI, qualifiedName + return .Attr~new(self, namespaceURI, qualifiedName) + end + else do + use strict arg namespaceURI, qualifiedName, localName + return .Attr~new(self, namespaceURI, qualifiedName, localName) + end + +::method createCDATASection + use strict arg data + return .CDATASection~new(self, data) + +::method createComment + use strict arg data + return .Comment~new(self, data) + +::method createDocumentFragment + use strict arg + return .DocumentFragment~new(self) + +::method createElement + use strict arg tagname + return .Element~new(self, tagname) + +::method createElementNS + if arg() == 2 then do + use strict arg namespaceURI, qualifiedName + return .Element~new(self, namespaceURI, qualifiedName) + end + else do + use strict arg namespaceURI, qualifiedName, localName + return .Element~new(self, namespaceURI, qualifiedName, localName) + end + +::method createEntityReference + use strict arg name + return .EntityReference~new(self, name) + +::method createProcessingInstruction + use strict arg target, data + return .ProcessingInstruction~new(self, target, data) + +::method createTextNode + use strict arg data + return .Text~new(self, data) + +::attribute docType GET +::attribute documentElement GET + expose docElement + use strict arg + return docElement + +::method getElementsByTagName + use strict arg tagName + return .DeepNodeList~new(self, tagname) + +::method getElementsByTagNameNS + use strict arg namespaceURI, localName + return .DeepNodeList~new(self, namespaceURI, localName) + +::method getImplementation + use strict arg + + return .DomImplementation~getDOMImplementation + +::attribute errorChecking +::attribute strictErrorChecking + +::attribute inputEncoding +::attribute xmlEncoding + +::attribute documentURI + +::method createDocumentType + use strict arg qualifiedName, publicID, systemID + + return .DocumentType~new(self, qualifiedName, publicID, systemID) + +::method createEntity + use strict arg name + return .Entity~new(self, name) + +::method createNotation + use strict arg name + return .Notation~new(self, name) + +::method importNode + use strict arg source, deep = .false + return self~importDocNode(source, deep, .false, .nil) + +::method importDocNode private + expose identifiers + use strict arg source, deep, cloningDoc, reversedIdentifiers + + newNode = .nil + type = source~nodeType + select + when type == .Node~ELEMENT_NODE then do + if source~localName == .nil then do + newElement = self~createElement(source~nodeName) + end + else do + newElement = self~createElementNS(source~namespaceURI, source~nodeName) + end + -- we need to copy the attributes for the element here...other + -- children are handled below + sourceAttrs = source~attributes + if sourceAttrs \= .nil then do + do attr over sourceAttrs + if attr~isSpecified | cloningDoc then do + -- if we're just importing, ignore the default attributes. + newAttr = self~importNode(attr, .true, cloningDoc, reversedIdentifiers) + if attr~localName == .nil then do + newElement~setAttributeNode(newAttr) + end + else do + newElement~setAttributeNodeNS(newAttr) + end + end + end + end + -- have a reversed identifer table? We need to check if + -- the element has an identifier and fix this up + if reversedIdentifiers \= .nil then do + elementId = reversedIdentifers[source] + if elementId \= .nil then do + if identifiers == .nil then do + identifers = .table~new + end + identifiers[elementId] = newElement + end + end + newNode = newElement + end + when type == .Node~ATTRIBUTE_NODE then do + if source~localName == .nil then do + newNode = self~createAttribute(source~nodeName) + end + else do + newNode = self~createAttributeNS(source~namespaceURI, source~nodeName) + end + -- we'll do a deep copy, unless this can be avoided in the simple + -- cases + deep = .true + -- if we have a string value, we can just copy that and + -- avoid doing the deep copy + if attr~hasStringValue then do + newNode~value = attr~value + deep = .false + end + end + when type == .Node~TEXT_NODE then do + newNode = self~createTextNode(source~nodeValue) + end + when type == .Node~CDATA_SECTION_NODE then do + newNode = self~createCDATASection(source~nodeValue) + end + when type == .Node~ENTITY_REFERENCE_NODE then do + newNode = self~createEntityReference(source~nodeName) + -- createEntityReference copies the subtree, so + -- disable the deep copy operation + deep = .false + end + when type == .Node~ENTITY_NODE then do + newNode = self~createEntity(source~nodeName) + newNode~publicId = source~publicId + newNode~systemId = source~systemId + newNode~notationName = source~notationName + -- the children need to be copied also...to do this, + -- we need to make the entity writeable + newNode = readOnly = .false + end + when type == .Node~PROCESSING_INSTRUCTION_NODE then do + newNode = self~createProcessingInstruction(source~nodeName, source~nodeValue) + end + when type == .Node~COMMENT_NODE then do + newNode = self~createComment(source~nodeValue) + end + when type == .Node~DOCUMENT_TYPE_NODE then do + newNode = self~createDocumentType(source~nodeName, source~publicId, source~systemId) + newNode~internalSubset = source~internalSubset + sourceMap = source~entities + newMap = newNode~entities + -- copy all of the entities, if thee are any + if sourceMap \= .nil then do + do item over sourceMap + newMap~setNamedItem(self~importNode(item, .true, .true, reversedIdentifers)) + end + end + sourceMap = source~notations + newMap = newNode~notations + -- copy all of the notations, if thee are any + if sourceMap \= .nil then do + do item over sourceMap + newMap~setNamedItem(self~importNode(item, .true, .true, reversedIdentifers)) + end + end + end + when type == .Node~DOCUMENT_FRAGMENT_NODE then do + newNode = self~createDocumentFragment + end + when type == .Node~NOTATION_NODE then do + newNode = self~createNotation(source~nodeName) + newNode~publicId = source~publicId + newNode~systemId = source~systemId + end + when type == .Node~DOCUMENT_NODE then do + .DomErrors~raiseError(.DomErrors~NOT_SUPPORTED_ERR) + end + otherwise do + .DomErrors~raiseError(.DomErrors~NOT_SUPPORTED_ERR) + end + end + + -- do we need to copy the child nodes too? + if deep then do + child = source~firstChild + do while child \= .nil + newNode~appendChild(self~importNode(child, .true, cloningDoc, reversedIdentifiers)) + end + end + + if newNode~nodeType == .Node~ENTITY_NODE then do + newNode~readOnly = .true + end + return newNode + +::method adoptNode + expose docType + use strict arg source + + if source == .nil then do + return .nil + end + + type = source~nodeType + + select + when type == .Node~ATTRIBUTE_NODE then do + -- detach from the owner if this is owned + if source~ownerDocument \= .nil then do + source~ownerElement~removeAttributeNode(source) + end + -- this is now specified, since it's no longer + -- derived from a default associated with an element + source~specified = .true + -- change the owner + source~ownerDocument = self + end + when type == .Node~ENTITY_NODE | type == .Node~NOTATION_NODE then do + .DomErrors~raiseError(.DomErrors~NO_MODIFICATION_ALLOWED_ERR) + end + when type == .Node~DOCUMENT_NODE | type == .Node~DOCUMENT_TYPE_NODE then do + .DomErrors~raiseError(.DomErrors~NOT_SUPPORTED_ERR) + end + when type == .Node~ENTITY_REFERENCE_NODE then do + parent = source~parentNode + if parent \= .nil then do + parent~removeChild(source) + end + -- remove the replacement value + child = source~firstChild + do while child \= .nil + source~removeChild(child) + child = source~firstChild + end + + source~ownerDocument = self + if docType \= .nil then do + entities = docType~entities + entityNode = entities~getNamedItem(source~nodeName) + if entityNode \= .nil then do + child = entityNode~firstChild + do while child \= .nil + newChild = child~cloneNode(.true) + source~appendChild(newChild) + child = child~nextSibling + end + end + end + end + when type == .Node~ELEMENT_NODE then do + parent = source~parentNode + if parent \= .nil then do + parent~removeChild(source) + end + source~ownerDocument = self + end + otherwise do + parent = source~parentNode + if parent \= .nil then do + parent~removeChild(source) + end + source~ownerDocument = self + end + end + -- return the adopted node + return source + +::method getElementById + use strict arg id + + return self~getIdentifer(id) + +::method getIdentifier + expose identifers + use strict arg id + if identifers == .nil then do + return .nil + end + + element = identifers[id] + if element \= .nil then do + parent = element~parentNode + do while parent \= .nil + if parent == self then do + return element + end + parent = parent~parentNode + end + end + + return .nil + +::method clearIdentifiers private + expose identifers + if identifers \= .nil then do + identifiers~empty + end + +::method putIdentifier + expose identifiers + use strict arg name, element + + if element == .nil then do + self~removeIdentifier(name) + end + else do + if identifiers == .nil then do + identifiers = .directory~new + end + identifers[name] = element + end + +::method removeIdentifier + expose identifiers + use strict arg name + if identifiers == .nil then do + return + end + + identifers~remove(name) + +::method identifiers + if identifiers == .nil then do + identifiers = .directory~new + end + + return identifers~allIndexes + +::method copy + use strict arg + newDoc = self~copy:super() + + newDoc~docType = .nil + newDoc~docElement = .nil + return newDoc + +::method changed + expose changes + changes += 1 + +::method addEventListener + use strict arg node, type, listener, useCapture + -- this is a nop + +::method removeEventListener + use strict arg node, type, listener, useCapture + +::method copyEventListeners + use strict arg source, target + +::method dispatchEvent + use strict arg node, event + +::method replacedText + use strict arg node + +::method deletedText + use strict arg node, offset, count + +::method insertedText + use strict arg node, offset, count + +::method modifyingCharacterData + use strict arg node, replace + +::method modifiedCharacterData + use strict arg node, oldValue, value, replace + +::method insertingNode + use strict arg node, replace + +::method insertedNode + use strict arg node, newInternal, replace + +::method removingNode + use strict arg node, oldChild, replace + +::method removedNode + use strict arg node, replace + +::method replacingNode + use strict arg node + +::method replacedNode + use strict arg node + +::method replacingData + use strict arg node + +::method replacedCharacterData + use strict arg node, oldValue, value + +::method modifiedAttrValue + use strict arg attr, oldValud + +::method setAttrNode + use strict arg attr, previous + +::method removedAttrNode + use strict arg attr, oldOwner, name + +::method renamedAttrNode + use strict arg oldAttr, newAttr + +::method renamedElement + use strict arg oldElement, newElement This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-18 14:46:59
|
Revision: 7920 http://oorexx.svn.sourceforge.net/oorexx/?rev=7920&view=rev Author: bigrixx Date: 2012-06-18 14:46:52 +0000 (Mon, 18 Jun 2012) Log Message: ----------- more element tests and some fixes Modified Paths: -------------- incubator/orxutils/xml/element.testgroup incubator/orxutils/xml/xmldom.cls Modified: incubator/orxutils/xml/element.testgroup =================================================================== --- incubator/orxutils/xml/element.testgroup 2012-06-18 12:14:16 UTC (rev 7919) +++ incubator/orxutils/xml/element.testgroup 2012-06-18 14:46:52 UTC (rev 7920) @@ -55,25 +55,40 @@ ::requires "xmldom.cls" ::class "element.testGroup" subclass ooTestCase public +::method init + expose dom document + forward class(super) continue + dom = .DomImplementation~implementation + document = dom~createDocument +::attribute dom +::attribute document + ::method testBaseElement - dom = .DomImplementation~implementation - doc = dom~createDocument + doc = self~document element = doc~createElement("FOO") self~assertTrue(element~isA(.Element)) self~assertTrue(element~isA(.Node)) self~assertNull(element~namespaceURI) --- self~assertEquals("FOO", element~localName) + self~assertEquals("FOO", element~localName) self~assertEquals(.node~ELEMENT_NODE, element~nodeType) self~assertEquals("FOO", element~nodeName) self~assertEquals("FOO", element~tagName) self~assertNull(element~baseURI) + self~assertNull(element~prefix) self~assertEquals("", element~getAttribute("XYZ")) self~assertNull(element~getAttributeNode("XYZ")) self~assertFalse(element~hasAttributes) self~assertFalse(element~hasAttribute("XYZ")) self~assertEquals(0, element~childElementCount) + self~assertNull(element~firstElementChild) + self~assertNull(element~lastElementChild) + attrs = element~attributes + self~assertEquals(0, attrs~length) + self~assertEquals(0, attrs~items) + self~assertNull(element~nextElementSibling) + self~assertNull(element~previousElementSibling) Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-18 12:14:16 UTC (rev 7919) +++ incubator/orxutils/xml/xmldom.cls 2012-06-18 14:46:52 UTC (rev 7920) @@ -110,10 +110,14 @@ use strict arg return nodes~copy -- make sure this is a copy +-- some compatibility methods to make nodelist feel like a Rexx collection ::method "[]" - return message("ITEM") + forward message("ITEM") +::method items + forward message("LENGTH") + /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Class: DeepNodeList */ @@ -550,6 +554,9 @@ return 0; end +::attribute attributes PRIVATE + +-- some convience methods for Rexx collection appearances ::method makearray expose attributes use strict arg @@ -558,7 +565,8 @@ ::method "[]" forward message("ITEM") -::attribute attributes PRIVATE +::method items + forward message("LENGTH") /*----------------------------------------------------------------------------*/ @@ -571,7 +579,7 @@ ::class "AttributeMap" subclass NamedNodeMap public ::method init expose hasDefaults - use strict arg ownerNode, defaults = . nil + use strict arg ownerNode, defaults = .nil self~init:super(ownerNode) hasDefaults = .false @@ -586,7 +594,7 @@ ::method setNamedItem use strict arg attribute - -- replaceing an attribute with itself does nothing + -- replacing an attribute with itself does nothing if attribute~isOwned then do return attribute end @@ -775,7 +783,7 @@ use strict arg ownerNode = .nil nodeId = self~class~getId childNodes = .NodeList~new - self~owned = .false -- unowned until we are added as a child + self~isowned = .false -- unowned until we are added as a child self~readonly = .false -- newly created nodes can be altered self~isFirstChild = .false -- not the first child until added to something. @@ -815,7 +823,7 @@ expose ownerDocument ownerNode -- if we're a child node, then ask our owner for the information - if self~owned then do + if self~isowned then do return ownerNode~ownerDocument end else do @@ -827,7 +835,7 @@ expose ownerNode use strict arg doc - if \self~owned then do + if \self~isowned then do ownerNode = doc end @@ -848,7 +856,7 @@ return .nil -- private attributes used for the implementation -::ATTRIBUTE owned PRIVATE +::ATTRIBUTE isowned PRIVATE ::ATTRIBUTE readonly PRIVATE ::ATTRIBUTE isFirstChild PRIVATE @@ -863,7 +871,7 @@ -- make a copy of ourselves newNode = self~copy -- neither owned or readonly - newNode~owned = .false + newNode~isowned = .false newNode~readOnly = .false return newNode @@ -2676,19 +2684,26 @@ if arg() == 2 then do use strict arg ownerDoc, nodeName self~init:super(ownerDoc) + -- these are the same if not provided + localName = nodeName end else if arg() == 3 then do use strict arg ownerDoc, namespaceURI, nodeName self~init:super(ownerDoc) - if nodeName \= .nil then do - self~setName(nodeName) - end + -- decode the name to see if there is a prefix + self~setName(namespaceURI, nodeName) end else do - use strict arg ownerDoc, namespaceURI, nodeName, localName + use strict arg ownerDoc, namespaceURI, nodeName, temp self~init:super(ownerDoc) + -- decode the name to see if there is a prefix + self~setName(namespaceURI, nodeName) + -- the provided version overrides anything decoded from the qname + localName = temp + end +-- decode a qualified name into its elements ::method setName private expose namespaceURI localName use arg qname @@ -2705,7 +2720,8 @@ localName = qname end else do - parse var qname localName (colon1) (colon2 + 1) localName + parse var qname prefix (colon1) (colon2 + 1) localName + -- TODO: validate the name information with the ownerdoc end -- support for the Document renameNode method @@ -3123,6 +3139,7 @@ end node = node~nextLogicalSibling(node) end + return .nil ::attribute previousElementSibling GET @@ -3141,6 +3158,7 @@ end node = node~previousLogicalSibling(node) end + return .nil ::method getFirstElementChild private use strict arg node @@ -3194,7 +3212,7 @@ end return .nil -::method getNextLogicalSibling private +::method nextLogicalSibling private use arg node next = node~nextSibling @@ -3212,7 +3230,7 @@ return next -::method getPreviousLogicalSibling private +::method previousLogicalSibling private use arg node previous = node~previousSibling This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-19 00:33:53
|
Revision: 7925 http://oorexx.svn.sourceforge.net/oorexx/?rev=7925&view=rev Author: bigrixx Date: 2012-06-19 00:33:46 +0000 (Tue, 19 Jun 2012) Log Message: ----------- some attribute tests and a lot of bug fixes Modified Paths: -------------- incubator/orxutils/xml/element.testgroup incubator/orxutils/xml/xmldom.cls Modified: incubator/orxutils/xml/element.testgroup =================================================================== --- incubator/orxutils/xml/element.testgroup 2012-06-19 00:20:46 UTC (rev 7924) +++ incubator/orxutils/xml/element.testgroup 2012-06-19 00:33:46 UTC (rev 7925) @@ -91,4 +91,77 @@ self~assertNull(element~nextElementSibling) self~assertNull(element~previousElementSibling) + element~rename("BAR") + self~assertEquals("BAR", element~localName) + self~assertEquals("BAR", element~nodeName) + self~assertEquals("BAR", element~tagName) + element~prefix = "foo" + self~assertEquals("BAR", element~localName) + self~assertEquals("foo:BAR", element~nodeName) + self~assertEquals("foo:BAR", element~tagName) +::method testBaseAttribute + + doc = self~document + + element = doc~createElement("FOO") + + self~assertEquals("", element~getAttribute("XYZ")) + self~assertNull(element~getAttributeNode("XYZ")) + -- just make sure a remove on an empty list doesn't cause an error + element~removeAttribute("XYZ") + + element~setAttribute("ABC", "123") + -- the attribute list is created lazily...ensure the unknown + -- attributes are still unknown + + self~assertEquals("", element~getAttribute("XYZ")) + self~assertNull(element~getAttributeNode("XYZ")) + + -- now check the added attribute + self~assertEquals("123", element~getAttribute("ABC")) + self~assertEquals("123", element~getAttributeNode("ABC")~value) + + -- remove the added attribute + element~removeAttribute("ABC") + -- make sure it is really gone + self~assertEquals("", element~getAttribute("ABC")) + self~assertNull(element~getAttributeNode("ABC")) + -- set to a new value + element~setAttribute("ABC", "456") + + self~assertEquals("456", element~getAttribute("ABC")) + -- get the attribute node + attr = element~getAttributeNode("ABC") + + -- verify the parent child relationship + self~assertSame(element, attr~element) + self~assertSame(element, attr~ownerelement) + + -- change the attribute node value...this should show up + -- in the element + attr~value = "789" + + self~assertEquals("789", element~getAttribute("ABC")) + -- remove the attribute by the node + element~removeAttributeNode(attr) + -- should be done now + self~assertEquals("", element~getAttribute("ABC")) + -- this should not be owned now + self~assertNull(attr~element) + self~assertNull(attr~ownerelement) + -- add this back directly using the attribute node + element~setAttributeNode(attr) + self~assertEquals("789", element~getAttribute("ABC")) + + -- rename the attribute + attr~rename("DEF") + -- verify this renamed correctly + self~assertEquals("", element~getAttribute("ABC")) + self~assertEquals("789", element~getAttribute("DEF")) + + -- verify the parent child relationship + self~assertSame(element, attr~element) + self~assertSame(element, attr~ownerelement) + + Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-19 00:20:46 UTC (rev 7924) +++ incubator/orxutils/xml/xmldom.cls 2012-06-19 00:33:46 UTC (rev 7925) @@ -290,9 +290,12 @@ ::class 'NamedNodeMap' public ::method init - expose ownerNode attributes + expose ownerNode attributes hasDefaults changed readonly use strict arg ownerNode attributes = .nil + hasDefaults = .false + changed = .false + readonly = .false /*----------------------------------------------------------------------------*/ @@ -301,7 +304,25 @@ /* Private methods */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ +::method findItemPoint private + expose attributes + use arg item + if attributes == .nil then do + return .nil + end + + s = attributes~supplier + do while s~available + attr = s~item + if attr == item then do + return s~index + end + end + + return .nil + + ::method findNamePoint private expose attributes use arg name @@ -350,7 +371,12 @@ return .nil +::attribute ownerNode +::attribute hasDefaults +::attribute changed +::attribute readonly + /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Class: NamedNodeMap */ @@ -639,7 +665,7 @@ if index \= .nil then do previous = attributes[i] attributes[i] = attribute - previous~ownerNode = self~ownerNode~ownerDocument + previous~ownerNode = ownerNode~ownerDocument previous~isOwned = .false previous~isSpecified = .true end @@ -662,7 +688,7 @@ return .nil end - return self~remove(self~attributes[index], index, true) + return self~remove(self~attributes[index], index, .true) ::method removeNamedItemNS use strict arg namespaceURI, name @@ -672,15 +698,25 @@ return .nil end - return self~remove(self~attributes[index], index, true) + return self~remove(self~attributes[index], index, .true) +::method removeItem + use strict arg attr, addDefault + + index = self~findItemPoint(attr) + if index == .nil then do + return .nil + end + + return self~remove(attr, index, addDefault) + ::method remove private use strict arg attr, index, addDefault = .false - ownerDocument = self~ownerNode~ownderDocument + ownerDocument = self~ownerNode~ownerDocument name = attr~nodeName - if attr~isIdAttribue then do - ownerDocument~removeIdentifier(attr~value) + if attr~isId then do + self~ownerDocument~removeIdentifier(attr~value) end attributes = self~attributes @@ -699,15 +735,15 @@ if newAttr~localName \== .nil then do newAttr~namespaceURI = attr~namespaceURI end - newAttr~ownerNode = ownerNode - newAttr~isOwned = true + newAttr~ownerNode = self~ownerNode + newAttr~isOwned = .true -- mark this as a default value - newAttr~isSpecified = false + newAttr~isSpecified = .false attributes[index] = newAttr setdefault = .true -- if this is the id attribute, make sure the document knows -- about this mapping - if attr~isIdAttribute then do + if attr~isId then do ownerDocument~putIdentifier(newAttr~nodeValue, ownerNode) end end @@ -721,10 +757,10 @@ attr~ownerNode = .nil attr~isOwned = .false attr~isSpecified = .true - attr~isIdAttribute = false + attr~idAttribute = .false -- notify the document - ownerDocument~removedAttrNode(attr, ownerNode, name) + ownerDocument~removedAttrNode(attr, self~ownerNode, name) return attr ::method cloneContent @@ -740,7 +776,6 @@ end end - /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Class: Node */ @@ -786,6 +821,7 @@ self~isowned = .false -- unowned until we are added as a child self~readonly = .false -- newly created nodes can be altered self~isFirstChild = .false -- not the first child until added to something. + self~isOwned = .false -- not owned until attached ::ATTRIBUTE nodeName GET -- superclasses overrid @@ -819,6 +855,8 @@ use strict arg return .false +::attribute ownerNode + ::ATTRIBUTE ownerDocument GET expose ownerDocument ownerNode @@ -856,9 +894,9 @@ return .nil -- private attributes used for the implementation -::ATTRIBUTE isowned PRIVATE -::ATTRIBUTE readonly PRIVATE -::ATTRIBUTE isFirstChild PRIVATE +::ATTRIBUTE isowned +::ATTRIBUTE readonly +::ATTRIBUTE isFirstChild -- default implementations designed to be overridden ::METHOD hasChildNodes @@ -968,7 +1006,14 @@ use strict arg key raise syntax 93.963 -- not supported +-- handle mutation events +::method changed + self~ownerdocument~changed +::method changes + return self~ownerdocument~changes + + /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Class: Node */ @@ -1123,7 +1168,7 @@ end -- inform the owner that this is happening - ownerDocument~insertingNode(this, replace) + ownerDocument~insertingNode(self, replace) -- make sure we've detached this node from any previous -- parent node. @@ -1225,10 +1270,10 @@ self~insertBefore(newChild, oldChild, .true) if newChild !== oldChild then do - removeChild(oldChild, true) + removeChild(oldChild, .true) end - ownerDocument.replacedNode(this) + ownerDocument.replacedNode(self) return oldChild ::method textContent @@ -1370,13 +1415,14 @@ /*----------------------------------------------------------------------------*/ ::class "Document" subclass ParentNode public ::method init - expose iterators ranges eventListeners grammarAccess doctype + expose iterators ranges eventListeners grammarAccess doctype hasMutationEvents use arg doctype = .nil, grammarAccess = .false self~init:super iterators = .nil ranges = .nil eventListeners = .nil + hasMutationEvents = .false ::method cloneNode use strict arg deep = .false @@ -1487,7 +1533,7 @@ .DomErrors~raiseError(.DomErrors~NOT_SUPPORTED_ERR) end -::attribute mutationEvents +::attribute hasMutationEvents ::method setEventListeners expose eventListeners @@ -1500,12 +1546,12 @@ if listeners == .nil then do eventListeners~remove(node) if eventListeners~isEmpty then do - self~mutationEvents = .false + self~hasMutationEvents = .false end end else do eventListeners[node] = listeners - self~mutationEvents = .true + self~hasMutationEvents = .true end ::method getEventListeners @@ -1821,22 +1867,22 @@ end ::method modifyingCharacterData - expose mutationEvents + expose hasMutationEvents use strict arg node, replace - if mutationEvents then do + if hasMutationEvents then do if \replace then do self~saveEnclosingAttr(node) end end ::method modifiedCharacterData - expose mutationEvents savedEnclosingAttr + expose hasMutationEvents savedEnclosingAttr use strict arg node, oldValue, value, replace - if mutationEvents then do + if hasMutationEvents then do self~mutationEventsModifiedCharacterData(node, oldValue, value, replace) end @@ -1860,20 +1906,20 @@ self~modifiedCharacterData(node, oldvalue, value, .false) ::method insertingNode - expose mutationEvents + expose hasMutationEvents use strict arg node, replace - if mutationEvents then do + if hasMutationEvents then do if \replace then do self~saveEnclosingAttr(node) end end ::method insertedNode - expose mutationEvents ranges + expose hasMutationEvents ranges use strict arg node, newInternal, replace - if mutationEvents then do + if hasMutationEvents then do self~mutationEventsInsertedNode(node, newInternal, replace) end @@ -1931,7 +1977,7 @@ end ::method removingNode - expose iterators ranges mutationEvents + expose iterators ranges hasMutationEvents use strict arg node, oldChild, replace if iterators \= .nil then do @@ -1942,7 +1988,7 @@ self~notifyRangesRemovingNode(oldChild) end - if mutationEvents then do + if hasMutationEvents then do self~mutationEventsRemovingNode(node, oldChild, replace) end @@ -2000,51 +2046,51 @@ end ::method removedNode - expose mutationEvents savedEnclosingAttr + expose hasMutationEvents savedEnclosingAttr use strict arg node, replace - if mutationEvents then do + if hasMutationEvents then do if \replace then do self~dispatchAggregateEvents(node, savedEnclosingAttr~node, savedEnclosingAttr~oldValue) end end ::method replacingNode - expose mutationEvents + expose hasMutationEvents use strict arg node - if mutationEvents then do + if hasMutationEvents then do self~saveEnclosingAttr(node) end ::method replacingData - expose mutationEvents + expose hasMutationEvents use strict arg node - if mutationEvents then do + if hasMutationEvents then do self~saveEnclosingAttr(node) end ::method replacedNode - expose mutationEvents savedEnclosingAttr + expose hasMutationEvents savedEnclosingAttr use strict arg node - if mutationEvents then do + if hasMutationEvents then do self~dispatchAggregateEvents(node, savedEnclosingAttr~node, saveEnclosingAttr~oldValue) end ::method modifiedAttrValue - expose mutationEvents + expose hasMutationEvents use strict arg attr, oldValue - if mutationEvents then do + if hasMutationEvents then do self~dispatchAggregateEvents(attr, attr, oldvalue, .MutationEvent~MODIFICATION) end ::method setAttrNode - expose mutationEvents + expose hasMutationEvents use strict arg attr, previous - if mutationEvents then do + if hasMutationEvents then do if previous == .nil then do self~dispatchAggregateEvents(attr~ownerNode, attr, .nil, .MutationEvent~ADDITION) end @@ -2054,10 +2100,10 @@ end ::method removeAttrNode - expose mutationEvents + expose hasMutationEvents use strict arg attr, oldOwner, name - if mutationEvents then do + if hasMutationEvents then do self~mutationEventRemovedAttrNode(attr, oldOwner, name) end @@ -2157,12 +2203,13 @@ ::class "Attr" subclass Node public ::method init - expose value name textNode namespaceURI localName type + expose value name textNode namespaceURI localName type idAttribute value = .nil type = .nil textNode = .nil namespaceURI = .nil localName = .nil + idAttribute = .false if arg() == 2 then do use strict arg ownerDocument, name self~init:super(ownerDoc) @@ -2201,14 +2248,13 @@ -- support for the Document renameNode method ::method rename - expose nodeName namespaceURI use strict arg uri, name = .nil if name == .nil then do - nodeName = uri + self~nodeName = uri end else do - nodeName = name - namespaceURI = uri + self~nodeName = name + self~namespaceURI = uri self~setName(name) end @@ -2253,12 +2299,10 @@ end ::attribute idAttribute SET - use strict arg value - self~isIdAttribute = value ::method isId - use strict arg - return self~isIdAttribute + expose idAttribute + return idAttribute ::method cloneNode expose value @@ -2287,6 +2331,10 @@ use strict arg return name +::attribute nodeName SET + expose name + use strict arg name + ::attribute nodeValue SET forward message("VALUE=") ::attribute nodeValue GET @@ -2348,7 +2396,7 @@ -- we might need to process an old value if it's a serious of text nodes if value \= .nil then do - if self~ownerDocument~mutationEvents then do + if self~ownerDocument~hasMutationEvents then do if self~hasMutationEvents then do -- if we have a string value and we need to -- broadcast mutation events, then we need to @@ -2365,7 +2413,7 @@ value = textNode textNode~ownerNode = this textNode~isOwned = .true - self~removeChild(textNode, true) + self~removeChild(textNode, .true) end else do oldValue = self~value @@ -2391,17 +2439,17 @@ end self~isSpecified = .true - if self~ownerDocument~mutationEvents then do + if self~ownerDocument~hasMutationEvents then do self~insertBefore(self~ownerDocument~createTextNode(newValue), .nil, .true) self~hasStringValue = .false - self~ownerDocument~modifiedAttrValue(this, oldvalue) + self~ownerDocument~modifiedAttrValue(self, oldvalue) end else do value = newValue - self~changed() + self~changed end - if self~isIdAttribute & self~ownderElement \= .nil then do + if self~isId & self~ownerElement \= .nil then do self~ownerDocument~putIdentifier(newvalue, ownerElement) end @@ -2412,7 +2460,7 @@ if value == .nil then do return "" end - -- if already a string, then set it directly + -- if already a string, then return it directly if value~isA(.String) then do return value end @@ -2467,10 +2515,9 @@ ::attribute ownerElement GET forward message("ELEMENT") -::attribute specified GET - forward message("ISSPECIFIED") -::attribute specified SET - forward message("ISSPECIFIED=") +-- some attribute properties +::attribute hasStringValue +::attribute isSpecified ::method hasChildNodes expose value @@ -2528,7 +2575,7 @@ -- node self~makeChildNode - self~ownerDocument~insertingNode(this, replace) + self~ownerDocument~insertingNode(self, replace) -- detach from any existing parent node oldParent = newChild~parentNode @@ -2572,7 +2619,7 @@ -- record the change self~changed - self~ownerDocument~insertedNode(this, newNode, replace) + self~ownerDocument~insertedNode(self, newNode, replace) return newChild @@ -2584,7 +2631,7 @@ return .nil end - self~ownerDocument~removingNode(this, oldNode, replace) + self~ownerDocument~removingNode(self, oldNode, replace) -- removing the first? if oldNode == value then do @@ -2609,7 +2656,7 @@ self~changed - ownerDocument~removedNode(this, replace) + ownerDocument~removedNode(self, replace) return oldNode @@ -2620,7 +2667,7 @@ self~ownerDocument~replacingNode(self) self~insertBefore(newChild, oldChild, .true) if newChild \= oldChild then do - self~removeChild(oldChild, true) + self~removeChild(oldChild, .true) end self~ownerDocument~repacingNode(self) @@ -2730,6 +2777,7 @@ use strict arg uri, name = .nil if name == .nil then do nodeName = uri + self~setName(nodeName) end else do nodeName = name @@ -2775,7 +2823,7 @@ use strict arg if attributes == .nil then do - attributes = .AttributeMap~new(this, .nil) + attributes = .AttributeMap~new(self, .nil) end return attributes @@ -2805,10 +2853,10 @@ forward class(super) continue -- also set this for all of the attributes if attributes \= .nil then do - attributes~ownderDocument = doc + attributes~ownerDocument = doc end - +-- retrieve the value of a named attribute ::method getAttribute expose attributes @@ -2825,7 +2873,7 @@ return attr~value end - +-- get the node associated with a specific named attribute ::method getAttributeNode expose attributes @@ -2839,7 +2887,7 @@ ::method getElementsByTagName use strict arg tagname -- this version does a lazy search - return .DeepNodeList~new(this, tagname) + return .DeepNodeList~new(self, tagname) -- this is the same as the nodename for an element ::attribute tagname GET @@ -2848,48 +2896,43 @@ ::method removeAttribute expose attributes - ust strict arg name + use strict arg name - if attrbutes \= .nil then do + if attributes \= .nil then do attributes~removeNamedItem(name) end ::method removeAttributeNode expose attributes - ust strict arg oldAttr + use strict arg oldAttr if attrbutes \= .nil then do - attributes~removItem(oldAttr, .true) + attributes~removeItem(oldAttr, .true) end ::method setAttribute - expose attributes - use strict arg name, value - attr = self~getAttributeName(name) + newAttr = self~getAttributeNode(name) if newAttr == .nil then do - newAttr = getOwnerDocument().createAttribute(name) + -- get the attribute map. This also creates it if + -- we don't have one yet + attributes = self~attributes + newAttr = self~ownerDocument~createAttribute(name) - if attributes =- .nil then do - attributes = .AttributeMap~new(this) - end - - newAttr~nodeValue = value + newAttr~value = value attributes~setNamedItem(newAttr) end else do - newAttr~nodeValue = value + newAttr~value = value end ::method setAttributeNode - expose attributes - use strict arg newAttr - if attributes == .nil then do - attributes = .AttributeMap~new(this) - end + -- get the attribute map. This also creates it if + -- we don't have one yet + attributes = self~attributes return attributes~setNamedItem(newAttr) @@ -2924,14 +2967,13 @@ localName = qualifiedName end - newAttr = getAttributeNodeNS(namespaceURI, localName) + newAttr = self~getAttributeNodeNS(namespaceURI, localName) if newAttr == .nil then do - newAttr = self~getOwnerDocument ~createAttributeNS(namespaceURI, qualifiedName) + newAttr = self~ownerDocument~createAttributeNS(namespaceURI, qualifiedName) + -- get the attribute map. This also creates it if + -- we don't have one yet + attributes = self~attributes - if attributes == .nil then do - attributes = .AttributeMap~new(this) - end - newAttr~nodeValue = value attributes~setNameItemNS(newAttr) end @@ -2951,7 +2993,6 @@ attributes~removeNamedItemNS(namespaceURI, localName) ::method getAttributeNodeNS - expose attributes use strict arg namespaceURI, localName if attributes == .nil then do @@ -2964,9 +3005,9 @@ expose attributes use strict arg newAttr - if attributes == .nil then do - return - end + -- get the attribute map. This also creates it if + -- we don't have one yet + attributes = self~attributes return attributes~setNamedItemNS(newAttr) @@ -2991,12 +3032,12 @@ ::method getElementsByTagNameNS use strict arg namespaceURI, localName - return .DeepNodeList~new(this, localName, namespaceURI) + return .DeepNodeList~new(self, localName, namespaceURI) ::method setIdAttributeNode use strict arg at, makeId - at~isIdAttribute = makeId + at~idAttribute = makeId if makeId then do self~ownerDocument~putIdentifier(at~value, this) end @@ -3012,7 +3053,7 @@ return end - at~isIdAttribute makeId + at~idAttribute = makeId if makeId then do self~ownerDocument~putIdentifier(at~value, this) end @@ -3028,7 +3069,7 @@ return end - at~isIdAttribute makeId + at~idAttribute = makeId if makeId then do self~ownerDocument~putIdentifier(at~value, this) end @@ -5417,7 +5458,7 @@ node = b do while node \= .nil if node == a then do - return true + return .true end node = node~parentNode end @@ -6205,7 +6246,7 @@ end -- this is now specified, since it's no longer -- derived from a default associated with an element - source~specified = .true + source~isspecified = .true -- change the owner source~ownerDocument = self end This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-20 14:07:46
|
Revision: 7934 http://oorexx.svn.sourceforge.net/oorexx/?rev=7934&view=rev Author: bigrixx Date: 2012-06-20 14:07:35 +0000 (Wed, 20 Jun 2012) Log Message: ----------- start of textcontent tests and some more bug fixes Modified Paths: -------------- incubator/orxutils/xml/element.testgroup incubator/orxutils/xml/xmldom.cls Modified: incubator/orxutils/xml/element.testgroup =================================================================== --- incubator/orxutils/xml/element.testgroup 2012-06-19 23:21:02 UTC (rev 7933) +++ incubator/orxutils/xml/element.testgroup 2012-06-20 14:07:35 UTC (rev 7934) @@ -103,7 +103,6 @@ ::method testBaseAttribute doc = self~document - element = doc~createElement("FOO") self~assertEquals("", element~getAttribute("XYZ")) @@ -165,3 +164,22 @@ self~assertSame(element, attr~ownerelement) +-- various tests for child nodes +::method testChildren + + doc = self~document + element = doc~createElement("FOO") + + -- should be zero initially + self~assertEquals("", element~textContent) + + element~textContent = 123 + self~assertEquals(123, element~textContent) + + text = element~firstChild + + -- this should be a text node as the first child now + self~assertTrue(text~isA(.Text)) + self~assertTrue(text~isA(.Node)) + self~assertEquals(.node~TEXT_NODE, text~nodeType) + self~assertEquals(123, text~textContent) Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-19 23:21:02 UTC (rev 7933) +++ incubator/orxutils/xml/xmldom.cls 2012-06-20 14:07:35 UTC (rev 7934) @@ -54,7 +54,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class 'NodeList' public +::class "NodeList" public ::method init expose nodes -- we're a read-only list...the owning node returns the list, we work off @@ -125,7 +125,7 @@ /*----------------------------------------------------------------------------*/ -::class DeepNodeList subclass NodeList public +::class "DeepNodeList" subclass NodeList public ::method init expose rootNode tagName changes nodes nsName @@ -288,7 +288,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class 'NamedNodeMap' public +::class "NamedNodeMap" public ::method init expose ownerNode attributes hasDefaults changed readonly use strict arg ownerNode @@ -782,7 +782,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::CLASS 'Node' public +::CLASS "Node" public ::CONSTANT ELEMENT_NODE 1 ::CONSTANT ATTRIBUTE_NODE 2 ::CONSTANT TEXT_NODE 3 @@ -797,12 +797,12 @@ ::CONSTANT NOTATION_NODE 12 -- initialize a counter to give new nodes a unique id -::METHOD init class +::method init class expose ctr ctr = 0 -- get the next id for new nodes -::METHOD getId class private +::method getId class private expose ctr ctr += 1 return ctr @@ -813,7 +813,7 @@ /* Description: instance initialization. */ /*----------------------------------------------------------------------------*/ -::METHOD init +::method init expose ownerNode childNodes nodeId use strict arg ownerNode = .nil nodeId = self~class~getId @@ -822,42 +822,45 @@ self~readonly = .false -- newly created nodes can be altered self~isFirstChild = .false -- not the first child until added to something. self~isOwned = .false -- not owned until attached + self~isIgnorableWhitespace = .false -- only text nodes have this -::ATTRIBUTE nodeName GET --- superclasses overrid -::ATTRIBUTE nodeValue GET +::attribute isIgnorableWhitespace + +::attribute nodeName GET +-- superclasses override +::attribute nodeValue GET return .nil -::ATTRIBUTE nodeValue SET +::attribute nodeValue SET return -- default behavior is to do nothing...superclasses override this -::ATTRIBUTE nodeType GET +::attribute nodeType GET -- superclasses override -::ATTRIBUTE parentNode GET +::attribute parentNode GET return .nil -::ATTRIBUTE childNodes GET +::attribute childNodes GET use strict arg -- the nodes implement the NodeList methods directly, so -- all we need to do is return ourself return self -::ATTRIBUTE firstChild GET +::attribute firstChild GET return .nil -- superclasses override -::ATTRIBUTE lastChild GET +::attribute lastChild GET return .nil -- superclasses override -::ATTRIBUTE previousSibling GET +::attribute previousSibling GET -- superclasses override -::ATTRIBUTE nextSibling GET +::attribute nextSibling GET -- superclasses override -::ATTRIBUTE attributes GET +::attribute attributes GET return .nil -::METHOD hasAttributes +::method hasAttributes use strict arg return .false ::attribute ownerNode -::ATTRIBUTE ownerDocument GET +::attribute ownerDocument GET expose ownerDocument ownerNode -- if we're a child node, then ask our owner for the information @@ -869,7 +872,7 @@ return ownerNode end -::ATTRIBUTE ownerDocument SET PRIVATE +::attribute ownerDocument SET PRIVATE expose ownerNode use strict arg doc @@ -877,34 +880,34 @@ ownerNode = doc end -::ATTRIBUTE namespaceURI GET +::attribute namespaceURI GET use strict arg return .nil -::ATTRIBUTE prefix GET +::attribute prefix GET use strict arg return .nil -::ATTRIBUTE prefix SET +::attribute prefix SET -- this is an error by default .DomErrors~raiseError(.DomErrors~NAMESPACE_ERR) -::ATTRIBUTE localName GET +::attribute localName GET use strict arg return .nil -::ATTRIBUTE baseURI GET +::attribute baseURI GET use strict arg return .nil -- private attributes used for the implementation -::ATTRIBUTE isowned -::ATTRIBUTE readonly -::ATTRIBUTE isFirstChild +::attribute isowned +::attribute readonly +::attribute isFirstChild -- default implementations designed to be overridden -::METHOD hasChildNodes +::method hasChildNodes use strict arg return .false; -- base cloning method -::METHOD cloneNode +::method cloneNode use strict arg deep = .false -- make a copy of ourselves newNode = self~copy @@ -914,56 +917,56 @@ return newNode -::METHOD isSupported +::method isSupported use strict arg feature, version return .false -::METHOD insertBefore +::method insertBefore use strict arg newChild, refChild -- not implemented in the base node .DomErrors~raiseError(.DomErrors~Hierarchy_request_err) -::METHOD replaceChild +::method replaceChild use strict arg newChild, oldChild -- not implemented in the base node .DomErrors~raiseError(.DomErrors~Hierarchy_request_err) -::METHOD removeChild +::method removeChild use strict arg oldChild -- not implemented in the base node .DomErrors~raiseError(.DomErrors~Not_found_err) -::METHOD appendChild +::method appendChild use strict arg newChild return self~insertBefore(newChild, .nil) -::METHOD compareDocumentPosition +::method compareDocumentPosition use strict arg other raise syntax 93.963 -- not supported -::ATTRIBUTE textContent GET +::attribute textContent GET forward message("NODEVALUE") -::ATTRIBUTE textContent SET +::attribute textContent SET forward message("NODEVALUE=") -::METHOD isSameNode +::method isSameNode use strict arg other return self~identityHash = other~identityHash -::METHOD lookupPrefix +::method lookupPrefix use strict arg uri raise syntax 93.963 -- not supported -::METHOD isDefaultNamespace +::method isDefaultNamespace use strict arg uri raise syntax 93.963 -- not supported -::METHOD lookupNamespaceURI +::method lookupNamespaceURI use strict arg prefix raise syntax 93.963 -- not supported -::METHOD isEqualNode +::method isEqualNode use strict arg other if self == other then do @@ -994,15 +997,15 @@ return .false end -::METHOD getFeature +::method getFeature use strict arg feature, version return .nil -::METHOD setUserData +::method setUserData use strict arg key, date, handler raise syntax 93.963 -- not supported -::METHOD getUserData +::method getUserData use strict arg key raise syntax 93.963 -- not supported @@ -1053,7 +1056,7 @@ return .array~new(0) ::method "[]" - return message("ITEM") + forward message("ITEM") /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ @@ -1276,7 +1279,7 @@ ownerDocument.replacedNode(self) return oldChild -::method textContent +::attribute textContent GET use strict arg child = self~firstChild @@ -1308,16 +1311,16 @@ child = child~nextSibling end -::method hasTextContext private +::method hasTextContent private use arg child type = child~nodeType - if type \= .Node~COMMENT_NODE && - - child \= .Node~PROCESSING_INSTRUCTION_NODE && - - child \= .Node~TEXT_NODE then do + if type \= .Node~COMMENT_NODE & - + type \= .Node~PROCESSING_INSTRUCTION_NODE & - + type \= .Node~TEXT_NODE then do return .false end - return \child~isIgnorableWhilespace + return \child~isIgnorableWhitespace ::attribute textContent SET use strict arg text @@ -1371,7 +1374,7 @@ /* Class: DocumentFragment */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class 'DocumentFragment' public subclass ParentNode +::class "DocumentFragment" public subclass ParentNode ::attribute nodeType GET return .Node~DOCUMENT_FRAGMENT_NODE @@ -2123,7 +2126,7 @@ ::method renamedAttrNode ::method renamedElement -::class EventListener public +::class "EventListener" public ::method init expose type useCapture listener use strict arg type, listener, useCapture @@ -2153,7 +2156,7 @@ return -- all errors are just ignored -::class EventTracker public +::class "EventTracker" public ::method init expose captures total bubble total @@ -2187,7 +2190,7 @@ bubbles -= 1 end -::class enclosingAttr public +::class "EnclosingAttr" public ::method init expose node oldValue use strict arg node, oldValue @@ -3399,7 +3402,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class Text subclass CharacterData public +::class "Text" subclass CharacterData public ::attribute nodeType GET use strict arg @@ -3603,7 +3606,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class DocumentType subclass Node public +::class "DocumentType" subclass Node public /*----------------------------------------------------------------------------*/ @@ -3941,7 +3944,7 @@ return .nil -::class DOMErrors public +::class "DOMErrors" public ::constant HIERARCHY_REQUEST_ERR "An attempt was made to insert a node where it is not permitted." ::constant INDEX_SIZE_ERR "The index or size is negative, or greater than the allowed value." ::constant INUSE_ATTRIBUTE_ERR "An attempt is made to add an attribute that is already in use elsewhere." @@ -3973,7 +3976,7 @@ /* Class: DOMEvent */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class DOMEvent public +::class "DOMEvent" public ::method init expose initialized target eventPhase currentTarget timeStamp stopPropagation preventDefault initialized = .false @@ -4006,7 +4009,7 @@ use strict arg preventDefault = .true -::class MutationEvent subclass DOMEvent public +::class "MutationEvent" subclass DOMEvent public ::constant DOM_SUBTREE_MODIFIED "DOMSubtreeModified" ::constant DOM_NODE_INSERTED "DOMNodeInserted" ::constant DOM_NODE_REMOVED "DOMNodeRemoved" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-20 21:13:12
|
Revision: 7935 http://oorexx.svn.sourceforge.net/oorexx/?rev=7935&view=rev Author: bigrixx Date: 2012-06-20 21:13:06 +0000 (Wed, 20 Jun 2012) Log Message: ----------- more textcontent work Modified Paths: -------------- incubator/orxutils/xml/element.testgroup incubator/orxutils/xml/xmldom.cls Modified: incubator/orxutils/xml/element.testgroup =================================================================== --- incubator/orxutils/xml/element.testgroup 2012-06-20 14:07:35 UTC (rev 7934) +++ incubator/orxutils/xml/element.testgroup 2012-06-20 21:13:06 UTC (rev 7935) @@ -183,3 +183,23 @@ self~assertTrue(text~isA(.Node)) self~assertEquals(.node~TEXT_NODE, text~nodeType) self~assertEquals(123, text~textContent) + + newText = doc~createTextNode("ABC") + element~appendChild(newText) + + -- should be two text nodes now, and the text content + -- should concatenate the values + self~assertEquals("123ABC", element~textContent) + + -- this should remove all of the text nodes + element~textContent = "" + self~assertEquals("", element~textContent) + + -- now add back in and delete by assigning to .nil + element~textContent = "DEF" + self~assertEquals("DEF", element~textContent) + + -- this should remove all of the text nodes again + element~textContent = .nil + self~assertEquals("", element~textContent) + Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-20 14:07:35 UTC (rev 7934) +++ incubator/orxutils/xml/xmldom.cls 2012-06-20 21:13:06 UTC (rev 7935) @@ -1234,7 +1234,9 @@ -- removing the first child if oldChild == firstChild then do firstChild = firstChild~nextSibling - firstChild~previousSibling = .nil + if firstChild \= .nil then do + firstChild~previousSibling = .nil + end -- if this was the only child, then clear out everything if lastChild == oldChild then do lastChild = .nil @@ -1264,7 +1266,7 @@ -- note the change update self~changed - ownerDocument~removeNode(self, replace) + ownerDocument~removedNode(self, replace) return oldChild ::method replaceChild @@ -1295,18 +1297,22 @@ end else do buffer = .mutablebuffer~new - buildTextContent(buffer) + self~buildTextContent(buffer) return buffer~string end end return "" +-- private method to build up text content from multiple nodes ::method buildTextContent private use arg buffer child = self~firstChild do while child \= .nil if self~hasTextContent(child) then do - child~buildTextContext(buffer) + content = child~nodeValue + if nodeValue \= .nil then do + buffer~append(content) + end end child = child~nextSibling end @@ -1327,6 +1333,7 @@ child = self~firstChild do while child \= .nil self~removeChild(child) + child = self~firstChild end -- create a text node and append This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-21 14:29:15
|
Revision: 7942 http://oorexx.svn.sourceforge.net/oorexx/?rev=7942&view=rev Author: bigrixx Date: 2012-06-21 14:29:04 +0000 (Thu, 21 Jun 2012) Log Message: ----------- childe elements tests and some more fixes Modified Paths: -------------- incubator/orxutils/xml/element.testgroup incubator/orxutils/xml/xmldom.cls Modified: incubator/orxutils/xml/element.testgroup =================================================================== --- incubator/orxutils/xml/element.testgroup 2012-06-21 02:30:25 UTC (rev 7941) +++ incubator/orxutils/xml/element.testgroup 2012-06-21 14:29:04 UTC (rev 7942) @@ -105,6 +105,8 @@ doc = self~document element = doc~createElement("FOO") + self~assertFalse(element~hasAttributes) + self~assertFalse(element~hasAttribute("XYZ")) self~assertEquals("", element~getAttribute("XYZ")) self~assertNull(element~getAttributeNode("XYZ")) -- just make sure a remove on an empty list doesn't cause an error @@ -114,16 +116,21 @@ -- the attribute list is created lazily...ensure the unknown -- attributes are still unknown + self~assertTrue(element~hasAttributes) + self~assertFalse(element~hasAttribute("XYZ")) self~assertEquals("", element~getAttribute("XYZ")) self~assertNull(element~getAttributeNode("XYZ")) -- now check the added attribute + self~assertTrue(element~hasAttribute("ABC")) self~assertEquals("123", element~getAttribute("ABC")) self~assertEquals("123", element~getAttributeNode("ABC")~value) -- remove the added attribute element~removeAttribute("ABC") -- make sure it is really gone + self~assertFalse(element~hasAttributes) + self~assertFalse(element~hasAttribute("ABC")) self~assertEquals("", element~getAttribute("ABC")) self~assertNull(element~getAttributeNode("ABC")) -- set to a new value @@ -164,8 +171,8 @@ self~assertSame(element, attr~ownerelement) --- various tests for child nodes -::method testChildren +-- various tests for text content +::method testTextContent doc = self~document element = doc~createElement("FOO") @@ -203,3 +210,48 @@ element~textContent = .nil self~assertEquals("", element~textContent) + +::method testChildren + + doc = self~document + -- this is the parent node we'll be adding everything else to + element = doc~createElement("PARENT") + + self~assertNull(element~firstChild) + self~assertNull(element~lastChild) + self~assertFalse(element~hasChildNodes) + self~assertEquals(0, element~length) + self~assertNull(element~item(0)) + self~assertNull(element[0]) + + nodeList = element~childNodes + + self~assertEquals(0, nodeList~length) + self~assertNull(nodeList~item(0)) + self~assertNull(nodeList[0]) + self~assertEquals(0, nodeList~items) + + -- validate the makearray results with no children + array = element~makearray + self~assertEquals(0, array~items) + + -- time to start adding children to see how things change + child1 = doc~createElement("CHILD1") + element~appendChild(child1) + + self~assertSame(child1, element~firstChild) + self~assertSame(child1, element~lastChild) + self~assertTrue(element~hasChildNodes) + self~assertEquals(1, element~length) + self~assertSame(child1, element~item(0)) + self~assertSame(child1, element[0]) + self~assertNull(element~item(1)) + + -- we don't request a new nodelist...this should see the + -- updates using the existing reference + + self~assertEquals(1, nodeList~length) + self~assertSame(child1, nodeList~item(0)) + self~assertSame(child1, nodeList[0]) + self~assertEquals(1, nodeList~items) + Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-21 02:30:25 UTC (rev 7941) +++ incubator/orxutils/xml/xmldom.cls 2012-06-21 14:29:04 UTC (rev 7942) @@ -1050,14 +1050,18 @@ -- always returns 0 return 0 +-- some useful compatibility items ::method makearray use strict arg - -- just an empty array + -- just an empty array here return .array~new(0) ::method "[]" forward message("ITEM") +::method items + forward message("LENGTH") + /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Class: ChildNode base type for nodes that can be children of other nodes */ @@ -1149,7 +1153,8 @@ child = child.nextSibling end -::method hasChildren +-- returns true if the node currently has child nodes +::method hasChildNodes expose firstChild use strict arg return firstChild \= .nil @@ -1348,22 +1353,22 @@ return childNodes ::attribute item GET - expose firstNode childNodes + expose firstChild childNodes use strict arg index if index < 0 || index >= childNodes then do return .nil end + child = firstChild - do while index > 0 + loop index child = child~nextSibling - index -= 1 end return child ::method makearray - expose firstNode childNodes + expose firstChild childNodes use strict arg result = .array~new(childNodes) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-21 20:27:52
|
Revision: 7943 http://oorexx.svn.sourceforge.net/oorexx/?rev=7943&view=rev Author: bigrixx Date: 2012-06-21 20:27:46 +0000 (Thu, 21 Jun 2012) Log Message: ----------- more node insertion work Modified Paths: -------------- incubator/orxutils/xml/element.testgroup incubator/orxutils/xml/xmldom.cls Modified: incubator/orxutils/xml/element.testgroup =================================================================== --- incubator/orxutils/xml/element.testgroup 2012-06-21 14:29:04 UTC (rev 7942) +++ incubator/orxutils/xml/element.testgroup 2012-06-21 20:27:46 UTC (rev 7943) @@ -190,6 +190,7 @@ self~assertTrue(text~isA(.Node)) self~assertEquals(.node~TEXT_NODE, text~nodeType) self~assertEquals(123, text~textContent) + self~assertSame(element, text~parentNode) newText = doc~createTextNode("ABC") element~appendChild(newText) @@ -237,10 +238,19 @@ -- time to start adding children to see how things change child1 = doc~createElement("CHILD1") + -- quick check of some of the node relationship values before + -- we insert this + self~assertNull(child1~parentNode) + self~assertNull(child1~nextSibling) + self~assertNull(child1~previousSibling) + element~appendChild(child1) self~assertSame(child1, element~firstChild) self~assertSame(child1, element~lastChild) + self~assertSame(element, child1~parentNode) + self~assertNull(child1~nextSibling) + self~assertNull(child1~previousSibling) self~assertTrue(element~hasChildNodes) self~assertEquals(1, element~length) self~assertSame(child1, element~item(0)) @@ -255,3 +265,70 @@ self~assertSame(child1, nodeList[0]) self~assertEquals(1, nodeList~items) + -- check the make array result + array = element~makearray + self~assertEquals(1, array~items) + self~assertSame(child1, array[1]) + + -- add a second node, and check everything is still ok + child2 = doc~createElement("CHILD2") + element~appendChild(child2) + + self~assertSame(child1, element~firstChild) + self~assertSame(child2, element~lastChild) + self~assertEquals(2, element~length) + self~assertSame(child1, element~item(0)) + self~assertSame(child2, element~item(1)) + + self~assertSame(child2, child1~nextSibling) + self~assertNull(child1~previousSibling) + + self~assertSame(child1, child2~previousSibling) + self~assertNull(child2~nextSibling) + + -- check the make array result + array = element~makearray + self~assertEquals(2, array~items) + self~assertSame(child1, array[1]) + self~assertSame(child2, array[2]) + + -- Now some insertions. We'll insert several here, and check the + -- results at the end + child3 = doc~createElement("CHILD3") + -- new first element + element~insertBefore(child3, child1) + child4 = doc~createElement("CHILD4") + -- between 1 and 2 + element~insertBefore(child4, child2) + + child5 = doc~createElement("CHILD5") + -- between appended to the end + element~insertBefore(child5, .nil) + + -- we should have 5 elements now, in the + -- order 3, 1, 4, 2, 5 + self~assertEquals(5, element~length) + self~assertSame(child3, nodeList[0]) + self~assertSame(child1, nodeList[1]) + self~assertSame(child4, nodeList[2]) + self~assertSame(child2, nodeList[3]) + self~assertSame(child5, nodeList[4]) + + -- ok, now this gets fun. The DOM spec says + -- an inserted element will be removed from its current + -- parent, so we'll use insert to move things around a little + + -- now 1, 4, 2, 5, 3 + element~insertBefore(child3) + -- now 1, 2, 4, 5, 3 + element~insertBefore(child2, child4) + -- now 1, 2, 3, 4, 5 + element~insertBefore(child3, child4) + + -- now verify the order + self~assertEquals(5, element~length) + self~assertSame(child1, nodeList[0]) + self~assertSame(child2, nodeList[1]) + self~assertSame(child3, nodeList[2]) + self~assertSame(child4, nodeList[3]) + self~assertSame(child5, nodeList[4]) Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-21 14:29:04 UTC (rev 7942) +++ incubator/orxutils/xml/xmldom.cls 2012-06-21 20:27:46 UTC (rev 7943) @@ -50,11 +50,51 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ +/* Class: NodeList -- Abstract NodeList mixin */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +::class "NodeList" public mixinclass Object + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ /* Class: NodeList */ +/* Public methods */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "NodeList" public +/*----------------------------------------------------------------------------*/ +/* Method: item */ +/* Description: get a list item. */ +/*----------------------------------------------------------------------------*/ + +::method item abstract + +/*----------------------------------------------------------------------------*/ +/* Method: length */ +/* Description: get the number of items in the list. */ +/*----------------------------------------------------------------------------*/ +::method length abstract + + +-- some compatibility methods to make nodelist feel like a Rexx collection + +::method makearray abstract + +::method "[]" + forward message("ITEM") + +::method items + forward message("LENGTH") + + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: NodeListImpl -- concrete NodeList class */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +::class "NodeListImpl" public inherit NodeList ::method init expose nodes -- we're a read-only list...the owning node returns the list, we work off @@ -105,27 +145,19 @@ use strict arg return nodes~items +-- some compatibility methods to make nodelist feel like a Rexx collection ::method makearray expose nodes use strict arg return nodes~copy -- make sure this is a copy --- some compatibility methods to make nodelist feel like a Rexx collection -::method "[]" - forward message("ITEM") - -::method items - forward message("LENGTH") - - /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Class: DeepNodeList */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ - -::class "DeepNodeList" subclass NodeList public +::class "DeepNodeList" subclass NodeListImpl public ::method init expose rootNode tagName changes nodes nsName @@ -817,7 +849,7 @@ expose ownerNode childNodes nodeId use strict arg ownerNode = .nil nodeId = self~class~getId - childNodes = .NodeList~new + childNodes = .NodeListImpl~new self~isowned = .false -- unowned until we are added as a child self~readonly = .false -- newly created nodes can be altered self~isFirstChild = .false -- not the first child until added to something. @@ -1164,7 +1196,7 @@ ::method insertBefore expose firstChild lastChild ownerDocument childNodes - use arg newChild, refChild, replace = .false + use arg newChild, refChild = .nil, replace = .false -- this case is really a no-op, but we need to go through the steps -- in case we need to signal events. @@ -1207,20 +1239,21 @@ else do -- insertion at the beginning, need to adjust if refChild == firstChild then do - newChild~firstSibling = firstChild + newChild~nextSibling = firstChild newChild~previousSibling = .nil firstChild~previousSibling = newChild firstChild = newChild end -- insertion in the middle else do - previousNode = refNode~previousSibling + previousNode = refChild~previousSibling previousNode~nextSibling = newChild newChild~previousSibling = previousNode - newChild~nextSibling = refNode - refNode~previousSibling = newChild + newChild~nextSibling = refChild + refChild~previousSibling = newChild end end + -- bump the count of nodes childNodes += 1 @@ -1371,14 +1404,14 @@ expose firstChild childNodes use strict arg - result = .array~new(childNodes) + array = .array~new(childNodes) child = firstChild - do while child \= .nil - result~append(child) + do i = 1 while child \= .nil + array[i] = child child = child~nextSibling end - return result + return array /*----------------------------------------------------------------------------*/ @@ -2735,7 +2768,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "Element" subclass ParentNode public +::class "Element" subclass ParentNode public inherit NodeList ::method init expose nodeName attributes namespaceURI localName type attributes = .nil @@ -3321,7 +3354,7 @@ ::attribute childNodes GET use strict arg -- always returns an empty node list - return .NodeList~new + return .NodeListImpl~new ::attribute nodeValue GET expose data This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-21 23:08:25
|
Revision: 7944 http://oorexx.svn.sourceforge.net/oorexx/?rev=7944&view=rev Author: bigrixx Date: 2012-06-21 23:08:19 +0000 (Thu, 21 Jun 2012) Log Message: ----------- child node replace/remove work Modified Paths: -------------- incubator/orxutils/xml/element.testgroup incubator/orxutils/xml/xmldom.cls Modified: incubator/orxutils/xml/element.testgroup =================================================================== --- incubator/orxutils/xml/element.testgroup 2012-06-21 20:27:46 UTC (rev 7943) +++ incubator/orxutils/xml/element.testgroup 2012-06-21 23:08:19 UTC (rev 7944) @@ -227,6 +227,7 @@ nodeList = element~childNodes + self~assertTrue(nodeList~isA(.NodeList)) self~assertEquals(0, nodeList~length) self~assertNull(nodeList~item(0)) self~assertNull(nodeList[0]) @@ -332,3 +333,28 @@ self~assertSame(child3, nodeList[2]) self~assertSame(child4, nodeList[3]) self~assertSame(child5, nodeList[4]) + + -- now some removals/replacements + self~assertSame(child1, element~replaceChild(child5, child1)) + self~assertEquals(4, element~length) + self~assertSame(child5, element~firstChild) + self~assertSame(child4, element~lastChild) + + -- remove from the middle + self~assertSame(child2, element~removeChild(child2)) + self~assertEquals(3, element~length) + + -- the end + self~assertSame(child4, element~removeChild(child4)) + self~assertEquals(2, element~length) + + -- the beginning + self~assertSame(child5, element~removeChild(child5)) + self~assertEquals(1, element~length) + + -- and the last one + self~assertSame(child3, element~removeChild(child3)) + self~assertEquals(0, element~length) + + self~assertNull(element~firstChild) + self~assertNull(element~lastChild) Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-21 20:27:46 UTC (rev 7943) +++ incubator/orxutils/xml/xmldom.cls 2012-06-21 23:08:19 UTC (rev 7944) @@ -1005,27 +1005,27 @@ return .true end - if self~nodetype != other~nodetype then do + if self~nodetype \= other~nodetype then do return .false end - if self~nodename != other~nodename then do + if self~nodename \= other~nodename then do return .false end - if self~localname != other~localname then do + if self~localname \= other~localname then do return .false end - if self~namespaceURI != other~namespaceURI then do + if self~namespaceURI \= other~namespaceURI then do return .false end - if self~prefix != other~prefix then do + if self~prefix \= other~prefix then do return .false end - if self~nodevalue != other~nodevalue then do + if self~nodevalue \= other~nodevalue then do return .false end @@ -1312,11 +1312,11 @@ use strict arg newChild, oldChild self~insertBefore(newChild, oldChild, .true) - if newChild !== oldChild then do - removeChild(oldChild, .true) + if newChild \== oldChild then do + self~removeChild(oldChild, .true) end - ownerDocument.replacedNode(self) + ownerDocument~replacedNode(self) return oldChild ::attribute textContent GET @@ -4787,7 +4787,7 @@ realEnd = endContainer~parentNode end - if realStart != realEnd then do + if realStart \= realEnd then do DomErrors~raiseError(.DomErrors~BAD_BOUNDARY_POINTS_ERR) end @@ -4998,9 +4998,9 @@ expose removeChild use strict arg parent, child removeChild = child - result parent~removeChild(child) + old = parent~removeChild(child) removeChild = .nil - return result + return old ::method removeNode This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-22 16:13:11
|
Revision: 7951 http://oorexx.svn.sourceforge.net/oorexx/?rev=7951&view=rev Author: bigrixx Date: 2012-06-22 16:13:04 +0000 (Fri, 22 Jun 2012) Log Message: ----------- more namespace work Modified Paths: -------------- incubator/orxutils/xml/element.testgroup incubator/orxutils/xml/xmldom.cls Modified: incubator/orxutils/xml/element.testgroup =================================================================== --- incubator/orxutils/xml/element.testgroup 2012-06-22 03:12:58 UTC (rev 7950) +++ incubator/orxutils/xml/element.testgroup 2012-06-22 16:13:04 UTC (rev 7951) @@ -112,7 +112,10 @@ -- just make sure a remove on an empty list doesn't cause an error element~removeAttribute("XYZ") - element~setAttribute("ABC", "123") + attr = element~setAttribute("ABC", "123") + + -- verify we got a good attribute node back + self~assertTrue(attr~isA(.attr)) -- the attribute list is created lazily...ensure the unknown -- attributes are still unknown @@ -126,8 +129,11 @@ self~assertEquals("123", element~getAttribute("ABC")) self~assertEquals("123", element~getAttributeNode("ABC")~value) - -- remove the added attribute - element~removeAttribute("ABC") + -- remove the added attribute (should return the node) + attr = element~removeAttribute("ABC") + -- verify we got a good attribute node back + self~assertTrue(attr~isA(.attr)) + -- make sure it is really gone self~assertFalse(element~hasAttributes) self~assertFalse(element~hasAttribute("ABC")) @@ -159,6 +165,9 @@ -- add this back directly using the attribute node element~setAttributeNode(attr) self~assertEquals("789", element~getAttribute("ABC")) + -- verify the parent/child relationship + self~assertSame(element, attr~element) + self~assertSame(element, attr~ownerelement) -- rename the attribute attr~rename("DEF") @@ -358,3 +367,43 @@ self~assertNull(element~firstChild) self~assertNull(element~lastChild) + +::method testElementNamespace + + doc = self~document + -- this is the parent node we'll be adding everything else to + element = doc~createElement("FOO") + + child1 = doc~createElementNS("http://www.oorexx.org/xml/unittest.xml", "oorexx:foo") + + self~assertEquals("http://www.oorexx.org/xml/unittest.xml", child1~namespaceURI) + self~assertEquals("oorexx:foo", child1~nodeName) + self~assertEquals("oorexx:foo", child1~tagName) + self~assertEquals("foo", child1~localName) + self~assertEquals("oorexx", child1~prefix) + + -- DOM 3 allows the prefix to be explicitly set + child1~prefix = "rexx" + + self~assertEquals("rexx:foo", child1~nodeName) + self~assertEquals("rexx:foo", child1~tagName) + self~assertEquals("foo", child1~localName) + self~assertEquals("rexx", child1~prefix) + +::method testAttributeNamespace + + doc = self~document + -- this is the parent node we'll be adding everything else to + element = doc~createElement("FOO") + + attr = element~setAttributeNS("http://www.oorexx.org/xml/unittest.xml", "oorexx:foo", "bar") + + self~assertTrue(attr~isa(.attr)) + self~assertEquals("bar", attr~value) + self~assertEquals("bar", attr~nodevalue) + self~assertEquals("oorexx:foo", attr~nodename) + -- NB: attributes support name, but not tagname + self~assertEquals("oorexx:foo", attr~name) + self~assertEquals("foo", attr~localname) + self~assertEquals("oorexx", attr~prefix) + self~assertEquals("http://www.oorexx.org/xml/unittest.xml", attr~namespaceURI) Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-22 03:12:58 UTC (rev 7950) +++ incubator/orxutils/xml/xmldom.cls 2012-06-22 16:13:04 UTC (rev 7951) @@ -2251,32 +2251,25 @@ ::class "Attr" subclass Node public ::method init - expose value name textNode namespaceURI localName type idAttribute + expose value nodeName textNode namespaceURI localName type idAttribute prefix value = .nil type = .nil textNode = .nil namespaceURI = .nil localName = .nil + prefix = .nil idAttribute = .false - if arg() == 2 then do - use strict arg ownerDocument, name - self~init:super(ownerDoc) + use strict arg ownerDoc, nodeName, namespaceURI = .nil, explicitLocalName = .nil + self~init:super(ownerDoc) + self~setName(nodeName) + if explicitLocalName \= .nil then do + localName = explicitLocalName end - else if arg() == 3 then do - use strict arg ownerDoc, namespaceURI, nodeName - self~init:super(ownerDoc) - self~setName(nodeName) - end - else do - use strict arg ownerDoc, namespaceURI, nodeName, localName - self~init:super(ownerDoc) - end - self~init:super(ownerDocument) self~isSpecified = .false self~hasStringValue = .true ::method setName private - expose namespaceURI localName + expose namespaceURI localName prefix use arg qname -- null string is the same as not there if namspaceURI == "" then do @@ -2291,7 +2284,7 @@ localName = qname end else do - parse var qname localName (colon1) (colon2 + 1) localName + parse var qname prefix =(colon1) =(colon2 + 1) localName end -- support for the Document renameNode method @@ -2374,21 +2367,13 @@ use strict arg return .Node~ATTRIBUTE_NODE -::attribute nodeName GET - expose name - use strict arg - return name +::attribute nodeName -::attribute nodeName SET - expose name - use strict arg name - ::attribute nodeValue SET forward message("VALUE=") ::attribute nodeValue GET forward message("VALUE") - ::attribute typeName GET expose type use strict arg @@ -2433,13 +2418,17 @@ -- we provide all of our own type information directly return this + +-- name is the same as nodename ::attribute name GET + forward message("NODENAME") +::attribute name SET + forward message("NODENAME=") ::attribute value SET expose value textNode use strict arg newValue - self~ownerElement oldvalue = "" -- we might need to process an old value if it's a serious of text nodes @@ -2786,13 +2775,13 @@ use strict arg ownerDoc, namespaceURI, nodeName self~init:super(ownerDoc) -- decode the name to see if there is a prefix - self~setName(namespaceURI, nodeName) + self~setName(nodeName) end else do use strict arg ownerDoc, namespaceURI, nodeName, temp self~init:super(ownerDoc) -- decode the name to see if there is a prefix - self~setName(namespaceURI, nodeName) + self~setName(nodeName) -- the provided version overrides anything decoded from the qname localName = temp @@ -2803,7 +2792,7 @@ expose namespaceURI localName use arg qname -- null string is the same as not there - if namspaceURI == "" then do + if namespaceURI == "" then do namespaceURI = .nil end @@ -2815,7 +2804,7 @@ localName = qname end else do - parse var qname prefix (colon1) (colon2 + 1) localName + parse var qname prefix =(colon1) =(colon2 + 1) localName -- TODO: validate the name information with the ownerdoc end @@ -2947,16 +2936,18 @@ use strict arg name if attributes \= .nil then do - attributes~removeNamedItem(name) + return attributes~removeNamedItem(name) end + return .nil ::method removeAttributeNode expose attributes use strict arg oldAttr if attrbutes \= .nil then do - attributes~removeItem(oldAttr, .true) + return attributes~removeItem(oldAttr, .true) end + return .nil ::method setAttribute use strict arg name, value @@ -2974,6 +2965,7 @@ else do newAttr~value = value end + return newAttr ::method setAttributeNode use strict arg newAttr @@ -3002,6 +2994,7 @@ end + -- set an attribute using a namespace URI and a qualified name ::method setAttributeNS espose attributes use strict arg namespaceURI, qualifiedName, value @@ -3023,12 +3016,13 @@ attributes = self~attributes newAttr~nodeValue = value - attributes~setNameItemNS(newAttr) + attributes~setNamedItemNS(newAttr) end else do newAttr~name = qualifiedName newAttr~nodeValue = value end + return newAttr ::method removeAttributeNS expose attributes @@ -3041,16 +3035,16 @@ attributes~removeNamedItemNS(namespaceURI, localName) ::method getAttributeNodeNS + expose attributes use strict arg namespaceURI, localName if attributes == .nil then do - return + return .nil end return attributes~getNamedItemNS(namespaceURI, localName) ::method setAttributeNodeNS - expose attributes use strict arg newAttr -- get the attribute map. This also creates it if @@ -6050,11 +6044,11 @@ ::method createAttributeNS if arg() == 2 then do use strict arg namespaceURI, qualifiedName - return .Attr~new(self, namespaceURI, qualifiedName) + return .Attr~new(self, qualifiedName, namespaceURI) end else do use strict arg namespaceURI, qualifiedName, localName - return .Attr~new(self, namespaceURI, qualifiedName, localName) + return .Attr~new(self, qualifiedName, namespaceURI, localName) end ::method createCDATASection This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-22 23:17:42
|
Revision: 7952 http://oorexx.svn.sourceforge.net/oorexx/?rev=7952&view=rev Author: bigrixx Date: 2012-06-22 23:17:35 +0000 (Fri, 22 Jun 2012) Log Message: ----------- more namespace work Modified Paths: -------------- incubator/orxutils/xml/element.testgroup incubator/orxutils/xml/xmldom.cls Modified: incubator/orxutils/xml/element.testgroup =================================================================== --- incubator/orxutils/xml/element.testgroup 2012-06-22 16:13:04 UTC (rev 7951) +++ incubator/orxutils/xml/element.testgroup 2012-06-22 23:17:35 UTC (rev 7952) @@ -407,3 +407,46 @@ self~assertEquals("foo", attr~localname) self~assertEquals("oorexx", attr~prefix) self~assertEquals("http://www.oorexx.org/xml/unittest.xml", attr~namespaceURI) + + -- this should be locateable via the fully qualified name, but not + -- by the local name + self~assertEquals("bar", element~getAttribute("oorexx:foo")) + self~assertEquals("", element~getAttribute("foo")) + self~assertSame(attr, element~getAttributeNode("oorexx:foo")) + self~assertNull(element~getAttributeNode("foo")) + -- now search by the NS version + + self~assertTrue(element~hasAttribute("oorexx:foo")) + self~assertTrue(element~hasAttributeNS("http://www.oorexx.org/xml/unittest.xml", "foo")) + self~assertEquals("bar", element~getAttributeNS("http://www.oorexx.org/xml/unittest.xml", "foo")) + self~assertSame(attr, element~getAttributeNodeNS("http://www.oorexx.org/xml/unittest.xml", "foo")) + + -- get the attribute list and retry these queries + attributes = element~attributes + self~assertSame(attr, attributes~getNamedItem("oorexx:foo")) + self~assertSame(attr, attributes~getNamedItemNS("http://www.oorexx.org/xml/unittest.xml", "foo")) + + self~assertSame(attr, element~removeAttribute("oorexx:foo")) + self~assertEquals("", element~getAttribute("oorexx:foo")) + + -- add back in + self~assertNull(element~setAttributeNodeNS(attr)) + self~assertEquals("bar", element~getAttributeNS("http://www.oorexx.org/xml/unittest.xml", "foo")) + + -- create a replacement attribute + attr2 = doc~createAttributeNS("http://www.oorexx.org/xml/unittest.xml", "oorexx:foo") + attr2~value = "123" + -- and replace + self~assertSame(attr, element~setAttributeNodeNS(attr2)) + + self~assertEquals("123", element~getAttributeNS("http://www.oorexx.org/xml/unittest.xml", "foo")) + + -- remove using the namespace + self~assertSame(attr2, element~removeAttributeNS("http://www.oorexx.org/xml/unittest.xml", "foo")) + self~assertEquals("", element~getAttributeNS("http://www.oorexx.org/xml/unittest.xml", "foo")) + -- now test sets and removes using the attribute list + + self~assertNull(attributes~setNamedItemNS(attr)) + self~assertEquals("bar", element~getAttributeNS("http://www.oorexx.org/xml/unittest.xml", "foo")) + self~assertSame(attr, attributes~removeNamedItemNS("http://www.oorexx.org/xml/unittest.xml", "foo")) + self~assertEquals("", element~getAttributeNS("http://www.oorexx.org/xml/unittest.xml", "foo")) Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-22 16:13:04 UTC (rev 7951) +++ incubator/orxutils/xml/xmldom.cls 2012-06-22 23:17:35 UTC (rev 7952) @@ -373,10 +373,10 @@ return .nil - + -- locate the index of a given namespace/localname pair ::method findNamePointNS private expose attributes - use arg name, namespace + use arg namespace, name if attributes == .nil then do return .nil @@ -399,6 +399,7 @@ return s~index end end + s~next end return .nil @@ -445,14 +446,14 @@ ::method getNamedItemNS expose attributes - use strict arg name, namespace + use strict arg namespace, name if attributes == .nil then do return .nil end do attribute over attributes - if attribute~name == name & attribute~namespaceURI == namespace then do + if attribute~localname == name & attribute~namespaceURI == namespace then do return attribute end end @@ -494,7 +495,7 @@ expose attributes use strict arg node - index = self~findNamePointNS(node~localName, node~namespaceURI) + index = self~findNamePointNS(node~namespaceURI, node~localName) previous = .nil if index \= .nil then do @@ -547,7 +548,7 @@ expose attributes use strict arg namespace, name - index = self~findNamePointNS(name, namespace) + index = self~findNamePointNS(namespace, name) previous = .nil if index \= .nil then do @@ -683,7 +684,7 @@ ::method setNamedItemNS use strict arg attribute - -- replaceing an attribute with itself does nothing + -- replacing an attribute with itself does nothing if attribute~isOwned then do return attribute end @@ -691,13 +692,13 @@ attribute~ownerNode = self~ownerNode attribute~isOwned = .true - index = self~findNamePointNS(attribute~namespaceURI, attribute~nodeName) + index = self~findNamePointNS(attribute~namespaceURI, attribute~localName) attributes = self~attributes previous = .nil if index \= .nil then do - previous = attributes[i] - attributes[i] = attribute - previous~ownerNode = ownerNode~ownerDocument + previous = attributes[index] + attributes[index] = attribute + previous~ownerNode = self~ownerNode~ownerDocument previous~isOwned = .false previous~isSpecified = .true end @@ -725,7 +726,7 @@ ::method removeNamedItemNS use strict arg namespaceURI, name - index = self~findNamePointNS(namspaceURI, name) + index = self~findNamePointNS(namespaceURI, name) if index == .nil then do return .nil end @@ -2996,7 +2997,7 @@ -- set an attribute using a namespace URI and a qualified name ::method setAttributeNS - espose attributes + expose attributes use strict arg namespaceURI, qualifiedName, value index = qualifiedName~pos(":") @@ -3029,10 +3030,10 @@ use strict arg namespaceURI, localName if attributes == .nil then do - return + return .nil end - attributes~removeNamedItemNS(namespaceURI, localName) + return attributes~removeNamedItemNS(namespaceURI, localName) ::method getAttributeNodeNS expose attributes This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-23 17:42:25
|
Revision: 7955 http://oorexx.svn.sourceforge.net/oorexx/?rev=7955&view=rev Author: bigrixx Date: 2012-06-23 17:42:18 +0000 (Sat, 23 Jun 2012) Log Message: ----------- restructure into interface classes and implementations. Modified Paths: -------------- incubator/orxutils/xml/element.testgroup incubator/orxutils/xml/xmldom.cls Modified: incubator/orxutils/xml/element.testgroup =================================================================== --- incubator/orxutils/xml/element.testgroup 2012-06-23 16:54:47 UTC (rev 7954) +++ incubator/orxutils/xml/element.testgroup 2012-06-23 17:42:18 UTC (rev 7955) @@ -58,7 +58,7 @@ ::method init expose dom document forward class(super) continue - dom = .DomImplementation~implementation + dom = .ooRexxDOM~implementation document = dom~createDocument ::attribute dom Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-23 16:54:47 UTC (rev 7954) +++ incubator/orxutils/xml/xmldom.cls 2012-06-23 17:42:18 UTC (rev 7955) @@ -35,8 +35,6 @@ /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ -/* Author: W. David Ashley */ -/* */ /*----------------------------------------------------------------------------*/ @@ -50,19 +48,18 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: NodeList -- Abstract NodeList mixin */ +/* Section: Abstract DOM interface class definitions */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "NodeList" public mixinclass Object - /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: NodeList */ -/* Public methods */ +/* Class: NodeList -- Abstract NodeList mixin */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ +::class "NodeList" public mixinclass Object + /*----------------------------------------------------------------------------*/ /* Method: item */ /* Description: get a list item. */ @@ -78,18 +75,188 @@ -- some compatibility methods to make nodelist feel like a Rexx collection - ::method makearray abstract - ::method "[]" forward message("ITEM") - ::method items forward message("LENGTH") +-- DOM Node interface class +::class "Node" public mixinclass Object +-- various type definitions +::constant ELEMENT_NODE 1 +::constant ATTRIBUTE_NODE 2 +::constant TEXT_NODE 3 +::constant CDATA_SECTION_NODE 4 +::constant ENTITY_REFERENCE_NODE 5 +::constant ENTITY_NODE 6 +::constant PROCESSING_INSTRUCTION_NODE 7 +::constant COMMENT_NODE 8 +::constant DOCUMENT_NODE 9 +::constant DOCUMENT_TYPE_NODE 10 +::constant DOCUMENT_FRAGMENT_NODE 11 +::constant NOTATION_NODE 12 +::method appendNode abstract +::method cloneNode abstract +::method attributes abstract +::method childNodes abstract +::method firstChild abstract +::method lastChild abstract +::method localName abstract +::method namespaceUri abstract +::method nextSibling abstract +::method nodeName abstract +::method nodeType abstract +::method nodeValue abstract +::method "nodeValue=" abstract +::method ownerDocument abstract +::method parentNode abstract +::method prefix abstract +::method "prefix=" abstract +::method previousSibling abstract +::method hasAttributes abstract +::method hasChildNodes abstract +::method insertBefore abstract +::method isSupported abstract +::method normalize abstract +::method removeChild abstract +::method replaceChild abstract + +-- an abstract attribute interface definition +::class "Attr" mixinclass Node public +::method name abstract +::method ownerElement abstract +::method isSpecified abstract +::method value abstract +::method "value=" abstract + +-- an abstract characterdata interface definition +::class "CharacterData" mixinclass Node public +::method appendData abstract +::method deleteData abstract +::method data abstract +::method "data=" abstract +::method length abstract +::method insertData abstract +::method replaceData abstract +::method substringData abstract + +-- abstract text definition +::class "Text" mixinclass CharacterData public +::method splitText + +-- abstract CDATA section definition +::class "CDATASection" mixinclass Text public +-- no additional methods defined on this interface + +-- abstract Comment definition +::class "Comment" mixinclass CharacterData public +-- no additional methods defined on this interface + +-- abstract document interface +::class "Document" mixinclass Node public +::method createAttribute abstract +::method createAttributeNS abstract +::method createCDATASection abstract +::method createComment abstract +::method createDocumentFragment abstract +::method createElement abstract +::method createElementNS abstract +::method createEntityReference abstract +::method createProcessinginstruction abstract +::method createTextNode abstract +::method doctype abstract +::method documentElement abstract +::method getElementByID abstract +::method getElementsByTagName abstract +::method getElementsByTagNameNS abstract +::method implementation abstract +::method version abstract +::method importNode abstract +::method "encoding=" abstract + +-- abstract documentfragment definition +::class "DocumentFragment" mixinclass Node public +-- no additional methods defined on this interface + +-- abstract documenttype definition +::class "DocumentType" mixinclass Node public +::method entities abstract +::method internalSubset abstract +::method name abstract +::method notations abstract +::method publicID abstract +::method systemID abstract + +-- abstract DOMImplementation definiton +::class "DOMImplementation" mixinclass Object public +::method createDocument abstract +::method createDocumentType abstract +::method hasFeature abstract + +-- abstract Element definition +::class "Element" mixinclass Node public +::method getAttribute abstract +::method getAttributeNode abstract +::method getAttributeNS abstract +::method getAttributeNodeNS abstract +::method getElementsByTagName abstract +::method getElementsByTagNameNS abstract +::method tagName abstract +::method "tagName=" abstract +::method hasAttribute abstract +::method hasAttributeNS abstract +::method removeAttribute abstract +::method removeAttributeNode abstract +::method removeAttributeNS abstract +::method setAttribute abstract +::method setAttributeNode abstract +::method setAttributeNodeNS abstract +::method setAttributeNS abstract + +-- abstract Entity definition +::class "Entity" mixinclass Node public +::method encoding abstract +::method notationName abstract +::method systemId abstract +::method version abstract + +-- abstract entityreference definition +::class "EntityReference" mixinclass Node public +-- no additional methods defined on this interface + +-- abstract NameNodeMap definition +::class "NamedNodeMap" mixinclass Object public +::method length abstract +::method getNamedItem abstract +::method getNamedItemNS abstract +::method item abstract +::method removeNamedItem abstract +::method removeNamedItemNS abstract +::method setNamedItem abstract +::method setNamedItemNS abstract + +-- abstract notation definition +::class "Notation" mixinclass Node public +::method publicID abstract +::method systemID abstract + +-- abstract processinginstruction definition +::class "ProcessingInstruction" mixinclass Node public +::method data abstract +::method target abstract +::method "data=" abstract + /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ +/* Section: Concrete implementation of the DOM classes */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ /* Class: NodeListImpl -- concrete NodeList class */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ @@ -320,7 +487,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "NamedNodeMap" public +::class "NamedNodeMapImpl" public ::method init expose ownerNode attributes hasDefaults changed readonly use strict arg ownerNode @@ -635,7 +802,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "AttributeMap" subclass NamedNodeMap public +::class "AttributeMap" subclass NamedNodeMapImpl public ::method init expose hasDefaults use strict arg ownerNode, defaults = .nil @@ -815,19 +982,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::CLASS "Node" public -::CONSTANT ELEMENT_NODE 1 -::CONSTANT ATTRIBUTE_NODE 2 -::CONSTANT TEXT_NODE 3 -::CONSTANT CDATA_SECTION_NODE 4 -::CONSTANT ENTITY_REFERENCE_NODE 5 -::CONSTANT ENTITY_NODE 6 -::CONSTANT PROCESSING_INSTRUCTION_NODE 7 -::CONSTANT COMMENT_NODE 8 -::CONSTANT DOCUMENT_NODE 9 -::CONSTANT DOCUMENT_TYPE_NODE 10 -::CONSTANT DOCUMENT_FRAGMENT_NODE 11 -::CONSTANT NOTATION_NODE 12 +::CLASS "NodeImpl" public inherit Node -- initialize a counter to give new nodes a unique id ::method init class @@ -1101,7 +1256,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "ChildNode" subclass Node public +::class "ChildNode" subclass NodeImpl public ::method init expose previousSibling nextSibling forward class(super) continue @@ -1420,7 +1575,7 @@ /* Class: DocumentFragment */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "DocumentFragment" public subclass ParentNode +::class "DocumentFragmentImpl" public subclass ParentNode ::attribute nodeType GET return .Node~DOCUMENT_FRAGMENT_NODE @@ -1462,7 +1617,7 @@ /* Class: Document */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "Document" subclass ParentNode public +::class "DocumentImpl" subclass ParentNode public ::method init expose iterators ranges eventListeners grammarAccess doctype hasMutationEvents use arg doctype = .nil, grammarAccess = .false @@ -1476,13 +1631,13 @@ ::method cloneNode use strict arg deep = .false - newDoc = .Document~new + newDoc = self~class~new self~cloneDocument(newDoc, deep) return newDoc ::method implementation -- this is a singleton - return .DOMImplementation~implementation + return .ooRexxDOM~implementation ::method createNodeIterator expose iterators @@ -2172,7 +2327,7 @@ ::method renamedAttrNode ::method renamedElement -::class "EventListener" public +::class "EventListenerImpl" public ::method init expose type useCapture listener use strict arg type, listener, useCapture @@ -2202,7 +2357,7 @@ return -- all errors are just ignored -::class "EventTracker" public +::class "EventTrackerImpl" public ::method init expose captures total bubble total @@ -2250,7 +2405,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "Attr" subclass Node public +::class "AttrImpl" public subclass NodeImpl inherit Attr ::method init expose value nodeName textNode namespaceURI localName type idAttribute prefix value = .nil @@ -2758,7 +2913,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "Element" subclass ParentNode public inherit NodeList +::class "ElementImpl" subclass ParentNode public inherit Element NodeList ::method init expose nodeName attributes namespaceURI localName type attributes = .nil @@ -3340,7 +3495,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "CharacterData" subclass ChildNode public +::class "CharacterDataImpl" public subclass ChildNode inherit CharacterData ::method init expose data use strict arg ownerDocument, data @@ -3442,7 +3597,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "Text" subclass CharacterData public +::class "TextImpl" public subclass CharacterDataImpl inherit Text ::attribute nodeType GET use strict arg @@ -3630,7 +3785,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "CDATASection" subclass Text PUBLIC +::class "CDATASectionImpl" public subclass TextImpl inherit CDATASection ::attribute nodeType GET use strict arg return .Node~CDATA_SECTION_NODE @@ -3646,7 +3801,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "DocumentType" subclass Node public +::class "DocumentTypeImpl" public subclass NodeImpl inherit DocumentType /*----------------------------------------------------------------------------*/ @@ -3675,8 +3830,8 @@ self~nodeName = name self~nodeType = 10 self~nodeValue = .nil - self~entities = .NamedNodeMap~new - self~notations = .NamedNodeMap~new + self~entities = .NamedNodeMapImpl~new + self~notations = .NamedNodeMapImpl~new /*----------------------------------------------------------------------------*/ /* Method: name */ @@ -3715,7 +3870,7 @@ /* Class: Notation */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "Notation" subclass Node PUBLIC +::class "NotationImpl" public subclass NodeImpl inherit Notation ::method init expose name publicId systemId baseURI use strict arg ownerDoc, name @@ -3745,7 +3900,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "Entity" subclass ParentNode PUBLIC +::class "EntityImpl" public subclass ParentNode inherit Entity ::method init expose name publicId systemId XmlEncoding inputEncoding XMLversion notationName baseURI use strict arg ownerDoc, name @@ -3782,7 +3937,7 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "EntityReference" subclass ParentNode public +::class "EntityReferenceImpl" public subclass ParentNode inherit EntityReference ::method init expose name baseURI use strict arg ownerDoc, name @@ -3843,7 +3998,7 @@ /* Class: ProcessingInstruction */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "ProcessingInstruction" subclass CharacterData PUBLIC +::class "ProcessingInstructionImpl" public subclass CharacterDataImpl inherit ProcessingInstruction ::method init expose target use strict arg ownerDocument, target, data @@ -3870,11 +4025,11 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* Class: DOMImplementation */ +/* Class: ooRexxDOM */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "DOMImplementation" public +::class "ooRexxDOM" public inherit DOMImplementation ::method init class expose singleton singleton = .nil @@ -3883,7 +4038,7 @@ expose singleton use strict arg if singleton == .nil then do - singleton = .DOMImplementation~new + singleton = self~new end return singleton @@ -5879,7 +6034,7 @@ /* Class: CoreDocument */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class "CoreDocument" subclass Document public +::class "CoreDocument" subclass DocumentImpl public ::method init expose docType docElement encoding actualEncoding version standalone documentURI - userdata identifiers domNormalizer configuration xpathEvaluator changes - @@ -5942,6 +6097,7 @@ sup = identifiers~supplier do while sup~available reversedIdentifiers[sup~item] = sup~index + sup~next end end @@ -6040,55 +6196,55 @@ ::method createAttribute use strict arg name - return .Attr~new(self, name) + return .AttrImpl~new(self, name) ::method createAttributeNS if arg() == 2 then do use strict arg namespaceURI, qualifiedName - return .Attr~new(self, qualifiedName, namespaceURI) + return .AttrImpl~new(self, qualifiedName, namespaceURI) end else do use strict arg namespaceURI, qualifiedName, localName - return .Attr~new(self, qualifiedName, namespaceURI, localName) + return .AttrImpl~new(self, qualifiedName, namespaceURI, localName) end ::method createCDATASection use strict arg data - return .CDATASection~new(self, data) + return .CDATASectionImpl~new(self, data) ::method createComment use strict arg data - return .Comment~new(self, data) + return .CommentImpl~new(self, data) ::method createDocumentFragment use strict arg - return .DocumentFragment~new(self) + return .DocumentFragmentImpl~new(self) ::method createElement use strict arg tagname - return .Element~new(self, tagname) + return .ElementImpl~new(self, tagname) ::method createElementNS if arg() == 2 then do use strict arg namespaceURI, qualifiedName - return .Element~new(self, namespaceURI, qualifiedName) + return .ElementImpl~new(self, namespaceURI, qualifiedName) end else do use strict arg namespaceURI, qualifiedName, localName - return .Element~new(self, namespaceURI, qualifiedName, localName) + return .ElementImpl~new(self, namespaceURI, qualifiedName, localName) end ::method createEntityReference use strict arg name - return .EntityReference~new(self, name) + return .EntityReferenceImpl~new(self, name) ::method createProcessingInstruction use strict arg target, data - return .ProcessingInstruction~new(self, target, data) + return .ProcessingInstructionImpl~new(self, target, data) ::method createTextNode use strict arg data - return .Text~new(self, data) + return .TextImpl~new(self, data) ::attribute docType GET ::attribute documentElement GET @@ -6120,15 +6276,15 @@ ::method createDocumentType use strict arg qualifiedName, publicID, systemID - return .DocumentType~new(self, qualifiedName, publicID, systemID) + return .DocumentTypeImpl~new(self, qualifiedName, publicID, systemID) ::method createEntity use strict arg name - return .Entity~new(self, name) + return .EntityImpl~new(self, name) ::method createNotation use strict arg name - return .Notation~new(self, name) + return .NotationImpl~new(self, name) ::method importNode use strict arg source, deep = .false This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-23 23:35:00
|
Revision: 7958 http://oorexx.svn.sourceforge.net/oorexx/?rev=7958&view=rev Author: bigrixx Date: 2012-06-23 23:34:54 +0000 (Sat, 23 Jun 2012) Log Message: ----------- element tree search tests Modified Paths: -------------- incubator/orxutils/xml/element.testgroup incubator/orxutils/xml/xmldom.cls Modified: incubator/orxutils/xml/element.testgroup =================================================================== --- incubator/orxutils/xml/element.testgroup 2012-06-23 20:23:10 UTC (rev 7957) +++ incubator/orxutils/xml/element.testgroup 2012-06-23 23:34:54 UTC (rev 7958) @@ -450,3 +450,59 @@ self~assertEquals("bar", element~getAttributeNS("http://www.oorexx.org/xml/unittest.xml", "foo")) self~assertSame(attr, attributes~removeNamedItemNS("http://www.oorexx.org/xml/unittest.xml", "foo")) self~assertEquals("", element~getAttributeNS("http://www.oorexx.org/xml/unittest.xml", "foo")) + +::method testGetElements + + doc = self~document + -- this is the parent node we'll be adding everything else to + element = doc~createElement("FOO") + -- now create a bunch of children that we can arrange in different order to search + child1 = doc~createElementNS("http://www.oorexx.org/xml/unittest.xml", "oorexx:foo") + child2 = doc~createElementNS("http://www.oorexx.org/xml/unittest.xml", "oorexx:foo") + child3 = doc~createElementNS("http://www.oorexx.org/xml/unittest.xml", "oorexx:foo") + child4 = doc~createElementNS("http://www.oorexx.org/xml/unittest.xml", "oorexx:foo") + child5 = doc~createElementNS("http://www.oorexx.org/xml/unittest.xml", "oorexx:foo") + child6 = doc~createElementNS("http://www.oorexx.org/xml/unittest.xml", "oorexx:foo") + + -- and a few that won't match + nomatch1 = doc~createElementNS("http://www.oorexx.org/xml/unittest.xml", "oorexx:bar") + nomatch2 = doc~createElementNS("http://www.oorexx.org/xml/unittest.xml", "oorexx:bar") + nomatch3 = doc~createElementNS("http://www.oorexx.org/xml/unittest.xml", "oorexx:bar") + + element~appendChild(child1) + element~appendChild(nomatch1) + element~appendChild(child2) + element~appendChild(nomatch2) + element~appendChild(child3) + element~appendChild(nomatch3) + element~appendChild(child3) + + list = element~getElementsByTagName("oorexx:foo") + self~validateNodeList(.array~of(child1, child2, child3), list) + list = element~getElementsByTagNameNS("http://www.oorexx.org/xml/unittest.xml", "foo") + self~validateNodeList(.array~of(child1, child2, child3), list) + -- get a new element to add to + element = doc~createElement("FOO") + element~appendChild(nomatch1) + element~appendChild(nomatch2) + element~appendChild(nomatch3) + + nomatch1~appendChild(child1) + nomatch1~appendChild(child2) + nomatch2~appendChild(child3) + nomatch3~appendChild(child4) + child4~appendChild(child5) + child4~appendChild(child6) + list = element~getElementsByTagName("oorexx:foo") + self~validateNodeList(.array~of(child1, child2, child3, child4, child5, child6), list) + list = element~getElementsByTagNameNS("http://www.oorexx.org/xml/unittest.xml", "foo") + self~validateNodeList(.array~of(child1, child2, child3, child4, child5, child6), list) + +::method validateNodelist + use arg expected, source + + self~assertEquals(expected~items, source~length) + + loop i = 1 to expected~items + self~assertSame(expected[i], source[i - 1], "Element" i) + end Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-23 20:23:10 UTC (rev 7957) +++ incubator/orxutils/xml/xmldom.cls 2012-06-23 23:34:54 UTC (rev 7958) @@ -318,6 +318,9 @@ use strict arg return nodes~copy -- make sure this is a copy +-- access to the set of nodes +::attribute nodes + /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Class: DeepNodeList */ @@ -326,26 +329,27 @@ ::class "DeepNodeList" subclass NodeListImpl public ::method init - expose rootNode tagName changes nodes nsName + expose rootNode tagName changes nsName + use strict arg rootNode, tagName, nsName = .nil - use strict arg rootNode, tagName, nsName = .nil - nodes = .Array~new + self~init:super changes = 0 -- lazy search for the matching nodes. This only fills in the cache -- as far as the last valid requested position ::method item - expose rootNode changes nodes + expose rootNode changes use strict arg index + -- if the tree has changed, we need to restart this if rootNode~changes \= changes then do - nodes = .array~new + self~nodes = .array~new changes = rootNode~changes end - currentSize = nodes~items + currentSize = self~nodes~items if index < currentSize then do - return nodes[index + 1] + return self~nodes[index + 1] end else do -- we need to continue the traversal from the last node added @@ -353,14 +357,14 @@ thisNode = rootNode end else do - thisNode = nodes[currentSize] + thisNode = self~nodes[currentSize] end -- keep adding up to the one we're looking for do while index > currentSize - thisNode = self~nexMatchingElementAfter(thisNode) + thisNode = self~nextMatchingElementAfter(thisNode) if thisNode \= .nil then do - nodes~append(thisNode) + self~nodes~append(thisNode) currentSize += currentSize end else do @@ -377,42 +381,37 @@ use strict arg -- this forces everything to be initialized self~item(999999999) - return nodes~items + return self~nodes~items ::method makearray expose nodes use strict arg -- this forces everything to be initialized self~item(999999999) - return nodes~copy + return self~nodes~copy ::method nextMatchingElementAfter private expose rootNode tagName nsName use arg current - do while current \= nil + do while current \= .nil -- go down to the first child if it has one if current~hasChildNodes then do current = current~firstChild end - -- no children and we're at the rootnode, so we - -- don't go up or to any siblings - else if current == rootNode then do - return .nil - end - -- now try for a sibling of our current position - next = current~nextSibling - -- if we found one, then this is our next candidate - if next \= .nil then do + -- if not the root, then check for a sibling + else if current \= rootNode, current~nextSibling \= .nil then do + next = current~nextSibling current = next end else do next = .nil -- now we step "up and to the right" for as many attempts as needed -- or utnil we pop back to the root node - do while current \= rootNode + loop while current \= rootNode current = current~parentNode next = current~nextSibling + -- we have a next, so quit if next \= .nil then do leave end @@ -6272,6 +6271,7 @@ ::attribute xmlEncoding ::attribute documentURI +::attribute changes GET ::method createDocumentType use strict arg qualifiedName, publicID, systemID This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-24 19:52:50
|
Revision: 7961 http://oorexx.svn.sourceforge.net/oorexx/?rev=7961&view=rev Author: bigrixx Date: 2012-06-24 19:52:44 +0000 (Sun, 24 Jun 2012) Log Message: ----------- start of some Text node test cases Modified Paths: -------------- incubator/orxutils/xml/xmldom.cls Added Paths: ----------- incubator/orxutils/xml/characterdata.testgroup Added: incubator/orxutils/xml/characterdata.testgroup =================================================================== --- incubator/orxutils/xml/characterdata.testgroup (rev 0) +++ incubator/orxutils/xml/characterdata.testgroup 2012-06-24 19:52:44 UTC (rev 7961) @@ -0,0 +1,114 @@ +#!/usr/bin/rexx +/* + SVN Revision: $Rev: 3371 $ + Change Date: $Date: 2008-09-21 00:33:29 -0400 (Sun, 21 Sep 2008) $ +*/ +/*----------------------------------------------------------------------------*/ +/* */ +/* Copyright (c) 2005-2010 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.oorexx.org/license.html */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 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. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS 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 COPYRIGHT */ +/* OWNER OR 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. */ +/* */ +/*----------------------------------------------------------------------------*/ + parse source . . fileSpec; + + group = .TestGroup~new(fileSpec) + group~add(.text.testGroup) + + if group~isAutomatedTest then return group + + testResult = group~suite~execute~~print + +return testResult +-- End of entry point. + +::requires "ooTest.frm" -- load the ooRexxUnit classes +::requires "xmldom.cls" + +::class "characterdata.testGroup" subclass ooTestCase public +::method setup + expose dom document + dom = .ooRexxDOM~implementation + document = dom~createDocument + +::attribute dom +::attribute document +::attribute nodeName +::attribute nodeClass +::attribute nodeType + +::method testBaseNode + root = self~document~createElement("root") + + node = self~createNode("xyz") + + self~assertTrue(node~isa(self~nodeclass)) + self~assertEquals(self~nodeName, node~nodeName) + self~assertEquals(self~nodeName, node~localName) + self~assertEquals("xyz", node~data) + self~assertEquals("xyz", node~nodeValue) + self~assertEquals("xyz"~length, node~length) + self~assertEquals(self~nodeType, node~nodetype) + self~assertNull(node~parentNode) + self~assertNull(node~nextSibling) + self~assertNull(node~previousSibling) + self~assertNull(node~firstChild) + self~assertNull(node~lastChild) + self~assertNull(node~attributes) + self~assertNull(node~prefix) + self~assertNull(node~namespaceURI) + self~assertNull(node~item(0)) + self~assertFalse(node~hasAttributes) + self~assertFalse(node~hasChildNodes) + + self~assertEquals(0, node~childNodes~length) + + -- add this to the part + root~appendChild(node) + + self~assertSame(root, node~parentNode) + self~assertEquals("xyz", root~textContent) + -- the text content does not change the element nodeValue + self~assertEquals(.nil, root~nodeValue) + +::class "text.testgroup" subclass characterdata.testgroup public +::method setup + forward class(super) continue + self~nodeName = "#text" + self~nodeClass = .Text + self~nodeType = .Node~TEXT_NODE + +::method createNode + use arg text + return self~document~createTextNode(text) + + Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-24 19:52:03 UTC (rev 7960) +++ incubator/orxutils/xml/xmldom.cls 2012-06-24 19:52:44 UTC (rev 7961) @@ -1076,9 +1076,11 @@ ::attribute prefix SET -- this is an error by default .DomErrors~raiseError(.DomErrors~NAMESPACE_ERR) +-- for node types that don't support a real localname, +-- this is the same as nodeName ::attribute localName GET use strict arg - return .nil + return self~nodeName ::attribute baseURI GET use strict arg return .nil This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-25 22:46:12
|
Revision: 7965 http://oorexx.svn.sourceforge.net/oorexx/?rev=7965&view=rev Author: bigrixx Date: 2012-06-25 22:46:05 +0000 (Mon, 25 Jun 2012) Log Message: ----------- finish up the characterdata tests and fixes Modified Paths: -------------- incubator/orxutils/xml/characterdata.testgroup incubator/orxutils/xml/element.testgroup incubator/orxutils/xml/xmldom.cls Modified: incubator/orxutils/xml/characterdata.testgroup =================================================================== --- incubator/orxutils/xml/characterdata.testgroup 2012-06-25 03:08:14 UTC (rev 7964) +++ incubator/orxutils/xml/characterdata.testgroup 2012-06-25 22:46:05 UTC (rev 7965) @@ -43,6 +43,8 @@ group = .TestGroup~new(fileSpec) group~add(.text.testGroup) + group~add(.comment.testGroup) + group~add(.processinginstruction.testGroup) if group~isAutomatedTest then return group @@ -100,6 +102,78 @@ -- the text content does not change the element nodeValue self~assertEquals(.nil, root~nodeValue) +::method testCommonStringMethods + + node = self~createNode("xyz") + -- appending + node~appendData("abc") + self~assertEquals("xyzabc", node~data) + node~appendData("") + self~assertEquals("xyzabc", node~data) + + -- deleting + node~deleteData(0, 1) + self~assertEquals("yzabc", node~data) + node~deleteData(1, 2) + self~assertEquals("ybc", node~data) + node~deleteData(2, 10) + self~assertEquals("yb", node~data) + + -- inserting + node~insertData(0, "123") + self~assertEquals("123yb", node~data) + node~insertData(3, "") + self~assertEquals("123yb", node~data) + node~insertData(4, "456") + self~assertEquals("123y456b", node~data) + node~insertData(8, "789") + self~assertEquals("123y456b789", node~data) + +-- replacing + node~replaceData(3, 1, "xxxx") + self~assertEquals("123xxxx456b789", node~data) + node~replaceData(0, 1, "") + self~assertEquals("23xxxx456b789", node~data) + node~replaceData(6, 20, "000") + self~assertEquals("23xxxx000", node~data) + +-- setting + node~data = "" + self~assertEquals("", node~data) + self~assertEquals("", node~nodeValue) + node~data = "abc" + self~assertEquals("abc", node~data) + self~assertEquals("abc", node~nodeValue) + +-- substring + self~assertEquals("ab", node~substringData(0, 2)) + self~assertEquals("", node~substringData(0, 0)) + -- NB uses Rexx padding rules + self~assertEquals("abc ", node~substringData(0, 4)) + + +::class "comment.testgroup" subclass characterdata.testgroup public +::method setup + forward class(super) continue + self~nodeName = "#comment" + self~nodeClass = .Comment + self~nodeType = .Node~COMMENT_NODE + +::method createNode + use arg text + return self~document~createComment(text) + +::class "processinginstruction.testgroup" subclass characterdata.testgroup public +::method setup + forward class(super) continue + self~nodeName = "TARGET" + self~nodeClass = .ProcessingInstruction + self~nodeType = .Node~PROCESSING_INSTRUCTION_NODE + +::method createNode + use arg text + return self~document~createProcessingInstruction("TARGET", text) + ::class "text.testgroup" subclass characterdata.testgroup public ::method setup forward class(super) continue @@ -111,4 +185,45 @@ use arg text return self~document~createTextNode(text) +-- this method only applies to the Text node type +::method testSplitText + -- a root element to ensure the split node gets added as a child + root = self~document~createElement("root") + node = self~createNode("1234567890") + root~appendChild(node) + + self~assertEquals("67890", node~splitText(5)~data) + self~assertEquals(2, root~length) + self~assertEquals("12345", node~data) + -- there should be a following sibling with the remainder of the data + self~assertEquals("67890", node~nextSibling~data) + + root = self~document~createElement("root") + node = self~createNode("1234567890") + root~appendChild(node) + + -- split before the first character + self~assertEquals("1234567890", node~splitText(0)~data) + self~assertEquals("", node~data) + self~assertEquals("1234567890", node~nextSibling~data) + + root = self~document~createElement("root") + node = self~createNode("1234567890") + root~appendChild(node) + + -- split after the last character + self~assertEquals("", node~splitText(10)~data) + self~assertEquals("1234567890", node~data) + self~assertEquals("", node~nextSibling~data) + + + -- this text node has no parent element...this should return an + -- "orphan" node + node = self~createNode("1234567890") + + newNode = node~splitText(5) + self~assertEquals("67890", newNode~data) + self~assertEquals("12345", node~data) + self~assertNull(node~nextSibling) + self~assertNull(node~previousSibling) Modified: incubator/orxutils/xml/element.testgroup =================================================================== --- incubator/orxutils/xml/element.testgroup 2012-06-25 03:08:14 UTC (rev 7964) +++ incubator/orxutils/xml/element.testgroup 2012-06-25 22:46:05 UTC (rev 7965) @@ -55,9 +55,8 @@ ::requires "xmldom.cls" ::class "element.testGroup" subclass ooTestCase public -::method init +::method setup expose dom document - forward class(super) continue dom = .ooRexxDOM~implementation document = dom~createDocument Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-06-25 03:08:14 UTC (rev 7964) +++ incubator/orxutils/xml/xmldom.cls 2012-06-25 22:46:05 UTC (rev 7965) @@ -3524,6 +3524,9 @@ self~ownerDocument~modifiedCharacterData(self, oldValue, value, replace) ::attribute data GET + forward message("NODEVALUE") +::attribute data SET + forward message("NODEVALUE=") ::attribute length GET expose data use strict arg @@ -3536,7 +3539,7 @@ return end - self~setNodeValue(data||newData) + self~nodeValue = data||newData ::method deleteData expose data @@ -3550,7 +3553,7 @@ newData = data~delstr(offset + 1, count) end -- set the node value to the adjusted version - self~nodeValue = newData + data = newData self~ownerDocument~deletedText(self, offset, count) @@ -3558,14 +3561,13 @@ expose data use strict arg offset, newData, replace = .false - if offset >= data~length then do - newValue = data - end - else do - newValue = date~insert(newData, offset +1) - end + -- NB: In this case, we don't add one to the offset because + -- the Rexx insert function inserts after the given offset, not + -- before. This actually works to our advantage. + newValue = data~insert(newData, offset) + data = newValue - self~ownerDocument~deletedText(self, offset, data~length) + self~ownerDocument~insertedText(self, offset, newData~length) ::method replaceData expose data @@ -3582,18 +3584,31 @@ self~ownerDocument~replacedCharacterData(self, oldvalue, data) -::method setData - forward message("NODEVALUE=") - ::method substringData expose data use strict arg offset, count - return data~substring(offset + 1, count) + return data~substr(offset + 1, count) /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ +/* Class: Text -- a DOM comment node */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +::class "CommentImpl" public subclass CharacterDataImpl inherit Comment +::attribute nodeType GET + use strict arg + return .Node~COMMENT_NODE + +::attribute nodeName GET + use strict arg + return "#comment" + + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ /* Class: Text -- a DOM text node */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ @@ -3765,16 +3780,15 @@ return currentNode ::method splitText - expose data use strict arg offset - newText = self~ownerDocument~createTextNode(data~substr(offset + 1)) - self~nodeValue = data~substr(1, offset) + newText = self~ownerDocument~createTextNode(self~data~substr(offset + 1)) + self~nodeValue = self~data~substr(1, offset) -- now insert the new text node parent = self~parentNode - if parentNode \= .nil then do - parentNode~insertBefore(newText, self~nextSibling) + if parent \= .nil then do + parent~insertBefore(newText, self~nextSibling) end return newText This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-06-29 21:11:52
|
Revision: 7977 http://oorexx.svn.sourceforge.net/oorexx/?rev=7977&view=rev Author: bigrixx Date: 2012-06-29 21:11:45 +0000 (Fri, 29 Jun 2012) Log Message: ----------- redo the parser, including adding cdata support Modified Paths: -------------- incubator/orxutils/xml/testxml.rex incubator/orxutils/xml/testxml.xml incubator/orxutils/xml/xmlparser.cls Modified: incubator/orxutils/xml/testxml.rex =================================================================== --- incubator/orxutils/xml/testxml.rex 2012-06-29 17:40:44 UTC (rev 7976) +++ incubator/orxutils/xml/testxml.rex 2012-06-29 21:11:45 UTC (rev 7977) @@ -53,7 +53,7 @@ use arg chunk call charout , '<'chunk~tag if chunk~attr <> .nil then do f over chunk~attr - call charout , ' 'f'="'self~textxlate(chunk~attr[f])'"' + call charout , ' 'f'="'chunk~attr[f]'"' end say '>' return @@ -63,16 +63,31 @@ say '</'chunk~tag'>' return -::method passthrough +::method doctypeDecl use arg chunk say '<'chunk~text'>' return +::method comment +use arg chunk +say '<!--'chunk~text'-->' +return + +::method processingInstruction +use arg chunk +say '<?'chunk~tag chunk~text'?>' +return + ::method text use arg chunk say chunk~text return +::method cdata +use arg chunk +say "<![CDATA["chunk~text"]]>" +return + ::method error use arg err say err~text Modified: incubator/orxutils/xml/testxml.xml =================================================================== --- incubator/orxutils/xml/testxml.xml 2012-06-29 17:40:44 UTC (rev 7976) +++ incubator/orxutils/xml/testxml.xml 2012-06-29 21:11:45 UTC (rev 7977) @@ -23,7 +23,20 @@ text chunk.</para> </chapter> - - + <example> + <![CDATA[ + function matchwo(a,b) + { + if (a < b && a < 0) then + { + return 1; + } + else + { + return 0; + } + } + ]]> + </example> </book> Modified: incubator/orxutils/xml/xmlparser.cls =================================================================== --- incubator/orxutils/xml/xmlparser.cls 2012-06-29 17:40:44 UTC (rev 7976) +++ incubator/orxutils/xml/xmlparser.cls 2012-06-29 21:11:45 UTC (rev 7977) @@ -95,26 +95,42 @@ /*----------------------------------------------------------------------------*/ ::constant parserver '0.5' -- the version of this parser +::constant eol '0a'x -- newline character used for XML +::constant tab '09'x ::attribute src private -- the array of xml lines to be parsed ::attribute lineidx private -- the index into the array of xml lines ::attribute charidx private -- the index into a xml line ::attribute errortxt private -- error text ::attribute eof private -- done parsing? +::attribute xmlerror private -- the last error + /*----------------------------------------------------------------------------*/ +/* Method: setErrorPoint */ +/* Description: record current position for error reporting */ +/*----------------------------------------------------------------------------*/ +::method setErrorPoint + expose errlineidx errcharidx lineidx charidx + errlineidx = lineidx + errcharidx = charidx + +/*----------------------------------------------------------------------------*/ /* Method: create_error */ /* Description: creates an xmlerror instance. */ /*----------------------------------------------------------------------------*/ ::method create_error private -use strict arg msg, errline, errpos -xmlerror = .xmlerror~new -xmlerror~text = msg -xmlerror~filename = self~xmlfile -xmlerror~line = errline -xmlerror~charpos = errpos -return xmlerror + expose errlineidx errcharidx xmlerror eof + use strict arg msg + xmlerror = .xmlerror~new + xmlerror~text = 'Error on line' errlineidx', column' errcharidx':' msg + xmlerror~filename = self~xmlfile + xmlerror~line = errline + xmlerror~charpos = errpos + -- turn on the eof indicator so nothing else gets processed + eof = .true + self~error(xmlerror) -- pass this to the processing routine /*----------------------------------------------------------------------------*/ @@ -127,6 +143,8 @@ -- NOTE: This works fine for both strings and mutablebuffer. Care should be -- taken to ensure it remains that way. +text = text~changestr(''', "'") +text = text~changestr('"', '"') text = text~changestr('>', '>') text = text~changestr('<', '<') text = text~changestr('&', '&') -- always do this one last! @@ -139,167 +157,405 @@ /*----------------------------------------------------------------------------*/ ::method currentchar private -expose src lineidx charidx -use strict arg -if lineidx > src~items then return .nil -return src[lineidx]~subChar(charidx) + expose src lineidx charidx + use strict arg + if lineidx > src~items then return .nil + -- report eol as the currennt char if the index is zero + if charidx == 0 then do + return self~eof + end + return src[lineidx]~subChar(charidx) +/*----------------------------------------------------------------------------*/ +/* Method: checkeol */ +/* Description: handle end of line situations */ +/*----------------------------------------------------------------------------*/ +::method checkeol private + expose src lineidx charidx eof + if charidx > src[lineidx]~length then do + lineidx += 1 + charidx = 0 -- this indicates we just crossed a boundary + end + if lineidx > src~items then do + eof = .true + end + /*----------------------------------------------------------------------------*/ /* Method: getchar */ /* Description: get a single character from the xml document. */ /*----------------------------------------------------------------------------*/ ::method getchar private -expose src lineidx charidx eof -use strict arg -character = src[lineidx]~subchar(charidx) -charidx += 1 -if charidx > src[lineidx]~length then do - lineidx += 1 - charidx = 1 - end -if lineidx > src~items then do - eof = .true - return '' - end -return character + expose src lineidx charidx eof + use strict arg eol = .false + -- we set to zero if the last character crossed a line boundary + -- we might want this, we might not want this... + if charidx == 0 then do + -- advance to the first real character + charidx = 1 + -- if newlines are requested, then return it now + if eol then do + return self~eol + end + end + character = src[lineidx]~subchar(charidx) + charidx += 1 + self~checkeol + return character + /*----------------------------------------------------------------------------*/ +/* Method: checkchar */ +/* Description: check ahead to see if a given string are the next characters */ +/* up in the sequence. If there is a match, then the read pointer is */ +/* advanced past the matching characters, otherwise the position remains */ +/* unchanged. Matches will not cross line boundaries */ +/*----------------------------------------------------------------------------*/ + +::method checkChar private + expose charidx lineidx src + use strict arg string + -- if we are at a linened boundary, this is always false + if charidx == 0 then do + return .false + end + -- check for a match + if src[lineidx]~match(charidx, string) then do + -- advance the position if it matches + charidx += string~length + self~checkeol + return .true + end + return .false + + +/*----------------------------------------------------------------------------*/ /* Method: getchunk */ /* Description: returns a chunk of the xml document. */ /*----------------------------------------------------------------------------*/ ::method getchunk private -expose src lineidx charidx errortxt eof -use strict arg -errlineidx = lineidx -errcharidx = charidx -chunk = .xmlchunk~new -if self~currentchar() <> '<' then do - /* we found some CDATA */ + expose src lineidx charidx errortxt eof + use strict arg + -- remember the position for error reporting + self~setErrorPoint + -- something other than a tag? + if \self~checkChar('<') then do + -- handle the text part of an element + return self~parseText + end + + -- closing element tag? + if self~checkChar("/") then do + return self~parseEndElement + end + -- is this CDATA? + else if self~checkchar("![CDATA[") then do + return self~parseCData + end + -- is this a comment? + else if self~checkchar("!--") then do + return self~parseComment + end + -- is this a !DOCTYPE declaration? + else if self~checkChar('!DOCTYPE') then do + return self~parseDocType + end + -- a processing instruction like <?xml >? + else if self~checkChar('?') then do + return self~parseProcessingInstruction + end + -- some sort of processing instruction. Of particular importance are CDATA tags + else do + -- handle an element tag + return self~parseElement + end + + +/*----------------------------------------------------------------------------*/ +/* Method: scanToTagEnd */ +/* Description: scan to the end of an element tag, returning all of the */ +/* characters between */ +/* Arguments: none */ +/*----------------------------------------------------------------------------*/ +::method scanToTagEnd + expose eof + element = .mutablebuffer~new + -- scan until we find the closing > of the element. This + -- may span lines...if we find a line break, then replace it + -- with a blank + do while \eof + char = self~getChar(.true) + -- if we've hit a line break, replace with a space instead + if char == self~eol then char = ' ' + element~append(char) + -- we're done once we hit the end + if self~checkChar('>') then leave + end + return element + +/*----------------------------------------------------------------------------*/ +/* Method: scanToTagEndNested */ +/* Description: scan to the end of an element tag, returning all of the */ +/* characters between. This allows for nested elements */ +/* Arguments: none */ +/*----------------------------------------------------------------------------*/ +::method scanToTagEndNested + expose eof + instruction = .mutablebuffer~new + -- scan until we find the closing > of the element. This + -- may span lines...if we find a line break, then replace it + -- with a blank + nestlevel = 0 + do while \eof + -- It is possible for tags to be contained within other tags in XML + -- processing tags. The next two IF statements take care of that nesting + -- possibility. It will be up to the user to parse out the contained + -- tags. This also includes lineends unmodified + if self~currentchar() = '<' then nestlevel += 1 + if self~currentchar() = '>' then do + -- if we're still nested, just reduce the nesting level + if nestlevel > 0 then nestlevel -= 1 + -- done parsing this + else do + self~getChar + leave + end + end + instruction~append(self~getchar(.true)) + end + + return instruction + + +/*----------------------------------------------------------------------------*/ +/* Method: parseText */ +/* Description: parse out element text, maintaining line breaks */ +/* Arguments: none */ +/*----------------------------------------------------------------------------*/ +::method parseText + expose eof + chunk = .xmlchunk~new + -- we found some text data text = .mutablebuffer~new - curline = lineidx - do while eof = .false & self~currentchar() <> '<' + do while eof = .false, self~currentchar() <> '<' -- Do NOT collapse the white space and newlines out of the chunk! -- We leave that task up to the client of this class. -- Instead, we return a chunk with .endofline stuck in between -- at the linebreaks. - text~append(self~getchar()) - if curline <> lineidx then do - text~append(.endofline) - curline = lineidx - end - end + text~append(self~getchar(.true)) + end chunk~text = self~xlatetext(text)~string~strip - if chunk~text <> '' then + -- if this chunk if just whitespace characters (including lineneds), just + -- ignore it. + if chunk~text~verify(' '||self~tab||self~eol) \= 0 then self~text(chunk) -- call the public override method return chunk - end -/* we found an XML tag, process it */ -character = self~getchar() -- skip the '<' -element = .mutablebuffer~new -curline = lineidx -nestlevel = 0 -do while eof = .false - if element~substr(1, 1) = '!' then do - -- It is possible for tags to be contained within other tags in XML - -- processing tags. The next two IF statements take care of that nesting - -- possibility. It will be up to the user to parse out the contained - -- tags. - if self~currentchar() = '<' then nestlevel = nestlevel + 1 - if self~currentchar() = '>' & level > 0 then nestlevel = nestlevel - 1 + + +/*----------------------------------------------------------------------------*/ +/* Method: parseCData */ +/* Description: parse out CDATA test, maintaining line breaks */ +/* Arguments: none */ +/*----------------------------------------------------------------------------*/ +::method parseCData + expose eof + chunk = .xmlchunk~new + -- we found some text data + data = .mutablebuffer~new + do while eof = .false + char = self~getchar(.true) + -- potential ending marker? + if char == ']' then do + -- test for the rest of the marker + if self~checkChar(']>') then leave + end + + -- Do NOT collapse the white space and newlines out of the chunk! + -- We leave that task up to the client of this class. + -- Instead, we return a chunk with .eol stuck in between + -- at the linebreaks. + data~append(char) + end + + -- cdata information does not recognize entities. + chunk~text = data~string + self~cdata(chunk) -- call the public override method + return chunk + +/*----------------------------------------------------------------------------*/ +/* Method: parseComment */ +/* Description: parse out Comment data, maintaining line breaks */ +/* Arguments: none */ +/*----------------------------------------------------------------------------*/ +::method parseComment + expose eof + chunk = .xmlchunk~new + -- we found some text data + data = .mutablebuffer~new + do while eof = .false + char = self~getchar(.true) + -- potential ending marker? + if char == '-' then do + -- test for the rest of the marker + if self~checkChar('->') then leave end - element~append(self~getchar()) - if curline <> lineidx then do - element~append(' ') - curline = lineidx - end - if self~currentchar() = '>' & nestlevel = 0 then leave + + -- Do NOT collapse the white space and newlines out of the chunk! + -- We leave that task up to the client of this class. + -- Instead, we return a chunk with .eol stuck in between + -- at the linebreaks. + data~append(char) end -if eof = .true then do - errortxt = 'Error line' errlineidx': EOF within an XML tag.' - self~error(self~create_error(errortxt, errlineidx, errcharidx)) -- call the public override method - return .nil - end --- element is now a string value -element = element~string~strip() -select - when element~subchar(1) = '/' then do - chunk~tag = element~substr(2) - self~end_element(chunk) -- call the public override method + + -- comment information does not recognize entities. + chunk~text = data~string + self~comment(chunk) -- call the public override method + return chunk + +/*----------------------------------------------------------------------------*/ +/* Method: parseEndElement */ +/* Description: parse out a closing element tag, calling the handlers */ +/* Arguments: none */ +/*----------------------------------------------------------------------------*/ +::method parseEndElement + element = self~scanToTagEnd + chunk = .xmlchunk~new + chunk~tag = element + self~end_element(chunk) -- call the public override method + return chunk + + +/*----------------------------------------------------------------------------*/ +/* Method: parseAttributes */ +/* Description: parse attribute values from a string */ +/* Arguments: the attribute string */ +/*----------------------------------------------------------------------------*/ +::method parseAttributes + use arg element + + -- Note: this is the "=" form, which will ignore the whitespace + if element = '' then return .nil + attr = .directory~new + loop while element \= '' + -- attribute values must be quoted strings, but either single or + -- double quotes can be used... + assignment = element~pos('=') + -- hmmm, no assignment found, this is invalid + if assignment = 0 then do + -- do not allow attributes without values! + errortxt = 'Error line' errlineidx 'column' errcharidx || , + ': Invalid tag attribute' element'.' + -- create the error message and handle termination + self~create_error('Invalid tag attribute' element'.') + return .nil end - when pos('?', element~subchar(1)) > 0 then do - chunk~tag = '' - chunk~text = element - self~passthrough(chunk) -- call the public override method + -- pull off the attribute name and see what sort of + -- value we have + parse var element attrname =(assignment) +1 element + if element~match(1, "'") then do + parse var element "'" value "'" element end - when pos('!--', element~substr(1, 3)) > 0 then do - chunk~tag = '' - chunk~text = element - self~passthrough(chunk) -- call the public override method + else if element~match(1, '"') then do + parse var element '"' value '"' element end - when pos('!', element~subchar(1)) > 0 then do - chunk~tag = '' - chunk~text = element - self~passthrough(chunk) -- call the public override method + else do + -- do not allow attributes without values! + self~create_error('Invalid attribute value' element'.') -- call the public override method + return .nil end - when element~matchChar(1, xrange('a', 'z') || xrange('A', 'Z')) then do - parse var element tag element - -- the following is needed in case the '/' immediately follows the tag - if tag~pos('/') > 0 then do - tag = tag~substr(1, tag~length - 1) - element = '/' element - end - chunk~tag = tag - /* process the attributes */ - if element~length > 0 then chunk~attr = .directory~new - do while element~length() > 0 - if pos('="', element~word(1)) > 0 then do - parse var element attrname . '="' attrvalue . '"' element - attrvalue = self~xlatetext(attrvalue) - chunk~attr[attrname] = attrvalue - end - else if pos("='", element~word(1)) > 0 then do - parse var element attrname . "='" attrvalue . "'" element - attrvalue = self~xlatetext(attrvalue) - chunk~attr[attrname] = attrvalue - end - else do - parse var element attrname element - if attrname <> '/' then do - -- do not allow attributes without values! - errortxt = 'Error line' errlineidx 'column' errcharidx || , - ': Invalid tag attribute' attrname'.' - self~error(self~create_error(errortxt, errlineidx, errcharidx)) -- call the public override method - /* stop parsing */ - eof = .true - return .nil - end - end - end - self~start_element(chunk) -- call the public override method - if attrname = '/' then do - endchunk = .xmlchunk~new - endchunk~tag = tag - self~end_element(endchunk) -- call the public override method - end - end - otherwise do - errortxt = 'Error line' errlineidx 'column 'errcharidx': Invalid tag name.' - self~error(self~create_error(errortxt, errlineidx, errcharidx)) -- call the public override method - /* stop parsing */ - eof = .true - return .nil - end - end -character = self~getchar() -- skip the '>' -return chunk + -- these have the entities translated out + attr[attrname] = self~xlatetext(value) + end + return attr /*----------------------------------------------------------------------------*/ +/* Method: parseElement */ +/* Description: parse out an element tag, calling the handlers */ +/* Arguments: none */ /*----------------------------------------------------------------------------*/ + +::method parseElement + element = self~scanToTagEnd + chunk = .xmlchunk~new + -- assume this is not a complete tag element + endTag = .false + -- if the close is here, then truncate and remember to send + -- the end element notification + if element~match(element~length, '/') then do + element~setBufferSize(element~length - 1) + endTag = .true + end + -- convert to a string and strip now + element = element~string~strip + + -- ok, now process the attributes, if any + + -- strip off the tag and parse off each of the attributes + parse var element chunk~tag element + + -- now parse out the attributes + chunk~attr = self~parseAttributes(element) + + self~start_element(chunk) -- call the public override method + -- self terminating element? + if endTag then do + endchunk = .xmlchunk~new + endchunk~tag = chunk~tag + self~end_element(endchunk) -- call the public override method + end + + return chunk + + +/*----------------------------------------------------------------------------*/ +/* Method: parseProcessingInstruction */ +/* Description: parse out a processing instruction tag */ +/* Arguments: none */ +/*----------------------------------------------------------------------------*/ +::method parseProcessingInstruction + expose eof + + chunk = .xmlchunk~new + instruction = self~scanToTagEnd + if eof then do + self~create_error('EOF within an XML tag.') -- call the public override method + return .nil + end + -- instruction is now a string value + instruction = instruction~string~strip + + -- strip off the target name and parse off each of the attributes + parse var instruction chunk~tag chunk~text '?' + self~processingInstruction(chunk) -- call the public override method + return chunk + + +/*----------------------------------------------------------------------------*/ +/* Method: parseDoctype */ +/* Description: parse out a complex doctype tag. No attempt is made to */ +/* interpret the information, including the nested parts */ +/* Arguments: none */ +/*----------------------------------------------------------------------------*/ +::method parseDoctype + expose eof + + chunk = .xmlchunk~new + chunk~text = self~scanToTagEndNested~string~strip + if eof then do + self~create_error('EOF within a DOCTYPE tag.') -- call the public override method + return .nil + end + chunk~tag = '' + self~doctypeDecl(chunk) -- call the public override method + return chunk + + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ /* Class: XMLPARSER */ /* Public methods */ /*----------------------------------------------------------------------------*/ @@ -307,8 +563,27 @@ ::attribute xmlfile private -- the XML file name, if known +/*----------------------------------------------------------------------------*/ +/* Method: start_document */ +/* Description: called before the start of document processing */ +/* Arguments: none */ +/*----------------------------------------------------------------------------*/ +::method start_document +/* this method is designed to be overridden by a subclass */ + use strict arg + /*----------------------------------------------------------------------------*/ +/* Method: end_document */ +/* Description: called after all parsing has completed */ +/* Arguments: none */ +/*----------------------------------------------------------------------------*/ + +::method end_document +/* this method is designed to be overridden by a subclass */ + use strict arg + +/*----------------------------------------------------------------------------*/ /* Method: start_element */ /* Description: called when a start element tag has been encountered. */ /* Arguments: an xmlchunk instance. */ @@ -316,10 +591,8 @@ ::method start_element /* this method is designed to be overridden by a subclass */ -use strict arg chunk -return + use strict arg chunk - /*----------------------------------------------------------------------------*/ /* Method: end_element */ /* Description: called when an end element tag has been encountered. */ @@ -328,10 +601,8 @@ ::method end_element /* this method is designed to be overridden by a subclass */ -use strict arg chunk -return + use strict arg chunk - /*----------------------------------------------------------------------------*/ /* Method: text */ /* Description: called when character data has been encountered. */ @@ -340,24 +611,45 @@ ::method text /* this method is designed to be overridden by a subclass */ -use strict arg chunk -return + use strict arg chunk +/*----------------------------------------------------------------------------*/ +/* Method: called when a comment tag has been encountered */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ +::method comment +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + /*----------------------------------------------------------------------------*/ -/* Method: passthrough */ -/* Description: called when comment tag or a processing instruction has been */ -/* encountered. */ +/* Method: called when a CDATA tag has been encountered */ /* Arguments: an xmlchunk instance. */ /*----------------------------------------------------------------------------*/ -::method passthrough +::method cdata /* this method is designed to be overridden by a subclass */ -use strict arg chunk -return + use strict arg chunk +/*----------------------------------------------------------------------------*/ +/* Method: called when a processing instruction has been encountered */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ +::method processingInstruction +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + /*----------------------------------------------------------------------------*/ +/* Method: called when a CDATA tag has been encountered */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method doctypeDecl +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ /* Method: error */ /* Description: called on an error. */ /* Arguments: an xmlerror instance. */ @@ -365,17 +657,15 @@ ::method error /* this method is designed to be overridden by a subclass */ -use strict arg xmlerror -return + use strict arg xmlerror - /*----------------------------------------------------------------------------*/ /* Method: getversion */ /* Description: return the version of this class. */ /*----------------------------------------------------------------------------*/ -::method getversion -return self~parserver +::method version + return self~parserver /*----------------------------------------------------------------------------*/ @@ -384,23 +674,31 @@ /*----------------------------------------------------------------------------*/ ::method parse_array -expose src lineidx charidx errortxt eof -use strict arg src -eof = .false -/* make sure this is an xml document */ -if src[1]~pos('<?xml') <> 1 then do - errortxt = 'Error: Invalid XML document.' - self~error(self~create_error(errortxt, 1, 1)) - return - end -/* parse the xml array */ -lineidx = 1 -charidx = 1 -errortxt = '' -do while eof = .false - chunk = self~getchunk() - end -return errortxt + expose src lineidx charidx eof xmlerror + use strict arg src + eof = .false + /* parse the xml array */ + lineidx = 1 + charidx = 1 + xmlerror = .nil + -- set the initial error point + self~setErrorPoint + /* make sure this is an xml document */ + if src[1]~pos('<?xml') <> 1 then do + self~create_error('Invalid XML document.') + return xmlerror~text + end + self~start_document + do while \eof + self~getchunk + end + -- we send the end_document even if there is an error + self~end_document + -- if we had an error, return the message as a return value + if xmlerror \= .nil then do + return xmlerror~text + end + return '' /*----------------------------------------------------------------------------*/ @@ -409,19 +707,18 @@ /*----------------------------------------------------------------------------*/ ::method parse_file -expose errortxt xmlfile -use strict arg xmlfile -tfile = .stream~new(xmlfile) -errortxt = tfile~open('read') -if errortxt <> 'READY:' then do - tfile~close() - return errortxt - end -lines = tfile~arrayin() -tfile~close() + expose xmlfile + use strict arg xmlfile + tfile = .stream~new(xmlfile) + errortxt = tfile~open('read') + if errortxt <> 'READY:' then do + tfile~close() + return errortxt + end + lines = tfile~arrayin() + tfile~close() -errortxt = self~parse_array(lines) -return errortxt + return self~parse_array(lines) /*----------------------------------------------------------------------------*/ @@ -431,12 +728,10 @@ /*----------------------------------------------------------------------------*/ ::method parse_stream -expose errortxt -use strict arg tfile -lines = tfile~arrayin() + use strict arg tfile + lines = tfile~arrayin() -errortxt = self~parse_array(lines) -return errortxt + return self~parse_array(lines) /*----------------------------------------------------------------------------*/ @@ -473,19 +768,17 @@ ::method init use strict arg -self~text = .nil -- For the start_element and passthrough methods this contains - -- the entire text string enclosed within the '<' and '>' - -- brackets. For the text method it contains a single line - -- of CDATA text. -self~tag = .nil -- For the start_element and end_element methods this is - -- the XML element (tag) name. For the end_element method the - -- leading '/' character is not a part of this string. -self~attr = .nil -- For the start_element method this is an ooRexx directory - -- class instance. Each attribute and value is contained in - -- the ooRexx directory instance. -return + self~text = .nil -- For the start_element and passthrough methods this contains + -- the entire text string enclosed within the '<' and '>' + -- brackets. For the text method it contains a single line + -- of CDATA text. + self~tag = .nil -- For the start_element and end_element methods this is + -- the XML element (tag) name. For the end_element method the + -- leading '/' character is not a part of this string. + self~attr = .nil -- For the start_element method this is an ooRexx directory + -- class instance. Each attribute and value is contained in + -- the ooRexx directory instance. - /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Class: XMLERROR */ @@ -521,10 +814,9 @@ /*----------------------------------------------------------------------------*/ ::method init -use strict arg -self~text = '' -self~filename = '' -self~line = 0 -self~charpos = 0 -return + use strict arg + self~text = '' + self~filename = '' + self~line = 0 + self~charpos = 0 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-07-01 00:37:54
|
Revision: 7985 http://oorexx.svn.sourceforge.net/oorexx/?rev=7985&view=rev Author: bigrixx Date: 2012-07-01 00:37:46 +0000 (Sun, 01 Jul 2012) Log Message: ----------- Numerous parser improvements Modified Paths: -------------- incubator/orxutils/xml/testxml.rex incubator/orxutils/xml/xmlparser.cls Modified: incubator/orxutils/xml/testxml.rex =================================================================== --- incubator/orxutils/xml/testxml.rex 2012-06-30 21:23:59 UTC (rev 7984) +++ incubator/orxutils/xml/testxml.rex 2012-07-01 00:37:46 UTC (rev 7985) @@ -65,7 +65,7 @@ ::method doctypeDecl use arg chunk -say '<'chunk~text'>' +say '<!DOCTYPE'chunk~text'>' return ::method comment Modified: incubator/orxutils/xml/xmlparser.cls =================================================================== --- incubator/orxutils/xml/xmlparser.cls 2012-06-30 21:23:59 UTC (rev 7984) +++ incubator/orxutils/xml/xmlparser.cls 2012-07-01 00:37:46 UTC (rev 7985) @@ -261,6 +261,8 @@ -- turn on the eof indicator so nothing else gets processed eof = .true self~error(xmlerror) -- pass this to the processing routine + -- now raise this as a syntax error to get back to the base + raise syntax 93.900 array(msg, xmlerror) /*----------------------------------------------------------------------------*/ @@ -405,6 +407,66 @@ /*----------------------------------------------------------------------------*/ +/* Method: parseName */ +/* Description: parse out a valid XML name. This will update the source */ +/* mutable buffer to remove the parsed out name. */ +/* Arguments: A source mutablebuffer */ +/*----------------------------------------------------------------------------*/ +::method parseName + use strict arg buffer + + -- if not at a namestart character, this is invalid. Return an error + -- indicator + if \buffer~matchChar(1, .xmlchar~namestart) then return .nil + -- scan for the end character + nameend = buffer~verify(.xmlchar~name,,2) + if nameend = 0 then nameend = buffer~length + 1 + -- extract the name + name = buffer~substr(1, nameend - 1) + -- remove this from the buffer + buffer~delstr(1, nameend - 1) + return name + + +/*----------------------------------------------------------------------------*/ +/* Method: parseQuotedValue */ +/* Description: parse out a valid quoted XML value string. This will update */ +/* the source buffer to remove the parsed out string. */ +/* Arguments: A source mutablebuffer */ +/*----------------------------------------------------------------------------*/ +::method parseQuotedValue + use strict arg buffer + + -- We must be at a quoted string value now...return .nil if not found + if \buffer~matchChar(1, '''"') then return .nil + delimiter = buffer~subchar(1) + -- scan for the end character + nameend = buffer~pos(delimiter, 2) + -- missing closing quote + if nameend = 0 then return .nil + -- extract the name + name = buffer~substr(2, nameend - 2) + -- remove this from the buffer + buffer~delstr(1, nameend + 1) + return name + + +/*----------------------------------------------------------------------------*/ +/* Method: skipWhiteSpace */ +/* Description: skip over whitespace in a buffer. This will update */ +/* the source buffer to remove the leading whitespace */ +/* Arguments: A source mutablebuffer */ +/*----------------------------------------------------------------------------*/ +::method skipWhiteSpace + use strict arg buffer + + firstNonBlank = buffer~verify(.xmlchar~space) + -- this is either all whitespace or we delete up to the first non-blank + if firstNonBlank = 0 then buffer~setBufferSize(0) + else buffer~delstr(1, firstNonBlank - 1) + + +/*----------------------------------------------------------------------------*/ /* Method: scanToTagEnd */ /* Description: scan to the end of an element tag, returning all of the */ /* characters between */ @@ -556,7 +618,9 @@ ::method parseEndElement element = self~scanToTagEnd chunk = .xmlchunk~new - chunk~tag = element + chunk~tag = self~parseName(element) + if chunk~tag == .nil then self~check_error("Invalid element end tag" element".") + if element~string \= '' then self~check_error("Invalid element end tag" element".") self~end_element(chunk) -- call the public override method return chunk @@ -569,38 +633,25 @@ ::method parseAttributes use arg element + -- skip over any leading white space + self~skipWhiteSpace(element) -- Note: this is the "=" form, which will ignore the whitespace - if element = '' then return .nil + if element~length = '' then return .nil attr = .directory~new - loop while element \= '' - -- attribute values must be quoted strings, but either single or - -- double quotes can be used... - assignment = element~pos('=') - -- hmmm, no assignment found, this is invalid - if assignment = 0 then do - -- do not allow attributes without values! - errortxt = 'Error line' errlineidx 'column' errcharidx || , - ': Invalid tag attribute' element'.' - -- create the error message and handle termination - self~create_error('Invalid tag attribute' element'.') - return .nil - end - -- pull off the attribute name and see what sort of - -- value we have - parse var element attrname =(assignment) +1 element - if element~match(1, "'") then do - parse var element "'" value "'" element - end - else if element~match(1, '"') then do - parse var element '"' value '"' element - end - else do - -- do not allow attributes without values! - self~create_error('Invalid attribute value' element'.') -- call the public override method - return .nil - end + loop while element~length \= 0 + -- parse off the name + attrname = self~parseName(element) + if attrname == .nil then self~create_error("Invalid attribute name" element".") + -- there must be an equal sign here + if \element~match(1, '=') then self~create_error("Invalid element attribute" element".") + -- step over the '=' + element~delstr(1, 1) + value = self~parseQuotedValue(element) + if value == .nil then self~create_error("Invalid attribute value" element".") -- these have the entities translated out attr[attrname] = self~xlatetext(value) + -- skip over any leading white space + self~skipWhiteSpace(element) end return attr @@ -622,13 +673,10 @@ element~setBufferSize(element~length - 1) endTag = .true end - -- convert to a string and strip now - element = .xmlchar~stripWhiteSpace(element)~string - -- ok, now process the attributes, if any - -- strip off the tag and parse off each of the attributes - parse var element chunk~tag element + chunk~tag = self~parseName(element) + if chunk~tag == .nil then self~create_error('Invalid element name.') -- now parse out the attributes chunk~attr = self~parseAttributes(element) @@ -654,15 +702,18 @@ chunk = .xmlchunk~new instruction = self~scanToTagEnd + if \instruction~match(instruction~length, '?') then self~create_error('Invalid processing instruction close tag.') + -- remove the ? from the end of the data + instruction~delstr(instruction~length) + if eof then do self~create_error('EOF within an XML tag.') -- call the public override method - return .nil end - -- instruction is now a string value - instruction = .xmlchar~stripWhiteSpace(instruction)~string + -- parse off the target name + chunk~tag = self~parseName(instruction) + if chunk~tag == .nil then self~create_error('Invalid processing instruction name.') + chunk~text = instruction~string - -- strip off the target name and parse off each of the attributes - parse var instruction chunk~tag chunk~text '?' self~processingInstruction(chunk) -- call the public override method return chunk @@ -680,7 +731,6 @@ chunk~text = .xmlchar~stripWhiteSpace(self~scanToTagEndNested)~string if eof then do self~create_error('EOF within a DOCTYPE tag.') -- call the public override method - return .nil end chunk~tag = '' self~doctypeDecl(chunk) -- call the public override method @@ -814,12 +864,12 @@ lineidx = 1 charidx = 1 xmlerror = .nil + signal on syntax -- set the initial error point self~setErrorPoint /* make sure this is an xml document */ if src[1]~pos('<?xml') <> 1 then do self~create_error('Invalid XML document.') - return xmlerror~text end self~start_document do while \eof @@ -827,11 +877,14 @@ end -- we send the end_document even if there is an error self~end_document + return '' +syntax: -- if we had an error, return the message as a return value if xmlerror \= .nil then do return xmlerror~text end - return '' + -- reraise any real syntax errors + raise propagate /*----------------------------------------------------------------------------*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-07-01 22:47:07
|
Revision: 7988 http://oorexx.svn.sourceforge.net/oorexx/?rev=7988&view=rev Author: bigrixx Date: 2012-07-01 22:47:01 +0000 (Sun, 01 Jul 2012) Log Message: ----------- Start of a domparser class Modified Paths: -------------- incubator/orxutils/xml/xmldom.cls incubator/orxutils/xml/xmlparser.cls Added Paths: ----------- incubator/orxutils/xml/domparser.cls Removed Paths: ------------- incubator/orxutils/xml/parsers/DOMParser.cls Added: incubator/orxutils/xml/domparser.cls =================================================================== --- incubator/orxutils/xml/domparser.cls (rev 0) +++ incubator/orxutils/xml/domparser.cls 2012-07-01 22:47:01 UTC (rev 7988) @@ -0,0 +1,260 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Description: DOM Parser for XML */ +/* */ +/* Copyright (c) 2012 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.ibm.com/developerworks/oss/CPLv1.0.htm */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 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. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS 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 COPYRIGHT */ +/* OWNER OR 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. */ +/* */ +/* Author: W. David Ashley */ +/* Contributors: Ruurd Idenburg */ +/* */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: XMLPARSER */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + + +::class "DomParser" subclass XMLParser + +/*----------------------------------------------------------------------------*/ +/* Method: start_document */ +/* Description: called before the start of document processing */ +/* Arguments: none */ +/*----------------------------------------------------------------------------*/ + +::method start_document +/* this method is designed to be overridden by a subclass */ + use strict arg + +/*----------------------------------------------------------------------------*/ +/* Method: end_document */ +/* Description: called after all parsing has completed */ +/* Arguments: none */ +/*----------------------------------------------------------------------------*/ + +::method end_document +/* this method is designed to be overridden by a subclass */ + use strict arg + +/*----------------------------------------------------------------------------*/ +/* Method: start_element */ +/* Description: called when a start element tag has been encountered. */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method start_element +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ +/* Method: end_element */ +/* Description: called when an end element tag has been encountered. */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method end_element +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ +/* Method: text */ +/* Description: called when character data has been encountered. */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method text +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ +/* Method: called when a comment tag has been encountered */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method comment +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ +/* Method: called when a CDATA tag has been encountered */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method cdata +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ +/* Method: called when a processing instruction has been encountered */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method processingInstruction +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ +/* Method: called when a <!DOCTYPE tag has been encountered */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method doctypeDecl +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ +/* Method: error */ +/* Description: called on an error. */ +/* Arguments: an xmlerror instance. */ +/*----------------------------------------------------------------------------*/ + +::method error +/* this method is designed to be overridden by a subclass */ + use strict arg xmlerror +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ +/* Class: ElementContext */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +-- class to manage the parsing context of an element under construction. +::class elementContext public +::constant xmlNamespace "http://www.w3.org/XML/1998/namespace" +::constant xmlnsNamespace "http://www.w3.org/2000/xmlns/" +-- the default W3C-defined reserved prefix mappings +::attribute defaultPrefixMap class +-- the parent node context to this node +::attribute parent + +::method init class + expose defaultPrefixMap + + defaultPrefixMap = .directory~new + defaultPrefixMap['xml'] = self~xmlNamespace + defaultPrefixMap['xmlns'] = self~xmlnsNamespace + +::method init + expose parser element parent + use strict arg parser, chunk, parent + + -- step one, figure out all of the namespaces associated with this + -- element. This is merged from the parent and extracted from the + -- attributes. + self~resolveNameSpaces(chunk, parent) + -- resolve the namespace for this based on whether the tag name has a + -- prefix + namespace = self~resolvePrefix(chunk~tag) + -- create the element + element = parser~doc~createElementNS(namespace, chunk~tag) + + -- now process all of the attributes + loop attr over chunk~attr + -- special meaning for this one + if attr == "xmlns" then namespace = self~xmlnsNamespace + -- otherwise go through the normal resolution process + else namespace = self~resolvePrefix(attr) + -- add the attribute to the the element + element~setAttributeNS(namespace, attr, chunk~attr[attr]) + end + +-- the element being constructed +::attribute element +-- URI of any namespace default applied to attributes and children +::attribute defaultNamespace +-- map of prefixes known in this element context +::attribute prefixMap + +::method resolveNameSpaces + expose prefixMap defaultNamespace parser + use strict arg chunk, parent + + -- if we have a parent node, then start out by inheriting the + -- xmlns declarations from it. + if parent \= .nil then do + defaultNamespace = parent~defaultNamespace + prefixMap = parent~prefixMap~copy + end + else do + -- no default (yet) and start with the default prefix map + defaultNamespace = .nil + prefixMap = .ElementContext~defaultPrefixMap~copy + end + + -- now look for xmlns attributes for this node + loop attrName over chunk~attr + -- default namespace has been specified for this element. This + -- will apply to any untagged attributes and children of this node. + if attrName == "xmlns" then do + uri = chunk~attr[attrName] + -- verify we're not attempting to use the standard namespaces illegally. + if uri == self~xmlNamespace then parser~create_error("URI" self~xmlNamespace "may not be used as the default element namespace.") + if uri == self~xmlnsNamespace then parser~create_error("URI" self~xmlnsNamespace "may not be used as the default element namespace.") + defaultNamespace = uri + end + -- tagged as an xmlns: prefix definition + else if attrName~match(1, "xmlns:") then do + -- add this value to our prefix map + parse var attrName ":" prefix + if prefix = "xml" | prefix = "xmlns" then parser~create_error("Prefix" prefix "may not be redefined in a document.") + if \.xmlchar~isNCName(prefix) then parser~create_error("Invalid prefix name" prefix".") + prefixMap[prefix] = value + end + end + +-- resolve a prefix to its URI equivalent for the current element context. +::method resolvePrefix + expose parser defaultNamespace prefixMap + use arg tagName + + -- no prefix on the tag name, so use the default + if tagName~pos(":") == 0 then return defaultNamespace + + parse var tagname prefix ':' localName + + -- this needs to be in the map, otherwise it is an error + namespace = prefixMap[prefix] + if namespace = .nil then parser~createError("Unknown namespace prefix:" prefix) + if \.xmlchar~isNCName(localName) then parser~create_error("Invalid XML localName" localName".") + + return namespace + +-- add a child node to this element +::method addChildNode + expose element + use strict arg node + element~appendChild(node) + +::requires "xmldom.cls" +::requires "xmlparser.cls" Deleted: incubator/orxutils/xml/parsers/DOMParser.cls =================================================================== --- incubator/orxutils/xml/parsers/DOMParser.cls 2012-07-01 19:45:39 UTC (rev 7987) +++ incubator/orxutils/xml/parsers/DOMParser.cls 2012-07-01 22:47:01 UTC (rev 7988) @@ -1,6 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ -/* Class: CoreDOMImplementation */ -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ - Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-07-01 19:45:39 UTC (rev 7987) +++ incubator/orxutils/xml/xmldom.cls 2012-07-01 22:47:01 UTC (rev 7988) @@ -2,7 +2,7 @@ /* */ /* Description: An implementation of the Document Object Model in ooRexx. */ /* */ -/* Copyright (c) 2006 Rexx Language Association. All rights reserved. */ +/* Copyright (c) 2012 Rexx Language Association. All rights reserved. */ /* */ /* This program and the accompanying materials are made available under */ /* the terms of the Common Public License v1.0 which accompanies this */ @@ -37,17 +37,8 @@ /* */ /*----------------------------------------------------------------------------*/ - /*----------------------------------------------------------------------------*/ -/* */ -/* NOTE!!!!!!!!!!! */ -/* This class file does not yet work! It is under development! */ -/* It is VERY incomplete! */ -/* */ /*----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------*/ -/*----------------------------------------------------------------------------*/ /* Section: Abstract DOM interface class definitions */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ Modified: incubator/orxutils/xml/xmlparser.cls =================================================================== --- incubator/orxutils/xml/xmlparser.cls 2012-07-01 19:45:39 UTC (rev 7987) +++ incubator/orxutils/xml/xmlparser.cls 2012-07-01 22:47:01 UTC (rev 7988) @@ -702,13 +702,14 @@ chunk = .xmlchunk~new instruction = self~scanToTagEnd - if \instruction~match(instruction~length, '?') then self~create_error('Invalid processing instruction close tag.') - -- remove the ? from the end of the data - instruction~delstr(instruction~length) if eof then do self~create_error('EOF within an XML tag.') -- call the public override method end + + if \instruction~match(instruction~length, '?') then self~create_error('Invalid processing instruction close tag.') + -- remove the ? from the end of the data + instruction~delstr(instruction~length) -- parse off the target name chunk~tag = self~parseName(instruction) if chunk~tag == .nil then self~create_error('Invalid processing instruction name.') @@ -824,7 +825,7 @@ use strict arg chunk /*----------------------------------------------------------------------------*/ -/* Method: called when a CDATA tag has been encountered */ +/* Method: called when a <!DOCTYPE tag has been encountered */ /* Arguments: an xmlchunk instance. */ /*----------------------------------------------------------------------------*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-07-02 18:14:43
|
Revision: 7991 http://oorexx.svn.sourceforge.net/oorexx/?rev=7991&view=rev Author: bigrixx Date: 2012-07-02 18:14:36 +0000 (Mon, 02 Jul 2012) Log Message: ----------- Rework the subclassing model and more work on the dom parser Modified Paths: -------------- incubator/orxutils/xml/domparser.cls incubator/orxutils/xml/xmldom.cls incubator/orxutils/xml/xmlparser.cls Modified: incubator/orxutils/xml/domparser.cls =================================================================== --- incubator/orxutils/xml/domparser.cls 2012-07-02 02:58:54 UTC (rev 7990) +++ incubator/orxutils/xml/domparser.cls 2012-07-02 18:14:36 UTC (rev 7991) @@ -35,9 +35,6 @@ /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ -/* Author: W. David Ashley */ -/* Contributors: Ruurd Idenburg */ -/* */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ @@ -46,18 +43,77 @@ /*----------------------------------------------------------------------------*/ -::class "DomParser" subclass XMLParser +::class "DomParser" inherit xmlcontenthandler +::method init + expose parser + -- create a parser instance with this parser as the content handler + parser = .xmlparser~new(self) + /*----------------------------------------------------------------------------*/ +/* Method: parse_array */ +/* Description: parse the specified array of XML code. */ +/*----------------------------------------------------------------------------*/ + +::method parse_array + expose doc parser + + -- have the parser process this + forward to(parser) continue + -- return the doc instance. If this failed, then the + -- error can be retrieved after the fact + return doc + + +/*----------------------------------------------------------------------------*/ +/* Method: parse_file */ +/* Description: parse the specified file of XML code. */ +/*----------------------------------------------------------------------------*/ + +::method parse_file + expose doc parser + + -- have the parser process this + forward to(parser) continue + -- return the doc instance. If this failed, then the + -- error can be retrieved after the fact + return doc + +/*----------------------------------------------------------------------------*/ +/* Method: parse_stream */ +/* Description: parse the specified stream of XML code */ +/* The stream should be opened, and will not be closed at the end*/ +/*----------------------------------------------------------------------------*/ + +::method parse_stream + expose doc parser + + -- have the parser process this + forward to(parser) continue + -- return the doc instance. If this failed, then the + -- error can be retrieved after the fact + return doc + + +/*----------------------------------------------------------------------------*/ /* Method: start_document */ /* Description: called before the start of document processing */ /* Arguments: none */ /*----------------------------------------------------------------------------*/ ::method start_document -/* this method is designed to be overridden by a subclass */ + expose doc dom xmlerror currentElement rootElement use strict arg + -- clear parsing state + xmlerror = .nil + currentElement = .nil + rootElement = .nil + + -- we're live...get the DOM and create a document instance + dom = .ooRexxDOM~implementation + document = dom~createDocument + /*----------------------------------------------------------------------------*/ /* Method: end_document */ /* Description: called after all parsing has completed */ @@ -75,9 +131,23 @@ /*----------------------------------------------------------------------------*/ ::method start_element -/* this method is designed to be overridden by a subclass */ + expose currentElement rootElement doc + use strict arg chunk + -- create a new context for the new element, inheriting the namespace + -- definitions from the parents. + newElement = .ElementContext~new(self, chunk currentElement) + + -- set the root element if this is the first one + if rootElement == .nil then do + rootElement = newElement + -- add this as the root element of the document + doc~appendChild(newElement) + end + -- this is the top of the stack + currentElement = newElement + /*----------------------------------------------------------------------------*/ /* Method: end_element */ /* Description: called when an end element tag has been encountered. */ @@ -85,9 +155,15 @@ /*----------------------------------------------------------------------------*/ ::method end_element -/* this method is designed to be overridden by a subclass */ + expose currentElement use strict arg chunk + -- this must be an exact match + if chunk~tag \== currentElement~element~tagName then + self~create_error("End tag" chunk~tag "does not match current element" element~tagName) + -- pop this off the stack and make it the new current + currentElement = currentElement~parent + /*----------------------------------------------------------------------------*/ /* Method: text */ /* Description: called when character data has been encountered. */ @@ -95,45 +171,60 @@ /*----------------------------------------------------------------------------*/ ::method text -/* this method is designed to be overridden by a subclass */ + expose doc currentElement use strict arg chunk + -- an element may have multiple text nodes, so we need to + -- explicitly create the node and append it as a child to the current element + text = doc~createTextNode(chunk~text) + currentElement~appendChild(text) + /*----------------------------------------------------------------------------*/ /* Method: called when a comment tag has been encountered */ /* Arguments: an xmlchunk instance. */ /*----------------------------------------------------------------------------*/ ::method comment -/* this method is designed to be overridden by a subclass */ + expose doc currentElement use strict arg chunk + -- just create the node and add to the current element + currentElement~appendChild(doc~createComment(chunk~text)) + /*----------------------------------------------------------------------------*/ /* Method: called when a CDATA tag has been encountered */ /* Arguments: an xmlchunk instance. */ /*----------------------------------------------------------------------------*/ ::method cdata -/* this method is designed to be overridden by a subclass */ + expose doc currentElement use strict arg chunk + -- just create the node and add to the current element + currentElement~appendChild(doc~createCDataSection(chunk~text)) + /*----------------------------------------------------------------------------*/ /* Method: called when a processing instruction has been encountered */ /* Arguments: an xmlchunk instance. */ /*----------------------------------------------------------------------------*/ ::method processingInstruction -/* this method is designed to be overridden by a subclass */ + expose doc currentElement use strict arg chunk + -- just create the node and add to the current element + currentElement~appendChild(doc~createProcessingInstruction(chunk~tag, chunk~text)) + /*----------------------------------------------------------------------------*/ /* Method: called when a <!DOCTYPE tag has been encountered */ /* Arguments: an xmlchunk instance. */ /*----------------------------------------------------------------------------*/ ::method doctypeDecl -/* this method is designed to be overridden by a subclass */ use strict arg chunk + -- not handled currently + /*----------------------------------------------------------------------------*/ /* Method: error */ /* Description: called on an error. */ @@ -141,8 +232,12 @@ /*----------------------------------------------------------------------------*/ ::method error -/* this method is designed to be overridden by a subclass */ + expose xmlerror doc use strict arg xmlerror + -- no document to return if there's an error + doc = .nil + + /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ /* Class: ElementContext */ Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-07-02 02:58:54 UTC (rev 7990) +++ incubator/orxutils/xml/xmldom.cls 2012-07-02 18:14:36 UTC (rev 7991) @@ -155,7 +155,7 @@ ::method createElement abstract ::method createElementNS abstract ::method createEntityReference abstract -::method createProcessinginstruction abstract +::method createProcessingInstruction abstract ::method createTextNode abstract ::method doctype abstract ::method documentElement abstract Modified: incubator/orxutils/xml/xmlparser.cls =================================================================== --- incubator/orxutils/xml/xmlparser.cls 2012-07-02 02:58:54 UTC (rev 7990) +++ incubator/orxutils/xml/xmlparser.cls 2012-07-02 18:14:36 UTC (rev 7991) @@ -208,13 +208,120 @@ end + /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ +/* Class: XMLCONTENTHANDLER */ +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ + +-- class for plugging in a content handler for parsing events +::class "XmlContentHandler" mixinclass Object public + +/*----------------------------------------------------------------------------*/ +/* Method: start_document */ +/* Description: called before the start of document processing */ +/* Arguments: none */ +/*----------------------------------------------------------------------------*/ + +::method start_document +/* this method is designed to be overridden by a subclass */ + use strict arg + +/*----------------------------------------------------------------------------*/ +/* Method: end_document */ +/* Description: called after all parsing has completed */ +/* Arguments: none */ +/*----------------------------------------------------------------------------*/ + +::method end_document +/* this method is designed to be overridden by a subclass */ + use strict arg + +/*----------------------------------------------------------------------------*/ +/* Method: start_element */ +/* Description: called when a start element tag has been encountered. */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method start_element +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ +/* Method: end_element */ +/* Description: called when an end element tag has been encountered. */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method end_element +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ +/* Method: text */ +/* Description: called when character data has been encountered. */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method text +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ +/* Method: called when a comment tag has been encountered */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method comment +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ +/* Method: called when a CDATA tag has been encountered */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method cdata +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ +/* Method: called when a processing instruction has been encountered */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method processingInstruction +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ +/* Method: called when a <!DOCTYPE tag has been encountered */ +/* Arguments: an xmlchunk instance. */ +/*----------------------------------------------------------------------------*/ + +::method doctypeDecl +/* this method is designed to be overridden by a subclass */ + use strict arg chunk + +/*----------------------------------------------------------------------------*/ +/* Method: error */ +/* Description: called on an error. */ +/* Arguments: an xmlerror instance. */ +/*----------------------------------------------------------------------------*/ + +::method error +/* this method is designed to be overridden by a subclass */ + use strict arg xmlerror + + +/*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ /* Class: XMLPARSER */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -::class xmlparser subclass object public +::class xmlparser subclass object public inherit xmlcontenthandler /*----------------------------------------------------------------------------*/ @@ -224,6 +331,11 @@ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ +::method init + expose contentHandler + -- the default content handler is to redirect to ourselves...useful for subclassing + use strict arg contentHandler = (self) + ::constant parserver '0.5' -- the version of this parser ::constant eol '0a'x -- newline character used for XML ::constant tab '09'x @@ -251,7 +363,7 @@ /*----------------------------------------------------------------------------*/ ::method create_error private - expose errlineidx errcharidx xmlerror eof + expose errlineidx errcharidx xmlerror eof contentHandler use strict arg msg xmlerror = .xmlerror~new xmlerror~text = 'Error on line' errlineidx', column' errcharidx':' msg @@ -260,7 +372,7 @@ xmlerror~charpos = errpos -- turn on the eof indicator so nothing else gets processed eof = .true - self~error(xmlerror) -- pass this to the processing routine + contentHandler~error(xmlerror) -- pass this to the processing routine -- now raise this as a syntax error to get back to the base raise syntax 93.900 array(msg, xmlerror) @@ -528,7 +640,7 @@ /* Arguments: none */ /*----------------------------------------------------------------------------*/ ::method parseText - expose eof + expose eof contentHandler chunk = .xmlchunk~new -- we found some text data text = .mutablebuffer~new @@ -546,7 +658,7 @@ -- if this chunk if just whitespace characters (including lineneds), just -- ignore it. if chunk~text~verify(' '||self~tab||self~eol) \= 0 then - self~text(chunk) -- call the public override method + contentHandler~text(chunk) -- call the public override method return chunk @@ -556,7 +668,7 @@ /* Arguments: none */ /*----------------------------------------------------------------------------*/ ::method parseCData - expose eof + expose eof contentHandler chunk = .xmlchunk~new -- we found some text data data = .mutablebuffer~new @@ -577,7 +689,7 @@ -- cdata information does not recognize entities. chunk~text = data~string - self~cdata(chunk) -- call the public override method + contentHandler~cdata(chunk) -- call the public override method return chunk /*----------------------------------------------------------------------------*/ @@ -586,7 +698,7 @@ /* Arguments: none */ /*----------------------------------------------------------------------------*/ ::method parseComment - expose eof + expose eof contentHandler chunk = .xmlchunk~new -- we found some text data data = .mutablebuffer~new @@ -607,7 +719,7 @@ -- comment information does not recognize entities. chunk~text = data~string - self~comment(chunk) -- call the public override method + contentHandler~comment(chunk) -- call the public override method return chunk /*----------------------------------------------------------------------------*/ @@ -616,12 +728,13 @@ /* Arguments: none */ /*----------------------------------------------------------------------------*/ ::method parseEndElement + expose contentHandler element = self~scanToTagEnd chunk = .xmlchunk~new chunk~tag = self~parseName(element) if chunk~tag == .nil then self~check_error("Invalid element end tag" element".") if element~string \= '' then self~check_error("Invalid element end tag" element".") - self~end_element(chunk) -- call the public override method + contentHandler~end_element(chunk) -- call the public override method return chunk @@ -663,6 +776,7 @@ /*----------------------------------------------------------------------------*/ ::method parseElement + expose contentHandler element = self~scanToTagEnd chunk = .xmlchunk~new -- assume this is not a complete tag element @@ -681,12 +795,12 @@ -- now parse out the attributes chunk~attr = self~parseAttributes(element) - self~start_element(chunk) -- call the public override method + contentHandler~start_element(chunk) -- call the public override method -- self terminating element? if endTag then do endchunk = .xmlchunk~new endchunk~tag = chunk~tag - self~end_element(endchunk) -- call the public override method + contentHandler~end_element(endchunk) -- call the public override method end return chunk @@ -698,7 +812,7 @@ /* Arguments: none */ /*----------------------------------------------------------------------------*/ ::method parseProcessingInstruction - expose eof + expose eof contentHandler chunk = .xmlchunk~new instruction = self~scanToTagEnd @@ -715,7 +829,7 @@ if chunk~tag == .nil then self~create_error('Invalid processing instruction name.') chunk~text = instruction~string - self~processingInstruction(chunk) -- call the public override method + contentHandler~processingInstruction(chunk) -- call the public override method return chunk @@ -726,7 +840,7 @@ /* Arguments: none */ /*----------------------------------------------------------------------------*/ ::method parseDoctype - expose eof + expose eof contentHandler chunk = .xmlchunk~new chunk~text = .xmlchar~stripWhiteSpace(self~scanToTagEndNested)~string @@ -734,7 +848,7 @@ self~create_error('EOF within a DOCTYPE tag.') -- call the public override method end chunk~tag = '' - self~doctypeDecl(chunk) -- call the public override method + contentHandler~doctypeDecl(chunk) -- call the public override method return chunk @@ -748,102 +862,6 @@ ::attribute xmlfile private -- the XML file name, if known /*----------------------------------------------------------------------------*/ -/* Method: start_document */ -/* Description: called before the start of document processing */ -/* Arguments: none */ -/*----------------------------------------------------------------------------*/ - -::method start_document -/* this method is designed to be overridden by a subclass */ - use strict arg - -/*----------------------------------------------------------------------------*/ -/* Method: end_document */ -/* Description: called after all parsing has completed */ -/* Arguments: none */ -/*----------------------------------------------------------------------------*/ - -::method end_document -/* this method is designed to be overridden by a subclass */ - use strict arg - -/*----------------------------------------------------------------------------*/ -/* Method: start_element */ -/* Description: called when a start element tag has been encountered. */ -/* Arguments: an xmlchunk instance. */ -/*----------------------------------------------------------------------------*/ - -::method start_element -/* this method is designed to be overridden by a subclass */ - use strict arg chunk - -/*----------------------------------------------------------------------------*/ -/* Method: end_element */ -/* Description: called when an end element tag has been encountered. */ -/* Arguments: an xmlchunk instance. */ -/*----------------------------------------------------------------------------*/ - -::method end_element -/* this method is designed to be overridden by a subclass */ - use strict arg chunk - -/*----------------------------------------------------------------------------*/ -/* Method: text */ -/* Description: called when character data has been encountered. */ -/* Arguments: an xmlchunk instance. */ -/*----------------------------------------------------------------------------*/ - -::method text -/* this method is designed to be overridden by a subclass */ - use strict arg chunk - -/*----------------------------------------------------------------------------*/ -/* Method: called when a comment tag has been encountered */ -/* Arguments: an xmlchunk instance. */ -/*----------------------------------------------------------------------------*/ - -::method comment -/* this method is designed to be overridden by a subclass */ - use strict arg chunk - -/*----------------------------------------------------------------------------*/ -/* Method: called when a CDATA tag has been encountered */ -/* Arguments: an xmlchunk instance. */ -/*----------------------------------------------------------------------------*/ - -::method cdata -/* this method is designed to be overridden by a subclass */ - use strict arg chunk - -/*----------------------------------------------------------------------------*/ -/* Method: called when a processing instruction has been encountered */ -/* Arguments: an xmlchunk instance. */ -/*----------------------------------------------------------------------------*/ - -::method processingInstruction -/* this method is designed to be overridden by a subclass */ - use strict arg chunk - -/*----------------------------------------------------------------------------*/ -/* Method: called when a <!DOCTYPE tag has been encountered */ -/* Arguments: an xmlchunk instance. */ -/*----------------------------------------------------------------------------*/ - -::method doctypeDecl -/* this method is designed to be overridden by a subclass */ - use strict arg chunk - -/*----------------------------------------------------------------------------*/ -/* Method: error */ -/* Description: called on an error. */ -/* Arguments: an xmlerror instance. */ -/*----------------------------------------------------------------------------*/ - -::method error -/* this method is designed to be overridden by a subclass */ - use strict arg xmlerror - -/*----------------------------------------------------------------------------*/ /* Method: getversion */ /* Description: return the version of this class. */ /*----------------------------------------------------------------------------*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2012-07-02 20:05:10
|
Revision: 7992 http://oorexx.svn.sourceforge.net/oorexx/?rev=7992&view=rev Author: bigrixx Date: 2012-07-02 20:05:03 +0000 (Mon, 02 Jul 2012) Log Message: ----------- DOM parser is working at least minimally now Modified Paths: -------------- incubator/orxutils/xml/domparser.cls incubator/orxutils/xml/xmldom.cls incubator/orxutils/xml/xmlparser.cls Added Paths: ----------- incubator/orxutils/xml/testdom.rex Modified: incubator/orxutils/xml/domparser.cls =================================================================== --- incubator/orxutils/xml/domparser.cls 2012-07-02 18:14:36 UTC (rev 7991) +++ incubator/orxutils/xml/domparser.cls 2012-07-02 20:05:03 UTC (rev 7992) @@ -43,13 +43,16 @@ /*----------------------------------------------------------------------------*/ -::class "DomParser" inherit xmlcontenthandler +::class "DomParser" public inherit xmlcontenthandler ::method init expose parser -- create a parser instance with this parser as the content handler parser = .xmlparser~new(self) +-- the document currently being constructed +::attribute doc + /*----------------------------------------------------------------------------*/ /* Method: parse_array */ /* Description: parse the specified array of XML code. */ @@ -112,7 +115,7 @@ -- we're live...get the DOM and create a document instance dom = .ooRexxDOM~implementation - document = dom~createDocument + doc = dom~createDocument /*----------------------------------------------------------------------------*/ /* Method: end_document */ @@ -137,13 +140,13 @@ -- create a new context for the new element, inheriting the namespace -- definitions from the parents. - newElement = .ElementContext~new(self, chunk currentElement) + newElement = .ElementContext~new(self, chunk, currentElement) -- set the root element if this is the first one if rootElement == .nil then do rootElement = newElement -- add this as the root element of the document - doc~appendChild(newElement) + doc~appendChild(newElement~element) end -- this is the top of the stack currentElement = newElement @@ -177,7 +180,7 @@ -- an element may have multiple text nodes, so we need to -- explicitly create the node and append it as a child to the current element text = doc~createTextNode(chunk~text) - currentElement~appendChild(text) + currentElement~element~appendChild(text) /*----------------------------------------------------------------------------*/ /* Method: called when a comment tag has been encountered */ @@ -188,8 +191,16 @@ expose doc currentElement use strict arg chunk - -- just create the node and add to the current element - currentElement~appendChild(doc~createComment(chunk~text)) + -- comments can appear anywhere...even before the first element + -- if we have a current element being processed, then add this to that + if currentElement \= .nil then do + -- just create the node and add to the current element + currentElement~element~appendChild(doc~createComment(chunk~text)) + end + else do + -- add the comment to the document as a child + doc~appendChild(doc~createComment(chunk~text)) + end /*----------------------------------------------------------------------------*/ /* Method: called when a CDATA tag has been encountered */ @@ -201,7 +212,7 @@ use strict arg chunk -- just create the node and add to the current element - currentElement~appendChild(doc~createCDataSection(chunk~text)) + currentElement~element~appendChild(doc~createCDataSection(chunk~text)) /*----------------------------------------------------------------------------*/ /* Method: called when a processing instruction has been encountered */ @@ -212,8 +223,15 @@ expose doc currentElement use strict arg chunk - -- just create the node and add to the current element - currentElement~appendChild(doc~createProcessingInstruction(chunk~tag, chunk~text)) + -- if we have a current element being processed, then add this to that + if currentElement \= .nil then do + -- just create the node and add to the current element + currentElement~element~appendChild(doc~createProcessingInstruction(chunk~tag, chunk~text)) + end + else do + -- add the processing instruction to the document as a child + doc~appendChild(doc~createProcessingInstruction(chunk~tag, chunk~text)) + end /*----------------------------------------------------------------------------*/ /* Method: called when a <!DOCTYPE tag has been encountered */ Added: incubator/orxutils/xml/testdom.rex =================================================================== --- incubator/orxutils/xml/testdom.rex (rev 0) +++ incubator/orxutils/xml/testdom.rex 2012-07-02 20:05:03 UTC (rev 7992) @@ -0,0 +1,54 @@ +/*----------------------------------------------------------------------------*/ +/* */ +/* Description: Test the XML parser class. */ +/* */ +/* Copyright (c) 2006 Rexx Language Association. All rights reserved. */ +/* */ +/* This program and the accompanying materials are made available under */ +/* the terms of the Common Public License v1.0 which accompanies this */ +/* distribution. A copy is also available at the following address: */ +/* http://www.ibm.com/developerworks/oss/CPLv1.0.htm */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* 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. */ +/* */ +/* Neither the name of Rexx Language Association nor the names */ +/* of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS 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 COPYRIGHT */ +/* OWNER OR 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. */ +/* */ +/* Author: W. David Ashley */ +/* */ +/*----------------------------------------------------------------------------*/ + + +parser = .domparser~new() +doc = parser~parse_file('testxml.xml') +if doc == .nil then do + say parser~xmlerror~text + exit +end +root = doc~documentElement +say root~tagName + +return + +::requires 'domparser.cls' Modified: incubator/orxutils/xml/xmldom.cls =================================================================== --- incubator/orxutils/xml/xmldom.cls 2012-07-02 18:14:36 UTC (rev 7991) +++ incubator/orxutils/xml/xmldom.cls 2012-07-02 20:05:03 UTC (rev 7992) @@ -1320,12 +1320,12 @@ end return newNode -::attribute ownerDocument GET ::attribute ownerDocument SET private - expose ownerDocument firstChild + expose firstChild + use strict arg doc -- we need to set this at the higher levels too - self~"OWNERDOCUMENT":super(doc) + forward class(super) continue -- set this in each of the children too child = firstChild do while child \= .nil @@ -1343,7 +1343,7 @@ ::attribute lastChild GET ::method insertBefore - expose firstChild lastChild ownerDocument childNodes + expose firstChild lastChild childNodes use arg newChild, refChild = .nil, replace = .false -- this case is really a no-op, but we need to go through the steps @@ -1356,7 +1356,7 @@ end -- inform the owner that this is happening - ownerDocument~insertingNode(self, replace) + self~ownerDocument~insertingNode(self, replace) -- make sure we've detached this node from any previous -- parent node. @@ -1408,14 +1408,14 @@ -- broadcast a change event self~changed -- inform the document of this update - ownerDocument~insertedNode(self, newChild, replace) + self~ownerDocument~insertedNode(self, newChild, replace) return newChild ::method removeChild - expose firstChild lastChild ownerDocument childNodes + expose firstChild lastChild childNodes use strict arg oldChild, replace = .false - ownerDocument~removingNode(self, oldChild, replace) + self~ownerDocument~removingNode(self, oldChild, replace) -- removing the first child if oldChild == firstChild then do @@ -1452,11 +1452,10 @@ -- note the change update self~changed - ownerDocument~removedNode(self, replace) + self~ownerDocument~removedNode(self, replace) return oldChild ::method replaceChild - expose ownerDocument use strict arg newChild, oldChild self~insertBefore(newChild, oldChild, .true) @@ -1464,7 +1463,7 @@ self~removeChild(oldChild, .true) end - ownerDocument~replacedNode(self) + self~ownerDocument~replacedNode(self) return oldChild ::attribute textContent GET @@ -6047,6 +6046,7 @@ allowGrammerAccess errorChecking documentNumber nodeCounter nodeTable use strict arg docType = .nil, grammarAccess = .false self~init:super(.nil) + -- we are our own owning document for purposes of child appends self~ownerDocument = self docElement = .nil @@ -6072,11 +6072,6 @@ appendChild(docType) end -::attribute ownerDocument GET - use strict arg - -- documents don't have an owner - return .nil - ::attribute nodeType GET use strict arg return .Node~DOCUMENT_NODE Modified: incubator/orxutils/xml/xmlparser.cls =================================================================== --- incubator/orxutils/xml/xmlparser.cls 2012-07-02 18:14:36 UTC (rev 7991) +++ incubator/orxutils/xml/xmlparser.cls 2012-07-02 20:05:03 UTC (rev 7992) @@ -876,7 +876,7 @@ /*----------------------------------------------------------------------------*/ ::method parse_array - expose src lineidx charidx eof xmlerror + expose src lineidx charidx eof xmlerror contentHandler use strict arg src eof = .false /* parse the xml array */ @@ -890,12 +890,12 @@ if src[1]~pos('<?xml') <> 1 then do self~create_error('Invalid XML document.') end - self~start_document + contentHandler~start_document do while \eof self~getchunk end -- we send the end_document even if there is an error - self~end_document + contentHandler~end_document return '' syntax: -- if we had an error, return the message as a return value This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |