sax 0.1.1 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. {1289345704997-0.9273225662764162 → package}/LICENSE +0 -0
  2. {1289345704997-0.9273225662764162 → package}/README.md +10 -6
  3. {1289345704997-0.9273225662764162 → package}/examples/example.js +0 -0
  4. {1289345704997-0.9273225662764162 → package}/examples/not-pretty.xml +0 -0
  5. {1289345704997-0.9273225662764162 → package}/examples/pretty-print.js +0 -0
  6. {1289345704997-0.9273225662764162 → package}/examples/strict.dtd +0 -0
  7. {1289345704997-0.9273225662764162 → package}/examples/switch-bench.js +0 -0
  8. {1289345704997-0.9273225662764162 → package}/examples/test.html +0 -0
  9. {1289345704997-0.9273225662764162 → package}/examples/test.xml +0 -0
  10. {1289345704997-0.9273225662764162 → package}/lib/sax.js +41 -16
  11. {1289345704997-0.9273225662764162 → package}/package.json +1 -1
  12. {1289345704997-0.9273225662764162 → package}/test/buffer-overrun.js +5 -2
  13. {1289345704997-0.9273225662764162 → package}/test/cdata-chunked.js +3 -2
  14. package/test/cdata-end-split.js +15 -0
  15. package/test/cdata-fake-end.js +28 -0
  16. package/test/cdata-multiple.js +15 -0
  17. {1289345704997-0.9273225662764162 → package}/test/cdata.js +2 -0
  18. {1289345704997-0.9273225662764162 → package}/test/index.js +29 -25
  19. package/test/issue-23.js +43 -0
  20. package/test/parser-position.js +27 -0
  21. {1289345704997-0.9273225662764162 → package}/test/self-closing-child-strict.js +0 -0
  22. {1289345704997-0.9273225662764162 → package}/test/self-closing-child.js +0 -0
  23. {1289345704997-0.9273225662764162 → package}/test/self-closing-tag.js +0 -0
  24. {1289345704997-0.9273225662764162 → package}/test/trailing-non-whitespace.js +0 -0
  25. 1289345704997-0.9273225662764162/._LICENSE +0 -0
  26. 1289345704997-0.9273225662764162/._README.md +0 -0
  27. 1289345704997-0.9273225662764162/examples/._example.js +0 -0
  28. 1289345704997-0.9273225662764162/examples/._not-pretty.xml +0 -0
  29. 1289345704997-0.9273225662764162/examples/._pretty-print.js +0 -0
  30. 1289345704997-0.9273225662764162/examples/._strict.dtd +0 -0
  31. 1289345704997-0.9273225662764162/examples/._switch-bench.js +0 -0
  32. 1289345704997-0.9273225662764162/examples/._test.html +0 -0
  33. 1289345704997-0.9273225662764162/examples/._test.xml +0 -0
  34. 1289345704997-0.9273225662764162/lib/._sax.js +0 -0
  35. 1289345704997-0.9273225662764162/test/._buffer-overrun.js +0 -0
  36. 1289345704997-0.9273225662764162/test/._cdata-chunked.js +0 -0
  37. 1289345704997-0.9273225662764162/test/._cdata.js +0 -0
  38. 1289345704997-0.9273225662764162/test/._self-closing-child-strict.js +0 -0
  39. 1289345704997-0.9273225662764162/test/._self-closing-child.js +0 -0
  40. 1289345704997-0.9273225662764162/test/._self-closing-tag.js +0 -0
  41. 1289345704997-0.9273225662764162/test/._trailing-non-whitespace.js +0 -0
File without changes
@@ -38,9 +38,9 @@ Unknown entities will fail in strict mode, and in loose mode, will pass through
38
38
  var sax = require("./lib/sax"),
39
39
  strict = true, // set to false for html-mode
40
40
  parser = sax.parser(strict);
41
-
41
+
42
42
  parser.onerror = function (e) {
43
- // an error happened.
43
+ // an error happened.
44
44
  };
45
45
  parser.ontext = function (t) {
46
46
  // got some text. t is the string of text.
@@ -54,7 +54,7 @@ Unknown entities will fail in strict mode, and in loose mode, will pass through
54
54
  parser.onend = function () {
55
55
  // parser stream is done, and ready to have more stuff written to it.
56
56
  };
57
-
57
+
58
58
  parser.write('<xml>Hello, <who name="world">world</who>!</xml>').close();
59
59
 
60
60
  ## Arguments
@@ -90,7 +90,7 @@ At all times, the parser object will have the following members:
90
90
  `line`, `column`, `position` - Indications of the position in the XML document where
91
91
  the parser currently is looking.
92
92
 
93
- `closed` - Boolean indicating whether or not the parser can be written to. If it's
93
+ `closed` - Boolean indicating whether or not the parser can be written to. If it's
94
94
  `true`, then wait for the `ready` event to write again.
95
95
 
96
96
  `strict` - Boolean indicating whether or not the parser is a jerk.
@@ -133,10 +133,14 @@ will have `closeTag` emitted immediately after `openTag`. Argument: tag name.
133
133
 
134
134
  `comment` - A comment node. Argument: the string of the comment.
135
135
 
136
- `cdata` - A `<![CDATA[` block. Since `<![CDATA[` blocks can get quite large, this event
136
+ `opencdata` - The opening tag of a `<![CDATA[` block.
137
+
138
+ `cdata` - The text of a `<![CDATA[` block. Since `<![CDATA[` blocks can get quite large, this event
137
139
  may fire multiple times for a single block, if it is broken up into multiple `write()`s.
138
140
  Argument: the string of random character data.
139
141
 
142
+ `closecdata` - The closing tag (`]]>`) of a `<![CDATA[` block.
143
+
140
144
  `end` - Indication that the closed stream has ended.
141
145
 
142
146
  `ready` - Indication that the stream has reset, and is ready to be written to.
@@ -146,4 +150,4 @@ Argument: the string of random character data.
146
150
  Build an HTML parser on top of this, which follows the same parsing rules as web browsers.
147
151
 
148
152
  Make it fast by replacing the trampoline with a switch, and not buffering so much
149
- stuff.
153
+ stuff.
@@ -1,5 +1,6 @@
1
+ // wrapper for non-node envs
2
+ ;(function (sax) {
1
3
 
2
- var sax = exports;
3
4
  sax.parser = function (strict, opt) { return new SAXParser(strict, opt) };
4
5
  sax.SAXParser = SAXParser;
5
6
 
@@ -38,18 +39,23 @@ function SAXParser (strict, opt) {
38
39
  emit(this, "onready");
39
40
  }
40
41
  function checkBufferLength (parser) {
41
- var maxAllowed = sax.MAX_BUFFER_LENGTH,
42
+ var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10),
42
43
  maxActual = 0;
43
44
  for (var i = 0, l = buffers.length; i < l; i ++) {
44
45
  var len = parser[buffers[i]].length;
45
46
  if (len > maxAllowed) {
46
- if (buffers[i] === "textNode") {
47
- // Text nodes can get big, and since they're buffered, we can get here
48
- // under normal conditions. Avoid issues by emitting the text node now,
49
- // so at least it won't get any bigger.
50
- closeText(parser);
51
- } else {
52
- error(parser, "Max buffer length exceeded: "+buffers[i]);
47
+ // Text/cdata nodes can get big, and since they're buffered,
48
+ // we can get here under normal conditions.
49
+ // Avoid issues by emitting the text node now,
50
+ // so at least it won't get any bigger.
51
+ switch (buffers[i]) {
52
+ case "textNode": closeText(parser) ; break
53
+ case "cdata":
54
+ emitNode(parser, "oncdata", parser.cdata)
55
+ parser.cdata = ""
56
+ break
57
+ default:
58
+ error(parser, "Max buffer length exceeded: "+buffers[i])
53
59
  }
54
60
  }
55
61
  maxActual = Math.max(maxActual, len);
@@ -112,9 +118,9 @@ sax.STATE =
112
118
  , ATTRIB : S++ // <a
113
119
  , ATTRIB_NAME : S++ // <a foo
114
120
  , ATTRIB_NAME_SAW_WHITE : S++ // <a foo _
115
- , ATTRIB_VALUE : S++ // <a foo="bar
121
+ , ATTRIB_VALUE : S++ // <a foo=
116
122
  , ATTRIB_VALUE_QUOTED : S++ // <a foo="bar
117
- , ATTRIB_VALUE_UNQUOTED : S++ // <a foo="bar
123
+ , ATTRIB_VALUE_UNQUOTED : S++ // <a foo=bar
118
124
  , ATTRIB_VALUE_ENTITY_Q : S++ // <foo bar="&quot;"
119
125
  , ATTRIB_VALUE_ENTITY_U : S++ // <foo bar=&quot;
120
126
  , CLOSE_TAG : S++ // </a
@@ -136,7 +142,7 @@ S = sax.STATE;
136
142
  sax.EVENTS = [ // for discoverability.
137
143
  "text", "processinginstruction", "sgmldeclaration",
138
144
  "doctype", "comment", "attribute", "opentag", "closetag",
139
- "cdata", "error", "end", "ready" ];
145
+ "opencdata", "cdata", "closecdata", "error", "end", "ready" ];
140
146
 
141
147
  function emit (parser, event, data) {
142
148
  parser[event] && parser[event](data);
@@ -268,6 +274,20 @@ function write (chunk) {
268
274
  }
269
275
  continue;
270
276
  case S.TEXT:
277
+ if (parser.sawRoot && !parser.closedRoot) {
278
+ var starti = i-1;
279
+ while (c && c!=="<" && c!=="&") {
280
+ c = chunk.charAt(i++);
281
+ if (c) {
282
+ parser.position ++;
283
+ if (c === "\n") {
284
+ parser.line ++;
285
+ parser.column = 0;
286
+ } else parser.column ++;
287
+ }
288
+ }
289
+ parser.textNode += chunk.substring(starti, i-1);
290
+ }
271
291
  if (c === "<") parser.state = S.OPEN_WAKA;
272
292
  else {
273
293
  if (not(whitespace, c) && (!parser.sawRoot || parser.closedRoot))
@@ -300,6 +320,7 @@ function write (chunk) {
300
320
  continue;
301
321
  case S.SGML_DECL:
302
322
  if ((parser.sgmlDecl+c).toUpperCase() === CDATA) {
323
+ emitNode(parser, "onopencdata");
303
324
  parser.state = S.CDATA;
304
325
  parser.sgmlDecl = "";
305
326
  parser.cdata = "";
@@ -398,8 +419,11 @@ function write (chunk) {
398
419
  case S.CDATA_ENDING_2:
399
420
  if (c === ">") {
400
421
  if (parser.cdata) emitNode(parser, "oncdata", parser.cdata);
422
+ emitNode(parser, "onclosecdata");
401
423
  parser.cdata = "";
402
424
  parser.state = S.TEXT;
425
+ } else if (c === "]") {
426
+ parser.cdata += "]"
403
427
  } else {
404
428
  parser.cdata += "]]" + c;
405
429
  parser.state = S.CDATA;
@@ -586,10 +610,11 @@ function write (chunk) {
586
610
  }
587
611
  } // while
588
612
  // cdata blocks can get very big under normal conditions. emit and move on.
589
- if (parser.state === S.CDATA && parser.cdata) {
590
- emitNode(parser, "oncdata", parser.cdata);
591
- parser.cdata = "";
592
- }
613
+ // if (parser.state === S.CDATA && parser.cdata) {
614
+ // emitNode(parser, "oncdata", parser.cdata);
615
+ // parser.cdata = "";
616
+ // }
593
617
  if (parser.position >= parser.bufferCheckPosition) checkBufferLength(parser);
594
618
  return parser;
595
619
  }
620
+ })(typeof exports === "undefined" ? sax = {} : exports)
@@ -1,6 +1,6 @@
1
1
  { "name" : "sax"
2
2
  , "author" : "Isaac Z. Schlueter <i@izs.me>"
3
- , "version" : "0.1.1"
3
+ , "version" : "0.1.5"
4
4
  , "main" : "lib/sax"
5
5
  , "license" : "MIT"
6
6
  , "scripts" : { "test" : "node test/index.js" }
@@ -1,5 +1,7 @@
1
1
  // set this really low so that I don't have to put 64 MB of xml in here.
2
- require(require("path").join(__dirname, "../lib/sax")).MAX_BUFFER_LENGTH = 5;
2
+ var sax = require("../lib/sax")
3
+ var bl = sax.MAX_BUFFER_LENGTH
4
+ sax.MAX_BUFFER_LENGTH = 5;
3
5
 
4
6
  require(__dirname).test({
5
7
  expect : [
@@ -19,4 +21,5 @@ require(__dirname).test({
19
21
  .write("STUVWXYZ>")
20
22
  .write("yo")
21
23
  .write("</abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ>")
22
- .close();
24
+ .close();
25
+ sax.MAX_BUFFER_LENGTH = bl
@@ -2,8 +2,9 @@
2
2
  require(__dirname).test({
3
3
  expect : [
4
4
  ["opentag", {"name": "R","attributes": {}}],
5
- ["cdata", " this is "],
6
- ["cdata", "character data  "],
5
+ ["opencdata", undefined],
6
+ ["cdata", " this is character data  "],
7
+ ["closecdata", undefined],
7
8
  ["closetag", "R"]
8
9
  ]
9
10
  }).write("<r><![CDATA[ this is ").write("character data  ").write("]]></r>").close();
@@ -0,0 +1,15 @@
1
+
2
+ require(__dirname).test({
3
+ expect : [
4
+ ["opentag", {"name": "R","attributes": {}}],
5
+ ["opencdata", undefined],
6
+ ["cdata", " this is "],
7
+ ["closecdata", undefined],
8
+ ["closetag", "R"]
9
+ ]
10
+ })
11
+ .write("<r><![CDATA[ this is ]")
12
+ .write("]>")
13
+ .write("</r>")
14
+ .close();
15
+
@@ -0,0 +1,28 @@
1
+
2
+ var p = require(__dirname).test({
3
+ expect : [
4
+ ["opentag", {"name": "R","attributes": {}}],
5
+ ["opencdata", undefined],
6
+ ["cdata", "[[[[[[[[]]]]]]]]"],
7
+ ["closecdata", undefined],
8
+ ["closetag", "R"]
9
+ ]
10
+ })
11
+ var x = "<r><![CDATA[[[[[[[[[]]]]]]]]]]></r>"
12
+ for (var i = 0; i < x.length ; i ++) {
13
+ p.write(x.charAt(i))
14
+ }
15
+ p.close();
16
+
17
+
18
+ var p2 = require(__dirname).test({
19
+ expect : [
20
+ ["opentag", {"name": "R","attributes": {}}],
21
+ ["opencdata", undefined],
22
+ ["cdata", "[[[[[[[[]]]]]]]]"],
23
+ ["closecdata", undefined],
24
+ ["closetag", "R"]
25
+ ]
26
+ })
27
+ var x = "<r><![CDATA[[[[[[[[[]]]]]]]]]]></r>"
28
+ p2.write(x).close();
@@ -0,0 +1,15 @@
1
+
2
+ require(__dirname).test({
3
+ expect : [
4
+ ["opentag", {"name": "R","attributes": {}}],
5
+ ["opencdata", undefined],
6
+ ["cdata", " this is "],
7
+ ["closecdata", undefined],
8
+ ["opencdata", undefined],
9
+ ["cdata", "character data  "],
10
+ ["closecdata", undefined],
11
+ ["closetag", "R"]
12
+ ]
13
+ }).write("<r><![CDATA[ this is ]]>").write("<![CDA").write("T").write("A[")
14
+ .write("character data  ").write("]]></r>").close();
15
+
@@ -2,7 +2,9 @@ require(__dirname).test({
2
2
  xml : "<r><![CDATA[ this is character data  ]]></r>",
3
3
  expect : [
4
4
  ["opentag", {"name": "R","attributes": {}}],
5
+ ["opencdata", undefined],
5
6
  ["cdata", " this is character data  "],
7
+ ["closecdata", undefined],
6
8
  ["closetag", "R"]
7
9
  ]
8
10
  });
@@ -21,17 +21,18 @@ exports.test = function test (options) {
21
21
  assert.ok( e < expect.length,
22
22
  "expectation #"+e+" "+sys.inspect(expect[e])+"\n"+
23
23
  "Unexpected event: "+ev+" "+(n ? sys.inspect(n) : ""));
24
+ var inspected = n instanceof Error ? "\n"+ n.message : sys.inspect(n)
24
25
  assert.equal(ev, expect[e][0],
25
26
  "expectation #"+e+"\n"+
26
27
  "Didn't get expected event\n"+
27
28
  "expect: "+expect[e][0] + " " +sys.inspect(expect[e][1])+"\n"+
28
- "actual: "+ev+" "+sys.inspect(n)+"\n");
29
+ "actual: "+ev+" "+inspected+"\n");
29
30
  if (ev === "error") assert.equal(n.message, expect[e][1]);
30
31
  else assert.deepEqual(n, expect[e][1],
31
32
  "expectation #"+e+"\n"+
32
33
  "Didn't get expected argument\n"+
33
34
  "expect: "+expect[e][0] + " " +sys.inspect(expect[e][1])+"\n"+
34
- "actual: "+ev+" "+sys.inspect(n)+"\n");
35
+ "actual: "+ev+" "+inspected+"\n");
35
36
  e++;
36
37
  if (ev === "error") parser.resume();
37
38
  };
@@ -40,30 +41,33 @@ exports.test = function test (options) {
40
41
  return parser;
41
42
  }
42
43
 
43
- if (module.id === ".") {
44
+ if (module === require.main) {
44
45
  var running = true,
45
46
  failures = 0;
46
- function fail (file, next) { return function (er) {
47
+ function fail (file, er) {
47
48
  sys.error("Failed: "+file);
48
- sys.error(er.message);
49
+ sys.error(er.stack || er.message);
49
50
  failures ++;
50
- next();
51
- }}
52
-
53
- fs.readdir(__dirname, function (error, files) {(function T (f) {
54
- var file = files[f];
55
- if (!file) {
56
- if (!failures) return sys.puts("ok");
57
- else return sys.error(failures + " failure" + (failures > 1 ? "s" : ""));
58
- }
59
- if (path.basename(file) === path.basename(__filename))
60
- return process.nextTick(function () { T(f + 1) });
61
- // run this test.
62
- function next () { T(f + 1) };
63
- if (/\.js$/.exec(file)) {
64
- require.async(__dirname + "/"+file.replace(/\.js$/, ''), function (er) {
65
- return (er) ? fail(file, next) : next()
66
- });
67
- }
68
- })(0)});
69
- }
51
+ }
52
+
53
+ fs.readdir(__dirname, function (error, files) {
54
+ files = files.filter(function (file) {
55
+ return (/\.js$/.exec(file) && file !== 'index.js')
56
+ })
57
+ var n = files.length
58
+ , i = 0
59
+ console.log("0.." + n)
60
+ files.forEach(function (file) {
61
+ // run this test.
62
+ try {
63
+ require(path.resolve(__dirname, file))
64
+ console.log("ok " + (++i) + " - " + file)
65
+ } catch (er) {
66
+ console.log("not ok "+ (++i) + " - " + file)
67
+ fail(file, er)
68
+ }
69
+ })
70
+ if (!failures) return console.log("#all pass");
71
+ else return console.error(failures + " failure" + (failures > 1 ? "s" : ""));
72
+ });
73
+ }
@@ -0,0 +1,43 @@
1
+
2
+ require(__dirname).test
3
+ ( { xml :
4
+ "<compileClassesResponse>"+
5
+ "<result>"+
6
+ "<bodyCrc>653724009</bodyCrc>"+
7
+ "<column>-1</column>"+
8
+ "<id>01pG0000002KoSUIA0</id>"+
9
+ "<line>-1</line>"+
10
+ "<name>CalendarController</name>"+
11
+ "<success>true</success>"+
12
+ "</result>"+
13
+ "</compileClassesResponse>"
14
+
15
+ , expect :
16
+ [ [ "opentag", { name: "COMPILECLASSESRESPONSE", attributes: {} } ]
17
+ , [ "opentag", { name : "RESULT", attributes: {} } ]
18
+ , [ "opentag", { name: "BODYCRC", attributes: {} } ]
19
+ , [ "text", "653724009" ]
20
+ , [ "closetag", "BODYCRC" ]
21
+ , [ "opentag", { name: "COLUMN", attributes: {} } ]
22
+ , [ "text", "-1" ]
23
+ , [ "closetag", "COLUMN" ]
24
+ , [ "opentag", { name: "ID", attributes: {} } ]
25
+ , [ "text", "01pG0000002KoSUIA0" ]
26
+ , [ "closetag", "ID" ]
27
+ , [ "opentag", {name: "LINE", attributes: {} } ]
28
+ , [ "text", "-1" ]
29
+ , [ "closetag", "LINE" ]
30
+ , [ "opentag", {name: "NAME", attributes: {} } ]
31
+ , [ "text", "CalendarController" ]
32
+ , [ "closetag", "NAME" ]
33
+ , [ "opentag", {name: "SUCCESS", attributes: {} } ]
34
+ , [ "text", "true" ]
35
+ , [ "closetag", "SUCCESS" ]
36
+ , [ "closetag", "RESULT" ]
37
+ , [ "closetag", "COMPILECLASSESRESPONSE" ]
38
+ ]
39
+ , strict : false
40
+ , opt : {}
41
+ }
42
+ )
43
+
@@ -0,0 +1,27 @@
1
+ var sax = require("../lib/sax"),
2
+ assert = require("assert")
3
+
4
+ function testPosition(chunks, expectedEvents) {
5
+ var parser = sax.parser();
6
+ expectedEvents.forEach(function(expectation) {
7
+ parser['on' + expectation[0]] = function() {
8
+ assert.equal(parser.position, expectation[1]);
9
+ }
10
+ });
11
+ chunks.forEach(function(chunk) {
12
+ parser.write(chunk);
13
+ });
14
+ };
15
+
16
+ testPosition(['<div>abcdefgh</div>'],
17
+ [ ['opentag', 5]
18
+ , ['text', 19]
19
+ , ['closetag', 19]
20
+ ]);
21
+
22
+ testPosition(['<div>abcde','fgh</div>'],
23
+ [ ['opentag', 5]
24
+ , ['text', 19]
25
+ , ['closetag', 19]
26
+ ]);
27
+
Binary file