mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
165 lines
6.7 KiB
JavaScript
165 lines
6.7 KiB
JavaScript
/*
|
|
* Copyright 2011 eBay Software Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
define.Class(
|
|
'raptor/templating/compiler/ParseTreeBuilder',
|
|
['raptor'],
|
|
function(raptor, require, exports, module) {
|
|
"use strict";
|
|
|
|
var logger = module.logger(),
|
|
sax = require('raptor/xml/sax'),
|
|
forEach = raptor.forEach,
|
|
TextNode = require('raptor/templating/compiler/TextNode'),
|
|
ElementNode = require('raptor/templating/compiler/ElementNode');
|
|
|
|
|
|
var ParseTreeBuilder = function() {
|
|
};
|
|
|
|
ParseTreeBuilder.parse = function(src, filePath, taglibs) {
|
|
var builder = new ParseTreeBuilder();
|
|
return builder.parse(src, filePath, taglibs);
|
|
};
|
|
|
|
ParseTreeBuilder.prototype = {
|
|
/**
|
|
* @param src {String} The XML source code to parse
|
|
* @param src {String} The file path (for debugging and error reporting purposes)
|
|
* @param taglibs {raptor/templating/compiler/TaglibCollection} The taglib collection. Required for resolving taglib URIs when short names are used.
|
|
*/
|
|
parse: function(src, filePath, taglibs) {
|
|
var logger = logger,
|
|
parentNode = null,
|
|
rootNode = null,
|
|
prevTextNode = null,
|
|
imports,
|
|
parser = sax.createParser({
|
|
trim: false,
|
|
normalize: false,
|
|
dom: src.documentElement != null
|
|
}),
|
|
characters = function(t, isCDATA) {
|
|
if (!parentNode) {
|
|
return; //Some bad XML parsers allow text after the ending element...
|
|
}
|
|
if (prevTextNode) {
|
|
prevTextNode.text += t;
|
|
}
|
|
else {
|
|
prevTextNode = new TextNode(t);
|
|
prevTextNode.pos = parser.getPos();
|
|
parentNode.appendChild(prevTextNode);
|
|
}
|
|
};
|
|
|
|
parser.on({
|
|
error: function(e) {
|
|
throw raptor.createError(e);
|
|
},
|
|
|
|
characters: function(t) {
|
|
characters(t, false);
|
|
},
|
|
|
|
cdata: function(t) {
|
|
characters(t, true);
|
|
},
|
|
|
|
startElement: function(el) {
|
|
prevTextNode = null;
|
|
var importsAttr,
|
|
importedAttr,
|
|
importedTag;
|
|
|
|
var elementNode = new ElementNode(
|
|
el.getLocalName(),
|
|
taglibs.resolveURI(el.getNamespaceURI()),
|
|
el.getPrefix());
|
|
|
|
|
|
elementNode.addNamespaceMappings(el.getNamespaceMappings());
|
|
|
|
elementNode.pos = parser.getPos();
|
|
|
|
forEach(el.getAttributes(), function(attr) {
|
|
if (attr.getLocalName() === 'imports' && !attr.getNamespaceURI()) {
|
|
importsAttr = attr.getValue();
|
|
}
|
|
}, this);
|
|
|
|
|
|
|
|
if (parentNode) {
|
|
|
|
parentNode.appendChild(elementNode);
|
|
}
|
|
else {
|
|
rootNode = elementNode;
|
|
if (importsAttr) {
|
|
imports = taglibs.getImports(importsAttr);
|
|
}
|
|
}
|
|
|
|
forEach(el.getAttributes(), function(attr) {
|
|
var attrURI = taglibs.resolveURI(attr.getNamespaceURI()),
|
|
attrLocalName = attr.getLocalName(),
|
|
attrPrefix = attr.getPrefix();
|
|
|
|
|
|
if (!attrURI && imports && (importedAttr = imports.getImportedAttribute(attrLocalName))) {
|
|
attrURI = importedAttr.uri;
|
|
attrLocalName = importedAttr.name;
|
|
attrPrefix = importedAttr.prefix;
|
|
}
|
|
|
|
elementNode.setAttributeNS(
|
|
attrURI,
|
|
attrLocalName,
|
|
attr.getValue(),
|
|
attrPrefix);
|
|
}, this);
|
|
|
|
if (!elementNode.uri && imports && (importedTag = imports.getImportedTag(elementNode.localName))) {
|
|
elementNode.uri = importedTag.uri;
|
|
elementNode.localName = importedTag.name;
|
|
elementNode.prefix = importedTag.prefix;
|
|
}
|
|
|
|
parentNode = elementNode;
|
|
},
|
|
|
|
endElement: function () {
|
|
prevTextNode = null;
|
|
|
|
parentNode = parentNode.parentNode;
|
|
}
|
|
}, this);
|
|
|
|
parser.parse(src, filePath);
|
|
|
|
rootNode.setRoot(true);
|
|
|
|
return rootNode;
|
|
},
|
|
|
|
getRootNode: function() {
|
|
return this.rootNode;
|
|
}
|
|
};
|
|
|
|
return ParseTreeBuilder;
|
|
}); |