Skip to content

Commit

Permalink
add locator support and merge to many contribution
Browse files Browse the repository at this point in the history
  • Loading branch information
jindw committed Sep 3, 2012
1 parent 9544e7d commit 47fa9b8
Show file tree
Hide file tree
Showing 7 changed files with 1,064 additions and 17 deletions.
35 changes: 25 additions & 10 deletions dom-parser.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
function DOMParser(){
function DOMParser(pos){
this.recordPositions = pos;

}
DOMParser.prototype.parseFromString = function(source,mimeType){
var sax = new XMLReader();
var handler = new DOMHandler();
var defaultNSMap = {};
var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"}
if(this.recordPositions){
handler.setDocumentLocator({})
}
sax.contentHandler = handler;
sax.lexicalHandler = handler;
sax.errorHandler = handler;
Expand All @@ -30,7 +34,10 @@ function DOMHandler() {
this.errors = [];
this.cdata = false;
}

function position(locator,node){
node.lineNumber = locator.lineNumber;
node.columnNumber = locator.columnNumber;
}
/**
* @see org.xml.sax.ContentHandler#startDocument
* @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
Expand All @@ -39,7 +46,7 @@ DOMHandler.prototype = {
startDocument : function() {
this.document = new DOMImplementation().createDocument(null, null, null);
if (this.locator) {
this.document.documentURI = this.locator.getSystemId();
this.document.documentURI = this.locator.systemId;
}
},
startElement:function(namespaceURI, localName, qName, attrs) {
Expand All @@ -48,6 +55,8 @@ DOMHandler.prototype = {
var len = attrs.length;
appendElement(this, el);
this.currentElement = el;

this.locator && position(this.locator,el)
for (var i = 0 ; i < len; i++) {
var namespaceURI = attrs.getURI(i);
var value = attrs.getValue(i);
Expand All @@ -69,6 +78,7 @@ DOMHandler.prototype = {
},
processingInstruction:function(target, data) {
var ins = this.document.createProcessingInstruction(target, data);
this.locator && position(this.locator,ins)
appendElement(this, ins);
},
ignorableWhitespace:function(ch, start, length) {
Expand All @@ -77,12 +87,13 @@ DOMHandler.prototype = {
chars = _toString.apply(this,arguments)
if(this.currentElement && chars){
if (this.cdata) {
var cdataNode = this.document.createCDATASection(chars);
this.currentElement.appendChild(cdataNode);
var charNode = this.document.createCDATASection(chars);
this.currentElement.appendChild(charNode);
} else {
var textNode = this.document.createTextNode(chars);
this.currentElement.appendChild(textNode);
var charNode = this.document.createTextNode(chars);
this.currentElement.appendChild(charNode);
}
this.locator && position(this.locator,charNode)
}
},
skippedEntity:function(name) {
Expand All @@ -91,13 +102,16 @@ DOMHandler.prototype = {
this.document.normalize();
},
setDocumentLocator:function (locator) {
this.locator = locator;
if(this.locator = locator){
locator.lineNumber = 0;
}
},
//LexicalHandler
comment:function(chars, start, length) {
chars = _toString.apply(this,arguments)
var comment = this.document.createComment(chars);
appendElement(this, comment);
var comm = this.document.createComment(chars);
this.locator && position(this.locator,comm)
appendElement(this, comm);
},

startCDATA:function() {
Expand All @@ -112,6 +126,7 @@ DOMHandler.prototype = {
var impl = this.document.implementation;
if (impl && impl.createDocumentType) {
var dt = impl.createDocumentType(name, publicId, systemId);
this.locator && position(this.locator,dt)
appendElement(this, dt);
}
},
Expand Down
10 changes: 5 additions & 5 deletions dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -946,9 +946,9 @@ function serializeToString(node,buf){
}
return;
case ATTRIBUTE_NODE:
return buf.push(' ',node.name,'="',node.value.replace(/[<>&"]/g,_xmlEncoder),'"');
return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"');
case TEXT_NODE:
return buf.push(node.data.replace(/[<>&]/g,_xmlEncoder));
return buf.push(node.data.replace(/[<&]/g,_xmlEncoder));
case CDATA_SECTION_NODE:
return buf.push( '<![CDATA[',node.data,']]>');
case COMMENT_NODE:
Expand Down Expand Up @@ -1091,9 +1091,9 @@ try{
while(this.firstChild){
this.removeChild(this.firstChild);
}
if(String(data)!=''){
this.appendChild(this.ownerDocument.createTextNode(data));
}
if(data || String(data)){
this.appendChild(this.ownerDocument.createTextNode(data));
}
break;
default:
//TODO:
Expand Down
18 changes: 18 additions & 0 deletions sax.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,24 @@ function parse(source,defaultNSMapCopy,entityMap,contentHandler,lexHandler,error
}
function appendText(end){
var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
locator&&position(start);
contentHandler.characters(xt,0,end-start);
start = end
}
function position(start,m){
while(start>=endPos && (m = linePattern.exec(source))){
startPos = m.index;
endPos = startPos + m[0].length;
locator.lineNumber++;
//console.log('line++:',locator,startPos,endPos)
}
locator.columnNumber = start-startPos+1;
}
var locator = contentHandler.locator;
var linePattern = /.+(?:\r\n?|\n)|.*$/g
var startPos = 0;
var endPos = 0;

var elStack = [{currentNSMap:defaultNSMapCopy}]
var closeMap = {};
var start = 0;
Expand All @@ -61,9 +76,11 @@ function parse(source,defaultNSMapCopy,entityMap,contentHandler,lexHandler,error
break;
// end elment
case '?':// <?...?>
locator&&position(i);
end = parseInstruction(source,i,lexHandler);
break;
case '!':// <!doctype,<![CDATA,<!--
locator&&position(i);
end = parseDCC(source,i,contentHandler,lexHandler);
break;
default:
Expand All @@ -74,6 +91,7 @@ function parse(source,defaultNSMapCopy,entityMap,contentHandler,lexHandler,error
return;
}else{
try{
locator&&position(i);
var end = parseElementAttribute(source,i,entityReplacer,contentHandler,lexHandler,closeMap,elStack);
}catch(e){
end = -1;
Expand Down
2 changes: 1 addition & 1 deletion test/dom/serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ wows.describe('XML Serializer').addBatch({
'text node containing "]]>"': function() {
var doc = new DOMParser().parseFromString('<test/>', 'text/xml');
doc.documentElement.appendChild(doc.createTextNode('hello ]]> there'));
console.assert(doc.documentElement.firstChild.toString() == 'hello ]]&gt; there');
console.assert(doc.documentElement.firstChild.toString() == 'hello ]]> there',doc.documentElement.firstChild.toString());
},
'<script> element with no children': function() {
var doc = new DOMParser().parseFromString('<html><script></script></html>', 'text/html');
Expand Down
6 changes: 5 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,14 @@ DOMParser.prototype.parseFromString = function(data,mimeType){
}
return doc;
}

console.log('test dom:')
require('./dom');
console.log('test parse-element:')
require('./parse-element');
console.log('test node:')
require('./node');
console.log('test namespace:')
require('./namespace');
console.log('test normalize:')
require('./html/normalize');
//require('./big-file-performance');
24 changes: 24 additions & 0 deletions test/locator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
var wows = require('vows');
var DOMParser = require('xmldom').DOMParser;

function assertPosition(n, line, col) {
console.assert(n.lineNumber == line,'lineNumber:'+n.lineNumber+'/'+line);
console.assert(n.columnNumber == col,'columnNumber:'+n.columnNumber+'/'+col);
}

wows.describe('DOMLocator').addBatch({
'node positions': function() {
var parser = new DOMParser(true);
var doc = parser.parseFromString('<?xml version="1.0"?><!-- aaa -->\n<test>\n <a attr="value"><![CDATA[1]]>something\n</a>x</test>', 'text/xml');
var test = doc.documentElement;
var a = test.firstChild.nextSibling;
assertPosition(doc.firstChild, 1, 1);
assertPosition(doc.firstChild.nextSibling, 1, 1+'<?xml version="1.0"?>'.length);
assertPosition(test, 2, 1);
//assertPosition(test.firstChild, 1, 7);
assertPosition(a, 3, 3);
assertPosition(a.firstChild, 3, 19);
assertPosition(a.firstChild.nextSibling, 3, 19+'<![CDATA[1]]>'.length);
assertPosition(test.lastChild, 4, 5);
},
}).run();

0 comments on commit 47fa9b8

Please sign in to comment.