aboutsummaryrefslogtreecommitdiff
path: root/tools/jsdoc-toolkit-2.4.0/app/handlers/XMLDOC/XMLParse.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/jsdoc-toolkit-2.4.0/app/handlers/XMLDOC/XMLParse.js')
-rwxr-xr-xtools/jsdoc-toolkit-2.4.0/app/handlers/XMLDOC/XMLParse.js292
1 files changed, 292 insertions, 0 deletions
diff --git a/tools/jsdoc-toolkit-2.4.0/app/handlers/XMLDOC/XMLParse.js b/tools/jsdoc-toolkit-2.4.0/app/handlers/XMLDOC/XMLParse.js
new file mode 100755
index 0000000..78e8f45
--- /dev/null
+++ b/tools/jsdoc-toolkit-2.4.0/app/handlers/XMLDOC/XMLParse.js
@@ -0,0 +1,292 @@
+LOG.inform("XMLDOC.Parser loaded");
+
+/**
+ * XML Parser object. Returns an {@link #XMLDOC.Parser.node} which is
+ * the root element of the parsed document.
+ * <p/>
+ * By default, this parser will only handle well formed XML. To
+ * allow the parser to handle HTML, set the <tt>XMLDOC.Parser.strictMode</tt>
+ * variable to <tt>false</tt> before calling <tt>XMLDOC.Parser.parse()</tt>.
+ * <p/>
+ * <i>Note: If you pass poorly formed XML, it will cause the parser to throw
+ * an exception.</i>
+ *
+ * @author Brett Fattori (bfattori@fry.com)
+ * @author $Author: micmath $
+ * @version $Revision: 497 $
+ */
+XMLDOC.Parser = {};
+
+/**
+ * Strict mode setting. Setting this to false allows HTML-style source to
+ * be parsed. Normally, well formed XML has defined end tags, or empty tags
+ * are properly formed. Default: <tt>true</tt>
+ * @type Boolean
+ */
+XMLDOC.Parser.strictMode = true;
+
+/**
+ * A node in an XML Document. Node types are ROOT, ELEMENT, COMMENT, PI, and TEXT.
+ * @param parent {XMLDOC.Parser.node} The parent node
+ * @param name {String} The node name
+ * @param type {String} One of the types
+ */
+XMLDOC.Parser.node = function(parent, name, type)
+{
+ this.name = name;
+ this.type = type || "ELEMENT";
+ this.parent = parent;
+ this.charData = "";
+ this.attrs = {};
+ this.nodes = [];
+ this.cPtr = 0;
+
+ XMLDOC.Parser.node.prototype.getAttributeNames = function() {
+ var a = [];
+ for (var o in this.attrs)
+ {
+ a.push(o);
+ }
+
+ return a;
+ };
+
+ XMLDOC.Parser.node.prototype.getAttribute = function(attr) {
+ return this.attrs[attr];
+ };
+
+ XMLDOC.Parser.node.prototype.setAttribute = function(attr, val) {
+ this.attrs[attr] = val;
+ };
+
+ XMLDOC.Parser.node.prototype.getChild = function(idx) {
+ return this.nodes[idx];
+ };
+
+ XMLDOC.Parser.node.prototype.parentNode = function() {
+ return this.parent;
+ };
+
+ XMLDOC.Parser.node.prototype.firstChild = function() {
+ return this.nodes[0];
+ };
+
+ XMLDOC.Parser.node.prototype.lastChild = function() {
+ return this.nodes[this.nodes.length - 1];
+ };
+
+ XMLDOC.Parser.node.prototype.nextSibling = function() {
+ var p = this.parent;
+ if (p && (p.nodes.indexOf(this) + 1 != p.nodes.length))
+ {
+ return p.getChild(p.nodes.indexOf(this) + 1);
+ }
+ return null;
+ };
+
+ XMLDOC.Parser.node.prototype.prevSibling = function() {
+ var p = this.parent;
+ if (p && (p.nodes.indexOf(this) - 1 >= 0))
+ {
+ return p.getChild(p.nodes.indexOf(this) - 1);
+ }
+ return null;
+ };
+};
+
+/**
+ * Parse an XML Document from the specified source. The XML should be
+ * well formed, unless strict mode is disabled, then the parser will
+ * handle HTML-style XML documents.
+ * @param src {String} The source to parse
+ */
+XMLDOC.Parser.parse = function(src)
+{
+ var A = [];
+
+ // Normailize whitespace
+ A = src.split("\r\n");
+ src = A.join("\n");
+ A = src.split("\r");
+ src = A.join("\n");
+
+ // Remove XML and DOCTYPE specifier
+ src.replace(/<\?XML .*\?>/i, "");
+ src.replace(/<!DOCTYPE .*\>/i, "");
+
+ // The document is the root node and cannot be modified or removed
+ var doc = new XMLDOC.Parser.node(null, "ROOT", "DOCUMENT");
+
+ // Let's break it down
+ XMLDOC.Parser.eat(doc, src);
+
+ return doc;
+};
+
+/**
+ * The XML fragment processing routine. This method is private and should not be called
+ * directly.
+ * @param parentNode {XMLDOC.Parser.node} The node which is the parent of this fragment
+ * @param src {String} The source within the fragment to process
+ * @private
+ */
+XMLDOC.Parser.eat = function(parentNode, src)
+{
+ // A simple tag def
+ var reTag = new RegExp("<(!|)(\\?|--|)((.|\\s)*?)\\2>","g");
+
+ // Special tag types
+ var reCommentTag = /<!--((.|\s)*?)-->/;
+ var rePITag = /<\?((.|\s)*?)\?>/;
+
+ // A start tag (with potential empty marker)
+ var reStartTag = /<(.*?)( +([\w_\-]*)=(\"|')(.*)\4)*(\/)?>/;
+
+ // An empty HTML style tag (not proper XML, but we'll accept it so we can process HTML)
+ var reHTMLEmptyTag = /<(.*?)( +([\w_\-]*)=(\"|')(.*)\4)*>/;
+
+ // Fully enclosing tag with nested tags
+ var reEnclosingTag = /<(.*?)( +([\w_\-]*)=(\"|')(.*?)\4)*>((.|\s)*?)<\/\1>/;
+
+ // Breaks down attributes
+ var reAttributes = new RegExp(" +([\\w_\\-]*)=(\"|')(.*?)\\2","g");
+
+ // Find us a tag
+ var tag;
+ while ((tag = reTag.exec(src)) != null)
+ {
+ if (tag.index > 0)
+ {
+ // The next tag has some text before it
+ var text = src.substring(0, tag.index).replace(/^[ \t\n]+((.|\n)*?)[ \t\n]+$/, "$1");
+
+ if (text.length > 0 && (text != "\n"))
+ {
+ var txtnode = new XMLDOC.Parser.node(parentNode, "", "TEXT");
+ txtnode.charData = text;
+
+ // Append the new text node
+ parentNode.nodes.push(txtnode);
+ }
+
+ // Reset the lastIndex of reTag
+ reTag.lastIndex -= src.substring(0, tag.index).length;
+
+ // Eat the text
+ src = src.substring(tag.index);
+ }
+
+ if (reCommentTag.test(tag[0]))
+ {
+ // Is this a comment?
+ var comment = new XMLDOC.Parser.node(parentNode, "", "COMMENT");
+ comment.charData = reCommentTag.exec(tag[0])[1];
+
+ // Append the comment
+ parentNode.nodes.push(comment);
+
+ // Move the lastIndex of reTag
+ reTag.lastIndex -= tag[0].length;
+
+ // Eat the tag
+ src = src.replace(reCommentTag, "");
+ }
+ else if (rePITag.test(tag[0]))
+ {
+ // Is this a processing instruction?
+ var pi = new XMLDOC.Parser.node(parentNode, "", "PI");
+ pi.charData = rePITag.exec(tag[0])[1];
+
+ // Append the processing instruction
+ parentNode.nodes.push(pi);
+
+ // Move the lastIndex of reTag
+ reTag.lastIndex -= tag[0].length;
+
+ // Eat the tag
+ src = src.replace(rePITag, "");
+ }
+ else if (reStartTag.test(tag[0]))
+ {
+ // Break it down
+ var e = reStartTag.exec(tag[0]);
+ var elem = new XMLDOC.Parser.node(parentNode, e[1], "ELEMENT");
+
+ // Get attributes from the tag
+ var a;
+ while ((a = reAttributes.exec(e[2])) != null )
+ {
+ elem.attrs[a[1]] = a[3];
+ }
+
+ // Is this an empty XML-style tag?
+ if (e[6] == "/")
+ {
+ // Append the empty element
+ parentNode.nodes.push(elem);
+
+ // Move the lastIndex of reTag (include the start tag length)
+ reTag.lastIndex -= e[0].length;
+
+ // Eat the tag
+ src = src.replace(reStartTag, "");
+ }
+ else
+ {
+ // Check for malformed XML tags
+ var htmlParsed = false;
+ var htmlStartTag = reHTMLEmptyTag.exec(src);
+
+ // See if there isn't an end tag within this block
+ var reHTMLEndTag = new RegExp("</" + htmlStartTag[1] + ">");
+ var htmlEndTag = reHTMLEndTag.exec(src);
+
+ if (XMLDOC.Parser.strictMode && htmlEndTag == null)
+ {
+ // Poorly formed XML fails in strict mode
+ var err = new Error("Malformed XML passed to XMLDOC.Parser... Error contains malformed 'src'");
+ err.src = src;
+ throw err;
+ }
+ else if (htmlEndTag == null)
+ {
+ // This is an HTML-style empty tag, store the element for it in non-strict mode
+ parentNode.nodes.push(elem);
+
+ // Eat the tag
+ src = src.replace(reHTMLEmptyTag, "");
+ htmlParsed = true;
+ }
+
+ // If we didn't parse HTML-style, it must be an enclosing tag
+ if (!htmlParsed)
+ {
+ var enc = reEnclosingTag.exec(src);
+
+ // Go deeper into the document
+ XMLDOC.Parser.eat(elem, enc[6]);
+
+ // Append the new element node
+ parentNode.nodes.push(elem);
+
+ // Eat the tag
+ src = src.replace(reEnclosingTag, "");
+ }
+ }
+
+ // Reset the lastIndex of reTag
+ reTag.lastIndex = 0;
+ }
+ }
+
+ // No tag was found... append the text if there is any
+ src = src.replace(/^[ \t\n]+((.|\n)*?)[ \t\n]+$/, "$1");
+ if (src.length > 0 && (src != "\n"))
+ {
+ var txtNode = new XMLDOC.Parser.node(parentNode, "", "TEXT");
+ txtNode.charData = src;
+
+ // Append the new text node
+ parentNode.nodes.push(txtNode);
+ }
+};