[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r10316: Corrections and new implemen
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r10316: Corrections and new implementations of XMLNode methods and XML parsing. |
Date: |
Fri, 21 Nov 2008 13:03:31 +0100 |
User-agent: |
Bazaar (1.5) |
------------------------------------------------------------
revno: 10316
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Fri 2008-11-21 13:03:31 +0100
message:
Corrections and new implementations of XMLNode methods and XML parsing.
modified:
libcore/asobj/XMLNode_as.cpp
libcore/asobj/XMLNode_as.h
libcore/asobj/XML_as.cpp
libcore/asobj/XML_as.h
testsuite/actionscript.all/XMLNode.as
------------------------------------------------------------
revno: 10315.1.1
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Fri 2008-11-21 09:11:07 +0100
message:
Allow setting XMLNode attributes.
modified:
libcore/asobj/XMLNode_as.cpp
libcore/asobj/XMLNode_as.h
libcore/asobj/XML_as.cpp
------------------------------------------------------------
revno: 10315.1.2
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Fri 2008-11-21 09:14:38 +0100
message:
Test passes.
modified:
testsuite/actionscript.all/XMLNode.as
------------------------------------------------------------
revno: 10315.1.3
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Fri 2008-11-21 09:26:05 +0100
message:
Test enumeration order of attributes (it's normal, but different from
order when parsing, which suggests that parsing constructs values in
a different order).
modified:
libcore/asobj/XMLNode_as.cpp
testsuite/actionscript.all/XMLNode.as
------------------------------------------------------------
revno: 10315.1.4
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Fri 2008-11-21 10:51:27 +0100
message:
Correct attribute construction order during parsing. Implement
XMLNode.getNamespaceForPrefix.
modified:
libcore/asobj/XMLNode_as.cpp
libcore/asobj/XMLNode_as.h
libcore/asobj/XML_as.cpp
libcore/asobj/XML_as.h
testsuite/actionscript.all/XMLNode.as
------------------------------------------------------------
revno: 10315.1.5
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Fri 2008-11-21 11:50:16 +0100
message:
Implement XMLNode.getPrefixForNamespace.
modified:
libcore/asobj/XMLNode_as.cpp
libcore/asobj/XMLNode_as.h
testsuite/actionscript.all/XMLNode.as
------------------------------------------------------------
revno: 10315.1.6
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Fri 2008-11-21 12:10:23 +0100
message:
Add some more tests and a minor correction to attributes parsing.
modified:
libcore/asobj/XML_as.cpp
testsuite/actionscript.all/XMLNode.as
=== modified file 'libcore/asobj/XMLNode_as.cpp'
--- a/libcore/asobj/XMLNode_as.cpp 2008-11-20 17:50:40 +0000
+++ b/libcore/asobj/XMLNode_as.cpp 2008-11-21 10:50:16 +0000
@@ -27,7 +27,9 @@
#include "Object.h" // for getObjectInterface
#include "VM.h" // for getting the string_table.
#include "string_table.h"
+#include "PropertyList.h"
+#include <boost/bind.hpp>
#include <string>
#include <sstream>
#include <vector>
@@ -37,6 +39,16 @@
namespace gnash {
+namespace {
+ void enumerateAttributes(const XMLNode_as& node,
+ PropertyList::SortedPropertyList&attributes);
+ bool prefixMatches(const PropertyList::SortedPropertyList::value_type& val,
+ const std::string& prefix);
+ bool namespaceMatches(
+ const PropertyList::SortedPropertyList::value_type& val,
+ const std::string& ns);
+}
+
static as_value xmlnode_new(const fn_call& fn);
static as_value xmlnode_nodename(const fn_call& fn);
static as_value xmlnode_node_value(const fn_call& fn);
@@ -67,6 +79,7 @@
:
as_object(getXMLNodeInterface()),
_parent(0),
+ _attributes(new as_object),
_type(Element)
{
//log_debug("%s: %p", __PRETTY_FUNCTION__, this);
@@ -79,6 +92,7 @@
:
as_object(getXMLNodeInterface()),
_parent(0), // _parent is never implicitly copied
+ _attributes(0),
_name(tpl._name),
_value(tpl._value),
_type(tpl._type)
@@ -243,7 +257,8 @@
XMLNode_as *previous_node = NULL;
Children::reverse_iterator itx;
- for (itx = _parent->_children.rbegin(); itx != _parent->_children.rend();
itx++)
+ for (itx = _parent->_children.rbegin(); itx != _parent->_children.rend();
+ itx++)
{
if (itx->get() == this)
{
@@ -261,6 +276,77 @@
stringify(*this, xmlout, encode);
}
+void
+XMLNode_as::setAttribute(const std::string& name, const std::string& value)
+{
+ if (_attributes) {
+ string_table& st = _vm.getStringTable();
+ _attributes->set_member(st.find(name), value);
+ }
+}
+
+bool
+XMLNode_as::getPrefixForNamespace(const std::string& ns, std::string& prefix)
+{
+ XMLNode_as* node = this;
+ PropertyList::SortedPropertyList::const_iterator it;
+
+ while (node)
+ {
+ PropertyList::SortedPropertyList attrs;
+ enumerateAttributes(*node, attrs);
+ if (!attrs.empty())
+ {
+ it = std::find_if(attrs.begin(), attrs.end(),
+ boost::bind(namespaceMatches, _1, ns));
+ if (it != attrs.end()) break;
+ }
+ node = node->getParent();
+ }
+
+ // None found.
+ if (!node) return false;
+
+ // Return the matching prefix
+ const std::string& name = it->first;
+ std::string::size_type pos = name.find(':');
+
+ /// If we have a match and there is no colon, this is a standard
+ /// namespace.
+ if (pos == std::string::npos) return true;
+
+ prefix = name.substr(pos + 1);
+ return true;
+
+}
+
+void
+XMLNode_as::getNamespaceForPrefix(const std::string& prefix, std::string& ns)
+{
+ XMLNode_as* node = this;
+ PropertyList::SortedPropertyList::const_iterator it;
+
+ while (node)
+ {
+ PropertyList::SortedPropertyList attrs;
+ enumerateAttributes(*node, attrs);
+ if (!attrs.empty())
+ {
+ it = std::find_if(attrs.begin(), attrs.end(),
+ boost::bind(prefixMatches, _1, prefix));
+ if (it != attrs.end()) break;
+ }
+ node = node->getParent();
+ }
+
+ // None found; return undefined
+ if (!node) return;
+
+ // Return the matching namespace
+ ns = it->second;
+
+}
+
/* static private */
void
XMLNode_as::stringify(const XMLNode_as& xml, std::ostream& xmlout, bool
encode)
@@ -278,16 +364,20 @@
#endif
// Create the beginning of the tag
- if ( nodename.size() )
+ if (!nodename.empty())
{
xmlout << "<" << nodename;
// Process the attributes, if any
- Attributes::const_iterator ita;
- for (ita = xml._attributes.begin(); ita != xml._attributes.end();
ita++)
- {
- const XMLAttr& xa = *ita;
- xmlout << " " << xa.name() << "=\"" << xa.value() << "\"";
+ PropertyList::SortedPropertyList attrs;
+ enumerateAttributes(xml, attrs);
+ if (!attrs.empty()) {
+
+ for (PropertyList::SortedPropertyList::const_iterator i =
+ attrs.begin(), e = attrs.end(); i != e; ++i) {
+
+ xmlout << " " << i->first << "=\"" << i->second << "\"";
+ }
}
// If the node has no content, just close the tag now
@@ -499,8 +589,15 @@
xmlnode_getNamespaceForPrefix(const fn_call& fn)
{
boost::intrusive_ptr<XMLNode_as> ptr = ensureType<XMLNode_as>(fn.this_ptr);
- log_unimpl("XMLNode.getNamespaceForPrefix");
- return as_value();
+ if (!fn.nargs) {
+ return as_value();
+ }
+
+ std::string ns;
+
+ ptr->getNamespaceForPrefix(fn.arg(0).to_string(), ns);
+ if (ns.empty()) return as_value();
+ return as_value(ns);
}
@@ -508,8 +605,18 @@
xmlnode_getPrefixForNamespace(const fn_call& fn)
{
boost::intrusive_ptr<XMLNode_as> ptr = ensureType<XMLNode_as>(fn.this_ptr);
- log_unimpl("XMLNode.getPrefixForNamespace");
- return as_value();
+ if (!fn.nargs) {
+ return as_value();
+ }
+
+ std::string prefix;
+
+ // Return undefined if none found; otherwise the prefix string found.
+ // This can be empty if it is a standard namespace.
+ if (!ptr->getPrefixForNamespace(fn.arg(0).to_string(), prefix)) {
+ return as_value();
+ }
+ return as_value(prefix);
}
@@ -640,10 +747,8 @@
as_value rv;
rv.set_null();
- //log_debug("xmlnode_node_value called with %d args against 'this' = %p",
fn.nargs, ptr);
if ( fn.nargs == 0 )
{
- //log_debug(" nodeValue() returns '%s'", ptr->nodeValue().c_str());
const std::string& val = ptr->nodeValue();
if ( ! val.empty() ) rv = val;
}
@@ -683,29 +788,11 @@
as_value
xmlnode_attributes(const fn_call& fn)
{
-
boost::intrusive_ptr<XMLNode_as> ptr = ensureType<XMLNode_as>(fn.this_ptr);
- VM& vm = ptr->getVM();
- string_table& st = vm.getStringTable();
-
- XMLNode_as::Attributes& attrs = ptr->attributes();
-
- // Attributes are simple objects.
- boost::intrusive_ptr<as_object> ret = new as_object();
-
- for (XMLNode_as::Attributes::const_iterator it=attrs.begin(),
- itEnd=attrs.end(); it != itEnd; ++it)
- {
-
- const XMLAttr& at = *it;
- const std::string& name = at.name();
- const std::string& val = at.value();
- // These must be enumerable !
- ret->set_member(st.find(name), val);
- }
-
- return as_value(ret);
+ as_object* attrs = ptr->getAttributes();
+ if (attrs) return as_value(attrs);
+ return as_value();
}
/// Read-only property; evaluates the specified XML object and
@@ -841,10 +928,66 @@
// Mark parent
if ( _parent ) _parent->setReachable();
+ // Mark attributes object
+ if (_attributes) _attributes->setReachable();
+
markAsObjectReachable();
}
#endif // GNASH_USE_GC
+namespace {
+
+void
+enumerateAttributes(const XMLNode_as& node,
+ PropertyList::SortedPropertyList& attrs)
+{
+ attrs.clear();
+ const as_object* obj = node.getAttributes();
+ if (obj) {
+ obj->enumerateProperties(attrs);
+ }
+
+}
+
+/// Return true if this attribute is a namespace specifier and the
+/// namespace matches.
+bool
+namespaceMatches(const PropertyList::SortedPropertyList::value_type& val,
+ const std::string& ns)
+{
+ StringNoCaseEqual noCaseCompare;
+ return (noCaseCompare(val.first.substr(0,5), "xmlns") &&
+ noCaseCompare(val.second, ns));
+}
+
+
+bool
+prefixMatches(const PropertyList::SortedPropertyList::value_type& val,
+ const std::string& prefix)
+{
+ const std::string& name = val.first;
+ StringNoCaseEqual noCaseCompare;
+
+ // An empty prefix searches for a standard namespace specifier.
+ // Attributes are stored with no trailing or leading whitespace,
+ // so a simple comparison should do. TODO: what about "xmlns:"?
+ if (prefix.empty()) {
+ return noCaseCompare(name, "xmlns");
+ }
+
+ if (!noCaseCompare(name.substr(0, 5), "xmlns")) return false;
+
+ std::string::size_type pos = name.find(':');
+
+ // There is no colon or nothing after the colon, so this node has
+ // no matching prefix.
+ if (pos == std::string::npos) return false;
+
+ return noCaseCompare(prefix, name.substr(pos + 1));
+}
+
+} // anonymous namespace
+
} // end of gnash namespace
// Local Variables:
=== modified file 'libcore/asobj/XMLNode_as.h'
--- a/libcore/asobj/XMLNode_as.h 2008-11-19 08:41:47 +0000
+++ b/libcore/asobj/XMLNode_as.h 2008-11-21 10:50:16 +0000
@@ -97,8 +97,7 @@
NodeType nodeType() const { return _type; }
/// Set the type of an XML Node.
- void nodeTypeSet(NodeType type)
- {
+ void nodeTypeSet(NodeType type) {
_type = type;
}
@@ -111,6 +110,14 @@
/// Set value of this node, overriding any previous value
void nodeValueSet(const std::string& value) { _value = value; }
+ /// Performs a recursive search of node attributes to find a match
+ void getNamespaceForPrefix(const std::string& prefix, std::string& ns);
+
+ /// Performs a recursive search of node attributes to find a match
+ //
+ /// @return false if no match found.
+ bool getPrefixForNamespace(const std::string& ns, std::string& prefix);
+
void setNamespaceURI(const std::string value) {
_namespaceURI = value;
}
@@ -129,12 +136,8 @@
// Use a list for quick erasing
typedef std::list< boost::intrusive_ptr<XMLNode_as> > Children;
- typedef std::vector< XMLAttr > Attributes;
-
Children& childNodes() { return _children; }
- Attributes& attributes() { return _attributes; }
-
XMLNode_as& operator = (XMLNode_as &node) {
log_debug("%s: \n", __PRETTY_FUNCTION__);
if (this == &node) return *this;
@@ -160,7 +163,6 @@
/// name, value, and attributes as the specified XML object. If deep
/// is set to true, all child nodes are recursively cloned, resulting
/// in an exact copy of the original object's document tree.
- ///
boost::intrusive_ptr<XMLNode_as> cloneNode(bool deep);
/// Append a child node the the XML object
@@ -175,10 +177,7 @@
/// node is placed in the new tree structure after it is removed from
/// its existing parent node.
///
- /// @param as
- /// The XMLNode_as ?
- ///
- /// @param node
+ /// @param childNode
/// same as XMLNode_as::obj ?
///
void appendChild(boost::intrusive_ptr<XMLNode_as> childNode);
@@ -221,14 +220,11 @@
/// for XML.sendAndLoad.
virtual void toString(std::ostream& str, bool encode = false) const;
- // We might turn this back to a dumb pointer, as long
- // as we'll make sure in the XMLNode destructor and
- // any child cleaning interface to set child parent
- // to NULL
- boost::intrusive_ptr<XMLNode_as> _parent;
-
- Children _children;
- Attributes _attributes;
+ as_object* getAttributes() { return _attributes; }
+
+ const as_object* getAttributes() const { return _attributes; }
+
+ void setAttribute(const std::string& name, const std::string& value);
protected:
@@ -243,15 +239,19 @@
virtual void markReachableResources() const;
#endif // GNASH_USE_GC
+ Children _children;
+
private:
- // TODO: make a lot more things private !
+ boost::intrusive_ptr<XMLNode_as> _parent;
+
+ as_object* _attributes;
std::string _name;
std::string _value;
- NodeType _type;
+ NodeType _type;
std::string _namespaceURI;
=== modified file 'libcore/asobj/XML_as.cpp'
--- a/libcore/asobj/XML_as.cpp 2008-11-19 08:41:47 +0000
+++ b/libcore/asobj/XML_as.cpp 2008-11-21 11:10:23 +0000
@@ -209,7 +209,7 @@
void
XML_as::parseAttribute(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it)
+ std::string::const_iterator& it, Attributes& attributes)
{
const std::string terminators("\r\t\n >=");
@@ -275,14 +275,14 @@
// Handle namespace. This is set once only for each node, and is also
// pushed to the attributes list once.
StringNoCaseEqual noCaseCompare;
- if (noCaseCompare(name, "xmlns")) {
+ if (noCaseCompare(name, "xmlns") || noCaseCompare(name, "xmlns:")) {
if (!node->getNamespaceURI().empty()) return;
node->setNamespaceURI(value);
}
- XMLAttr attr(name, value);
- node->_attributes.push_back(attr);
-
+ // This ensures values are not inserted twice, which is expected
+ // behaviour
+ attributes.insert(std::make_pair(name, value));
}
@@ -370,12 +370,14 @@
// Parse any attributes in an opening tag only, stopping at "/>" or
// '>'
+ // Attributes are added in reverse order and without any duplicates.
+ Attributes attributes;
while (it != xml.end() && *it != '>' && _status == XML_OK)
{
if (xml.end() - it > 1 && std::equal(it, it + 2, "/>")) break;
// This advances the iterator
- parseAttribute(childNode, xml, it);
+ parseAttribute(childNode, xml, it, attributes);
// Skip any whitespace. If we reach the end of the string,
// it's malformed.
@@ -384,6 +386,11 @@
return;
}
}
+
+ for (Attributes::const_reverse_iterator i = attributes.rbegin(),
+ e = attributes.rend(); i != e; ++i) {
+ childNode->setAttribute(i->first, i->second);
+ }
node->appendChild(childNode);
if (*it == '/') ++it;
@@ -556,7 +563,7 @@
{
// TODO: should set childs's parent to NULL ?
_children.clear();
- _attributes.clear();
+ //_attributes.clear();
_docTypeDecl.clear();
_xmlDecl.clear();
}
=== modified file 'libcore/asobj/XML_as.h'
--- a/libcore/asobj/XML_as.h 2008-11-19 08:41:47 +0000
+++ b/libcore/asobj/XML_as.h 2008-11-21 09:51:27 +0000
@@ -22,6 +22,7 @@
#include "XMLNode_as.h"
#include "log.h"
#include "dsodefs.h"
+#include "StringPredicates.h"
#include <map>
#include <string>
@@ -109,27 +110,6 @@
///
void parseXML(const std::string& xml);
- void parseTag(XMLNode_as*& node, const std::string& xml,
- std::string::const_iterator& it);
-
- void parseAttribute(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it);
-
- void parseDocTypeDecl(const std::string& xml,
- std::string::const_iterator& it);
-
- void parseText(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it);
-
- void parseXMLDecl(const std::string& xml,
- std::string::const_iterator& it);
-
- void parseComment(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it);
-
- void parseCData(XMLNode_as* node, const std::string& xml,
- std::string::const_iterator& it);
-
// An event handler that returns a what?
bool onLoad();
@@ -153,6 +133,29 @@
static const Entities& getEntities();
+ typedef std::map<std::string, std::string, StringNoCaseLessThen>
Attributes;
+
+ void parseTag(XMLNode_as*& node, const std::string& xml,
+ std::string::const_iterator& it);
+
+ void parseAttribute(XMLNode_as* node, const std::string& xml,
+ std::string::const_iterator& it, Attributes& attributes);
+
+ void parseDocTypeDecl(const std::string& xml,
+ std::string::const_iterator& it);
+
+ void parseText(XMLNode_as* node, const std::string& xml,
+ std::string::const_iterator& it);
+
+ void parseXMLDecl(const std::string& xml,
+ std::string::const_iterator& it);
+
+ void parseComment(XMLNode_as* node, const std::string& xml,
+ std::string::const_iterator& it);
+
+ void parseCData(XMLNode_as* node, const std::string& xml,
+ std::string::const_iterator& it);
+
/// Remove all children
void clear();
=== modified file 'testsuite/actionscript.all/XMLNode.as'
--- a/testsuite/actionscript.all/XMLNode.as 2008-11-20 17:50:40 +0000
+++ b/testsuite/actionscript.all/XMLNode.as 2008-11-21 11:10:23 +0000
@@ -204,23 +204,35 @@
check_equals(typeof(node2.attributes), "object");
node2.attributes[3] = "a3";
-xcheck_equals(node2.attributes[3], "a3");
-xcheck_equals(node2.attributes["3"], "a3");
+check_equals(node2.attributes[3], "a3");
+check_equals(node2.attributes["3"], "a3");
node2.attributes.a = "aa";
-xcheck_equals(node2.attributes.a, "aa");
-xcheck_equals(node2.attributes["a"], "aa");
-xcheck_equals(node2.toString(), '<node2 a="aa" 3="a3">second text
node</node2>');
+check_equals(node2.attributes.a, "aa");
+check_equals(node2.attributes["a"], "aa");
+check_equals(node2.toString(), '<node2 a="aa" 3="a3">second text
node</node2>');
// Seems not to be overwritable
node2.attributes = 3;
-xcheck_equals(node2.toString(), '<node2 a="aa" 3="a3">second text
node</node2>');
+check_equals(node2.toString(), '<node2 a="aa" 3="a3">second text
node</node2>');
ASSetPropFlags(XMLNode.prototype, "attributes", 0, 1);
node77 = doc.createElement("tag");
node77.attributes.a1 = "at1";
-xcheck_equals(node77.toString(), '<tag a1="at1" />');
+check_equals(node77.toString(), '<tag a1="at1" />');
node77.attributes = 5;
-xcheck_equals(node77.toString(), '<tag a1="at1" />');
+check_equals(node77.toString(), '<tag a1="at1" />');
+
+// Check order of attributes:
+
+node77.attributes.z = "z";
+node77.attributes.x = "x";
+node77.attributes.c = "c";
+node77.attributes.y = "y";
+node77.attributes.f = "f";
+node77.attributes[5] = "5";
+node77.attributes["$"] = "$";
+node77.attributes.x = "x2";
+check_equals(node77.toString(), '<tag $="$" 5="5" f="f" y="y" c="c" x="x2"
z="z" a1="at1" />');
// Check namespace functions.
@@ -232,12 +244,12 @@
check_equals(ns.attributes["xmlns"], "standard");
check_equals(ns.namespaceURI, "standard");
check_equals(ns.getNamespaceForPrefix(), undefined);
-xcheck_equals(ns.getNamespaceForPrefix(""), "standard");
-xcheck_equals(ns.getPrefixForNamespace("standard"), "");
+check_equals(ns.getNamespaceForPrefix(""), "standard");
+check_equals(ns.getPrefixForNamespace("standard"), "");
ns.attributes["xmlns"] = "standard2";
check_equals(ns.namespaceURI, "standard");
-xcheck_equals(ns.getNamespaceForPrefix(""), "standard2");
+check_equals(ns.getNamespaceForPrefix(""), "standard2");
ns = ns.firstChild;
check_equals(ns.nodeName, null);
@@ -249,8 +261,8 @@
ns = x.firstChild;
check_equals(ns.namespaceURI, "");
check_equals(ns.getNamespaceForPrefix(), undefined);
-xcheck_equals(ns.getNamespaceForPrefix("t"), "standard");
-xcheck_equals(ns.getPrefixForNamespace("standard"), "t");
+check_equals(ns.getNamespaceForPrefix("t"), "standard");
+check_equals(ns.getPrefixForNamespace("standard"), "t");
x = new XML('<tag xmlns:t="nst"><tag2 xmlns="nss"><tag3
xmlns:r="nsr"></tag3></tag2></tag>');
@@ -260,8 +272,8 @@
check_equals(n.getNamespaceForPrefix("r"), undefined);
check_equals(n.getPrefixForNamespace("nsr"), undefined);
check_equals(n.getNamespaceForPrefix(), undefined);
-xcheck_equals(n.getNamespaceForPrefix("t"), "nst");
-xcheck_equals(n.getPrefixForNamespace("nst"), "t");
+check_equals(n.getNamespaceForPrefix("t"), "nst");
+check_equals(n.getPrefixForNamespace("nst"), "t");
n = n.firstChild;
check_equals(n.nodeName, "tag2");
@@ -269,17 +281,28 @@
check_equals(n.getNamespaceForPrefix(), undefined);
check_equals(n.getNamespaceForPrefix("r"), undefined);
check_equals(n.getPrefixForNamespace("nsr"), undefined);
-xcheck_equals(n.getNamespaceForPrefix("t"), "nst");
-xcheck_equals(n.getPrefixForNamespace("nst"), "t");
+check_equals(n.getNamespaceForPrefix("t"), "nst");
+check_equals(n.getPrefixForNamespace("nst"), "t");
n = n.firstChild;
check_equals(n.nodeName, "tag3");
check_equals(n.namespaceURI, "nss");
check_equals(n.getNamespaceForPrefix(), undefined);
-xcheck_equals(n.getNamespaceForPrefix("r"), "nsr");
-xcheck_equals(n.getPrefixForNamespace("nsr"), "r");
-xcheck_equals(n.getNamespaceForPrefix("t"), "nst");
-xcheck_equals(n.getPrefixForNamespace("nst"), "t");
+check_equals(n.getNamespaceForPrefix("r"), "nsr");
+check_equals(n.getPrefixForNamespace("nsr"), "r");
+check_equals(n.getNamespaceForPrefix("t"), "nst");
+check_equals(n.getPrefixForNamespace("nst"), "t");
+
+// Poorly formed prefix namespaces: become standard namespaces
+x = new XML('<tag xmlns:="nst"><tag2 xmlns="nss"><tag3
xmlns:="nsr"></tag3></tag2></tag>');
+
+n = x.firstChild.firstChild.firstChild;
+check_equals(n.nodeName, "tag3");
+check_equals(n.namespaceURI, "nsr");
+check_equals(n.getPrefixForNamespace("nsr"), "");
+check_equals(n.getNamespaceForPrefix(), undefined);
+check_equals(n.getPrefixForNamespace("nst"), "");
+
// Multiple definition of standard namespace (first one counts, second never
// defined).
@@ -288,8 +311,9 @@
check_equals(ns.nodeName, "tag");
check_equals(ns.attributes["xmlns"], "standard");
check_equals(ns.namespaceURI, "standard");
-xcheck_equals(ns.getNamespaceForPrefix(""), "standard");
-xcheck_equals(ns.getPrefixForNamespace("standard"), "");
+check_equals(ns.getNamespaceForPrefix(""), "standard");
+
+check_equals(ns.getPrefixForNamespace("standard"), "");
check_equals(ns.getPrefixForNamespace("standard2"), undefined);
// Multiple definition of prefix during parsing (first one counts,
@@ -298,17 +322,17 @@
ns = x.firstChild;
check_equals(ns.nodeName, "tag");
check_equals(ns.attributes["xmlns"], undefined);
-xcheck_equals(ns.attributes["xmlns:n1"], "ns1");
+check_equals(ns.attributes["xmlns:n1"], "ns1");
check_equals(ns.namespaceURI, "");
-xcheck_equals(ns.getNamespaceForPrefix("n1"), "ns1");
-xcheck_equals(ns.getPrefixForNamespace("ns1"), "n1");
+check_equals(ns.getNamespaceForPrefix("n1"), "ns1");
+check_equals(ns.getPrefixForNamespace("ns1"), "n1");
check_equals(ns.getPrefixForNamespace("ns2"), undefined);
ns.attributes["xmlns:n1"] = "ns2";
check_equals(ns.attributes["xmlns:n1"], "ns2");
-xcheck_equals(ns.getNamespaceForPrefix("n1"), "ns2");
+check_equals(ns.getNamespaceForPrefix("n1"), "ns2");
check_equals(ns.getPrefixForNamespace("ns1"), undefined);
-xcheck_equals(ns.getPrefixForNamespace("ns2"), "n1");
+check_equals(ns.getPrefixForNamespace("ns2"), "n1");
// Setting via attributes
x = new XML('<tag></tag>');
@@ -317,7 +341,7 @@
check_equals(ns.attributes["xmlns"], undefined);
check_equals(ns.namespaceURI, "");
ns.attributes["xmlns"] = "nss";
-xcheck_equals(ns.attributes["xmlns"], "nss");
+check_equals(ns.attributes["xmlns"], "nss");
check_equals(ns.namespaceURI, "");
/// Prefix, localName
@@ -357,4 +381,4 @@
check_equals(ns.localName, "tag");
check_equals(ns.prefix, "");
-check_totals(169);
+check_totals(175);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10316: Corrections and new implementations of XMLNode methods and XML parsing.,
Benjamin Wolsey <=