tck-lambdas 0.3.4 → 0.3.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.
- checksums.yaml +4 -4
- data/README.md +42 -12
- data/lib/tck/lambdas/chistacojs/source/chistacojs.js +9 -5
- data/lib/tck/lambdas/chistacojs/source/chistescortos.js +2 -3
- data/lib/tck/lambdas/chistacojs/source/chyton.js +24 -0
- data/lib/tck/lambdas/chistacojs/source/conf.js +7 -0
- data/lib/tck/lambdas/chistacojs/source/node_modules/xmldom/__package__.js +4 -0
- data/lib/tck/lambdas/chistacojs/source/node_modules/xmldom/component.json +10 -0
- data/lib/tck/lambdas/chistacojs/source/node_modules/xmldom/dom-parser.js +249 -0
- data/lib/tck/lambdas/chistacojs/source/node_modules/xmldom/dom.js +1147 -0
- data/lib/tck/lambdas/chistacojs/source/node_modules/xmldom/package.json +101 -0
- data/lib/tck/lambdas/chistacojs/source/node_modules/xmldom/readme.md +219 -0
- data/lib/tck/lambdas/chistacojs/source/node_modules/xmldom/sax.js +586 -0
- data/lib/tck/lambdas/chistacojs/source/node_modules/xpath/README.md +96 -0
- data/lib/tck/lambdas/chistacojs/source/node_modules/xpath/package.json +71 -0
- data/lib/tck/lambdas/chistacojs/source/node_modules/xpath/test.js +804 -0
- data/lib/tck/lambdas/chistacojs/source/node_modules/xpath/xpath.js +4693 -0
- data/lib/tck/lambdas/chistacojs/source/refreshing_matter.js +2 -3
- data/lib/tck/lambdas/chistacojs/test/succeeded/chyton_module.json +1 -0
- data/lib/tck/lambdas/version.rb +1 -1
- metadata +15 -3
- data/lib/tck/lambdas/chistacojs/chistaco_diario.zip +0 -0
@@ -0,0 +1,586 @@
|
|
1
|
+
//[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
|
2
|
+
//[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
|
3
|
+
//[5] Name ::= NameStartChar (NameChar)*
|
4
|
+
var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]///\u10000-\uEFFFF
|
5
|
+
var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\u00B7\u0300-\u036F\\u203F-\u2040]");
|
6
|
+
var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
|
7
|
+
//var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
|
8
|
+
//var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',')
|
9
|
+
|
10
|
+
//S_TAG, S_ATTR, S_EQ, S_V
|
11
|
+
//S_ATTR_S, S_E, S_S, S_C
|
12
|
+
var S_TAG = 0;//tag name offerring
|
13
|
+
var S_ATTR = 1;//attr name offerring
|
14
|
+
var S_ATTR_S=2;//attr name end and space offer
|
15
|
+
var S_EQ = 3;//=space?
|
16
|
+
var S_V = 4;//attr value(no quot value only)
|
17
|
+
var S_E = 5;//attr value end and no space(quot end)
|
18
|
+
var S_S = 6;//(attr value end || tag end ) && (space offer)
|
19
|
+
var S_C = 7;//closed el<el />
|
20
|
+
|
21
|
+
function XMLReader(){
|
22
|
+
|
23
|
+
}
|
24
|
+
|
25
|
+
XMLReader.prototype = {
|
26
|
+
parse:function(source,defaultNSMap,entityMap){
|
27
|
+
var domBuilder = this.domBuilder;
|
28
|
+
domBuilder.startDocument();
|
29
|
+
_copy(defaultNSMap ,defaultNSMap = {})
|
30
|
+
parse(source,defaultNSMap,entityMap,
|
31
|
+
domBuilder,this.errorHandler);
|
32
|
+
domBuilder.endDocument();
|
33
|
+
}
|
34
|
+
}
|
35
|
+
function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
|
36
|
+
function fixedFromCharCode(code) {
|
37
|
+
// String.prototype.fromCharCode does not supports
|
38
|
+
// > 2 bytes unicode chars directly
|
39
|
+
if (code > 0xffff) {
|
40
|
+
code -= 0x10000;
|
41
|
+
var surrogate1 = 0xd800 + (code >> 10)
|
42
|
+
, surrogate2 = 0xdc00 + (code & 0x3ff);
|
43
|
+
|
44
|
+
return String.fromCharCode(surrogate1, surrogate2);
|
45
|
+
} else {
|
46
|
+
return String.fromCharCode(code);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
function entityReplacer(a){
|
50
|
+
var k = a.slice(1,-1);
|
51
|
+
if(k in entityMap){
|
52
|
+
return entityMap[k];
|
53
|
+
}else if(k.charAt(0) === '#'){
|
54
|
+
return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
|
55
|
+
}else{
|
56
|
+
errorHandler.error('entity not found:'+a);
|
57
|
+
return a;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
function appendText(end){//has some bugs
|
61
|
+
if(end>start){
|
62
|
+
var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
|
63
|
+
locator&&position(start);
|
64
|
+
domBuilder.characters(xt,0,end-start);
|
65
|
+
start = end
|
66
|
+
}
|
67
|
+
}
|
68
|
+
function position(p,m){
|
69
|
+
while(p>=lineEnd && (m = linePattern.exec(source))){
|
70
|
+
lineStart = m.index;
|
71
|
+
lineEnd = lineStart + m[0].length;
|
72
|
+
locator.lineNumber++;
|
73
|
+
//console.log('line++:',locator,startPos,endPos)
|
74
|
+
}
|
75
|
+
locator.columnNumber = p-lineStart+1;
|
76
|
+
}
|
77
|
+
var lineStart = 0;
|
78
|
+
var lineEnd = 0;
|
79
|
+
var linePattern = /.+(?:\r\n?|\n)|.*$/g
|
80
|
+
var locator = domBuilder.locator;
|
81
|
+
|
82
|
+
var parseStack = [{currentNSMap:defaultNSMapCopy}]
|
83
|
+
var closeMap = {};
|
84
|
+
var start = 0;
|
85
|
+
while(true){
|
86
|
+
try{
|
87
|
+
var tagStart = source.indexOf('<',start);
|
88
|
+
if(tagStart<0){
|
89
|
+
if(!source.substr(start).match(/^\s*$/)){
|
90
|
+
var doc = domBuilder.document;
|
91
|
+
var text = doc.createTextNode(source.substr(start));
|
92
|
+
doc.appendChild(text);
|
93
|
+
domBuilder.currentElement = text;
|
94
|
+
}
|
95
|
+
return;
|
96
|
+
}
|
97
|
+
if(tagStart>start){
|
98
|
+
appendText(tagStart);
|
99
|
+
}
|
100
|
+
switch(source.charAt(tagStart+1)){
|
101
|
+
case '/':
|
102
|
+
var end = source.indexOf('>',tagStart+3);
|
103
|
+
var tagName = source.substring(tagStart+2,end);
|
104
|
+
var config = parseStack.pop();
|
105
|
+
var localNSMap = config.localNSMap;
|
106
|
+
if(config.tagName != tagName){
|
107
|
+
errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName );
|
108
|
+
}
|
109
|
+
domBuilder.endElement(config.uri,config.localName,tagName);
|
110
|
+
if(localNSMap){
|
111
|
+
for(var prefix in localNSMap){
|
112
|
+
domBuilder.endPrefixMapping(prefix) ;
|
113
|
+
}
|
114
|
+
}
|
115
|
+
end++;
|
116
|
+
break;
|
117
|
+
// end elment
|
118
|
+
case '?':// <?...?>
|
119
|
+
locator&&position(tagStart);
|
120
|
+
end = parseInstruction(source,tagStart,domBuilder);
|
121
|
+
break;
|
122
|
+
case '!':// <!doctype,<![CDATA,<!--
|
123
|
+
locator&&position(tagStart);
|
124
|
+
end = parseDCC(source,tagStart,domBuilder,errorHandler);
|
125
|
+
break;
|
126
|
+
default:
|
127
|
+
|
128
|
+
locator&&position(tagStart);
|
129
|
+
|
130
|
+
var el = new ElementAttributes();
|
131
|
+
|
132
|
+
//elStartEnd
|
133
|
+
var end = parseElementStartPart(source,tagStart,el,entityReplacer,errorHandler);
|
134
|
+
var len = el.length;
|
135
|
+
|
136
|
+
if(locator){
|
137
|
+
if(len){
|
138
|
+
//attribute position fixed
|
139
|
+
for(var i = 0;i<len;i++){
|
140
|
+
var a = el[i];
|
141
|
+
position(a.offset);
|
142
|
+
a.offset = copyLocator(locator,{});
|
143
|
+
}
|
144
|
+
}
|
145
|
+
position(end);
|
146
|
+
}
|
147
|
+
if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
|
148
|
+
el.closed = true;
|
149
|
+
if(!entityMap.nbsp){
|
150
|
+
errorHandler.warning('unclosed xml attribute');
|
151
|
+
}
|
152
|
+
}
|
153
|
+
appendElement(el,domBuilder,parseStack);
|
154
|
+
|
155
|
+
|
156
|
+
if(el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed){
|
157
|
+
end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder)
|
158
|
+
}else{
|
159
|
+
end++;
|
160
|
+
}
|
161
|
+
}
|
162
|
+
}catch(e){
|
163
|
+
errorHandler.error('element parse error: '+e);
|
164
|
+
end = -1;
|
165
|
+
}
|
166
|
+
if(end>start){
|
167
|
+
start = end;
|
168
|
+
}else{
|
169
|
+
//TODO: 这里有可能sax回退,有位置错误风险
|
170
|
+
appendText(Math.max(tagStart,start)+1);
|
171
|
+
}
|
172
|
+
}
|
173
|
+
}
|
174
|
+
function copyLocator(f,t){
|
175
|
+
t.lineNumber = f.lineNumber;
|
176
|
+
t.columnNumber = f.columnNumber;
|
177
|
+
return t;
|
178
|
+
}
|
179
|
+
|
180
|
+
/**
|
181
|
+
* @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
|
182
|
+
* @return end of the elementStartPart(end of elementEndPart for selfClosed el)
|
183
|
+
*/
|
184
|
+
function parseElementStartPart(source,start,el,entityReplacer,errorHandler){
|
185
|
+
var attrName;
|
186
|
+
var value;
|
187
|
+
var p = ++start;
|
188
|
+
var s = S_TAG;//status
|
189
|
+
while(true){
|
190
|
+
var c = source.charAt(p);
|
191
|
+
switch(c){
|
192
|
+
case '=':
|
193
|
+
if(s === S_ATTR){//attrName
|
194
|
+
attrName = source.slice(start,p);
|
195
|
+
s = S_EQ;
|
196
|
+
}else if(s === S_ATTR_S){
|
197
|
+
s = S_EQ;
|
198
|
+
}else{
|
199
|
+
//fatalError: equal must after attrName or space after attrName
|
200
|
+
throw new Error('attribute equal must after attrName');
|
201
|
+
}
|
202
|
+
break;
|
203
|
+
case '\'':
|
204
|
+
case '"':
|
205
|
+
if(s === S_EQ){//equal
|
206
|
+
start = p+1;
|
207
|
+
p = source.indexOf(c,start)
|
208
|
+
if(p>0){
|
209
|
+
value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
|
210
|
+
el.add(attrName,value,start-1);
|
211
|
+
s = S_E;
|
212
|
+
}else{
|
213
|
+
//fatalError: no end quot match
|
214
|
+
throw new Error('attribute value no end \''+c+'\' match');
|
215
|
+
}
|
216
|
+
}else if(s == S_V){
|
217
|
+
value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
|
218
|
+
//console.log(attrName,value,start,p)
|
219
|
+
el.add(attrName,value,start);
|
220
|
+
//console.dir(el)
|
221
|
+
errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
|
222
|
+
start = p+1;
|
223
|
+
s = S_E
|
224
|
+
}else{
|
225
|
+
//fatalError: no equal before
|
226
|
+
throw new Error('attribute value must after "="');
|
227
|
+
}
|
228
|
+
break;
|
229
|
+
case '/':
|
230
|
+
switch(s){
|
231
|
+
case S_TAG:
|
232
|
+
el.setTagName(source.slice(start,p));
|
233
|
+
case S_E:
|
234
|
+
case S_S:
|
235
|
+
case S_C:
|
236
|
+
s = S_C;
|
237
|
+
el.closed = true;
|
238
|
+
case S_V:
|
239
|
+
case S_ATTR:
|
240
|
+
case S_ATTR_S:
|
241
|
+
break;
|
242
|
+
//case S_EQ:
|
243
|
+
default:
|
244
|
+
throw new Error("attribute invalid close char('/')")
|
245
|
+
}
|
246
|
+
break;
|
247
|
+
case ''://end document
|
248
|
+
//throw new Error('unexpected end of input')
|
249
|
+
errorHandler.error('unexpected end of input');
|
250
|
+
case '>':
|
251
|
+
switch(s){
|
252
|
+
case S_TAG:
|
253
|
+
el.setTagName(source.slice(start,p));
|
254
|
+
case S_E:
|
255
|
+
case S_S:
|
256
|
+
case S_C:
|
257
|
+
break;//normal
|
258
|
+
case S_V://Compatible state
|
259
|
+
case S_ATTR:
|
260
|
+
value = source.slice(start,p);
|
261
|
+
if(value.slice(-1) === '/'){
|
262
|
+
el.closed = true;
|
263
|
+
value = value.slice(0,-1)
|
264
|
+
}
|
265
|
+
case S_ATTR_S:
|
266
|
+
if(s === S_ATTR_S){
|
267
|
+
value = attrName;
|
268
|
+
}
|
269
|
+
if(s == S_V){
|
270
|
+
errorHandler.warning('attribute "'+value+'" missed quot(")!!');
|
271
|
+
el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start)
|
272
|
+
}else{
|
273
|
+
errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!')
|
274
|
+
el.add(value,value,start)
|
275
|
+
}
|
276
|
+
break;
|
277
|
+
case S_EQ:
|
278
|
+
throw new Error('attribute value missed!!');
|
279
|
+
}
|
280
|
+
// console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
|
281
|
+
return p;
|
282
|
+
/*xml space '\x20' | #x9 | #xD | #xA; */
|
283
|
+
case '\u0080':
|
284
|
+
c = ' ';
|
285
|
+
default:
|
286
|
+
if(c<= ' '){//space
|
287
|
+
switch(s){
|
288
|
+
case S_TAG:
|
289
|
+
el.setTagName(source.slice(start,p));//tagName
|
290
|
+
s = S_S;
|
291
|
+
break;
|
292
|
+
case S_ATTR:
|
293
|
+
attrName = source.slice(start,p)
|
294
|
+
s = S_ATTR_S;
|
295
|
+
break;
|
296
|
+
case S_V:
|
297
|
+
var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
|
298
|
+
errorHandler.warning('attribute "'+value+'" missed quot(")!!');
|
299
|
+
el.add(attrName,value,start)
|
300
|
+
case S_E:
|
301
|
+
s = S_S;
|
302
|
+
break;
|
303
|
+
//case S_S:
|
304
|
+
//case S_EQ:
|
305
|
+
//case S_ATTR_S:
|
306
|
+
// void();break;
|
307
|
+
//case S_C:
|
308
|
+
//ignore warning
|
309
|
+
}
|
310
|
+
}else{//not space
|
311
|
+
//S_TAG, S_ATTR, S_EQ, S_V
|
312
|
+
//S_ATTR_S, S_E, S_S, S_C
|
313
|
+
switch(s){
|
314
|
+
//case S_TAG:void();break;
|
315
|
+
//case S_ATTR:void();break;
|
316
|
+
//case S_V:void();break;
|
317
|
+
case S_ATTR_S:
|
318
|
+
errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead!!')
|
319
|
+
el.add(attrName,attrName,start);
|
320
|
+
start = p;
|
321
|
+
s = S_ATTR;
|
322
|
+
break;
|
323
|
+
case S_E:
|
324
|
+
errorHandler.warning('attribute space is required"'+attrName+'"!!')
|
325
|
+
case S_S:
|
326
|
+
s = S_ATTR;
|
327
|
+
start = p;
|
328
|
+
break;
|
329
|
+
case S_EQ:
|
330
|
+
s = S_V;
|
331
|
+
start = p;
|
332
|
+
break;
|
333
|
+
case S_C:
|
334
|
+
throw new Error("elements closed character '/' and '>' must be connected to");
|
335
|
+
}
|
336
|
+
}
|
337
|
+
}
|
338
|
+
p++;
|
339
|
+
}
|
340
|
+
}
|
341
|
+
/**
|
342
|
+
* @return end of the elementStartPart(end of elementEndPart for selfClosed el)
|
343
|
+
*/
|
344
|
+
function appendElement(el,domBuilder,parseStack){
|
345
|
+
var tagName = el.tagName;
|
346
|
+
var localNSMap = null;
|
347
|
+
var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
|
348
|
+
var i = el.length;
|
349
|
+
while(i--){
|
350
|
+
var a = el[i];
|
351
|
+
var qName = a.qName;
|
352
|
+
var value = a.value;
|
353
|
+
var nsp = qName.indexOf(':');
|
354
|
+
if(nsp>0){
|
355
|
+
var prefix = a.prefix = qName.slice(0,nsp);
|
356
|
+
var localName = qName.slice(nsp+1);
|
357
|
+
var nsPrefix = prefix === 'xmlns' && localName
|
358
|
+
}else{
|
359
|
+
localName = qName;
|
360
|
+
prefix = null
|
361
|
+
nsPrefix = qName === 'xmlns' && ''
|
362
|
+
}
|
363
|
+
//can not set prefix,because prefix !== ''
|
364
|
+
a.localName = localName ;
|
365
|
+
//prefix == null for no ns prefix attribute
|
366
|
+
if(nsPrefix !== false){//hack!!
|
367
|
+
if(localNSMap == null){
|
368
|
+
localNSMap = {}
|
369
|
+
//console.log(currentNSMap,0)
|
370
|
+
_copy(currentNSMap,currentNSMap={})
|
371
|
+
//console.log(currentNSMap,1)
|
372
|
+
}
|
373
|
+
currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
|
374
|
+
a.uri = 'http://www.w3.org/2000/xmlns/'
|
375
|
+
domBuilder.startPrefixMapping(nsPrefix, value)
|
376
|
+
}
|
377
|
+
}
|
378
|
+
var i = el.length;
|
379
|
+
while(i--){
|
380
|
+
a = el[i];
|
381
|
+
var prefix = a.prefix;
|
382
|
+
if(prefix){//no prefix attribute has no namespace
|
383
|
+
if(prefix === 'xml'){
|
384
|
+
a.uri = 'http://www.w3.org/XML/1998/namespace';
|
385
|
+
}if(prefix !== 'xmlns'){
|
386
|
+
a.uri = currentNSMap[prefix]
|
387
|
+
|
388
|
+
//{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
|
389
|
+
}
|
390
|
+
}
|
391
|
+
}
|
392
|
+
var nsp = tagName.indexOf(':');
|
393
|
+
if(nsp>0){
|
394
|
+
prefix = el.prefix = tagName.slice(0,nsp);
|
395
|
+
localName = el.localName = tagName.slice(nsp+1);
|
396
|
+
}else{
|
397
|
+
prefix = null;//important!!
|
398
|
+
localName = el.localName = tagName;
|
399
|
+
}
|
400
|
+
//no prefix element has default namespace
|
401
|
+
var ns = el.uri = currentNSMap[prefix || ''];
|
402
|
+
domBuilder.startElement(ns,localName,tagName,el);
|
403
|
+
//endPrefixMapping and startPrefixMapping have not any help for dom builder
|
404
|
+
//localNSMap = null
|
405
|
+
if(el.closed){
|
406
|
+
domBuilder.endElement(ns,localName,tagName);
|
407
|
+
if(localNSMap){
|
408
|
+
for(prefix in localNSMap){
|
409
|
+
domBuilder.endPrefixMapping(prefix)
|
410
|
+
}
|
411
|
+
}
|
412
|
+
}else{
|
413
|
+
el.currentNSMap = currentNSMap;
|
414
|
+
el.localNSMap = localNSMap;
|
415
|
+
parseStack.push(el);
|
416
|
+
}
|
417
|
+
}
|
418
|
+
function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
|
419
|
+
if(/^(?:script|textarea)$/i.test(tagName)){
|
420
|
+
var elEndStart = source.indexOf('</'+tagName+'>',elStartEnd);
|
421
|
+
var text = source.substring(elStartEnd+1,elEndStart);
|
422
|
+
if(/[&<]/.test(text)){
|
423
|
+
if(/^script$/i.test(tagName)){
|
424
|
+
//if(!/\]\]>/.test(text)){
|
425
|
+
//lexHandler.startCDATA();
|
426
|
+
domBuilder.characters(text,0,text.length);
|
427
|
+
//lexHandler.endCDATA();
|
428
|
+
return elEndStart;
|
429
|
+
//}
|
430
|
+
}//}else{//text area
|
431
|
+
text = text.replace(/&#?\w+;/g,entityReplacer);
|
432
|
+
domBuilder.characters(text,0,text.length);
|
433
|
+
return elEndStart;
|
434
|
+
//}
|
435
|
+
|
436
|
+
}
|
437
|
+
}
|
438
|
+
return elStartEnd+1;
|
439
|
+
}
|
440
|
+
function fixSelfClosed(source,elStartEnd,tagName,closeMap){
|
441
|
+
//if(tagName in closeMap){
|
442
|
+
var pos = closeMap[tagName];
|
443
|
+
if(pos == null){
|
444
|
+
//console.log(tagName)
|
445
|
+
pos = closeMap[tagName] = source.lastIndexOf('</'+tagName+'>')
|
446
|
+
}
|
447
|
+
return pos<elStartEnd;
|
448
|
+
//}
|
449
|
+
}
|
450
|
+
function _copy(source,target){
|
451
|
+
for(var n in source){target[n] = source[n]}
|
452
|
+
}
|
453
|
+
function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
|
454
|
+
var next= source.charAt(start+2)
|
455
|
+
switch(next){
|
456
|
+
case '-':
|
457
|
+
if(source.charAt(start + 3) === '-'){
|
458
|
+
var end = source.indexOf('-->',start+4);
|
459
|
+
//append comment source.substring(4,end)//<!--
|
460
|
+
if(end>start){
|
461
|
+
domBuilder.comment(source,start+4,end-start-4);
|
462
|
+
return end+3;
|
463
|
+
}else{
|
464
|
+
errorHandler.error("Unclosed comment");
|
465
|
+
return -1;
|
466
|
+
}
|
467
|
+
}else{
|
468
|
+
//error
|
469
|
+
return -1;
|
470
|
+
}
|
471
|
+
default:
|
472
|
+
if(source.substr(start+3,6) == 'CDATA['){
|
473
|
+
var end = source.indexOf(']]>',start+9);
|
474
|
+
domBuilder.startCDATA();
|
475
|
+
domBuilder.characters(source,start+9,end-start-9);
|
476
|
+
domBuilder.endCDATA()
|
477
|
+
return end+3;
|
478
|
+
}
|
479
|
+
//<!DOCTYPE
|
480
|
+
//startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
|
481
|
+
var matchs = split(source,start);
|
482
|
+
var len = matchs.length;
|
483
|
+
if(len>1 && /!doctype/i.test(matchs[0][0])){
|
484
|
+
var name = matchs[1][0];
|
485
|
+
var pubid = len>3 && /^public$/i.test(matchs[2][0]) && matchs[3][0]
|
486
|
+
var sysid = len>4 && matchs[4][0];
|
487
|
+
var lastMatch = matchs[len-1]
|
488
|
+
domBuilder.startDTD(name,pubid && pubid.replace(/^(['"])(.*?)\1$/,'$2'),
|
489
|
+
sysid && sysid.replace(/^(['"])(.*?)\1$/,'$2'));
|
490
|
+
domBuilder.endDTD();
|
491
|
+
|
492
|
+
return lastMatch.index+lastMatch[0].length
|
493
|
+
}
|
494
|
+
}
|
495
|
+
return -1;
|
496
|
+
}
|
497
|
+
|
498
|
+
|
499
|
+
|
500
|
+
function parseInstruction(source,start,domBuilder){
|
501
|
+
var end = source.indexOf('?>',start);
|
502
|
+
if(end){
|
503
|
+
var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
|
504
|
+
if(match){
|
505
|
+
var len = match[0].length;
|
506
|
+
domBuilder.processingInstruction(match[1], match[2]) ;
|
507
|
+
return end+2;
|
508
|
+
}else{//error
|
509
|
+
return -1;
|
510
|
+
}
|
511
|
+
}
|
512
|
+
return -1;
|
513
|
+
}
|
514
|
+
|
515
|
+
/**
|
516
|
+
* @param source
|
517
|
+
*/
|
518
|
+
function ElementAttributes(source){
|
519
|
+
|
520
|
+
}
|
521
|
+
ElementAttributes.prototype = {
|
522
|
+
setTagName:function(tagName){
|
523
|
+
if(!tagNamePattern.test(tagName)){
|
524
|
+
throw new Error('invalid tagName:'+tagName)
|
525
|
+
}
|
526
|
+
this.tagName = tagName
|
527
|
+
},
|
528
|
+
add:function(qName,value,offset){
|
529
|
+
if(!tagNamePattern.test(qName)){
|
530
|
+
throw new Error('invalid attribute:'+qName)
|
531
|
+
}
|
532
|
+
this[this.length++] = {qName:qName,value:value,offset:offset}
|
533
|
+
},
|
534
|
+
length:0,
|
535
|
+
getLocalName:function(i){return this[i].localName},
|
536
|
+
getOffset:function(i){return this[i].offset},
|
537
|
+
getQName:function(i){return this[i].qName},
|
538
|
+
getURI:function(i){return this[i].uri},
|
539
|
+
getValue:function(i){return this[i].value}
|
540
|
+
// ,getIndex:function(uri, localName)){
|
541
|
+
// if(localName){
|
542
|
+
//
|
543
|
+
// }else{
|
544
|
+
// var qName = uri
|
545
|
+
// }
|
546
|
+
// },
|
547
|
+
// getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
|
548
|
+
// getType:function(uri,localName){}
|
549
|
+
// getType:function(i){},
|
550
|
+
}
|
551
|
+
|
552
|
+
|
553
|
+
|
554
|
+
|
555
|
+
function _set_proto_(thiz,parent){
|
556
|
+
thiz.__proto__ = parent;
|
557
|
+
return thiz;
|
558
|
+
}
|
559
|
+
if(!(_set_proto_({},_set_proto_.prototype) instanceof _set_proto_)){
|
560
|
+
_set_proto_ = function(thiz,parent){
|
561
|
+
function p(){};
|
562
|
+
p.prototype = parent;
|
563
|
+
p = new p();
|
564
|
+
for(parent in thiz){
|
565
|
+
p[parent] = thiz[parent];
|
566
|
+
}
|
567
|
+
return p;
|
568
|
+
}
|
569
|
+
}
|
570
|
+
|
571
|
+
function split(source,start){
|
572
|
+
var match;
|
573
|
+
var buf = [];
|
574
|
+
var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
|
575
|
+
reg.lastIndex = start;
|
576
|
+
reg.exec(source);//skip <
|
577
|
+
while(match = reg.exec(source)){
|
578
|
+
buf.push(match);
|
579
|
+
if(match[1])return buf;
|
580
|
+
}
|
581
|
+
}
|
582
|
+
|
583
|
+
if(typeof require == 'function'){
|
584
|
+
exports.XMLReader = XMLReader;
|
585
|
+
}
|
586
|
+
|
@@ -0,0 +1,96 @@
|
|
1
|
+
## xpath
|
2
|
+
DOM 3 XPath 1.0 implemention and helper for JavaScript, with node.js support.
|
3
|
+
|
4
|
+
Originally written by Cameron McCormack ([blog](http://mcc.id.au/xpathjs)).
|
5
|
+
|
6
|
+
Additional contributions from
|
7
|
+
Yaron Naveh ([blog](http://webservices20.blogspot.com/))
|
8
|
+
goto100
|
9
|
+
Thomas Weinert
|
10
|
+
Jimmy Rishe
|
11
|
+
and [others](https://github.com/goto100/xpath/graphs/contributors)
|
12
|
+
|
13
|
+
## Install
|
14
|
+
Install with [npm](http://github.com/isaacs/npm):
|
15
|
+
|
16
|
+
npm install xpath
|
17
|
+
|
18
|
+
xpath is xml engine agnostic but I recommend to use [xmldom](https://github.com/jindw/xmldom):
|
19
|
+
|
20
|
+
npm install xmldom
|
21
|
+
|
22
|
+
|
23
|
+
## Your first xpath:
|
24
|
+
`````javascript
|
25
|
+
var xpath = require('xpath')
|
26
|
+
, dom = require('xmldom').DOMParser
|
27
|
+
|
28
|
+
var xml = "<book><title>Harry Potter</title></book>"
|
29
|
+
var doc = new dom().parseFromString(xml)
|
30
|
+
var nodes = xpath.select("//title", doc)
|
31
|
+
|
32
|
+
console.log(nodes[0].localName + ": " + nodes[0].firstChild.data)
|
33
|
+
console.log("node: " + nodes[0].toString())
|
34
|
+
`````
|
35
|
+
➡
|
36
|
+
|
37
|
+
title: Harry Potter
|
38
|
+
Node: <title>Harry Potter</title>
|
39
|
+
|
40
|
+
## Get text values directly
|
41
|
+
`````javascript
|
42
|
+
var xml = "<book><title>Harry Potter</title></book>"
|
43
|
+
var doc = new dom().parseFromString(xml)
|
44
|
+
var title = xpath.select("//title/text()", doc).toString()
|
45
|
+
|
46
|
+
console.log(title)
|
47
|
+
`````
|
48
|
+
➡
|
49
|
+
|
50
|
+
Harry Potter
|
51
|
+
|
52
|
+
## Namespaces
|
53
|
+
`````javascript
|
54
|
+
var xml = "<book><title xmlns='myns'>Harry Potter</title></book>"
|
55
|
+
var doc = new dom().parseFromString(xml)
|
56
|
+
var node = xpath.select("//*[local-name(.)='title' and namespace-uri(.)='myns']", doc)[0]
|
57
|
+
|
58
|
+
console.log(node.namespaceURI)
|
59
|
+
`````
|
60
|
+
➡
|
61
|
+
|
62
|
+
myns
|
63
|
+
|
64
|
+
## Namespaces with easy mappings
|
65
|
+
`````javascript
|
66
|
+
var xml = "<book xmlns:bookml='http://example.com/book'><bookml:title>Harry Potter</bookml:title></book>"
|
67
|
+
var select = xpath.useNamespaces({"bookml": "http://example.com/book"});
|
68
|
+
|
69
|
+
console.log(select('//bookml:title/text()', doc)[0].nodeValue);
|
70
|
+
`````
|
71
|
+
➡
|
72
|
+
|
73
|
+
Harry Potter
|
74
|
+
|
75
|
+
## Default namespace with mapping
|
76
|
+
`````javascript
|
77
|
+
var xml = "<book xmlns='http://example.com/book'><title>Harry Potter</title></book>"
|
78
|
+
var select = xpath.useNamespaces({"bookml": "http://example.com/book"});
|
79
|
+
|
80
|
+
console.log(select('//bookml:title/text()', doc)[0].nodeValue);
|
81
|
+
`````
|
82
|
+
➡
|
83
|
+
|
84
|
+
Harry Potter
|
85
|
+
|
86
|
+
## Attributes
|
87
|
+
`````javascript
|
88
|
+
var xml = "<book author='J. K. Rowling'><title>Harry Potter</title></book>"
|
89
|
+
var doc = new dom().parseFromString(xml)
|
90
|
+
var author = xpath.select1("/book/@author", doc).value
|
91
|
+
|
92
|
+
console.log(author)
|
93
|
+
`````
|
94
|
+
➡
|
95
|
+
|
96
|
+
J. K. Rowling
|