mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-07-04 19:12:51 +00:00
Add xmldom parser
Integrating this module allows us to do HTML/XML parsing under Node.js (there is no built-in support for Node.js; we can already do HTML/XML parsing in the browser). The implementation chosen is pure JavaScript, and will work in all configurations of TiddlyWiki.
This commit is contained in:
parent
176d2ccd76
commit
68b54a6e6f
8
plugins/tiddlywiki/xmldom/files/LICENSE
Normal file
8
plugins/tiddlywiki/xmldom/files/LICENSE
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
You can choose any one of those:
|
||||||
|
|
||||||
|
The MIT License (MIT):
|
||||||
|
|
||||||
|
link:http://opensource.org/licenses/MIT
|
||||||
|
|
||||||
|
LGPL:
|
||||||
|
http://www.gnu.org/licenses/lgpl.html
|
256
plugins/tiddlywiki/xmldom/files/dom-parser.js
Normal file
256
plugins/tiddlywiki/xmldom/files/dom-parser.js
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
function DOMParser(options){
|
||||||
|
this.options = options ||{locator:{}};
|
||||||
|
|
||||||
|
}
|
||||||
|
DOMParser.prototype.parseFromString = function(source,mimeType){
|
||||||
|
var options = this.options;
|
||||||
|
var sax = new XMLReader();
|
||||||
|
var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
|
||||||
|
var errorHandler = options.errorHandler;
|
||||||
|
var locator = options.locator;
|
||||||
|
var defaultNSMap = options.xmlns||{};
|
||||||
|
var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"}
|
||||||
|
if(locator){
|
||||||
|
domBuilder.setDocumentLocator(locator)
|
||||||
|
}
|
||||||
|
|
||||||
|
sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
|
||||||
|
sax.domBuilder = options.domBuilder || domBuilder;
|
||||||
|
if(/\/x?html?$/.test(mimeType)){
|
||||||
|
entityMap.nbsp = '\xa0';
|
||||||
|
entityMap.copy = '\xa9';
|
||||||
|
defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
|
||||||
|
}
|
||||||
|
defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
|
||||||
|
if(source){
|
||||||
|
sax.parse(source,defaultNSMap,entityMap);
|
||||||
|
}else{
|
||||||
|
sax.errorHandler.error("invalid document source");
|
||||||
|
}
|
||||||
|
return domBuilder.document;
|
||||||
|
}
|
||||||
|
function buildErrorHandler(errorImpl,domBuilder,locator){
|
||||||
|
if(!errorImpl){
|
||||||
|
if(domBuilder instanceof DOMHandler){
|
||||||
|
return domBuilder;
|
||||||
|
}
|
||||||
|
errorImpl = domBuilder ;
|
||||||
|
}
|
||||||
|
var errorHandler = {}
|
||||||
|
var isCallback = errorImpl instanceof Function;
|
||||||
|
locator = locator||{}
|
||||||
|
function build(key){
|
||||||
|
var fn = errorImpl[key];
|
||||||
|
if(!fn){
|
||||||
|
if(isCallback){
|
||||||
|
fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl;
|
||||||
|
}else{
|
||||||
|
var i=arguments.length;
|
||||||
|
while(--i){
|
||||||
|
if(fn = errorImpl[arguments[i]]){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errorHandler[key] = fn && function(msg){
|
||||||
|
fn(msg+_locator(locator));
|
||||||
|
}||function(){};
|
||||||
|
}
|
||||||
|
build('warning','warn');
|
||||||
|
build('error','warn','warning');
|
||||||
|
build('fatalError','warn','warning','error');
|
||||||
|
return errorHandler;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* +ContentHandler+ErrorHandler
|
||||||
|
* +LexicalHandler+EntityResolver2
|
||||||
|
* -DeclHandler-DTDHandler
|
||||||
|
*
|
||||||
|
* DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
|
||||||
|
* DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
|
||||||
|
* @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
|
||||||
|
*/
|
||||||
|
function DOMHandler() {
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
DOMHandler.prototype = {
|
||||||
|
startDocument : function() {
|
||||||
|
this.document = new DOMImplementation().createDocument(null, null, null);
|
||||||
|
if (this.locator) {
|
||||||
|
this.document.documentURI = this.locator.systemId;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
startElement:function(namespaceURI, localName, qName, attrs) {
|
||||||
|
var doc = this.document;
|
||||||
|
var el = doc.createElementNS(namespaceURI, qName||localName);
|
||||||
|
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);
|
||||||
|
var qName = attrs.getQName(i);
|
||||||
|
var attr = doc.createAttributeNS(namespaceURI, qName);
|
||||||
|
if( attr.getOffset){
|
||||||
|
position(attr.getOffset(1),attr)
|
||||||
|
}
|
||||||
|
attr.value = attr.nodeValue = value;
|
||||||
|
el.setAttributeNode(attr)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
endElement:function(namespaceURI, localName, qName) {
|
||||||
|
var current = this.currentElement
|
||||||
|
var tagName = current.tagName;
|
||||||
|
this.currentElement = current.parentNode;
|
||||||
|
},
|
||||||
|
startPrefixMapping:function(prefix, uri) {
|
||||||
|
},
|
||||||
|
endPrefixMapping:function(prefix) {
|
||||||
|
},
|
||||||
|
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) {
|
||||||
|
},
|
||||||
|
characters:function(chars, start, length) {
|
||||||
|
chars = _toString.apply(this,arguments)
|
||||||
|
//console.log(chars)
|
||||||
|
if(this.currentElement && chars){
|
||||||
|
if (this.cdata) {
|
||||||
|
var charNode = this.document.createCDATASection(chars);
|
||||||
|
this.currentElement.appendChild(charNode);
|
||||||
|
} else {
|
||||||
|
var charNode = this.document.createTextNode(chars);
|
||||||
|
this.currentElement.appendChild(charNode);
|
||||||
|
}
|
||||||
|
this.locator && position(this.locator,charNode)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
skippedEntity:function(name) {
|
||||||
|
},
|
||||||
|
endDocument:function() {
|
||||||
|
this.document.normalize();
|
||||||
|
},
|
||||||
|
setDocumentLocator:function (locator) {
|
||||||
|
if(this.locator = locator){// && !('lineNumber' in locator)){
|
||||||
|
locator.lineNumber = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//LexicalHandler
|
||||||
|
comment:function(chars, start, length) {
|
||||||
|
chars = _toString.apply(this,arguments)
|
||||||
|
var comm = this.document.createComment(chars);
|
||||||
|
this.locator && position(this.locator,comm)
|
||||||
|
appendElement(this, comm);
|
||||||
|
},
|
||||||
|
|
||||||
|
startCDATA:function() {
|
||||||
|
//used in characters() methods
|
||||||
|
this.cdata = true;
|
||||||
|
},
|
||||||
|
endCDATA:function() {
|
||||||
|
this.cdata = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
startDTD:function(name, publicId, systemId) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* @see org.xml.sax.ErrorHandler
|
||||||
|
* @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
|
||||||
|
*/
|
||||||
|
warning:function(error) {
|
||||||
|
console.warn(error,_locator(this.locator));
|
||||||
|
},
|
||||||
|
error:function(error) {
|
||||||
|
console.error(error,_locator(this.locator));
|
||||||
|
},
|
||||||
|
fatalError:function(error) {
|
||||||
|
console.error(error,_locator(this.locator));
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function _locator(l){
|
||||||
|
if(l){
|
||||||
|
return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function _toString(chars,start,length){
|
||||||
|
if(typeof chars == 'string'){
|
||||||
|
return chars.substr(start,length)
|
||||||
|
}else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
|
||||||
|
if(chars.length >= start+length || start){
|
||||||
|
return new java.lang.String(chars,start,length)+'';
|
||||||
|
}
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
|
||||||
|
* used method of org.xml.sax.ext.LexicalHandler:
|
||||||
|
* #comment(chars, start, length)
|
||||||
|
* #startCDATA()
|
||||||
|
* #endCDATA()
|
||||||
|
* #startDTD(name, publicId, systemId)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IGNORED method of org.xml.sax.ext.LexicalHandler:
|
||||||
|
* #endDTD()
|
||||||
|
* #startEntity(name)
|
||||||
|
* #endEntity(name)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
|
||||||
|
* IGNORED method of org.xml.sax.ext.DeclHandler
|
||||||
|
* #attributeDecl(eName, aName, type, mode, value)
|
||||||
|
* #elementDecl(name, model)
|
||||||
|
* #externalEntityDecl(name, publicId, systemId)
|
||||||
|
* #internalEntityDecl(name, value)
|
||||||
|
* @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
|
||||||
|
* IGNORED method of org.xml.sax.EntityResolver2
|
||||||
|
* #resolveEntity(String name,String publicId,String baseURI,String systemId)
|
||||||
|
* #resolveEntity(publicId, systemId)
|
||||||
|
* #getExternalSubset(name, baseURI)
|
||||||
|
* @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
|
||||||
|
* IGNORED method of org.xml.sax.DTDHandler
|
||||||
|
* #notationDecl(name, publicId, systemId) {};
|
||||||
|
* #unparsedEntityDecl(name, publicId, systemId, notationName) {};
|
||||||
|
*/
|
||||||
|
"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
|
||||||
|
DOMHandler.prototype[key] = function(){return null}
|
||||||
|
})
|
||||||
|
|
||||||
|
/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */
|
||||||
|
function appendElement (hander,node) {
|
||||||
|
if (!hander.currentElement) {
|
||||||
|
hander.document.appendChild(node);
|
||||||
|
} else {
|
||||||
|
hander.currentElement.appendChild(node);
|
||||||
|
}
|
||||||
|
}//appendChild and setAttributeNS are preformance key
|
||||||
|
|
||||||
|
if(typeof require == 'function'){
|
||||||
|
var XMLReader = require('./sax').XMLReader;
|
||||||
|
var DOMImplementation = exports.DOMImplementation = require('./dom').DOMImplementation;
|
||||||
|
exports.XMLSerializer = require('./dom').XMLSerializer ;
|
||||||
|
exports.DOMParser = DOMParser;
|
||||||
|
}
|
1141
plugins/tiddlywiki/xmldom/files/dom.js
Normal file
1141
plugins/tiddlywiki/xmldom/files/dom.js
Normal file
File diff suppressed because it is too large
Load Diff
219
plugins/tiddlywiki/xmldom/files/readme.md
Normal file
219
plugins/tiddlywiki/xmldom/files/readme.md
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
# XMLDOM [](http://travis-ci.org/bigeasy/xmldom) [](https://coveralls.io/r/bigeasy/xmldom) [](http://badge.fury.io/js/xmldom)
|
||||||
|
|
||||||
|
A JavaScript implementation of W3C DOM for Node.js, Rhino and the browser. Fully
|
||||||
|
compatible with `W3C DOM level2`; and some compatible with `level3`. Supports
|
||||||
|
`DOMParser` and `XMLSerializer` interface such as in browser.
|
||||||
|
|
||||||
|
Install:
|
||||||
|
-------
|
||||||
|
>npm install xmldom
|
||||||
|
|
||||||
|
Example:
|
||||||
|
====
|
||||||
|
```javascript
|
||||||
|
var DOMParser = require('xmldom').DOMParser;
|
||||||
|
var doc = new DOMParser().parseFromString(
|
||||||
|
'<xml xmlns="a" xmlns:c="./lite">\n'+
|
||||||
|
'\t<child>test</child>\n'+
|
||||||
|
'\t<child></child>\n'+
|
||||||
|
'\t<child/>\n'+
|
||||||
|
'</xml>'
|
||||||
|
,'text/xml');
|
||||||
|
doc.documentElement.setAttribute('x','y');
|
||||||
|
doc.documentElement.setAttributeNS('./lite','c:x','y2');
|
||||||
|
var nsAttr = doc.documentElement.getAttributeNS('./lite','x')
|
||||||
|
console.info(nsAttr)
|
||||||
|
console.info(doc)
|
||||||
|
```
|
||||||
|
API Reference
|
||||||
|
=====
|
||||||
|
|
||||||
|
* [DOMParser](https://developer.mozilla.org/en/DOMParser):
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
parseFromString(xmlsource,mimeType)
|
||||||
|
```
|
||||||
|
* **options extension** _by xmldom_(not BOM standard!!)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
//added the options argument
|
||||||
|
new DOMParser(options)
|
||||||
|
|
||||||
|
//errorHandler is supported
|
||||||
|
new DOMParser({
|
||||||
|
/**
|
||||||
|
* locator is always need for error position info
|
||||||
|
*/
|
||||||
|
locator:{},
|
||||||
|
/**
|
||||||
|
* you can override the errorHandler for xml parser
|
||||||
|
* @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
|
||||||
|
*/
|
||||||
|
errorHandler:{warning:function(w){console.warn(w)},error:callback,fatalError:callback}
|
||||||
|
//only callback model
|
||||||
|
//errorHandler:function(level,msg){console.log(level,msg)}
|
||||||
|
})
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
* [XMLSerializer](https://developer.mozilla.org/en/XMLSerializer)
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
serializeToString(node)
|
||||||
|
```
|
||||||
|
DOM level2 method and attribute:
|
||||||
|
------
|
||||||
|
|
||||||
|
* [Node](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247)
|
||||||
|
|
||||||
|
attribute:
|
||||||
|
nodeValue|prefix
|
||||||
|
readonly attribute:
|
||||||
|
nodeName|nodeType|parentNode|childNodes|firstChild|lastChild|previousSibling|nextSibling|attributes|ownerDocument|namespaceURI|localName
|
||||||
|
method:
|
||||||
|
insertBefore(newChild, refChild)
|
||||||
|
replaceChild(newChild, oldChild)
|
||||||
|
removeChild(oldChild)
|
||||||
|
appendChild(newChild)
|
||||||
|
hasChildNodes()
|
||||||
|
cloneNode(deep)
|
||||||
|
normalize()
|
||||||
|
isSupported(feature, version)
|
||||||
|
hasAttributes()
|
||||||
|
|
||||||
|
* [DOMImplementation](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-102161490)
|
||||||
|
|
||||||
|
method:
|
||||||
|
hasFeature(feature, version)
|
||||||
|
createDocumentType(qualifiedName, publicId, systemId)
|
||||||
|
createDocument(namespaceURI, qualifiedName, doctype)
|
||||||
|
|
||||||
|
* [Document](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#i-Document) : Node
|
||||||
|
|
||||||
|
readonly attribute:
|
||||||
|
doctype|implementation|documentElement
|
||||||
|
method:
|
||||||
|
createElement(tagName)
|
||||||
|
createDocumentFragment()
|
||||||
|
createTextNode(data)
|
||||||
|
createComment(data)
|
||||||
|
createCDATASection(data)
|
||||||
|
createProcessingInstruction(target, data)
|
||||||
|
createAttribute(name)
|
||||||
|
createEntityReference(name)
|
||||||
|
getElementsByTagName(tagname)
|
||||||
|
importNode(importedNode, deep)
|
||||||
|
createElementNS(namespaceURI, qualifiedName)
|
||||||
|
createAttributeNS(namespaceURI, qualifiedName)
|
||||||
|
getElementsByTagNameNS(namespaceURI, localName)
|
||||||
|
getElementById(elementId)
|
||||||
|
|
||||||
|
* [DocumentFragment](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-B63ED1A3) : Node
|
||||||
|
* [Element](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-745549614) : Node
|
||||||
|
|
||||||
|
readonly attribute:
|
||||||
|
tagName
|
||||||
|
method:
|
||||||
|
getAttribute(name)
|
||||||
|
setAttribute(name, value)
|
||||||
|
removeAttribute(name)
|
||||||
|
getAttributeNode(name)
|
||||||
|
setAttributeNode(newAttr)
|
||||||
|
removeAttributeNode(oldAttr)
|
||||||
|
getElementsByTagName(name)
|
||||||
|
getAttributeNS(namespaceURI, localName)
|
||||||
|
setAttributeNS(namespaceURI, qualifiedName, value)
|
||||||
|
removeAttributeNS(namespaceURI, localName)
|
||||||
|
getAttributeNodeNS(namespaceURI, localName)
|
||||||
|
setAttributeNodeNS(newAttr)
|
||||||
|
getElementsByTagNameNS(namespaceURI, localName)
|
||||||
|
hasAttribute(name)
|
||||||
|
hasAttributeNS(namespaceURI, localName)
|
||||||
|
|
||||||
|
* [Attr](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-637646024) : Node
|
||||||
|
|
||||||
|
attribute:
|
||||||
|
value
|
||||||
|
readonly attribute:
|
||||||
|
name|specified|ownerElement
|
||||||
|
|
||||||
|
* [NodeList](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177)
|
||||||
|
|
||||||
|
readonly attribute:
|
||||||
|
length
|
||||||
|
method:
|
||||||
|
item(index)
|
||||||
|
|
||||||
|
* [NamedNodeMap](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1780488922)
|
||||||
|
|
||||||
|
readonly attribute:
|
||||||
|
length
|
||||||
|
method:
|
||||||
|
getNamedItem(name)
|
||||||
|
setNamedItem(arg)
|
||||||
|
removeNamedItem(name)
|
||||||
|
item(index)
|
||||||
|
getNamedItemNS(namespaceURI, localName)
|
||||||
|
setNamedItemNS(arg)
|
||||||
|
removeNamedItemNS(namespaceURI, localName)
|
||||||
|
|
||||||
|
* [CharacterData](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-FF21A306) : Node
|
||||||
|
|
||||||
|
method:
|
||||||
|
substringData(offset, count)
|
||||||
|
appendData(arg)
|
||||||
|
insertData(offset, arg)
|
||||||
|
deleteData(offset, count)
|
||||||
|
replaceData(offset, count, arg)
|
||||||
|
|
||||||
|
* [Text](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1312295772) : CharacterData
|
||||||
|
|
||||||
|
method:
|
||||||
|
splitText(offset)
|
||||||
|
|
||||||
|
* [CDATASection](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-667469212)
|
||||||
|
* [Comment](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1728279322) : CharacterData
|
||||||
|
|
||||||
|
* [DocumentType](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-412266927)
|
||||||
|
|
||||||
|
readonly attribute:
|
||||||
|
name|entities|notations|publicId|systemId|internalSubset
|
||||||
|
|
||||||
|
* Notation : Node
|
||||||
|
|
||||||
|
readonly attribute:
|
||||||
|
publicId|systemId
|
||||||
|
|
||||||
|
* Entity : Node
|
||||||
|
|
||||||
|
readonly attribute:
|
||||||
|
publicId|systemId|notationName
|
||||||
|
|
||||||
|
* EntityReference : Node
|
||||||
|
* ProcessingInstruction : Node
|
||||||
|
|
||||||
|
attribute:
|
||||||
|
data
|
||||||
|
readonly attribute:
|
||||||
|
target
|
||||||
|
|
||||||
|
DOM level 3 support:
|
||||||
|
-----
|
||||||
|
|
||||||
|
* [Node](http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-textContent)
|
||||||
|
|
||||||
|
attribute:
|
||||||
|
textContent
|
||||||
|
method:
|
||||||
|
isDefaultNamespace(namespaceURI){
|
||||||
|
lookupNamespaceURI(prefix)
|
||||||
|
|
||||||
|
DOM extension by xmldom
|
||||||
|
---
|
||||||
|
* [Node] Source position extension;
|
||||||
|
|
||||||
|
attribute:
|
||||||
|
//Numbered starting from '1'
|
||||||
|
lineNumber
|
||||||
|
//Numbered starting from '1'
|
||||||
|
columnNumber
|
586
plugins/tiddlywiki/xmldom/files/sax.js
Normal file
586
plugins/tiddlywiki/xmldom/files/sax.js
Normal file
@ -0,0 +1,586 @@
|
|||||||
|
//[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]
|
||||||
|
//[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
|
||||||
|
//[5] Name ::= NameStartChar (NameChar)*
|
||||||
|
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
|
||||||
|
var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\u00B7\u0300-\u036F\\u203F-\u2040]");
|
||||||
|
var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
|
||||||
|
//var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
|
||||||
|
//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(',')
|
||||||
|
|
||||||
|
//S_TAG, S_ATTR, S_EQ, S_V
|
||||||
|
//S_ATTR_S, S_E, S_S, S_C
|
||||||
|
var S_TAG = 0;//tag name offerring
|
||||||
|
var S_ATTR = 1;//attr name offerring
|
||||||
|
var S_ATTR_S=2;//attr name end and space offer
|
||||||
|
var S_EQ = 3;//=space?
|
||||||
|
var S_V = 4;//attr value(no quot value only)
|
||||||
|
var S_E = 5;//attr value end and no space(quot end)
|
||||||
|
var S_S = 6;//(attr value end || tag end ) && (space offer)
|
||||||
|
var S_C = 7;//closed el<el />
|
||||||
|
|
||||||
|
function XMLReader(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLReader.prototype = {
|
||||||
|
parse:function(source,defaultNSMap,entityMap){
|
||||||
|
var domBuilder = this.domBuilder;
|
||||||
|
domBuilder.startDocument();
|
||||||
|
_copy(defaultNSMap ,defaultNSMap = {})
|
||||||
|
parse(source,defaultNSMap,entityMap,
|
||||||
|
domBuilder,this.errorHandler);
|
||||||
|
domBuilder.endDocument();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
|
||||||
|
function fixedFromCharCode(code) {
|
||||||
|
// String.prototype.fromCharCode does not supports
|
||||||
|
// > 2 bytes unicode chars directly
|
||||||
|
if (code > 0xffff) {
|
||||||
|
code -= 0x10000;
|
||||||
|
var surrogate1 = 0xd800 + (code >> 10)
|
||||||
|
, surrogate2 = 0xdc00 + (code & 0x3ff);
|
||||||
|
|
||||||
|
return String.fromCharCode(surrogate1, surrogate2);
|
||||||
|
} else {
|
||||||
|
return String.fromCharCode(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function entityReplacer(a){
|
||||||
|
var k = a.slice(1,-1);
|
||||||
|
if(k in entityMap){
|
||||||
|
return entityMap[k];
|
||||||
|
}else if(k.charAt(0) === '#'){
|
||||||
|
return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
|
||||||
|
}else{
|
||||||
|
errorHandler.error('entity not found:'+a);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function appendText(end){//has some bugs
|
||||||
|
if(end>start){
|
||||||
|
var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
|
||||||
|
locator&&position(start);
|
||||||
|
domBuilder.characters(xt,0,end-start);
|
||||||
|
start = end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function position(p,m){
|
||||||
|
while(p>=lineEnd && (m = linePattern.exec(source))){
|
||||||
|
lineStart = m.index;
|
||||||
|
lineEnd = lineStart + m[0].length;
|
||||||
|
locator.lineNumber++;
|
||||||
|
//console.log('line++:',locator,startPos,endPos)
|
||||||
|
}
|
||||||
|
locator.columnNumber = p-lineStart+1;
|
||||||
|
}
|
||||||
|
var lineStart = 0;
|
||||||
|
var lineEnd = 0;
|
||||||
|
var linePattern = /.+(?:\r\n?|\n)|.*$/g
|
||||||
|
var locator = domBuilder.locator;
|
||||||
|
|
||||||
|
var parseStack = [{currentNSMap:defaultNSMapCopy}]
|
||||||
|
var closeMap = {};
|
||||||
|
var start = 0;
|
||||||
|
while(true){
|
||||||
|
try{
|
||||||
|
var tagStart = source.indexOf('<',start);
|
||||||
|
if(tagStart<0){
|
||||||
|
if(!source.substr(start).match(/^\s*$/)){
|
||||||
|
var doc = domBuilder.document;
|
||||||
|
var text = doc.createTextNode(source.substr(start));
|
||||||
|
doc.appendChild(text);
|
||||||
|
domBuilder.currentElement = text;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(tagStart>start){
|
||||||
|
appendText(tagStart);
|
||||||
|
}
|
||||||
|
switch(source.charAt(tagStart+1)){
|
||||||
|
case '/':
|
||||||
|
var end = source.indexOf('>',tagStart+3);
|
||||||
|
var tagName = source.substring(tagStart+2,end);
|
||||||
|
var config = parseStack.pop();
|
||||||
|
var localNSMap = config.localNSMap;
|
||||||
|
if(config.tagName != tagName){
|
||||||
|
errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName );
|
||||||
|
}
|
||||||
|
domBuilder.endElement(config.uri,config.localName,tagName);
|
||||||
|
if(localNSMap){
|
||||||
|
for(var prefix in localNSMap){
|
||||||
|
domBuilder.endPrefixMapping(prefix) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end++;
|
||||||
|
break;
|
||||||
|
// end elment
|
||||||
|
case '?':// <?...?>
|
||||||
|
locator&&position(tagStart);
|
||||||
|
end = parseInstruction(source,tagStart,domBuilder);
|
||||||
|
break;
|
||||||
|
case '!':// <!doctype,<![CDATA,<!--
|
||||||
|
locator&&position(tagStart);
|
||||||
|
end = parseDCC(source,tagStart,domBuilder,errorHandler);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
locator&&position(tagStart);
|
||||||
|
|
||||||
|
var el = new ElementAttributes();
|
||||||
|
|
||||||
|
//elStartEnd
|
||||||
|
var end = parseElementStartPart(source,tagStart,el,entityReplacer,errorHandler);
|
||||||
|
var len = el.length;
|
||||||
|
|
||||||
|
if(locator){
|
||||||
|
if(len){
|
||||||
|
//attribute position fixed
|
||||||
|
for(var i = 0;i<len;i++){
|
||||||
|
var a = el[i];
|
||||||
|
position(a.offset);
|
||||||
|
a.offset = copyLocator(locator,{});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
position(end);
|
||||||
|
}
|
||||||
|
if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
|
||||||
|
el.closed = true;
|
||||||
|
if(!entityMap.nbsp){
|
||||||
|
errorHandler.warning('unclosed xml attribute');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appendElement(el,domBuilder,parseStack);
|
||||||
|
|
||||||
|
|
||||||
|
if(el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed){
|
||||||
|
end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder)
|
||||||
|
}else{
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
errorHandler.error('element parse error: '+e);
|
||||||
|
end = -1;
|
||||||
|
}
|
||||||
|
if(end>start){
|
||||||
|
start = end;
|
||||||
|
}else{
|
||||||
|
//TODO: 这里有可能sax回退,有位置错误风险
|
||||||
|
appendText(Math.max(tagStart,start)+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function copyLocator(f,t){
|
||||||
|
t.lineNumber = f.lineNumber;
|
||||||
|
t.columnNumber = f.columnNumber;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
|
||||||
|
* @return end of the elementStartPart(end of elementEndPart for selfClosed el)
|
||||||
|
*/
|
||||||
|
function parseElementStartPart(source,start,el,entityReplacer,errorHandler){
|
||||||
|
var attrName;
|
||||||
|
var value;
|
||||||
|
var p = ++start;
|
||||||
|
var s = S_TAG;//status
|
||||||
|
while(true){
|
||||||
|
var c = source.charAt(p);
|
||||||
|
switch(c){
|
||||||
|
case '=':
|
||||||
|
if(s === S_ATTR){//attrName
|
||||||
|
attrName = source.slice(start,p);
|
||||||
|
s = S_EQ;
|
||||||
|
}else if(s === S_ATTR_S){
|
||||||
|
s = S_EQ;
|
||||||
|
}else{
|
||||||
|
//fatalError: equal must after attrName or space after attrName
|
||||||
|
throw new Error('attribute equal must after attrName');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
case '"':
|
||||||
|
if(s === S_EQ){//equal
|
||||||
|
start = p+1;
|
||||||
|
p = source.indexOf(c,start)
|
||||||
|
if(p>0){
|
||||||
|
value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
|
||||||
|
el.add(attrName,value,start-1);
|
||||||
|
s = S_E;
|
||||||
|
}else{
|
||||||
|
//fatalError: no end quot match
|
||||||
|
throw new Error('attribute value no end \''+c+'\' match');
|
||||||
|
}
|
||||||
|
}else if(s == S_V){
|
||||||
|
value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
|
||||||
|
//console.log(attrName,value,start,p)
|
||||||
|
el.add(attrName,value,start);
|
||||||
|
//console.dir(el)
|
||||||
|
errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
|
||||||
|
start = p+1;
|
||||||
|
s = S_E
|
||||||
|
}else{
|
||||||
|
//fatalError: no equal before
|
||||||
|
throw new Error('attribute value must after "="');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
switch(s){
|
||||||
|
case S_TAG:
|
||||||
|
el.setTagName(source.slice(start,p));
|
||||||
|
case S_E:
|
||||||
|
case S_S:
|
||||||
|
case S_C:
|
||||||
|
s = S_C;
|
||||||
|
el.closed = true;
|
||||||
|
case S_V:
|
||||||
|
case S_ATTR:
|
||||||
|
case S_ATTR_S:
|
||||||
|
break;
|
||||||
|
//case S_EQ:
|
||||||
|
default:
|
||||||
|
throw new Error("attribute invalid close char('/')")
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ''://end document
|
||||||
|
//throw new Error('unexpected end of input')
|
||||||
|
errorHandler.error('unexpected end of input');
|
||||||
|
case '>':
|
||||||
|
switch(s){
|
||||||
|
case S_TAG:
|
||||||
|
el.setTagName(source.slice(start,p));
|
||||||
|
case S_E:
|
||||||
|
case S_S:
|
||||||
|
case S_C:
|
||||||
|
break;//normal
|
||||||
|
case S_V://Compatible state
|
||||||
|
case S_ATTR:
|
||||||
|
value = source.slice(start,p);
|
||||||
|
if(value.slice(-1) === '/'){
|
||||||
|
el.closed = true;
|
||||||
|
value = value.slice(0,-1)
|
||||||
|
}
|
||||||
|
case S_ATTR_S:
|
||||||
|
if(s === S_ATTR_S){
|
||||||
|
value = attrName;
|
||||||
|
}
|
||||||
|
if(s == S_V){
|
||||||
|
errorHandler.warning('attribute "'+value+'" missed quot(")!!');
|
||||||
|
el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start)
|
||||||
|
}else{
|
||||||
|
errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!')
|
||||||
|
el.add(value,value,start)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case S_EQ:
|
||||||
|
throw new Error('attribute value missed!!');
|
||||||
|
}
|
||||||
|
// console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
|
||||||
|
return p;
|
||||||
|
/*xml space '\x20' | #x9 | #xD | #xA; */
|
||||||
|
case '\u0080':
|
||||||
|
c = ' ';
|
||||||
|
default:
|
||||||
|
if(c<= ' '){//space
|
||||||
|
switch(s){
|
||||||
|
case S_TAG:
|
||||||
|
el.setTagName(source.slice(start,p));//tagName
|
||||||
|
s = S_S;
|
||||||
|
break;
|
||||||
|
case S_ATTR:
|
||||||
|
attrName = source.slice(start,p)
|
||||||
|
s = S_ATTR_S;
|
||||||
|
break;
|
||||||
|
case S_V:
|
||||||
|
var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
|
||||||
|
errorHandler.warning('attribute "'+value+'" missed quot(")!!');
|
||||||
|
el.add(attrName,value,start)
|
||||||
|
case S_E:
|
||||||
|
s = S_S;
|
||||||
|
break;
|
||||||
|
//case S_S:
|
||||||
|
//case S_EQ:
|
||||||
|
//case S_ATTR_S:
|
||||||
|
// void();break;
|
||||||
|
//case S_C:
|
||||||
|
//ignore warning
|
||||||
|
}
|
||||||
|
}else{//not space
|
||||||
|
//S_TAG, S_ATTR, S_EQ, S_V
|
||||||
|
//S_ATTR_S, S_E, S_S, S_C
|
||||||
|
switch(s){
|
||||||
|
//case S_TAG:void();break;
|
||||||
|
//case S_ATTR:void();break;
|
||||||
|
//case S_V:void();break;
|
||||||
|
case S_ATTR_S:
|
||||||
|
errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead!!')
|
||||||
|
el.add(attrName,attrName,start);
|
||||||
|
start = p;
|
||||||
|
s = S_ATTR;
|
||||||
|
break;
|
||||||
|
case S_E:
|
||||||
|
errorHandler.warning('attribute space is required"'+attrName+'"!!')
|
||||||
|
case S_S:
|
||||||
|
s = S_ATTR;
|
||||||
|
start = p;
|
||||||
|
break;
|
||||||
|
case S_EQ:
|
||||||
|
s = S_V;
|
||||||
|
start = p;
|
||||||
|
break;
|
||||||
|
case S_C:
|
||||||
|
throw new Error("elements closed character '/' and '>' must be connected to");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return end of the elementStartPart(end of elementEndPart for selfClosed el)
|
||||||
|
*/
|
||||||
|
function appendElement(el,domBuilder,parseStack){
|
||||||
|
var tagName = el.tagName;
|
||||||
|
var localNSMap = null;
|
||||||
|
var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
|
||||||
|
var i = el.length;
|
||||||
|
while(i--){
|
||||||
|
var a = el[i];
|
||||||
|
var qName = a.qName;
|
||||||
|
var value = a.value;
|
||||||
|
var nsp = qName.indexOf(':');
|
||||||
|
if(nsp>0){
|
||||||
|
var prefix = a.prefix = qName.slice(0,nsp);
|
||||||
|
var localName = qName.slice(nsp+1);
|
||||||
|
var nsPrefix = prefix === 'xmlns' && localName
|
||||||
|
}else{
|
||||||
|
localName = qName;
|
||||||
|
prefix = null
|
||||||
|
nsPrefix = qName === 'xmlns' && ''
|
||||||
|
}
|
||||||
|
//can not set prefix,because prefix !== ''
|
||||||
|
a.localName = localName ;
|
||||||
|
//prefix == null for no ns prefix attribute
|
||||||
|
if(nsPrefix !== false){//hack!!
|
||||||
|
if(localNSMap == null){
|
||||||
|
localNSMap = {}
|
||||||
|
//console.log(currentNSMap,0)
|
||||||
|
_copy(currentNSMap,currentNSMap={})
|
||||||
|
//console.log(currentNSMap,1)
|
||||||
|
}
|
||||||
|
currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
|
||||||
|
a.uri = 'http://www.w3.org/2000/xmlns/'
|
||||||
|
domBuilder.startPrefixMapping(nsPrefix, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var i = el.length;
|
||||||
|
while(i--){
|
||||||
|
a = el[i];
|
||||||
|
var prefix = a.prefix;
|
||||||
|
if(prefix){//no prefix attribute has no namespace
|
||||||
|
if(prefix === 'xml'){
|
||||||
|
a.uri = 'http://www.w3.org/XML/1998/namespace';
|
||||||
|
}if(prefix !== 'xmlns'){
|
||||||
|
a.uri = currentNSMap[prefix]
|
||||||
|
|
||||||
|
//{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var nsp = tagName.indexOf(':');
|
||||||
|
if(nsp>0){
|
||||||
|
prefix = el.prefix = tagName.slice(0,nsp);
|
||||||
|
localName = el.localName = tagName.slice(nsp+1);
|
||||||
|
}else{
|
||||||
|
prefix = null;//important!!
|
||||||
|
localName = el.localName = tagName;
|
||||||
|
}
|
||||||
|
//no prefix element has default namespace
|
||||||
|
var ns = el.uri = currentNSMap[prefix || ''];
|
||||||
|
domBuilder.startElement(ns,localName,tagName,el);
|
||||||
|
//endPrefixMapping and startPrefixMapping have not any help for dom builder
|
||||||
|
//localNSMap = null
|
||||||
|
if(el.closed){
|
||||||
|
domBuilder.endElement(ns,localName,tagName);
|
||||||
|
if(localNSMap){
|
||||||
|
for(prefix in localNSMap){
|
||||||
|
domBuilder.endPrefixMapping(prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
el.currentNSMap = currentNSMap;
|
||||||
|
el.localNSMap = localNSMap;
|
||||||
|
parseStack.push(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
|
||||||
|
if(/^(?:script|textarea)$/i.test(tagName)){
|
||||||
|
var elEndStart = source.indexOf('</'+tagName+'>',elStartEnd);
|
||||||
|
var text = source.substring(elStartEnd+1,elEndStart);
|
||||||
|
if(/[&<]/.test(text)){
|
||||||
|
if(/^script$/i.test(tagName)){
|
||||||
|
//if(!/\]\]>/.test(text)){
|
||||||
|
//lexHandler.startCDATA();
|
||||||
|
domBuilder.characters(text,0,text.length);
|
||||||
|
//lexHandler.endCDATA();
|
||||||
|
return elEndStart;
|
||||||
|
//}
|
||||||
|
}//}else{//text area
|
||||||
|
text = text.replace(/&#?\w+;/g,entityReplacer);
|
||||||
|
domBuilder.characters(text,0,text.length);
|
||||||
|
return elEndStart;
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return elStartEnd+1;
|
||||||
|
}
|
||||||
|
function fixSelfClosed(source,elStartEnd,tagName,closeMap){
|
||||||
|
//if(tagName in closeMap){
|
||||||
|
var pos = closeMap[tagName];
|
||||||
|
if(pos == null){
|
||||||
|
//console.log(tagName)
|
||||||
|
pos = closeMap[tagName] = source.lastIndexOf('</'+tagName+'>')
|
||||||
|
}
|
||||||
|
return pos<elStartEnd;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
function _copy(source,target){
|
||||||
|
for(var n in source){target[n] = source[n]}
|
||||||
|
}
|
||||||
|
function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
|
||||||
|
var next= source.charAt(start+2)
|
||||||
|
switch(next){
|
||||||
|
case '-':
|
||||||
|
if(source.charAt(start + 3) === '-'){
|
||||||
|
var end = source.indexOf('-->',start+4);
|
||||||
|
//append comment source.substring(4,end)//<!--
|
||||||
|
if(end>start){
|
||||||
|
domBuilder.comment(source,start+4,end-start-4);
|
||||||
|
return end+3;
|
||||||
|
}else{
|
||||||
|
errorHandler.error("Unclosed comment");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if(source.substr(start+3,6) == 'CDATA['){
|
||||||
|
var end = source.indexOf(']]>',start+9);
|
||||||
|
domBuilder.startCDATA();
|
||||||
|
domBuilder.characters(source,start+9,end-start-9);
|
||||||
|
domBuilder.endCDATA()
|
||||||
|
return end+3;
|
||||||
|
}
|
||||||
|
//<!DOCTYPE
|
||||||
|
//startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
|
||||||
|
var matchs = split(source,start);
|
||||||
|
var len = matchs.length;
|
||||||
|
if(len>1 && /!doctype/i.test(matchs[0][0])){
|
||||||
|
var name = matchs[1][0];
|
||||||
|
var pubid = len>3 && /^public$/i.test(matchs[2][0]) && matchs[3][0]
|
||||||
|
var sysid = len>4 && matchs[4][0];
|
||||||
|
var lastMatch = matchs[len-1]
|
||||||
|
domBuilder.startDTD(name,pubid && pubid.replace(/^(['"])(.*?)\1$/,'$2'),
|
||||||
|
sysid && sysid.replace(/^(['"])(.*?)\1$/,'$2'));
|
||||||
|
domBuilder.endDTD();
|
||||||
|
|
||||||
|
return lastMatch.index+lastMatch[0].length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function parseInstruction(source,start,domBuilder){
|
||||||
|
var end = source.indexOf('?>',start);
|
||||||
|
if(end){
|
||||||
|
var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
|
||||||
|
if(match){
|
||||||
|
var len = match[0].length;
|
||||||
|
domBuilder.processingInstruction(match[1], match[2]) ;
|
||||||
|
return end+2;
|
||||||
|
}else{//error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param source
|
||||||
|
*/
|
||||||
|
function ElementAttributes(source){
|
||||||
|
|
||||||
|
}
|
||||||
|
ElementAttributes.prototype = {
|
||||||
|
setTagName:function(tagName){
|
||||||
|
if(!tagNamePattern.test(tagName)){
|
||||||
|
throw new Error('invalid tagName:'+tagName)
|
||||||
|
}
|
||||||
|
this.tagName = tagName
|
||||||
|
},
|
||||||
|
add:function(qName,value,offset){
|
||||||
|
if(!tagNamePattern.test(qName)){
|
||||||
|
throw new Error('invalid attribute:'+qName)
|
||||||
|
}
|
||||||
|
this[this.length++] = {qName:qName,value:value,offset:offset}
|
||||||
|
},
|
||||||
|
length:0,
|
||||||
|
getLocalName:function(i){return this[i].localName},
|
||||||
|
getOffset:function(i){return this[i].offset},
|
||||||
|
getQName:function(i){return this[i].qName},
|
||||||
|
getURI:function(i){return this[i].uri},
|
||||||
|
getValue:function(i){return this[i].value}
|
||||||
|
// ,getIndex:function(uri, localName)){
|
||||||
|
// if(localName){
|
||||||
|
//
|
||||||
|
// }else{
|
||||||
|
// var qName = uri
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
|
||||||
|
// getType:function(uri,localName){}
|
||||||
|
// getType:function(i){},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function _set_proto_(thiz,parent){
|
||||||
|
thiz.__proto__ = parent;
|
||||||
|
return thiz;
|
||||||
|
}
|
||||||
|
if(!(_set_proto_({},_set_proto_.prototype) instanceof _set_proto_)){
|
||||||
|
_set_proto_ = function(thiz,parent){
|
||||||
|
function p(){};
|
||||||
|
p.prototype = parent;
|
||||||
|
p = new p();
|
||||||
|
for(parent in thiz){
|
||||||
|
p[parent] = thiz[parent];
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function split(source,start){
|
||||||
|
var match;
|
||||||
|
var buf = [];
|
||||||
|
var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
|
||||||
|
reg.lastIndex = start;
|
||||||
|
reg.exec(source);//skip <
|
||||||
|
while(match = reg.exec(source)){
|
||||||
|
buf.push(match);
|
||||||
|
if(match[1])return buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(typeof require == 'function'){
|
||||||
|
exports.XMLReader = XMLReader;
|
||||||
|
}
|
||||||
|
|
38
plugins/tiddlywiki/xmldom/files/tiddlywiki.files
Normal file
38
plugins/tiddlywiki/xmldom/files/tiddlywiki.files
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"tiddlers": [
|
||||||
|
{
|
||||||
|
"file": "dom.js",
|
||||||
|
"fields": {
|
||||||
|
"type": "application/javascript",
|
||||||
|
"title": "$:/plugins/tiddlywiki/xmldom/dom",
|
||||||
|
"module-type": "library"
|
||||||
|
},
|
||||||
|
"prefix": "",
|
||||||
|
"suffix": ""
|
||||||
|
},{
|
||||||
|
"file": "dom-parser.js",
|
||||||
|
"fields": {
|
||||||
|
"type": "application/javascript",
|
||||||
|
"title": "$:/plugins/tiddlywiki/xmldom/dom-parser",
|
||||||
|
"module-type": "library"
|
||||||
|
},
|
||||||
|
"prefix": "",
|
||||||
|
"suffix": ""
|
||||||
|
},{
|
||||||
|
"file": "sax.js",
|
||||||
|
"fields": {
|
||||||
|
"type": "application/javascript",
|
||||||
|
"title": "$:/plugins/tiddlywiki/xmldom/sax",
|
||||||
|
"module-type": "library"
|
||||||
|
},
|
||||||
|
"prefix": "",
|
||||||
|
"suffix": ""
|
||||||
|
},{
|
||||||
|
"file": "LICENSE",
|
||||||
|
"fields": {
|
||||||
|
"type": "text/plain",
|
||||||
|
"title": "$:/plugins/tiddlywiki/xmldom/license"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
7
plugins/tiddlywiki/xmldom/plugin.info
Normal file
7
plugins/tiddlywiki/xmldom/plugin.info
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"title": "$:/plugins/tiddlywiki/xmldom",
|
||||||
|
"description": "Wrapper for xmldom",
|
||||||
|
"author": "JeremyRuston",
|
||||||
|
"core-version": ">=5.0.0",
|
||||||
|
"list": "readme license"
|
||||||
|
}
|
3
plugins/tiddlywiki/xmldom/readme.tid
Normal file
3
plugins/tiddlywiki/xmldom/readme.tid
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
title: $:/plugins/tiddlywiki/xmldom/readme
|
||||||
|
|
||||||
|
This plugin packages [[xmldom|https://github.com/jindw/xmldom]] for use by other plugins. It does not provide any end-user visible features.
|
Loading…
x
Reference in New Issue
Block a user