[Pkg-javascript-commits] [sax.js] 01/15: Imported Upstream version 0.5.5
Jérémy Lal
kapouer at alioth.debian.org
Mon Sep 23 00:23:25 UTC 2013
This is an automated email from the git hooks/post-receive script.
kapouer pushed a commit to branch master
in repository sax.js.
commit ca152a199ae45949d9be8c1e1f760e5d95764954
Author: Jérémy Lal <kapouer at melix.org>
Date: Mon Sep 23 02:05:53 2013 +0200
Imported Upstream version 0.5.5
---
AUTHORS | 1 +
LICENSE | 47 +--
LICENSE-W3C.html | 188 ++++++++++++
README.md | 3 +-
component.json | 12 +
examples/example.js | 50 ++--
examples/switch-bench.js | 45 ---
lib/sax.js | 436 ++++++++++++++++++++++++----
package.json | 20 +-
test/attribute-name.js | 33 +++
test/buffer-overrun.js | 3 +-
test/case.js | 9 +-
test/cdata-chunked.js | 2 +-
test/cdata-end-split.js | 2 +-
test/cdata-fake-end.js | 4 +-
test/cdata-multiple.js | 2 +-
test/cdata.js | 2 +-
test/cyrillic.js | 8 +
test/duplicate-attribute.js | 13 +
test/entities.js | 10 +
test/entity-mega.js | 16 +
test/issue-23.js | 16 +-
test/issue-30.js | 4 +-
test/issue-35.js | 2 +-
test/issue-47.js | 9 +-
test/issue-49.js | 8 +-
test/issue-84.js | 13 +
test/script-close-better.js | 12 +
test/script.js | 6 +-
test/self-closing-child-strict.js | 12 +-
test/self-closing-child.js | 12 +-
test/self-closing-tag.js | 8 +-
test/stray-ending.js | 4 +-
test/trailing-attribute-no-value.js | 10 +
test/trailing-non-whitespace.js | 3 +-
test/unclosed-root.js | 11 +
test/unquoted.js | 3 +-
test/utf8-split.js | 32 ++
test/xmlns-issue-41.js | 1 +
test/xmlns-rebinding.js | 12 +-
test/xmlns-strict.js | 19 +-
test/xmlns-unbound-element.js | 33 +++
test/xmlns-unbound.js | 2 +-
test/xmlns-xml-default-ns.js | 31 ++
test/xmlns-xml-default-prefix-attribute.js | 1 +
test/xmlns-xml-default-prefix.js | 1 +
test/xmlns-xml-default-redefine.js | 1 +
47 files changed, 948 insertions(+), 224 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index 26d8659..7145cbc 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -7,3 +7,4 @@ Jann Horn <jann at Jann-PC.fritz.box>
Elijah Insua <tmpvar at gmail.com>
Henry Rawas <henryr at schakra.com>
Justin Makeig <jmpublic at makeig.com>
+Mike Schilling <mike at emotive.com>
diff --git a/LICENSE b/LICENSE
index 05a4010..62e4ccf 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,23 +1,32 @@
-Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
+Copyright (c) Isaac Z. Schlueter ("Author")
All rights reserved.
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
+The BSD License
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+
+
+The file "examples/strict.dtd" is licensed by the W3C and used according
+to the terms of the W3C SOFTWARE NOTICE AND LICENSE. See LICENSE-W3C.html
+for details.
diff --git a/LICENSE-W3C.html b/LICENSE-W3C.html
new file mode 100644
index 0000000..a611e3f
--- /dev/null
+++ b/LICENSE-W3C.html
@@ -0,0 +1,188 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><meta name="generator" content="HTML Tidy for Mac OS X (vers 31 October 2006 - Apple Inc. build 13), see www.w3.org" /><title>W3C Software Notice and License</title><link rel="stylesheet" href="/2008/site/css/minimum" type="text/css" media="handheld, all" /><style type="text/css" media="print, screen and (min-width: 481px)" xml:space="preserve">
+ @import url("/2008/site/css/advanced");
+</style><link href="/2008/site/css/minimum" rel="stylesheet" type="text/css" media="handheld, only screen and (max-device-width: 480px)" /><meta name="viewport" content="width=device-width" /><link rel="stylesheet" href="/2008/site/css/print" type="text/css" media="print" /><link rel="shortcut icon" href="/2008/site/images/favicon.ico" type="image/x-icon" /></head><body id="www-w3-org" class="w3c_public"><div id="w3c_container">
+
+
+
+ <div id="w3c_mast">
+ <h1 class="logo">
+ <a tabindex="2" accesskey="1" href="/"><img src="/2008/site/images/logo-w3c-mobile-lg" width="90" height="53" alt="W3C" /></a>
+ <span class="alt-logo">W3C</span>
+ </h1>
+
+ <div id="w3c_nav">
+
+
+
+ <form action="/Help/search" method="get" enctype="application/x-www-form-urlencoded"><div class="w3c_sec_nav"><!-- --></div><ul class="main_nav"><li class="first-item">
+ <a href="/standards/">Standards</a>
+ </li><li>
+ <a href="/participate/">Participate</a>
+ </li><li>
+ <a href="/Consortium/membership">Membership</a>
+ </li><li class="last-item">
+ <a href="/Consortium/">About W3C</a>
+ </li><li class="search-item">
+ <div id="search-form">
+ <input tabindex="3" class="text" name="q" value="" title="Search" type="text" />
+ <button id="search-submit" name="search-submit" type="submit"><img class="submit" src="/2008/site/images/search-button" alt="Search" width="21" height="17" /></button>
+ </div>
+ </li></ul></form>
+ </div>
+
+ </div>
+
+
+ <div id="w3c_main">
+ <div id="w3c_logo_shadow" class="w3c_leftCol">
+ <img height="32" alt="" src="/2008/site/images/logo-shadow" />
+ </div>
+
+ <div class="w3c_leftCol"><h2 class="offscreen">Site Navigation</h2>
+ <h3 class="category"><span class="ribbon"><a href="/Consortium/Legal/ipr-notice.html" title="Up to Policies and Legal Information">Policies and Legal Information <img src="/2008/site/images/header-link" alt="Header link" width="13" height="13" class="header-link" /></a></span></h3>
+ <ul class="theme">
+ <li><a href="/Consortium/Legal/2008/04-testsuite-copyright.html">Licenses for W3C Test Suites</a></li>
+ <li><a href="/2004/10/27-testcases.html">Policies for Contribution of Test Cases to W3C</a></li>
+ <li><a href="/Consortium/Legal/IPR-FAQ-20000620.html">Intellectual Rights FAQ</a></li>
+ <li><a href="/Consortium/Legal/privacy-statement-20000612.html">W3C Privacy Statements</a></li>
+ <li><a href="/Consortium/Legal/2002/copyright-documents-20021231.html">W3C Document License</a></li>
+ <li><a href="/Consortium/Legal/2002/trademarks-20021231.html">W3C Trademarks and Generic Terms</a></li>
+ <li><a href="/Consortium/Legal/2002/trademark-license-20021231.html">W3C® Trademark and Service Mark License</a></li>
+ <li><a class="current">W3C Software Notice and License</a></li>
+ <li><a href="/Consortium/Legal/2002/collaborators-agreement-20021231.html">W3C Invited Expert and Collaborators Agreement</a></li>
+ <li><a href="/Consortium/Persistence.html">W3C URI Persistence Policy</a></li>
+ <li><a href="/1999/10/21-mirroring-policy.html">Mirroring the W3C Site</a></li>
+ <li><a href="/Consortium/Legal/2006/08-copyright-translations.html">Translations of the Copyright Notice</a></li>
+ </ul>
+ <br /></div>
+ <div class="w3c_mainCol">
+ <div id="w3c_crumbs">
+ <div id="w3c_crumbs_frame">
+ <ul class="bct"> <!-- .bct / Breadcrumbs -->
+ <li class="skip"><a tabindex="1" accesskey="2" title="Skip to content (e.g., when browsing via audio)" href="#w3c_content_body">Skip</a></li>
+ <li><a href="/">W3C</a> <span class="cr">»</span> </li>
+ <li><a href="/Consortium/">About W3C</a> <span class="cr">»</span> </li>
+ <li><a href="/Consortium/facts.html">Facts About W3C</a> <span class="cr">»</span> </li>
+ <li><a href="/Consortium/Legal/ipr-notice.html">Policies and Legal Information</a> <span class="cr">»</span> </li>
+ <li class="current">W3C Software Notice and License</li>
+ </ul>
+ </div>
+ </div>
+ <h1 class="title">W3C Software Notice and License</h1>
+ <div id="w3c_content_body">
+ <div class="line">
+ <p class="intro tPadding">This work (and included software, documentation such as READMEs, or other
+related items) is being provided by the copyright holders under the following
+license.</p>
+<h2>License</h2>
+
+ <p class="tPadding">
+By obtaining, using and/or copying this work, you (the licensee)
+agree that you have read, understood, and will comply with the following
+terms and conditions.</p>
+
+ <p>Permission to copy, modify, and distribute this software and its
+documentation, with or without modification, for any purpose and without
+fee or royalty is hereby granted, provided that you include the following on
+ALL copies of the software and documentation or portions thereof, including
+modifications:</p>
+
+ <ul class="show_items"><li>The full text of this NOTICE in a location viewable to users of the
+ redistributed or derivative work.</li><li>Any pre-existing intellectual property disclaimers, notices, or terms
+ and conditions. If none exist, the <a href="copyright-software-short-notice-20021231.html">W3C Software Short
+ Notice</a> should be included (hypertext is preferred, text is permitted)
+ within the body of any redistributed or derivative code.</li><li>Notice of any changes or modifications to the files, including the date
+ changes were made. (We recommend you provide URIs to the location from
+ which the code is derived.)</li></ul>
+
+<h2>Disclaimers</h2>
+
+ <p>THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS
+MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
+PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE
+ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.</p>
+
+ <p>COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR
+DOCUMENTATION.</p>
+
+ <p>The name and trademarks of copyright holders may NOT be used in
+advertising or publicity pertaining to the software without specific, written
+prior permission. Title to copyright in this software and any associated
+documentation will at all times remain with copyright holders.</p>
+
+ <h2>Notes</h2>
+
+ <p>This version: http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231</p>
+
+ <p>This formulation of W3C's notice and license became active on December 31
+2002. This version removes the copyright ownership notice such that this
+license can be used with materials other than those owned by the W3C,
+reflects that ERCIM is now a host of the W3C, includes references to this
+specific dated version of the license, and removes the ambiguous grant of
+"use". Otherwise, this version is the same as the <a href="http://www.w3.org/Consortium/Legal/copyright-software-19980720">previous
+version</a> and is written so as to preserve the <a href="http://www.gnu.org/philosophy/license-list.html#GPLCompatibleLicenses">Free
+Software Foundation's assessment of GPL compatibility</a> and <a href="http://www.opensource.org/licenses/W3C.php">OSI's certification</a>
+under the <a href="http://www.opensource.org/docs/definition.php">Open Source
+Definition</a>.</p>
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+
+ </div><div id="w3c_footer">
+ <div id="w3c_footer-inner">
+ <h2 class="offscreen">Footer Navigation</h2>
+ <div class="w3c_footer-nav">
+ <h3>Navigation</h3>
+ <ul class="footer_top_nav"><li>
+ <a href="/">Home</a>
+ </li><li>
+ <a href="/standards/">Standards</a>
+ </li><li>
+ <a href="/participate/">Participate</a>
+ </li><li>
+ <a href="/Consortium/membership">Membership</a>
+ </li><li class="last-item">
+ <a href="/Consortium/">About W3C</a>
+ </li></ul>
+ </div>
+ <div class="w3c_footer-nav">
+ <h3>Contact W3C</h3>
+ <ul class="footer_bottom_nav"><li>
+ <a href="/Consortium/contact">Contact</a>
+ </li><li>
+ <a accesskey="0" href="/Help/">Help and FAQ</a>
+ </li><li>
+ <a href="/Consortium/sponsor/">Sponsor / Donate</a>
+ </li><li>
+ <a href="/Consortium/siteindex">Site Map</a>
+ </li><li>
+ <address id="w3c_signature">
+ <a href="http://lists.w3.org/Archives/Public/site-comments/">Feedback</a></address>
+ </li></ul>
+ </div>
+ <div class="w3c_footer-nav">
+ <h3>W3C Updates</h3>
+ <ul class="footer_follow_nav"><li>
+ <a href="http://twitter.com/W3C" title="Follow W3C on Twitter">
+ <img src="/2008/site/images/twitter-bird" alt="Twitter" width="78" height="83" class="social-icon" />
+ </a>
+ <a href="http://identi.ca/w3c" title="See W3C on Identica">
+ <img src="/2008/site/images/identica-logo" alt="Identica" width="91" height="83" class="social-icon" />
+ </a>
+ </li></ul>
+ </div>
+ <p class="copyright">Copyright © 2012 W3C <sup>®</sup> (<a href="http://www.csail.mit.edu/">
+ <acronym title="Massachusetts Institute of Technology">MIT</acronym>
+ </a>, <a href="http://www.ercim.org/">
+ <acronym title="European Research Consortium for Informatics and Mathematics"> ERCIM</acronym>
+ </a>, <a href="http://www.keio.ac.jp/">Keio</a>) <a href="/Consortium/Legal/ipr-notice">Usage policies apply</a>.</p>
+ </div>
+ </div><!-- Generated from data/scripts.php, ../../smarty/{scripts.tpl} --><!-- At the bottom for performance reasons --><div id="w3c_scripts">
+ <script type="text/javascript" src="/2008/site/js/main" xml:space="preserve"><!-- --></script>
+ </div></body></html>
diff --git a/README.md b/README.md
index 2e5462b..c965242 100644
--- a/README.md
+++ b/README.md
@@ -81,7 +81,7 @@ through unmolested.
// same chunks coming in also go out.
fs.createReadStream("file.xml")
.pipe(saxStream)
- .pipe(fs.createReadStream("file-copy.xml"))
+ .pipe(fs.createWriteStream("file-copy.xml"))
@@ -101,6 +101,7 @@ Settings supported:
* `lowercase` - Boolean. If true, then lowercase tag names and attribute names
in loose mode, rather than uppercasing them.
* `xmlns` - Boolean. If true, then namespaces are supported.
+* `position` - Boolean. If false, then don't track line/col/position.
## Methods
diff --git a/component.json b/component.json
new file mode 100644
index 0000000..96b5d73
--- /dev/null
+++ b/component.json
@@ -0,0 +1,12 @@
+{
+ "name": "sax",
+ "description": "An evented streaming XML parser in JavaScript",
+ "author": "Isaac Z. Schlueter <i at izs.me> (http://blog.izs.me/)",
+ "version": "0.5.2",
+ "main": "lib/sax.js",
+ "license": "BSD",
+ "scripts": [
+ "lib/sax.js"
+ ],
+ "repository": "git://github.com/isaacs/sax-js.git"
+}
diff --git a/examples/example.js b/examples/example.js
index e7f81e6..7b0246e 100644
--- a/examples/example.js
+++ b/examples/example.js
@@ -1,41 +1,29 @@
var fs = require("fs"),
- sys = require("sys"),
+ util = require("util"),
path = require("path"),
- xml = fs.cat(path.join(__dirname, "test.xml")),
+ xml = fs.readFileSync(path.join(__dirname, "test.xml"), "utf8"),
sax = require("../lib/sax"),
strict = sax.parser(true),
loose = sax.parser(false, {trim:true}),
inspector = function (ev) { return function (data) {
- // sys.error("");
- // sys.error(ev+": "+sys.inspect(data));
- // for (var i in data) sys.error(i+ " "+sys.inspect(data[i]));
- // sys.error(this.line+":"+this.column);
+ console.error("%s %s %j", this.line+":"+this.column, ev, data);
}};
-xml.addCallback(function (xml) {
- // strict.write(xml);
-
- sax.EVENTS.forEach(function (ev) {
- loose["on"+ev] = inspector(ev);
- });
- loose.onend = function () {
- // sys.error("end");
- // sys.error(sys.inspect(loose));
- };
-
- // do this one char at a time to verify that it works.
- // (function () {
- // if (xml) {
- // loose.write(xml.substr(0,1000));
- // xml = xml.substr(1000);
- // process.nextTick(arguments.callee);
- // } else loose.close();
- // })();
-
- for (var i = 0; i < 1000; i ++) {
- loose.write(xml);
- loose.close();
- }
-
+sax.EVENTS.forEach(function (ev) {
+ loose["on"+ev] = inspector(ev);
});
+loose.onend = function () {
+ console.error("end");
+ console.error(loose);
+};
+
+// do this in random bits at a time to verify that it works.
+(function () {
+ if (xml) {
+ var c = Math.ceil(Math.random() * 1000)
+ loose.write(xml.substr(0,c));
+ xml = xml.substr(c);
+ process.nextTick(arguments.callee);
+ } else loose.close();
+})();
diff --git a/examples/switch-bench.js b/examples/switch-bench.js
deleted file mode 100755
index 4d3cf14..0000000
--- a/examples/switch-bench.js
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/local/bin/node-bench
-
-var Promise = require("events").Promise;
-
-var xml = require("posix").cat("test.xml").wait(),
- path = require("path"),
- sax = require("../lib/sax"),
- saxT = require("../lib/sax-trampoline"),
-
- parser = sax.parser(false, {trim:true}),
- parserT = saxT.parser(false, {trim:true}),
-
- sys = require("sys");
-
-
-var count = exports.stepsPerLap = 500,
- l = xml.length,
- runs = 0;
-exports.countPerLap = 1000;
-exports.compare = {
- "switch" : function () {
- // sys.debug("switch runs: "+runs++);
- // for (var x = 0; x < l; x += 1000) {
- // parser.write(xml.substr(x, 1000))
- // }
- // for (var i = 0; i < count; i ++) {
- parser.write(xml);
- parser.close();
- // }
- // done();
- },
- trampoline : function () {
- // sys.debug("trampoline runs: "+runs++);
- // for (var x = 0; x < l; x += 1000) {
- // parserT.write(xml.substr(x, 1000))
- // }
- // for (var i = 0; i < count; i ++) {
- parserT.write(xml);
- parserT.close();
- // }
- // done();
- },
-};
-
-sys.debug("rock and roll...");
\ No newline at end of file
diff --git a/lib/sax.js b/lib/sax.js
index e44abc1..77e20ae 100644
--- a/lib/sax.js
+++ b/lib/sax.js
@@ -51,7 +51,7 @@ function SAXParser (strict, opt) {
parser.q = parser.c = ""
parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH
parser.opt = opt || {}
- parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags;
+ parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags
parser.looseCase = parser.opt.lowercase ? "toLowerCase" : "toUpperCase"
parser.tags = []
parser.closed = parser.closedRoot = parser.sawRoot = false
@@ -68,7 +68,10 @@ function SAXParser (strict, opt) {
if (parser.opt.xmlns) parser.ns = Object.create(rootNS)
// mostly just for error reporting
- parser.position = parser.line = parser.column = 0
+ parser.trackPosition = parser.opt.position !== false
+ if (parser.trackPosition) {
+ parser.position = parser.line = parser.column = 0
+ }
emit(parser, "onready")
}
@@ -155,7 +158,7 @@ function createStream (strict, opt) {
function SAXStream (strict, opt) {
if (!(this instanceof SAXStream)) return new SAXStream(strict, opt)
- Stream.apply(me)
+ Stream.apply(this)
this._parser = new SAXParser(strict, opt)
this.writable = true
@@ -176,6 +179,8 @@ function SAXStream (strict, opt) {
me._parser.error = null
}
+ this._decoder = null;
+
streamWraps.forEach(function (ev) {
Object.defineProperty(me, "on" + ev, {
get: function () { return me._parser["on" + ev] },
@@ -196,13 +201,24 @@ SAXStream.prototype = Object.create(Stream.prototype,
{ constructor: { value: SAXStream } })
SAXStream.prototype.write = function (data) {
+ if (typeof Buffer === 'function' &&
+ typeof Buffer.isBuffer === 'function' &&
+ Buffer.isBuffer(data)) {
+ if (!this._decoder) {
+ var SD = require('string_decoder').StringDecoder
+ this._decoder = new SD('utf8')
+ }
+ data = this._decoder.write(data);
+ }
+
this._parser.write(data.toString())
this.emit("data", data)
return true
}
SAXStream.prototype.end = function (chunk) {
- if (chunk && chunk.length) this._parser.write(chunk.toString())
+ if (chunk && chunk.length) this.write(chunk)
+ else if (this.leftovers) this._parser.write(this.leftovers.toString())
this._parser.end()
return true
}
@@ -230,8 +246,6 @@ var whitespace = "\r\n\t "
, number = "0124356789"
, letter = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
// (Letter | "_" | ":")
- , nameStart = letter+"_:"
- , nameBody = nameStart+number+"-."
, quote = "'\""
, entity = number+letter+"#"
, attribEnd = whitespace + ">"
@@ -245,8 +259,17 @@ var whitespace = "\r\n\t "
whitespace = charClass(whitespace)
number = charClass(number)
letter = charClass(letter)
-nameStart = charClass(nameStart)
-nameBody = charClass(nameBody)
+
+// http://www.w3.org/TR/REC-xml/#NT-NameStartChar
+// This implementation works on strings, a single character at a time
+// as such, it cannot ever support astral-plane characters (10000-EFFFF)
+// without a significant breaking change to either this parser, or the
+// JavaScript language. Implementation of an emoji-capable xml parser
+// is left as an exercise for the reader.
+var nameStart = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/
+
+var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040\.\d-]/
+
quote = charClass(quote)
entity = charClass(entity)
attribEnd = charClass(attribEnd)
@@ -258,12 +281,16 @@ function charClass (str) {
}, {})
}
+function isRegExp (c) {
+ return Object.prototype.toString.call(c) === '[object RegExp]'
+}
+
function is (charclass, c) {
- return charclass[c]
+ return isRegExp(charclass) ? !!c.match(charclass) : charclass[c]
}
function not (charclass, c) {
- return !charclass[c]
+ return !is(charclass, c)
}
var S = 0
@@ -287,7 +314,6 @@ sax.STATE =
, CDATA_ENDING_2 : S++ // ]]
, PROC_INST : S++ // <?hi
, PROC_INST_BODY : S++ // <?hi there
-, PROC_INST_QUOTED : S++ // <?hi "there
, PROC_INST_ENDING : S++ // <?hi "there" ?
, OPEN_TAG : S++ // <strong
, OPEN_TAG_SLASH : S++ // <strong /
@@ -306,13 +332,267 @@ sax.STATE =
}
sax.ENTITIES =
-{ "apos" : "'"
+{ "amp" : "&"
+, "gt" : ">"
+, "lt" : "<"
, "quot" : "\""
-, "amp" : "&"
-, "gt" : ">"
-, "lt" : "<"
+, "apos" : "'"
+, "AElig" : 198
+, "Aacute" : 193
+, "Acirc" : 194
+, "Agrave" : 192
+, "Aring" : 197
+, "Atilde" : 195
+, "Auml" : 196
+, "Ccedil" : 199
+, "ETH" : 208
+, "Eacute" : 201
+, "Ecirc" : 202
+, "Egrave" : 200
+, "Euml" : 203
+, "Iacute" : 205
+, "Icirc" : 206
+, "Igrave" : 204
+, "Iuml" : 207
+, "Ntilde" : 209
+, "Oacute" : 211
+, "Ocirc" : 212
+, "Ograve" : 210
+, "Oslash" : 216
+, "Otilde" : 213
+, "Ouml" : 214
+, "THORN" : 222
+, "Uacute" : 218
+, "Ucirc" : 219
+, "Ugrave" : 217
+, "Uuml" : 220
+, "Yacute" : 221
+, "aacute" : 225
+, "acirc" : 226
+, "aelig" : 230
+, "agrave" : 224
+, "aring" : 229
+, "atilde" : 227
+, "auml" : 228
+, "ccedil" : 231
+, "eacute" : 233
+, "ecirc" : 234
+, "egrave" : 232
+, "eth" : 240
+, "euml" : 235
+, "iacute" : 237
+, "icirc" : 238
+, "igrave" : 236
+, "iuml" : 239
+, "ntilde" : 241
+, "oacute" : 243
+, "ocirc" : 244
+, "ograve" : 242
+, "oslash" : 248
+, "otilde" : 245
+, "ouml" : 246
+, "szlig" : 223
+, "thorn" : 254
+, "uacute" : 250
+, "ucirc" : 251
+, "ugrave" : 249
+, "uuml" : 252
+, "yacute" : 253
+, "yuml" : 255
+, "copy" : 169
+, "reg" : 174
+, "nbsp" : 160
+, "iexcl" : 161
+, "cent" : 162
+, "pound" : 163
+, "curren" : 164
+, "yen" : 165
+, "brvbar" : 166
+, "sect" : 167
+, "uml" : 168
+, "ordf" : 170
+, "laquo" : 171
+, "not" : 172
+, "shy" : 173
+, "macr" : 175
+, "deg" : 176
+, "plusmn" : 177
+, "sup1" : 185
+, "sup2" : 178
+, "sup3" : 179
+, "acute" : 180
+, "micro" : 181
+, "para" : 182
+, "middot" : 183
+, "cedil" : 184
+, "ordm" : 186
+, "raquo" : 187
+, "frac14" : 188
+, "frac12" : 189
+, "frac34" : 190
+, "iquest" : 191
+, "times" : 215
+, "divide" : 247
+, "OElig" : 338
+, "oelig" : 339
+, "Scaron" : 352
+, "scaron" : 353
+, "Yuml" : 376
+, "fnof" : 402
+, "circ" : 710
+, "tilde" : 732
+, "Alpha" : 913
+, "Beta" : 914
+, "Gamma" : 915
+, "Delta" : 916
+, "Epsilon" : 917
+, "Zeta" : 918
+, "Eta" : 919
+, "Theta" : 920
+, "Iota" : 921
+, "Kappa" : 922
+, "Lambda" : 923
+, "Mu" : 924
+, "Nu" : 925
+, "Xi" : 926
+, "Omicron" : 927
+, "Pi" : 928
+, "Rho" : 929
+, "Sigma" : 931
+, "Tau" : 932
+, "Upsilon" : 933
+, "Phi" : 934
+, "Chi" : 935
+, "Psi" : 936
+, "Omega" : 937
+, "alpha" : 945
+, "beta" : 946
+, "gamma" : 947
+, "delta" : 948
+, "epsilon" : 949
+, "zeta" : 950
+, "eta" : 951
+, "theta" : 952
+, "iota" : 953
+, "kappa" : 954
+, "lambda" : 955
+, "mu" : 956
+, "nu" : 957
+, "xi" : 958
+, "omicron" : 959
+, "pi" : 960
+, "rho" : 961
+, "sigmaf" : 962
+, "sigma" : 963
+, "tau" : 964
+, "upsilon" : 965
+, "phi" : 966
+, "chi" : 967
+, "psi" : 968
+, "omega" : 969
+, "thetasym" : 977
+, "upsih" : 978
+, "piv" : 982
+, "ensp" : 8194
+, "emsp" : 8195
+, "thinsp" : 8201
+, "zwnj" : 8204
+, "zwj" : 8205
+, "lrm" : 8206
+, "rlm" : 8207
+, "ndash" : 8211
+, "mdash" : 8212
+, "lsquo" : 8216
+, "rsquo" : 8217
+, "sbquo" : 8218
+, "ldquo" : 8220
+, "rdquo" : 8221
+, "bdquo" : 8222
+, "dagger" : 8224
+, "Dagger" : 8225
+, "bull" : 8226
+, "hellip" : 8230
+, "permil" : 8240
+, "prime" : 8242
+, "Prime" : 8243
+, "lsaquo" : 8249
+, "rsaquo" : 8250
+, "oline" : 8254
+, "frasl" : 8260
+, "euro" : 8364
+, "image" : 8465
+, "weierp" : 8472
+, "real" : 8476
+, "trade" : 8482
+, "alefsym" : 8501
+, "larr" : 8592
+, "uarr" : 8593
+, "rarr" : 8594
+, "darr" : 8595
+, "harr" : 8596
+, "crarr" : 8629
+, "lArr" : 8656
+, "uArr" : 8657
+, "rArr" : 8658
+, "dArr" : 8659
+, "hArr" : 8660
+, "forall" : 8704
+, "part" : 8706
+, "exist" : 8707
+, "empty" : 8709
+, "nabla" : 8711
+, "isin" : 8712
+, "notin" : 8713
+, "ni" : 8715
+, "prod" : 8719
+, "sum" : 8721
+, "minus" : 8722
+, "lowast" : 8727
+, "radic" : 8730
+, "prop" : 8733
+, "infin" : 8734
+, "ang" : 8736
+, "and" : 8743
+, "or" : 8744
+, "cap" : 8745
+, "cup" : 8746
+, "int" : 8747
+, "there4" : 8756
+, "sim" : 8764
+, "cong" : 8773
+, "asymp" : 8776
+, "ne" : 8800
+, "equiv" : 8801
+, "le" : 8804
+, "ge" : 8805
+, "sub" : 8834
+, "sup" : 8835
+, "nsub" : 8836
+, "sube" : 8838
+, "supe" : 8839
+, "oplus" : 8853
+, "otimes" : 8855
+, "perp" : 8869
+, "sdot" : 8901
+, "lceil" : 8968
+, "rceil" : 8969
+, "lfloor" : 8970
+, "rfloor" : 8971
+, "lang" : 9001
+, "rang" : 9002
+, "loz" : 9674
+, "spades" : 9824
+, "clubs" : 9827
+, "hearts" : 9829
+, "diams" : 9830
}
+Object.keys(sax.ENTITIES).forEach(function (key) {
+ var e = sax.ENTITIES[key]
+ var s = typeof e === 'number' ? String.fromCharCode(e) : e
+ sax.ENTITIES[key] = s
+})
+
for (var S in sax.STATE) sax.STATE[sax.STATE[S]] = S
// shorthand
@@ -341,9 +621,11 @@ function textopts (opt, text) {
function error (parser, er) {
closeText(parser)
- er += "\nLine: "+parser.line+
- "\nColumn: "+parser.column+
- "\nChar: "+parser.c
+ if (parser.trackPosition) {
+ er += "\nLine: "+parser.line+
+ "\nColumn: "+parser.column+
+ "\nChar: "+parser.c
+ }
er = new Error(er)
parser.error = er
emit(parser, "onerror", er)
@@ -351,6 +633,7 @@ function error (parser, er) {
}
function end (parser) {
+ if (!parser.closedRoot) strictFail(parser, "Unclosed root tag")
if (parser.state !== S.TEXT) error(parser, "Unexpected end")
closeText(parser)
parser.c = ""
@@ -361,6 +644,8 @@ function end (parser) {
}
function strictFail (parser, message) {
+ if (typeof parser !== 'object' || !(parser instanceof SAXParser))
+ throw new Error('bad call to strictFail');
if (parser.strict) error(parser, message)
}
@@ -391,6 +676,12 @@ function qname (name) {
function attrib (parser) {
if (!parser.strict) parser.attribName = parser.attribName[parser.looseCase]()
+
+ if (parser.attribList.indexOf(parser.attribName) !== -1 ||
+ parser.tag.attributes.hasOwnProperty(parser.attribName)) {
+ return parser.attribName = parser.attribValue = ""
+ }
+
if (parser.opt.xmlns) {
var qn = qname(parser.attribName)
, prefix = qn.prefix
@@ -441,11 +732,12 @@ function openTag (parser, selfClosing) {
var qn = qname(parser.tagName)
tag.prefix = qn.prefix
tag.local = qn.local
- tag.uri = tag.ns[qn.prefix] || qn.prefix
+ tag.uri = tag.ns[qn.prefix] || ""
if (tag.prefix && !tag.uri) {
strictFail(parser, "Unbound namespace prefix: "
+ JSON.stringify(parser.tagName))
+ tag.uri = qn.prefix
}
var parent = parser.tags[parser.tags.length - 1] || parser
@@ -458,6 +750,8 @@ function openTag (parser, selfClosing) {
}
// handle deferred onattribute events
+ // Note: do not apply default ns to attributes:
+ // http://www.w3.org/TR/REC-xml-names/#defaulting
for (var i = 0, l = parser.attribList.length; i < l; i ++) {
var nv = parser.attribList[i]
var name = nv[0]
@@ -465,7 +759,7 @@ function openTag (parser, selfClosing) {
, qualName = qname(name)
, prefix = qualName.prefix
, local = qualName.local
- , uri = tag.ns[prefix] || ""
+ , uri = prefix == "" ? "" : (tag.ns[prefix] || "")
, a = { name: name
, value: value
, prefix: prefix
@@ -486,6 +780,8 @@ function openTag (parser, selfClosing) {
parser.attribList.length = 0
}
+ parser.tag.isSelfClosing = !!selfClosing
+
// process the tag
parser.sawRoot = true
parser.tags.push(parser.tag)
@@ -511,6 +807,18 @@ function closeTag (parser) {
parser.state = S.TEXT
return
}
+
+ if (parser.script) {
+ if (parser.tagName !== "script") {
+ parser.script += "</" + parser.tagName + ">"
+ parser.tagName = ""
+ parser.state = S.SCRIPT
+ return
+ }
+ emitNode(parser, "onscript", parser.script)
+ parser.script = ""
+ }
+
// first make sure that the closing tag actually exists.
// <a><b></c></b></a> will close everything, otherwise.
var t = parser.tags.length
@@ -558,10 +866,15 @@ function closeTag (parser) {
}
function parseEntity (parser) {
- var entity = parser.entity.toLowerCase()
+ var entity = parser.entity
+ , entityLC = entity.toLowerCase()
, num
, numStr = ""
- if (parser.ENTITIES[entity]) return parser.ENTITIES[entity]
+ if (parser.ENTITIES[entity])
+ return parser.ENTITIES[entity]
+ if (parser.ENTITIES[entityLC])
+ return parser.ENTITIES[entityLC]
+ entity = entityLC
if (entity.charAt(0) === "#") {
if (entity.charAt(1) === "x") {
entity = entity.slice(2)
@@ -589,16 +902,20 @@ function write (chunk) {
if (chunk === null) return end(parser)
var i = 0, c = ""
while (parser.c = c = chunk.charAt(i++)) {
- parser.position ++
- if (c === "\n") {
- parser.line ++
- parser.column = 0
- } else parser.column ++
+ if (parser.trackPosition) {
+ parser.position ++
+ if (c === "\n") {
+ parser.line ++
+ parser.column = 0
+ } else parser.column ++
+ }
switch (parser.state) {
case S.BEGIN:
- if (c === "<") parser.state = S.OPEN_WAKA
- else if (not(whitespace,c)) {
+ if (c === "<") {
+ parser.state = S.OPEN_WAKA
+ parser.startTagPosition = parser.position
+ } else if (not(whitespace,c)) {
// have to process this as a text node.
// weird, but happens.
strictFail(parser, "Non-whitespace before first tag.")
@@ -612,7 +929,7 @@ function write (chunk) {
var starti = i-1
while (c && c!=="<" && c!=="&") {
c = chunk.charAt(i++)
- if (c) {
+ if (c && parser.trackPosition) {
parser.position ++
if (c === "\n") {
parser.line ++
@@ -622,10 +939,12 @@ function write (chunk) {
}
parser.textNode += chunk.substring(starti, i-1)
}
- if (c === "<") parser.state = S.OPEN_WAKA
- else {
+ if (c === "<") {
+ parser.state = S.OPEN_WAKA
+ parser.startTagPosition = parser.position
+ } else {
if (not(whitespace, c) && (!parser.sawRoot || parser.closedRoot))
- strictFail("Text data outside of root node.")
+ strictFail(parser, "Text data outside of root node.")
if (c === "&") parser.state = S.TEXT_ENTITY
else parser.textNode += c
}
@@ -640,10 +959,7 @@ function write (chunk) {
case S.SCRIPT_ENDING:
if (c === "/") {
- emitNode(parser, "onscript", parser.script)
parser.state = S.CLOSE_TAG
- parser.script = ""
- parser.tagName = ""
} else {
parser.script += "<" + c
parser.state = S.SCRIPT
@@ -658,11 +974,9 @@ function write (chunk) {
} else if (is(whitespace, c)) {
// wait for it...
} else if (is(nameStart,c)) {
- parser.startTagPosition = parser.position - 1
parser.state = S.OPEN_TAG
parser.tagName = c
} else if (c === "/") {
- parser.startTagPosition = parser.position - 1
parser.state = S.CLOSE_TAG
parser.tagName = ""
} else if (c === "?") {
@@ -670,6 +984,11 @@ function write (chunk) {
parser.procInstName = parser.procInstBody = ""
} else {
strictFail(parser, "Unencoded <")
+ // if there was some whitespace, then add that in.
+ if (parser.startTagPosition + 1 < parser.position) {
+ var pad = parser.position - parser.startTagPosition
+ c = new Array(pad).join(" ") + c
+ }
parser.textNode += "<" + c
parser.state = S.TEXT
}
@@ -812,11 +1131,7 @@ function write (chunk) {
case S.PROC_INST_BODY:
if (!parser.procInstBody && is(whitespace, c)) continue
else if (c === "?") parser.state = S.PROC_INST_ENDING
- else if (is(quote, c)) {
- parser.state = S.PROC_INST_QUOTED
- parser.q = c
- parser.procInstBody += c
- } else parser.procInstBody += c
+ else parser.procInstBody += c
continue
case S.PROC_INST_ENDING:
@@ -833,14 +1148,6 @@ function write (chunk) {
}
continue
- case S.PROC_INST_QUOTED:
- parser.procInstBody += c
- if (c === parser.q) {
- parser.state = S.PROC_INST_BODY
- parser.q = ""
- }
- continue
-
case S.OPEN_TAG:
if (is(nameBody, c)) parser.tagName += c
else {
@@ -879,6 +1186,12 @@ function write (chunk) {
case S.ATTRIB_NAME:
if (c === "=") parser.state = S.ATTRIB_VALUE
+ else if (c === ">") {
+ strictFail(parser, "Attribute without value")
+ parser.attribValue = parser.attribName
+ attrib(parser)
+ openTag(parser)
+ }
else if (is(whitespace, c)) parser.state = S.ATTRIB_NAME_SAW_WHITE
else if (is(nameBody, c)) parser.attribName += c
else strictFail(parser, "Invalid attribute name")
@@ -942,13 +1255,22 @@ function write (chunk) {
case S.CLOSE_TAG:
if (!parser.tagName) {
if (is(whitespace, c)) continue
- else if (not(nameStart, c)) strictFail(parser,
- "Invalid tagname in closing tag.")
- else parser.tagName = c
+ else if (not(nameStart, c)) {
+ if (parser.script) {
+ parser.script += "</" + c
+ parser.state = S.SCRIPT
+ } else {
+ strictFail(parser, "Invalid tagname in closing tag.")
+ }
+ } else parser.tagName = c
}
else if (c === ">") closeTag(parser)
else if (is(nameBody, c)) parser.tagName += c
- else {
+ else if (parser.script) {
+ parser.script += "</" + parser.tagName
+ parser.tagName = ""
+ parser.state = S.SCRIPT
+ } else {
if (not(whitespace, c)) strictFail(parser,
"Invalid tagname in closing tag")
parser.state = S.CLOSE_TAG_SAW_WHITE
@@ -958,7 +1280,7 @@ function write (chunk) {
case S.CLOSE_TAG_SAW_WHITE:
if (is(whitespace, c)) continue
if (c === ">") closeTag(parser)
- else strictFail("Invalid characters in closing tag")
+ else strictFail(parser, "Invalid characters in closing tag")
continue
case S.TEXT_ENTITY:
@@ -984,7 +1306,7 @@ function write (chunk) {
}
else if (is(entity, c)) parser.entity += c
else {
- strictFail("Invalid character entity")
+ strictFail(parser, "Invalid character entity")
parser[buffer] += "&" + parser.entity + c
parser.entity = ""
parser.state = returnState
diff --git a/package.json b/package.json
index 9281cb0..8ee1759 100644
--- a/package.json
+++ b/package.json
@@ -1,10 +1,12 @@
-{ "name" : "sax"
-, "description": "An evented streaming XML parser in JavaScript"
-, "author" : "Isaac Z. Schlueter <i at izs.me> (http://blog.izs.me/)"
-, "version" : "0.4.0"
-, "main" : "lib/sax.js"
-, "license" : { "type": "MIT"
- , "url": "https://raw.github.com/isaacs/sax-js/master/LICENSE" }
-, "scripts" : { "test" : "node test/index.js" }
-, "repository": "git://github.com/isaacs/sax-js.git"
+{
+ "name": "sax",
+ "description": "An evented streaming XML parser in JavaScript",
+ "author": "Isaac Z. Schlueter <i at izs.me> (http://blog.izs.me/)",
+ "version": "0.5.5",
+ "main": "lib/sax.js",
+ "license": "BSD",
+ "scripts": {
+ "test": "node test/index.js"
+ },
+ "repository": "git://github.com/isaacs/sax-js.git"
}
diff --git a/test/attribute-name.js b/test/attribute-name.js
new file mode 100644
index 0000000..9ebbe58
--- /dev/null
+++ b/test/attribute-name.js
@@ -0,0 +1,33 @@
+require(__dirname).test(
+ { xml: "<root length='12345'></root>"
+ , expect: [
+ ["attribute", {
+ name: "length"
+ , value: "12345"
+ , prefix: ""
+ , local: "length"
+ , uri: ""
+ }]
+ , ["opentag", {
+ name: "root"
+ , prefix: ""
+ , local: "root"
+ , uri: ""
+ , attributes: {
+ length: {
+ name: "length"
+ , value: "12345"
+ , prefix: ""
+ , local: "length"
+ , uri: ""
+ }
+ }
+ , ns: {}
+ , isSelfClosing: false
+ }]
+ , ["closetag", "root"]
+ ]
+ , strict: true
+ , opt: { xmlns: true }
+ }
+)
diff --git a/test/buffer-overrun.js b/test/buffer-overrun.js
index 8d12fac..57d3c41 100644
--- a/test/buffer-overrun.js
+++ b/test/buffer-overrun.js
@@ -10,7 +10,8 @@ require(__dirname).test({
["error", "Max buffer length exceeded: tagName\nLine: 0\nColumn: 45\nChar: "],
["opentag", {
"name": "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ",
- "attributes": {}
+ "attributes": {},
+ "isSelfClosing": false
}],
["text", "yo"],
["closetag", "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"]
diff --git a/test/case.js b/test/case.js
index 35ee934..9da78ab 100644
--- a/test/case.js
+++ b/test/case.js
@@ -6,7 +6,8 @@ require(__dirname).test
[ [ "attribute", { name: "CLASS", value: "test" } ]
, [ "attribute", { name: "HELLO", value: "world" } ]
, [ "opentag", { name: "SPAN",
- attributes: { CLASS: "test", HELLO: "world" } } ]
+ attributes: { CLASS: "test", HELLO: "world" },
+ isSelfClosing: false } ]
, [ "closetag", "SPAN" ]
]
, strict : false
@@ -22,7 +23,8 @@ require(__dirname).test
[ [ "attribute", { name: "class", value: "test" } ]
, [ "attribute", { name: "hello", value: "world" } ]
, [ "opentag", { name: "span",
- attributes: { class: "test", hello: "world" } } ]
+ attributes: { class: "test", hello: "world" },
+ isSelfClosing: false } ]
, [ "closetag", "span" ]
]
, strict : false
@@ -38,7 +40,8 @@ require(__dirname).test
[ [ "attribute", { name: "class", value: "test" } ]
, [ "attribute", { name: "hello", value: "world" } ]
, [ "opentag", { name: "span",
- attributes: { class: "test", hello: "world" } } ]
+ attributes: { class: "test", hello: "world" },
+ isSelfClosing: false } ]
, [ "closetag", "span" ]
]
, strict : false
diff --git a/test/cdata-chunked.js b/test/cdata-chunked.js
index ccd5ee6..e3362bc 100644
--- a/test/cdata-chunked.js
+++ b/test/cdata-chunked.js
@@ -1,7 +1,7 @@
require(__dirname).test({
expect : [
- ["opentag", {"name": "R","attributes": {}}],
+ ["opentag", {"name": "R","attributes": {}, "isSelfClosing": false}],
["opencdata", undefined],
["cdata", " this is character data "],
["closecdata", undefined],
diff --git a/test/cdata-end-split.js b/test/cdata-end-split.js
index b41bd00..34f3450 100644
--- a/test/cdata-end-split.js
+++ b/test/cdata-end-split.js
@@ -1,7 +1,7 @@
require(__dirname).test({
expect : [
- ["opentag", {"name": "R","attributes": {}}],
+ ["opentag", {"name": "R","attributes": {}, "isSelfClosing": false}],
["opencdata", undefined],
["cdata", " this is "],
["closecdata", undefined],
diff --git a/test/cdata-fake-end.js b/test/cdata-fake-end.js
index 07aeac4..ccafa1b 100644
--- a/test/cdata-fake-end.js
+++ b/test/cdata-fake-end.js
@@ -1,7 +1,7 @@
var p = require(__dirname).test({
expect : [
- ["opentag", {"name": "R","attributes": {}}],
+ ["opentag", {"name": "R","attributes": {}, "isSelfClosing": false}],
["opencdata", undefined],
["cdata", "[[[[[[[[]]]]]]]]"],
["closecdata", undefined],
@@ -17,7 +17,7 @@ p.close();
var p2 = require(__dirname).test({
expect : [
- ["opentag", {"name": "R","attributes": {}}],
+ ["opentag", {"name": "R","attributes": {}, "isSelfClosing": false}],
["opencdata", undefined],
["cdata", "[[[[[[[[]]]]]]]]"],
["closecdata", undefined],
diff --git a/test/cdata-multiple.js b/test/cdata-multiple.js
index dab2015..8e2f911 100644
--- a/test/cdata-multiple.js
+++ b/test/cdata-multiple.js
@@ -1,7 +1,7 @@
require(__dirname).test({
expect : [
- ["opentag", {"name": "R","attributes": {}}],
+ ["opentag", {"name": "R","attributes": {}, "isSelfClosing": false}],
["opencdata", undefined],
["cdata", " this is "],
["closecdata", undefined],
diff --git a/test/cdata.js b/test/cdata.js
index 0f09cce..31a8a30 100644
--- a/test/cdata.js
+++ b/test/cdata.js
@@ -1,7 +1,7 @@
require(__dirname).test({
xml : "<r><![CDATA[ this is character data ]]></r>",
expect : [
- ["opentag", {"name": "R","attributes": {}}],
+ ["opentag", {"name": "R","attributes": {}, "isSelfClosing": false}],
["opencdata", undefined],
["cdata", " this is character data "],
["closecdata", undefined],
diff --git a/test/cyrillic.js b/test/cyrillic.js
new file mode 100644
index 0000000..f05dd1b
--- /dev/null
+++ b/test/cyrillic.js
@@ -0,0 +1,8 @@
+require(__dirname).test({
+ xml: '<Р>тест</Р>',
+ expect: [
+ ['opentag', {'name':'Р', attributes:{}, isSelfClosing: false}],
+ ['text', 'тест'],
+ ['closetag', 'Р']
+ ]
+});
diff --git a/test/duplicate-attribute.js b/test/duplicate-attribute.js
new file mode 100644
index 0000000..a21eb41
--- /dev/null
+++ b/test/duplicate-attribute.js
@@ -0,0 +1,13 @@
+require(__dirname).test
+ ( { xml :
+ "<span id=\"hello\" id=\"there\"></span>"
+ , expect :
+ [ [ "attribute", { name: "ID", value: "hello" } ]
+ , [ "opentag", { name: "SPAN",
+ attributes: { ID: "hello" }, isSelfClosing: false } ]
+ , [ "closetag", "SPAN" ]
+ ]
+ , strict : false
+ , opt : {}
+ }
+ )
diff --git a/test/entities.js b/test/entities.js
new file mode 100644
index 0000000..4901667
--- /dev/null
+++ b/test/entities.js
@@ -0,0 +1,10 @@
+require(__dirname).test({
+ xml: '<r>⌋ ' +
+ '♠ © → & ' +
+ '< < < < < > ℜ ℘ €</r>',
+ expect: [
+ ['opentag', {'name':'R', attributes:{}, isSelfClosing: false}],
+ ['text', '⌋ ♠ © → & < < < < < > ℜ ℘ €'],
+ ['closetag', 'R']
+ ]
+});
diff --git a/test/entity-mega.js b/test/entity-mega.js
new file mode 100644
index 0000000..4759a02
--- /dev/null
+++ b/test/entity-mega.js
@@ -0,0 +1,16 @@
+var sax = require('../');
+var xml = '<r>';
+var text = '';
+for (var i in sax.ENTITIES) {
+ xml += '&' + i + ';'
+ text += sax.ENTITIES[i]
+}
+xml += '</r>'
+require(__dirname).test({
+ xml: xml,
+ expect: [
+ ['opentag', {'name':'R', attributes:{}, isSelfClosing: false}],
+ ['text', text],
+ ['closetag', 'R']
+ ]
+});
diff --git a/test/issue-23.js b/test/issue-23.js
index e7991b2..ccbdc35 100644
--- a/test/issue-23.js
+++ b/test/issue-23.js
@@ -13,24 +13,24 @@ require(__dirname).test
"</compileClassesResponse>"
, expect :
- [ [ "opentag", { name: "COMPILECLASSESRESPONSE", attributes: {} } ]
- , [ "opentag", { name : "RESULT", attributes: {} } ]
- , [ "opentag", { name: "BODYCRC", attributes: {} } ]
+ [ [ "opentag", { name: "COMPILECLASSESRESPONSE", attributes: {}, isSelfClosing: false } ]
+ , [ "opentag", { name : "RESULT", attributes: {}, isSelfClosing: false } ]
+ , [ "opentag", { name: "BODYCRC", attributes: {}, isSelfClosing: false } ]
, [ "text", "653724009" ]
, [ "closetag", "BODYCRC" ]
- , [ "opentag", { name: "COLUMN", attributes: {} } ]
+ , [ "opentag", { name: "COLUMN", attributes: {}, isSelfClosing: false } ]
, [ "text", "-1" ]
, [ "closetag", "COLUMN" ]
- , [ "opentag", { name: "ID", attributes: {} } ]
+ , [ "opentag", { name: "ID", attributes: {}, isSelfClosing: false } ]
, [ "text", "01pG0000002KoSUIA0" ]
, [ "closetag", "ID" ]
- , [ "opentag", {name: "LINE", attributes: {} } ]
+ , [ "opentag", {name: "LINE", attributes: {}, isSelfClosing: false } ]
, [ "text", "-1" ]
, [ "closetag", "LINE" ]
- , [ "opentag", {name: "NAME", attributes: {} } ]
+ , [ "opentag", {name: "NAME", attributes: {}, isSelfClosing: false } ]
, [ "text", "CalendarController" ]
, [ "closetag", "NAME" ]
- , [ "opentag", {name: "SUCCESS", attributes: {} } ]
+ , [ "opentag", {name: "SUCCESS", attributes: {}, isSelfClosing: false } ]
, [ "text", "true" ]
, [ "closetag", "SUCCESS" ]
, [ "closetag", "RESULT" ]
diff --git a/test/issue-30.js b/test/issue-30.js
index c2cc809..771b14e 100644
--- a/test/issue-30.js
+++ b/test/issue-30.js
@@ -8,11 +8,11 @@ require(__dirname).test
"</xml>"
, expect :
- [ [ "opentag", { name: "xml", attributes: {} } ]
+ [ [ "opentag", { name: "xml", attributes: {}, isSelfClosing: false } ]
, [ "text", "\n" ]
, [ "comment", " \n comment with a single dash- in it\n" ]
, [ "text", "\n" ]
- , [ "opentag", { name: "data", attributes: {} } ]
+ , [ "opentag", { name: "data", attributes: {}, isSelfClosing: true } ]
, [ "closetag", "data" ]
, [ "text", "\n" ]
, [ "closetag", "xml" ]
diff --git a/test/issue-35.js b/test/issue-35.js
index 7c521c5..64d67b3 100644
--- a/test/issue-35.js
+++ b/test/issue-35.js
@@ -4,7 +4,7 @@ require(__dirname).test
"</xml>"
, expect :
- [ [ "opentag", { name: "xml", attributes: {} } ]
+ [ [ "opentag", { name: "xml", attributes: {}, isSelfClosing: false } ]
, [ "text", "\r\r\n" ]
, [ "closetag", "xml" ]
]
diff --git a/test/issue-47.js b/test/issue-47.js
index 911c7d0..661584a 100644
--- a/test/issue-47.js
+++ b/test/issue-47.js
@@ -1,12 +1,11 @@
// https://github.com/isaacs/sax-js/issues/47
require(__dirname).test
( { xml : '<a href="query.svc?x=1&y=2&z=3"/>'
- , expect : [
- [ "attribute", { name:'href', value:"query.svc?x=1&y=2&z=3"} ],
- [ "opentag", { name: "a", attributes: { href:"query.svc?x=1&y=2&z=3"} } ],
- [ "closetag", "a" ]
+ , expect : [
+ [ "attribute", { name:'HREF', value:"query.svc?x=1&y=2&z=3"} ],
+ [ "opentag", { name: "A", attributes: { HREF:"query.svc?x=1&y=2&z=3"}, isSelfClosing: true } ],
+ [ "closetag", "A" ]
]
- , strict : true
, opt : {}
}
)
diff --git a/test/issue-49.js b/test/issue-49.js
index 2964325..ff2fbf7 100644
--- a/test/issue-49.js
+++ b/test/issue-49.js
@@ -2,8 +2,8 @@
require(__dirname).test
( { xml : "<xml><script>hello world</script></xml>"
, expect :
- [ [ "opentag", { name: "xml", attributes: {} } ]
- , [ "opentag", { name: "script", attributes: {} } ]
+ [ [ "opentag", { name: "xml", attributes: {}, isSelfClosing: false } ]
+ , [ "opentag", { name: "script", attributes: {}, isSelfClosing: false } ]
, [ "text", "hello world" ]
, [ "closetag", "script" ]
, [ "closetag", "xml" ]
@@ -16,8 +16,8 @@ require(__dirname).test
require(__dirname).test
( { xml : "<xml><script><![CDATA[hello world]]></script></xml>"
, expect :
- [ [ "opentag", { name: "xml", attributes: {} } ]
- , [ "opentag", { name: "script", attributes: {} } ]
+ [ [ "opentag", { name: "xml", attributes: {}, isSelfClosing: false } ]
+ , [ "opentag", { name: "script", attributes: {}, isSelfClosing: false } ]
, [ "opencdata", undefined ]
, [ "cdata", "hello world" ]
, [ "closecdata", undefined ]
diff --git a/test/issue-84.js b/test/issue-84.js
new file mode 100644
index 0000000..0e7ee69
--- /dev/null
+++ b/test/issue-84.js
@@ -0,0 +1,13 @@
+// https://github.com/isaacs/sax-js/issues/49
+require(__dirname).test
+ ( { xml : "<?has unbalanced \"quotes?><xml>body</xml>"
+ , expect :
+ [ [ "processinginstruction", { name: "has", body: "unbalanced \"quotes" } ],
+ [ "opentag", { name: "xml", attributes: {}, isSelfClosing: false } ]
+ , [ "text", "body" ]
+ , [ "closetag", "xml" ]
+ ]
+ , strict : false
+ , opt : { lowercasetags: true, noscript: true }
+ }
+ )
diff --git a/test/script-close-better.js b/test/script-close-better.js
new file mode 100644
index 0000000..f4887b9
--- /dev/null
+++ b/test/script-close-better.js
@@ -0,0 +1,12 @@
+require(__dirname).test({
+ xml : "<html><head><script>'<div>foo</div></'</script></head></html>",
+ expect : [
+ ["opentag", {"name": "HTML","attributes": {}, isSelfClosing: false}],
+ ["opentag", {"name": "HEAD","attributes": {}, isSelfClosing: false}],
+ ["opentag", {"name": "SCRIPT","attributes": {}, isSelfClosing: false}],
+ ["script", "'<div>foo</div></'"],
+ ["closetag", "SCRIPT"],
+ ["closetag", "HEAD"],
+ ["closetag", "HTML"]
+ ]
+});
diff --git a/test/script.js b/test/script.js
index 464c051..fbda1f6 100644
--- a/test/script.js
+++ b/test/script.js
@@ -1,9 +1,9 @@
require(__dirname).test({
xml : "<html><head><script>if (1 < 0) { console.log('elo there'); }</script></head></html>",
expect : [
- ["opentag", {"name": "HTML","attributes": {}}],
- ["opentag", {"name": "HEAD","attributes": {}}],
- ["opentag", {"name": "SCRIPT","attributes": {}}],
+ ["opentag", {"name": "HTML","attributes": {}, "isSelfClosing": false}],
+ ["opentag", {"name": "HEAD","attributes": {}, "isSelfClosing": false}],
+ ["opentag", {"name": "SCRIPT","attributes": {}, "isSelfClosing": false}],
["script", "if (1 < 0) { console.log('elo there'); }"],
["closetag", "SCRIPT"],
["closetag", "HEAD"],
diff --git a/test/self-closing-child-strict.js b/test/self-closing-child-strict.js
index ce9c045..3d6e985 100644
--- a/test/self-closing-child-strict.js
+++ b/test/self-closing-child-strict.js
@@ -12,21 +12,25 @@ require(__dirname).test({
expect : [
["opentag", {
"name": "root",
- "attributes": {}
+ "attributes": {},
+ "isSelfClosing": false
}],
["opentag", {
"name": "child",
- "attributes": {}
+ "attributes": {},
+ "isSelfClosing": false
}],
["opentag", {
"name": "haha",
- "attributes": {}
+ "attributes": {},
+ "isSelfClosing": true
}],
["closetag", "haha"],
["closetag", "child"],
["opentag", {
"name": "monkey",
- "attributes": {}
+ "attributes": {},
+ "isSelfClosing": false
}],
["text", "=(|)"],
["closetag", "monkey"],
diff --git a/test/self-closing-child.js b/test/self-closing-child.js
index bc6b52b..f31c366 100644
--- a/test/self-closing-child.js
+++ b/test/self-closing-child.js
@@ -12,21 +12,25 @@ require(__dirname).test({
expect : [
["opentag", {
"name": "ROOT",
- "attributes": {}
+ "attributes": {},
+ "isSelfClosing": false
}],
["opentag", {
"name": "CHILD",
- "attributes": {}
+ "attributes": {},
+ "isSelfClosing": false
}],
["opentag", {
"name": "HAHA",
- "attributes": {}
+ "attributes": {},
+ "isSelfClosing": true
}],
["closetag", "HAHA"],
["closetag", "CHILD"],
["opentag", {
"name": "MONKEY",
- "attributes": {}
+ "attributes": {},
+ "isSelfClosing": false
}],
["text", "=(|)"],
["closetag", "MONKEY"],
diff --git a/test/self-closing-tag.js b/test/self-closing-tag.js
index b2c5736..d1d8b7c 100644
--- a/test/self-closing-tag.js
+++ b/test/self-closing-tag.js
@@ -9,14 +9,14 @@ require(__dirname).test({
"</monkey>"+
"</root> ",
expect : [
- ["opentag", {name:"ROOT", attributes:{}}],
- ["opentag", {name:"HAHA", attributes:{}}],
+ ["opentag", {name:"ROOT", attributes:{}, isSelfClosing: false}],
+ ["opentag", {name:"HAHA", attributes:{}, isSelfClosing: true}],
["closetag", "HAHA"],
- ["opentag", {name:"HAHA", attributes:{}}],
+ ["opentag", {name:"HAHA", attributes:{}, isSelfClosing: true}],
["closetag", "HAHA"],
// ["opentag", {name:"HAHA", attributes:{}}],
// ["closetag", "HAHA"],
- ["opentag", {name:"MONKEY", attributes:{}}],
+ ["opentag", {name:"MONKEY", attributes:{}, isSelfClosing: false}],
["text", "=(|)"],
["closetag", "MONKEY"],
["closetag", "ROOT"]
diff --git a/test/stray-ending.js b/test/stray-ending.js
index 6b0aa7f..bec467b 100644
--- a/test/stray-ending.js
+++ b/test/stray-ending.js
@@ -4,8 +4,8 @@ require(__dirname).test
( { xml :
"<a><b></c></b></a>"
, expect :
- [ [ "opentag", { name: "A", attributes: {} } ]
- , [ "opentag", { name: "B", attributes: {} } ]
+ [ [ "opentag", { name: "A", attributes: {}, isSelfClosing: false } ]
+ , [ "opentag", { name: "B", attributes: {}, isSelfClosing: false } ]
, [ "text", "</c>" ]
, [ "closetag", "B" ]
, [ "closetag", "A" ]
diff --git a/test/trailing-attribute-no-value.js b/test/trailing-attribute-no-value.js
new file mode 100644
index 0000000..222837f
--- /dev/null
+++ b/test/trailing-attribute-no-value.js
@@ -0,0 +1,10 @@
+
+require(__dirname).test({
+ xml :
+ "<root attrib>",
+ expect : [
+ ["attribute", {name:"ATTRIB", value:"attrib"}],
+ ["opentag", {name:"ROOT", attributes:{"ATTRIB":"attrib"}, isSelfClosing: false}]
+ ],
+ opt : { trim : true }
+});
diff --git a/test/trailing-non-whitespace.js b/test/trailing-non-whitespace.js
index 3e1fb2e..619578b 100644
--- a/test/trailing-non-whitespace.js
+++ b/test/trailing-non-whitespace.js
@@ -4,7 +4,8 @@ require(__dirname).test({
expect : [
["opentag", {
"name": "SPAN",
- "attributes": {}
+ "attributes": {},
+ isSelfClosing: false
}],
["text", "Welcome,"],
["closetag", "SPAN"],
diff --git a/test/unclosed-root.js b/test/unclosed-root.js
new file mode 100644
index 0000000..f4eeac6
--- /dev/null
+++ b/test/unclosed-root.js
@@ -0,0 +1,11 @@
+require(__dirname).test
+ ( { xml : "<root>"
+
+ , expect :
+ [ [ "opentag", { name: "root", attributes: {}, isSelfClosing: false } ]
+ , [ "error", "Unclosed root tag\nLine: 0\nColumn: 6\nChar: " ]
+ ]
+ , strict : true
+ , opt : {}
+ }
+ )
diff --git a/test/unquoted.js b/test/unquoted.js
index dbeb638..b3a9a81 100644
--- a/test/unquoted.js
+++ b/test/unquoted.js
@@ -7,7 +7,8 @@ require(__dirname).test
[ [ "attribute", { name: "CLASS", value: "test" } ]
, [ "attribute", { name: "HELLO", value: "world" } ]
, [ "opentag", { name: "SPAN",
- attributes: { CLASS: "test", HELLO: "world" } } ]
+ attributes: { CLASS: "test", HELLO: "world" },
+ isSelfClosing: false } ]
, [ "closetag", "SPAN" ]
]
, strict : false
diff --git a/test/utf8-split.js b/test/utf8-split.js
new file mode 100644
index 0000000..e22bc10
--- /dev/null
+++ b/test/utf8-split.js
@@ -0,0 +1,32 @@
+var assert = require('assert')
+var saxStream = require('../lib/sax').createStream()
+
+var b = new Buffer('误')
+
+saxStream.on('text', function(text) {
+ assert.equal(text, b.toString())
+})
+
+saxStream.write(new Buffer('<test><a>'))
+saxStream.write(b.slice(0, 1))
+saxStream.write(b.slice(1))
+saxStream.write(new Buffer('</a><b>'))
+saxStream.write(b.slice(0, 2))
+saxStream.write(b.slice(2))
+saxStream.write(new Buffer('</b><c>'))
+saxStream.write(b)
+saxStream.write(new Buffer('</c>'))
+saxStream.write(Buffer.concat([new Buffer('<d>'), b.slice(0, 1)]))
+saxStream.end(Buffer.concat([b.slice(1), new Buffer('</d></test>')]))
+
+var saxStream2 = require('../lib/sax').createStream()
+
+saxStream2.on('text', function(text) {
+ assert.equal(text, '�')
+});
+
+saxStream2.write(new Buffer('<e>'));
+saxStream2.write(new Buffer([0xC0]));
+saxStream2.write(new Buffer('</e>'));
+saxStream2.write(Buffer.concat([new Buffer('<f>'), b.slice(0,1)]));
+saxStream2.end();
diff --git a/test/xmlns-issue-41.js b/test/xmlns-issue-41.js
index 596d82b..17ab45a 100644
--- a/test/xmlns-issue-41.js
+++ b/test/xmlns-issue-41.js
@@ -48,6 +48,7 @@ var t = require(__dirname)
}
}
, ns: {"a": "http://ATTRIBUTE"}
+ , isSelfClosing: true
}
]
, ["closetag", "parent"]
diff --git a/test/xmlns-rebinding.js b/test/xmlns-rebinding.js
index f464876..07e0425 100644
--- a/test/xmlns-rebinding.js
+++ b/test/xmlns-rebinding.js
@@ -20,20 +20,23 @@ require(__dirname).test
, "xmlns:y": { name: "xmlns:y", value: "y1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "y" }
, "x:a": { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" }
, "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } },
- ns: { x: 'x1', y: 'y1' } } ]
+ ns: { x: 'x1', y: 'y1' },
+ isSelfClosing: false } ]
, [ "opennamespace", { prefix: "x", uri: "x2" } ]
, [ "attribute", { name: "xmlns:x", value: "x2", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } ]
, [ "opentag", { name: "rebind", uri: "", prefix: "", local: "rebind",
attributes: { "xmlns:x": { name: "xmlns:x", value: "x2", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } },
- ns: { x: 'x2' } } ]
+ ns: { x: 'x2' },
+ isSelfClosing: false } ]
, [ "attribute", { name: "x:a", value: "x2", uri: "x2", prefix: "x", local: "a" } ]
, [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ]
, [ "opentag", { name: "check", uri: "", prefix: "", local: "check",
attributes: { "x:a": { name: "x:a", value: "x2", uri: "x2", prefix: "x", local: "a" }
, "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } },
- ns: { x: 'x2' } } ]
+ ns: { x: 'x2' },
+ isSelfClosing: true } ]
, [ "closetag", "check" ]
@@ -45,7 +48,8 @@ require(__dirname).test
, [ "opentag", { name: "check", uri: "", prefix: "", local: "check",
attributes: { "x:a": { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" }
, "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } },
- ns: { x: 'x1', y: 'y1' } } ]
+ ns: { x: 'x1', y: 'y1' },
+ isSelfClosing: true } ]
, [ "closetag", "check" ]
, [ "closetag", "root" ]
diff --git a/test/xmlns-strict.js b/test/xmlns-strict.js
index 4ad615b..b5e3e51 100644
--- a/test/xmlns-strict.js
+++ b/test/xmlns-strict.js
@@ -14,12 +14,12 @@ require(__dirname).test
, expect :
[ [ "opentag", { name: "root", prefix: "", local: "root", uri: "",
- attributes: {}, ns: {} } ]
+ attributes: {}, ns: {}, isSelfClosing: false } ]
, [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ]
, [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "",
attributes: { "attr": { name: "attr", value: "normal", uri: "", prefix: "", local: "attr", uri: "" } },
- ns: {} } ]
+ ns: {}, isSelfClosing: true } ]
, [ "closetag", "plain" ]
, [ "opennamespace", { prefix: "", uri: "uri:default" } ]
@@ -27,11 +27,12 @@ require(__dirname).test
, [ "attribute", { name: "xmlns", value: "uri:default", prefix: "xmlns", local: "", uri: "http://www.w3.org/2000/xmlns/" } ]
, [ "opentag", { name: "ns1", prefix: "", local: "ns1", uri: "uri:default",
attributes: { "xmlns": { name: "xmlns", value: "uri:default", prefix: "xmlns", local: "", uri: "http://www.w3.org/2000/xmlns/" } },
- ns: { "": "uri:default" } } ]
+ ns: { "": "uri:default" }, isSelfClosing: false } ]
- , [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "uri:default" } ]
+ , [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ]
, [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "uri:default", ns: { '': 'uri:default' },
- attributes: { "attr": { name: "attr", value: "normal", prefix: "", local: "attr", uri: "uri:default" } } } ]
+ attributes: { "attr": { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } },
+ isSelfClosing: true } ]
, [ "closetag", "plain" ]
, [ "closetag", "ns1" ]
@@ -44,18 +45,20 @@ require(__dirname).test
, [ "opentag", { name: "ns2", prefix: "", local: "ns2", uri: "",
attributes: { "xmlns:a": { name: "xmlns:a", value: "uri:nsa", prefix: "xmlns", local: "a", uri: "http://www.w3.org/2000/xmlns/" } },
- ns: { a: "uri:nsa" } } ]
+ ns: { a: "uri:nsa" }, isSelfClosing: false } ]
, [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ]
, [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "",
attributes: { "attr": { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } },
- ns: { a: 'uri:nsa' } } ]
+ ns: { a: 'uri:nsa' },
+ isSelfClosing: true } ]
, [ "closetag", "plain" ]
, [ "attribute", { name: "a:attr", value: "namespaced", prefix: "a", local: "attr", uri: "uri:nsa" } ]
, [ "opentag", { name: "a:ns", prefix: "a", local: "ns", uri: "uri:nsa",
attributes: { "a:attr": { name: "a:attr", value: "namespaced", prefix: "a", local: "attr", uri: "uri:nsa" } },
- ns: { a: 'uri:nsa' } } ]
+ ns: { a: 'uri:nsa' },
+ isSelfClosing: true } ]
, [ "closetag", "a:ns" ]
, [ "closetag", "ns2" ]
diff --git a/test/xmlns-unbound-element.js b/test/xmlns-unbound-element.js
new file mode 100644
index 0000000..9d031a2
--- /dev/null
+++ b/test/xmlns-unbound-element.js
@@ -0,0 +1,33 @@
+require(__dirname).test(
+ { strict : true
+ , opt : { xmlns: true }
+ , expect :
+ [ [ "error", "Unbound namespace prefix: \"unbound:root\"\nLine: 0\nColumn: 15\nChar: >"]
+ , [ "opentag", { name: "unbound:root", uri: "unbound", prefix: "unbound", local: "root"
+ , attributes: {}, ns: {}, isSelfClosing: true } ]
+ , [ "closetag", "unbound:root" ]
+ ]
+ }
+).write("<unbound:root/>");
+
+require(__dirname).test(
+ { strict : true
+ , opt : { xmlns: true }
+ , expect :
+ [ [ "opennamespace", { prefix: "unbound", uri: "someuri" } ]
+ , [ "attribute", { name: 'xmlns:unbound', value: 'someuri'
+ , prefix: 'xmlns', local: 'unbound'
+ , uri: 'http://www.w3.org/2000/xmlns/' } ]
+ , [ "opentag", { name: "unbound:root", uri: "someuri", prefix: "unbound", local: "root"
+ , attributes: { 'xmlns:unbound': {
+ name: 'xmlns:unbound'
+ , value: 'someuri'
+ , prefix: 'xmlns'
+ , local: 'unbound'
+ , uri: 'http://www.w3.org/2000/xmlns/' } }
+ , ns: { "unbound": "someuri" }, isSelfClosing: true } ]
+ , [ "closetag", "unbound:root" ]
+ , [ "closenamespace", { prefix: 'unbound', uri: 'someuri' }]
+ ]
+ }
+).write("<unbound:root xmlns:unbound=\"someuri\"/>");
diff --git a/test/xmlns-unbound.js b/test/xmlns-unbound.js
index 2944b87..b740e26 100644
--- a/test/xmlns-unbound.js
+++ b/test/xmlns-unbound.js
@@ -8,7 +8,7 @@ require(__dirname).test(
, [ "attribute", { name: "unbound:attr", value: "value", uri: "unbound", prefix: "unbound", local: "attr" } ]
, [ "opentag", { name: "root", uri: "", prefix: "", local: "root",
attributes: { "unbound:attr": { name: "unbound:attr", value: "value", uri: "unbound", prefix: "unbound", local: "attr" } },
- ns: {} } ]
+ ns: {}, isSelfClosing: true } ]
, [ "closetag", "root" ]
]
}
diff --git a/test/xmlns-xml-default-ns.js b/test/xmlns-xml-default-ns.js
new file mode 100644
index 0000000..b1984d2
--- /dev/null
+++ b/test/xmlns-xml-default-ns.js
@@ -0,0 +1,31 @@
+var xmlns_attr =
+{
+ name: "xmlns", value: "http://foo", prefix: "xmlns",
+ local: "", uri : "http://www.w3.org/2000/xmlns/"
+};
+
+var attr_attr =
+{
+ name: "attr", value: "bar", prefix: "",
+ local : "attr", uri : ""
+};
+
+
+require(__dirname).test
+ ( { xml :
+ "<elm xmlns='http://foo' attr='bar'/>"
+ , expect :
+ [ [ "opennamespace", { prefix: "", uri: "http://foo" } ]
+ , [ "attribute", xmlns_attr ]
+ , [ "attribute", attr_attr ]
+ , [ "opentag", { name: "elm", prefix: "", local: "elm", uri : "http://foo",
+ ns : { "" : "http://foo" },
+ attributes: { xmlns: xmlns_attr, attr: attr_attr },
+ isSelfClosing: true } ]
+ , [ "closetag", "elm" ]
+ , [ "closenamespace", { prefix: "", uri: "http://foo"} ]
+ ]
+ , strict : true
+ , opt : {xmlns: true}
+ }
+ )
diff --git a/test/xmlns-xml-default-prefix-attribute.js b/test/xmlns-xml-default-prefix-attribute.js
index 16da771..e41f218 100644
--- a/test/xmlns-xml-default-prefix-attribute.js
+++ b/test/xmlns-xml-default-prefix-attribute.js
@@ -24,6 +24,7 @@ require(__dirname).test(
}
}
, ns: {}
+ , isSelfClosing: true
}
]
, ["closetag", "root"]
diff --git a/test/xmlns-xml-default-prefix.js b/test/xmlns-xml-default-prefix.js
index 9a1ce1b..a85b478 100644
--- a/test/xmlns-xml-default-prefix.js
+++ b/test/xmlns-xml-default-prefix.js
@@ -9,6 +9,7 @@ require(__dirname).test(
, local: "root"
, attributes: {}
, ns: {}
+ , isSelfClosing: true
}
]
, ["closetag", "xml:root"]
diff --git a/test/xmlns-xml-default-redefine.js b/test/xmlns-xml-default-redefine.js
index 1eba9c7..d35d5a0 100644
--- a/test/xmlns-xml-default-redefine.js
+++ b/test/xmlns-xml-default-redefine.js
@@ -29,6 +29,7 @@ require(__dirname).test(
}
}
, ns: {}
+ , isSelfClosing: true
}
]
, ["closetag", "xml:root"]
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/collab-maint/sax.js.git
More information about the Pkg-javascript-commits
mailing list