This commit is contained in:
jhx
2023-03-22 11:41:09 +08:00
parent d0dfc12286
commit f5efe88e4d
641 changed files with 505987 additions and 2 deletions
+391
View File
@@ -0,0 +1,391 @@
window.SINGLE_TAB = " ";
window.ImgCollapsed = "/static/images/collapsed.gif";
window.ImgExpanded = "/static/images/expanded.gif";
window.QuoteKeys = true;
function $id(id) { return document.getElementById(id); }
function IsArray(obj) {
return obj &&
typeof obj === 'object' &&
typeof obj.length === 'number' &&
!(obj.propertyIsEnumerable('length'));
}
function Process() {
SetTab();
window.IsCollapsible = $id("CollapsibleView").checked;
var json = $id("content").value;
var html = "";
try {
$("#codeall").css("display", "none");
$("#codeall2").css("display", "none");
if (json == "") json = "\"\"";
var obj = eval("[" + json + "]");
html = ProcessObject(obj[0], 0, false, false, false);
$id("Canvas").innerHTML = "<PRE class='CodeContainer'>" + html + "</PRE>";
} catch (e) {
$("#codeall").css("display", "block");
$("#codeall2").css("display", "block");
document.getElementById('errdiv').innerHTML = "输入的JSON数据格式不正确:" + e.message;
$id("Canvas").innerHTML = "";
}
}
window._dateObj = new Date();
window._regexpObj = new RegExp();
function ProcessObject(obj, indent, addComma, isArray, isPropertyContent) {
var html = "";
var comma = (addComma) ? "<span class='Comma'>,</span> " : "";
var type = typeof obj;
var clpsHtml = "";
if (IsArray(obj)) {
if (obj.length == 0) {
html += GetRow(indent, "<span class='ArrayBrace'>[ ]</span>" + comma, isPropertyContent);
} else {
clpsHtml = window.IsCollapsible ? "<span><img src=\"" + window.ImgExpanded + "\" onClick=\"ExpImgClicked(this)\" /></span><span class='collapsible'>" : "";
html += GetRow(indent, "<span class='ArrayBrace'>[</span>" + clpsHtml, isPropertyContent);
for (var i = 0; i < obj.length; i++) {
html += ProcessObject(obj[i], indent + 1, i < (obj.length - 1), true, false);
}
clpsHtml = window.IsCollapsible ? "</span>" : "";
html += GetRow(indent, clpsHtml + "<span class='ArrayBrace'>]</span>" + comma);
}
} else if (type == 'object') {
if (obj == null) {
html += FormatLiteral("null", "", comma, indent, isArray, "Null");
} else if (obj.constructor == window._dateObj.constructor) {
html += FormatLiteral("new Date(" + obj.getTime() + ") /*" + obj.toLocaleString() + "*/", "", comma, indent, isArray, "Date");
} else if (obj.constructor == window._regexpObj.constructor) {
html += FormatLiteral("new RegExp(" + obj + ")", "", comma, indent, isArray, "RegExp");
} else {
var numProps = 0;
for (var prop in obj) numProps++;
if (numProps == 0) {
html += GetRow(indent, "<span class='ObjectBrace'>{ }</span>" + comma, isPropertyContent);
} else {
clpsHtml = window.IsCollapsible ? "<span><img src=\"" + window.ImgExpanded + "\" onClick=\"ExpImgClicked(this)\" /></span><span class='collapsible'>" : "";
html += GetRow(indent, "<span class='ObjectBrace'>{</span>" + clpsHtml, isPropertyContent);
var j = 0;
for (var prop in obj) {
var quote = window.QuoteKeys ? "\"" : "";
html += GetRow(indent + 1, "<span class='PropertyName'>" + quote + prop + quote + "</span>: " + ProcessObject(obj[prop], indent + 1, ++j < numProps, false, true));
}
clpsHtml = window.IsCollapsible ? "</span>" : "";
html += GetRow(indent, clpsHtml + "<span class='ObjectBrace'>}</span>" + comma);
}
}
} else if (type == 'number') {
html += FormatLiteral(obj, "", comma, indent, isArray, "Number");
} else if (type == 'boolean') {
html += FormatLiteral(obj, "", comma, indent, isArray, "Boolean");
} else if (type == 'function') {
if (obj.constructor == window._regexpObj.constructor) {
html += FormatLiteral("new RegExp(" + obj + ")", "", comma, indent, isArray, "RegExp");
} else {
obj = FormatFunction(indent, obj);
html += FormatLiteral(obj, "", comma, indent, isArray, "Function");
}
} else if (type == 'undefined') {
html += FormatLiteral("undefined", "", comma, indent, isArray, "Null");
} else {
html += FormatLiteral(obj.toString().split("\\").join("\\\\").split('"').join('\\"'), "\"", comma, indent, isArray, "String");
}
return html;
}
function FormatLiteral(literal, quote, comma, indent, isArray, style) {
if (typeof literal == 'string')
literal = literal.split("<").join("&lt;").split(">").join("&gt;");
var str = "<span class='" + style + "'>" + quote + literal + quote + comma + "</span>";
if (isArray) str = GetRow(indent, str);
return str;
}
function FormatFunction(indent, obj) {
var tabs = "";
for (var i = 0; i < indent; i++) tabs += window.TAB;
var funcStrArray = obj.toString().split("\n");
var str = "";
for (var i = 0; i < funcStrArray.length; i++) {
str += ((i == 0) ? "" : tabs) + funcStrArray[i] + "\n";
}
return str;
}
function GetRow(indent, data, isPropertyContent) {
var tabs = "";
for (var i = 0; i < indent && !isPropertyContent; i++) tabs += window.TAB;
if (data != null && data.length > 0 && data.charAt(data.length - 1) != "\n")
data = data + "\n";
return tabs + data;
}
function CollapsibleViewClicked() {
$id("CollapsibleViewDetail").style.visibility = $id("CollapsibleView").checked ? "visible" : "hidden";
Process();
}
function QuoteKeysClicked() {
window.QuoteKeys = $id("QuoteKeys").checked;
Process();
}
function CollapseAllClicked() {
EnsureIsPopulated();
TraverseChildren($id("Canvas"), function (element) {
if (element.className == 'collapsible') {
MakeContentVisible(element, false);
}
}, 0);
}
function ExpandAllClicked() {
EnsureIsPopulated();
TraverseChildren($id("Canvas"), function (element) {
if (element.className == 'collapsible') {
MakeContentVisible(element, true);
}
}, 0);
}
function MakeContentVisible(element, visible) {
var img = element.previousSibling.firstChild;
if (!!img.tagName && img.tagName.toLowerCase() == "img") {
element.style.display = visible ? 'inline' : 'none';
element.previousSibling.firstChild.src = visible ? window.ImgExpanded : window.ImgCollapsed;
}
}
function TraverseChildren(element, func, depth) {
for (var i = 0; i < element.childNodes.length; i++) {
TraverseChildren(element.childNodes[i], func, depth + 1);
}
func(element, depth);
}
function ExpImgClicked(img) {
var container = img.parentNode.nextSibling;
if (!container) return;
var disp = "none";
var src = window.ImgCollapsed;
if (container.style.display == "none") {
disp = "inline";
src = window.ImgExpanded;
}
container.style.display = disp;
img.src = src;
}
function CollapseLevel(level) {
EnsureIsPopulated();
TraverseChildren($id("Canvas"), function (element, depth) {
if (element.className == 'collapsible') {
if (depth >= level) {
MakeContentVisible(element, false);
} else {
MakeContentVisible(element, true);
}
}
}, 0);
}
function TabSizeChanged() {
Process();
}
function SetTab() {
var select = $id("TabSize");
window.TAB = MultiplyString(parseInt(select.options[select.selectedIndex].value), window.SINGLE_TAB);
}
function EnsureIsPopulated() {
if (!$id("Canvas").innerHTML && !!$id("content").value) Process();
}
function MultiplyString(num, str) {
var sb = [];
for (var i = 0; i < num; i++) {
sb.push(str);
}
return sb.join("");
}
function SelectAllClicked() {
if (!!document.selection && !!document.selection.empty) {
document.selection.empty();
} else if (window.getSelection) {
var sel = window.getSelection();
if (sel.removeAllRanges) {
window.getSelection().removeAllRanges();
}
}
var range =
(!!document.body && !!document.body.createTextRange)
? document.body.createTextRange()
: document.createRange();
if (!!range.selectNode)
range.selectNode($id("Canvas"));
else if (range.moveToElementText)
range.moveToElementText($id("Canvas"));
if (!!range.select)
range.select($id("Canvas"));
else
window.getSelection().addRange(range);
}
function LinkToJson() {
var val = $id("content").value;
val = escape(val.split('/n').join(' ').split('/r').join(' '));
$id("InvisibleLinkUrl").value = val;
$id("InvisibleLink").submit();
}
@@ -0,0 +1,206 @@
/**
* JSON to XML jQuery plugin. Provides quick way to convert JSON object to XML
* string. To some extent, allows control over XML output.
* Just as jQuery itself, this plugin is released under both MIT & GPL licences.
*
* @version 1.02
* @author Micha Korecki, www.michalkorecki.com
*/
(function($) {
/**
* Converts JSON object to XML string.
*
* @param json object to convert
* @param options additional parameters
* @return XML string
*/
$.json2xml = function(json, options) {
settings = {};
settings = $.extend(true, settings, defaultSettings, options || { });
return '<?xml version="1.0" encoding="UTF-8"?>'+convertToXml(json, settings.rootTagName, '', 0);
};
var defaultSettings = {
formatOutput: true,
formatTextNodes: false,
indentString: ' ',
rootTagName: 'root',
ignore: [],
replace: [],
nodes: [],
///TODO: exceptions system
exceptions: []
};
/**
* This is actual settings object used throught plugin, default settings
* are stored separately to prevent overriding when using multiple times.
*/
var settings = {};
/**
* Core function parsing JSON to XML. It iterates over object properties and
* creates XML attributes appended to main tag, if property is primitive
* value (eg. string, number).
* Otherwise, if it's array or object, new node is created and appened to
* parent tag.
* You can alter this behaviour by providing values in settings.ignore,
* settings.replace and settings.nodes arrays.
*
* @param json object to parse
* @param tagName name of tag created for parsed object
* @param parentPath path to properly identify elements in ignore, replace
* and nodes arrays
* @param depth current element's depth
* @return XML string
*/
var convertToXml = function(json, tagName, parentPath, depth) {
var suffix = (settings.formatOutput) ? '\r\n' : '';
var indent = (settings.formatOutput) ? getIndent(depth) : '';
var xmlTag = indent + '<' + tagName;
var children = '';
for (var key in json) {
if (json.hasOwnProperty(key)) {
var propertyPath = parentPath + key;
var propertyName = getPropertyName(parentPath, key);
// element not in ignore array, process
if ($.inArray(propertyPath, settings.ignore) == -1) {
// array, create new child element
if ($.isArray(json[key])) {
children += createNodeFromArray(json[key], propertyName,
propertyPath + '.', depth + 1, suffix);
}
// object, new child element aswell
else if (typeof(json[key]) === 'object') {
children += convertToXml(json[key], propertyName,
propertyPath + '.', depth + 1);
}
// primitive value property as attribute
else {
// unless it's explicitly defined it should be node
if ( propertyName.indexOf('@')==-1) {
children += createTextNode(propertyName, json[key],
depth, suffix);
}
else {
propertyName = propertyName.replace('@','');
xmlTag += ' ' + propertyName + '="' + json[key] + '"';
}
}
}
}
}
// close tag properly
if (children !== '') {
xmlTag += '>' + suffix + children + indent + '</' + tagName + '>' + suffix;
}
else {
xmlTag += '/>' + suffix;
}
return xmlTag;
};
/**
* Creates indent string for provided depth value. See settings for details.
*
* @param depth
* @return indent string
*/
var getIndent = function(depth) {
var output = '';
for (var i = 0; i < depth; i++) {
output += settings.indentString;
}
return output;
};
/**
* Checks settings.replace array for provided name, if it exists returns
* replacement name. Else, original name is returned.
*
* @param parentPath path to this element's parent
* @param name name of element to look up
* @return element's final name
*/
var getPropertyName = function(parentPath, name) {
var index = settings.replace.length;
var searchName = parentPath + name;
while (index--) {
// settings.replace array consists of {original : replacement}
// objects
if (settings.replace[index].hasOwnProperty(searchName)) {
return settings.replace[index][searchName];
}
}
return name;
};
/**
* Creates XML node from javascript array object.
*
* @param source
* @param name XML element name
* @param path parent element path string
* @param depth
* @param suffix node suffix (whether to format output or not)
* @return XML tag string for provided array
*/
var createNodeFromArray = function(source, name, path, depth, suffix) {
var xmlNode = '';
if (source.length > 0) {
for (var index in source) {
// array's element isn't object - it's primitive value, which
// means array might need to be converted to text nodes
if (typeof(source[index]) !== 'object') {
// empty strings will be converted to empty nodes
if (source[index] === "") {
xmlNode += getIndent(depth) + '<' + name + '/>' + suffix;
}
else {
var textPrefix = (settings.formatTextNodes)
? suffix + getIndent(depth + 1) : '';
var textSuffix = (settings.formatTextNodes)
? suffix + getIndent(depth) : '';
xmlNode += getIndent(depth) + '<' + name + '>'
+ textPrefix + source[index] + textSuffix
+ '</' + name + '>' + suffix;
}
}
// else regular conversion applies
else {
xmlNode += convertToXml(source[index], name, path, depth);
}
}
}
// array is empty, also creating empty XML node
else {
xmlNode += getIndent(depth) + '<' + name + '/>' + suffix;
}
return xmlNode;
};
/**
* Creates node containing text only.
*
* @param name node's name
* @param text node text string
* @param parentDepth this node's parent element depth
* @param suffix node suffix (whether to format output or not)
* @return XML tag string
*/
var createTextNode = function(name, text, parentDepth, suffix) {
// unformatted text node: <node>value</node>
// formatting includes value indentation and new lines
var textPrefix = (settings.formatTextNodes)
? suffix + getIndent(parentDepth + 2) : '';
var textSuffix = (settings.formatTextNodes)
? suffix + getIndent(parentDepth + 1) : '';
var xmlNode = getIndent(parentDepth + 1) + '<' + name + '>'
+ textPrefix + text + textSuffix
+ '</' + name + '>' + suffix;
return xmlNode;
};
})(jQuery);
@@ -0,0 +1,193 @@
/*
### jQuery XML to JSON Plugin v1.3 - 2013-02-18 ###
* http://www.fyneworks.com/ - diego@fyneworks.com
* Licensed under http://en.wikipedia.org/wiki/MIT_License
###
Website: http://www.fyneworks.com/jquery/xml-to-json/
*//*
# INSPIRED BY: http://www.terracoder.com/
AND: http://www.thomasfrank.se/xml_to_json.html
AND: http://www.kawa.net/works/js/xml/objtree-e.html
*//*
This simple script converts XML (document of code) into a JSON object. It is the combination of 2
'xml to json' great parsers (see below) which allows for both 'simple' and 'extended' parsing modes.
*/
// Avoid collisions
;if(window.jQuery) (function($){
// Add function to jQuery namespace
$.extend({
// converts xml documents and xml text to json object
xml2json: function(xml, extended) {
if(!xml) return {}; // quick fail
//### PARSER LIBRARY
// Core function
function parseXML(node, simple){
if(!node) return null;
var txt = '', obj = null, att = null;
var nt = node.nodeType, nn = jsVar(node.localName || node.nodeName);
var nv = node.text || node.nodeValue || '';
/*DBG*/ //if(window.console) console.log(['x2j',nn,nt,nv.length+' bytes']);
if(node.childNodes){
if(node.childNodes.length>0){
/*DBG*/ //if(window.console) console.log(['x2j',nn,'CHILDREN',node.childNodes]);
$.each(node.childNodes, function(n,cn){
var cnt = cn.nodeType, cnn = jsVar(cn.localName || cn.nodeName);
var cnv = cn.text || cn.nodeValue || '';
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>a',cnn,cnt,cnv]);
if(cnt == 8){
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>b',cnn,'COMMENT (ignore)']);
return; // ignore comment node
}
else if(cnt == 3 || cnt == 4 || !cnn){
// ignore white-space in between tags
if(cnv.match(/^\s+$/)){
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>c',cnn,'WHITE-SPACE (ignore)']);
return;
};
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>d',cnn,'TEXT']);
txt += cnv.replace(/^\s+/,'').replace(/\s+$/,'');
// make sure we ditch trailing spaces from markup
}
else{
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>e',cnn,'OBJECT']);
obj = obj || {};
if(obj[cnn]){
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>f',cnn,'ARRAY']);
// http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child
if(!obj[cnn].length) obj[cnn] = myArr(obj[cnn]);
obj[cnn] = myArr(obj[cnn]);
obj[cnn][ obj[cnn].length ] = parseXML(cn, true/* simple */);
obj[cnn].length = obj[cnn].length;
}
else{
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>g',cnn,'dig deeper...']);
obj[cnn] = parseXML(cn);
};
};
});
};//node.childNodes.length>0
};//node.childNodes
if(node.attributes){
if(node.attributes.length>0){
/*DBG*/ //if(window.console) console.log(['x2j',nn,'ATTRIBUTES',node.attributes])
att = {}; obj = obj || {};
$.each(node.attributes, function(a,at){
var atn = jsVar('@'+at.name), atv = at.value;
att[atn] = atv;
if(obj[atn]){
/*DBG*/ //if(window.console) console.log(['x2j',nn,'attr>',atn,'ARRAY']);
// http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child
//if(!obj[atn].length) obj[atn] = myArr(obj[atn]);//[ obj[ atn ] ];
obj[cnn] = myArr(obj[cnn]);
obj[atn][ obj[atn].length ] = atv;
obj[atn].length = obj[atn].length;
}
else{
/*DBG*/ //if(window.console) console.log(['x2j',nn,'attr>',atn,'TEXT']);
obj[atn] = atv;
};
});
//obj['attributes'] = att;
};//node.attributes.length>0
};//node.attributes
if(obj){
obj = $.extend( (txt!='' ? new String(txt) : {}),/* {text:txt},*/ obj || {}/*, att || {}*/);
//txt = (obj.text) ? (typeof(obj.text)=='object' ? obj.text : [obj.text || '']).concat([txt]) : txt;
txt = (obj.text) ? ([obj.text || '']).concat([txt]) : txt;
if(txt) obj.text = txt;
txt = '';
};
var out = obj || txt;
//console.log([extended, simple, out]);
if(extended){
if(txt) out = {};//new String(out);
txt = out.text || txt || '';
if(txt) out.text = txt;
if(!simple) out = myArr(out);
};
return out;
};// parseXML
// Core Function End
// Utility functions
var jsVar = function(s){ return String(s || '').replace(/-/g,"_"); };
// NEW isNum function: 01/09/2010
// Thanks to Emile Grau, GigaTecnologies S.L., www.gigatransfer.com, www.mygigamail.com
function isNum(s){
// based on utility function isNum from xml2json plugin (http://www.fyneworks.com/ - diego@fyneworks.com)
// few bugs corrected from original function :
// - syntax error : regexp.test(string) instead of string.test(reg)
// - regexp modified to accept comma as decimal mark (latin syntax : 25,24 )
// - regexp modified to reject if no number before decimal mark : ".7" is not accepted
// - string is "trimmed", allowing to accept space at the beginning and end of string
var regexp=/^((-)?([0-9]+)(([\.\,]{0,1})([0-9]+))?$)/
return (typeof s == "number") || regexp.test(String((s && typeof s == "string") ? jQuery.trim(s) : ''));
};
// OLD isNum function: (for reference only)
//var isNum = function(s){ return (typeof s == "number") || String((s && typeof s == "string") ? s : '').test(/^((-)?([0-9]*)((\.{0,1})([0-9]+))?$)/); };
var myArr = function(o){
// http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child
//if(!o.length) o = [ o ]; o.length=o.length;
if(!$.isArray(o)) o = [ o ]; o.length=o.length;
// here is where you can attach additional functionality, such as searching and sorting...
return o;
};
// Utility functions End
//### PARSER LIBRARY END
// Convert plain text to xml
if(typeof xml=='string') xml = $.text2xml(xml);
// Quick fail if not xml (or if this is a node)
if(!xml.nodeType) return;
if(xml.nodeType == 3 || xml.nodeType == 4) return xml.nodeValue;
// Find xml root node
var root = (xml.nodeType == 9) ? xml.documentElement : xml;
// Convert xml to json
var out = parseXML(root, true /* simple */);
// Clean-up memory
xml = null; root = null;
// Send output
return out;
},
// Convert text to XML DOM
text2xml: function(str) {
// NOTE: I'd like to use jQuery for this, but jQuery makes all tags uppercase
//return $(xml)[0];
/* prior to jquery 1.9 */
/*
var out;
try{
var xml = ((!$.support.opacity && !$.support.style))?new ActiveXObject("Microsoft.XMLDOM"):new DOMParser();
xml.async = false;
}catch(e){ throw new Error("XML Parser could not be instantiated") };
try{
if((!$.support.opacity && !$.support.style)) out = (xml.loadXML(str))?xml:false;
else out = xml.parseFromString(str, "text/xml");
}catch(e){ throw new Error("Error parsing XML string") };
return out;
*/
/* jquery 1.9+ */
return $.parseXML(str);
}
}); // extend $
})(jQuery);
+334
View File
@@ -0,0 +1,334 @@
/*jslint evil: true, strict: false */
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
lastIndex, length, parse, prototype, push, replace, slice, stringify,
test, toJSON, toString, valueOf
*/
// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.
if (!this.JSON) {
this.JSON = {};
}
(function () {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
if (typeof Date.prototype.toJSON !== 'function') {
Date.prototype.toJSON = function (key) {
return isFinite(this.valueOf()) ?
this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z' : null;
};
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function (key) {
return this.valueOf();
};
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap,
indent,
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep;
function quote(string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
escapable.lastIndex = 0;
return escapable.test(string) ?
'"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string' ? c :
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' :
'"' + string + '"';
}
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0 ? '[]' :
gap ? '[\n' + gap +
partial.join(',\n' + gap) + '\n' +
mind + ']' :
'[' + partial.join(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
k = rep[i];
if (typeof k === 'string') {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0 ? '{}' :
gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
mind + '}' : '{' + partial.join(',') + '}';
gap = mind;
return v;
}
}
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
JSON.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var i;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
// If the space parameter is a string, it will be used as the indent string.
} else if (typeof space === 'string') {
indent = space;
}
// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', {'': value});
};
}
// If the JSON object does not yet have a parse method, give it one.
if (typeof JSON.parse !== 'function') {
JSON.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.
var j;
function walk(holder, key) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return typeof reviver === 'function' ?
walk({'': j}, '') : j;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.
throw new SyntaxError('JSON.parse');
};
}
}());
File diff suppressed because one or more lines are too long
+139
View File
@@ -0,0 +1,139 @@
var Fjson = (function () {
var _toString = Object.prototype.toString;
function format(object, indent_count) {
var html_fragment = '';
switch (_typeof(object)) {
case 'Null': 0
html_fragment = _format_null(object);
break;
case 'Boolean':
html_fragment = _format_boolean(object);
break;
case 'Number':
html_fragment = _format_number(object);
break;
case 'String':
html_fragment = _format_string(object);
break;
case 'Array':
html_fragment = _format_array(object, indent_count);
break;
case 'Object':
html_fragment = _format_object(object, indent_count);
break;
}
return html_fragment;
};
function _format_null(object) {
return '<span class="json_null">null</span>';
}
function _format_boolean(object) {
return '<span class="json_boolean">' + object + '</span>';
}
function _format_number(object) {
return '<span class="json_number">' + object + '</span>';
}
function _format_string(object) {
object = object.replace(/\</g, "&lt;");
object = object.replace(/\>/g, "&gt;");
if (0 <= object.search(/^http/)) {
object = '<a href="' + object + '" target="_blank" class="json_link">' + object + '</a>'
}
return '<span class="json_string">"' + object + '"</span>';
}
function _format_array(object, indent_count) {
var tmp_array = [];
for (var i = 0, size = object.length; i < size; ++i) {
tmp_array.push(indent_tab(indent_count) + format(object[i], indent_count + 1));
}
return '<span data-type="array" data-size="' + tmp_array.length + '"><i style="cursor:pointer;" class="fa fa-minus-square-o" onclick="hide(this)"></i>[<br/>'
+ tmp_array.join(',<br/>')
+ '<br/>' + indent_tab(indent_count - 1) + ']</span>';
}
function _format_object(object, indent_count) {
var tmp_array = [];
for (var key in object) {
tmp_array.push(indent_tab(indent_count) + '<span class="json_key">"' + key + '"</span>:' + format(object[key], indent_count + 1));
}
return '<span data-type="object"><i style="cursor:pointer;" class="fa fa-minus-square-o" onclick="hide(this)"></i>{<br/>'
+ tmp_array.join(',<br/>')
+ '<br/>' + indent_tab(indent_count - 1) + '}</span>';
}
function indent_tab(indent_count) {
return (new Array(indent_count + 1)).join('&nbsp;&nbsp;&nbsp;&nbsp;');
}
function _typeof(object) {
var tf = typeof object,
ts = _toString.call(object);
return null === object ? 'Null' :
'undefined' == tf ? 'Undefined' :
'boolean' == tf ? 'Boolean' :
'number' == tf ? 'Number' :
'string' == tf ? 'String' :
'[object Function]' == ts ? 'Function' :
'[object Array]' == ts ? 'Array' :
'[object Date]' == ts ? 'Date' : 'Object';
};
function loadCssString() {
var style = document.createElement('style');
style.type = 'text/css';
var code = Array.prototype.slice.apply(arguments).join('');
try {
style.appendChild(document.createTextNode(code));
} catch (ex) {
style.styleSheet.cssText = code;
}
document.getElementsByTagName('head')[0].appendChild(style);
}
loadCssString(
'.json_key{ color: #92278f;font-weight:bold;}',
'.json_null{color: #f1592a;font-weight:bold;}',
'.json_string{ color: #3ab54a;font-weight:bold;}',
'.json_number{ color: #25aae2;font-weight:bold;}',
'.json_link{ color: #717171;font-weight:bold;}',
'.json_array_brackets{}');
var _Fjson = function (origin_data) {
//this.data = origin_data ? origin_data :
//JSON && JSON.parse ? JSON.parse(origin_data) : eval('(' + origin_data + ')');
this.data = JSON.parse(origin_data);
};
_Fjson.prototype = {
constructor: Fjson,
toString: function () {
return format(this.data, 1);
}
}
return _Fjson;
})();
var last_html = '';
function hide(obj) {
var data_type = obj.parentNode.getAttribute('data-type');
var data_size = obj.parentNode.getAttribute('data-size');
obj.parentNode.setAttribute('data-inner', obj.parentNode.innerHTML);
if (data_type === 'array') {
obj.parentNode.innerHTML = '<i style="cursor:pointer;" class="fa fa-plus-square-o" onclick="show(this)"></i>Array[<span class="json_number">' + data_size + '</span>]';
} else {
obj.parentNode.innerHTML = '<i style="cursor:pointer;" class="fa fa-plus-square-o" onclick="show(this)"></i>Object{...}';
}
}
function show(obj) {
var innerHtml = obj.parentNode.getAttribute('data-inner');
obj.parentNode.innerHTML = innerHtml;
}
+524
View File
@@ -0,0 +1,524 @@
var jsonlint = function() {
var a = !0,
b = !1,
c = {},
d = function() {
var a = {
trace: function() {},
yy: {},
symbols_: {
error: 2,
JSONString: 3,
STRING: 4,
JSONNumber: 5,
NUMBER: 6,
JSONNullLiteral: 7,
NULL: 8,
JSONBooleanLiteral: 9,
TRUE: 10,
FALSE: 11,
JSONText: 12,
JSONValue: 13,
EOF: 14,
JSONObject: 15,
JSONArray: 16,
"{": 17,
"}": 18,
JSONMemberList: 19,
JSONMember: 20,
":": 21,
",": 22,
"[": 23,
"]": 24,
JSONElementList: 25,
$accept: 0,
$end: 1
},
terminals_: {
2: "error",
4: "<code>STRING</code>",
6: "<code>NUMBER</code>",
8: "<code>NULL</code>",
10: "<code>TRUE</code>",
11: "<code>FALSE</code>",
14: "<code>EOF</code>",
17: "<code>{</code>",
18: "<code>}</code>",
21: "<code>:</code>",
22: "<code>,</code>",
23: "<code>[</code>",
24: "<code>]</code>"
},
productions_: [0, [3, 1],
[5, 1],
[7, 1],
[9, 1],
[9, 1],
[12, 2],
[13, 1],
[13, 1],
[13, 1],
[13, 1],
[13, 1],
[13, 1],
[15, 2],
[15, 3],
[20, 3],
[19, 1],
[19, 3],
[16, 2],
[16, 3],
[25, 1],
[25, 3]
],
performAction: function(b, c, d, e, f, g, h) {
var i = g.length - 1;
switch (f) {
case 1:
this.$ = b.replace(/\\(\\|")/g, "$1").replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\v/g, " ").replace(/\\f/g, "\f").replace(/\\b/g, "\b");
break;
case 2:
this.$ = Number(b);
break;
case 3:
this.$ = null;
break;
case 4:
this.$ = !0;
break;
case 5:
this.$ = !1;
break;
case 6:
return this.$ = g[i - 1];
case 13:
this.$ = {};
break;
case 14:
this.$ = g[i - 1];
break;
case 15:
this.$ = [g[i - 2], g[i]];
break;
case 16:
this.$ = {}, this.$[g[i][0]] = g[i][1];
break;
case 17:
this.$ = g[i - 2], g[i - 2][g[i][0]] = g[i][1];
break;
case 18:
this.$ = [];
break;
case 19:
this.$ = g[i - 1];
break;
case 20:
this.$ = [g[i]];
break;
case 21:
this.$ = g[i - 2], g[i - 2].push(g[i])
}
},
table: [{
3: 5,
4: [1, 12],
5: 6,
6: [1, 13],
7: 3,
8: [1, 9],
9: 4,
10: [1, 10],
11: [1, 11],
12: 1,
13: 2,
15: 7,
16: 8,
17: [1, 14],
23: [1, 15]
}, {
1: [3]
}, {
14: [1, 16]
}, {
14: [2, 7],
18: [2, 7],
22: [2, 7],
24: [2, 7]
}, {
14: [2, 8],
18: [2, 8],
22: [2, 8],
24: [2, 8]
}, {
14: [2, 9],
18: [2, 9],
22: [2, 9],
24: [2, 9]
}, {
14: [2, 10],
18: [2, 10],
22: [2, 10],
24: [2, 10]
}, {
14: [2, 11],
18: [2, 11],
22: [2, 11],
24: [2, 11]
}, {
14: [2, 12],
18: [2, 12],
22: [2, 12],
24: [2, 12]
}, {
14: [2, 3],
18: [2, 3],
22: [2, 3],
24: [2, 3]
}, {
14: [2, 4],
18: [2, 4],
22: [2, 4],
24: [2, 4]
}, {
14: [2, 5],
18: [2, 5],
22: [2, 5],
24: [2, 5]
}, {
14: [2, 1],
18: [2, 1],
21: [2, 1],
22: [2, 1],
24: [2, 1]
}, {
14: [2, 2],
18: [2, 2],
22: [2, 2],
24: [2, 2]
}, {
3: 20,
4: [1, 12],
18: [1, 17],
19: 18,
20: 19
}, {
3: 5,
4: [1, 12],
5: 6,
6: [1, 13],
7: 3,
8: [1, 9],
9: 4,
10: [1, 10],
11: [1, 11],
13: 23,
15: 7,
16: 8,
17: [1, 14],
23: [1, 15],
24: [1, 21],
25: 22
}, {
1: [2, 6]
}, {
14: [2, 13],
18: [2, 13],
22: [2, 13],
24: [2, 13]
}, {
18: [1, 24],
22: [1, 25]
}, {
18: [2, 16],
22: [2, 16]
}, {
21: [1, 26]
}, {
14: [2, 18],
18: [2, 18],
22: [2, 18],
24: [2, 18]
}, {
22: [1, 28],
24: [1, 27]
}, {
22: [2, 20],
24: [2, 20]
}, {
14: [2, 14],
18: [2, 14],
22: [2, 14],
24: [2, 14]
}, {
3: 20,
4: [1, 12],
20: 29
}, {
3: 5,
4: [1, 12],
5: 6,
6: [1, 13],
7: 3,
8: [1, 9],
9: 4,
10: [1, 10],
11: [1, 11],
13: 30,
15: 7,
16: 8,
17: [1, 14],
23: [1, 15]
}, {
14: [2, 19],
18: [2, 19],
22: [2, 19],
24: [2, 19]
}, {
3: 5,
4: [1, 12],
5: 6,
6: [1, 13],
7: 3,
8: [1, 9],
9: 4,
10: [1, 10],
11: [1, 11],
13: 31,
15: 7,
16: 8,
17: [1, 14],
23: [1, 15]
}, {
18: [2, 17],
22: [2, 17]
}, {
18: [2, 15],
22: [2, 15]
}, {
22: [2, 21],
24: [2, 21]
}],
defaultActions: {
16: [2, 6]
},
parseError: function(b, c) {
throw new Error(b)
},
parse: function(b) {
function o(a) {
d.length = d.length - 2 * a, e.length = e.length - a, f.length = f.length - a
}
function p() {
var a;
return a = c.lexer.lex() || 1, typeof a != "number" && (a = c.symbols_[a] || a), a
}
var c = this,
d = [0],
e = [null],
f = [],
g = this.table,
h = "",
i = 0,
j = 0,
k = 0,
l = 2,
m = 1;
this.lexer.setInput(b), this.lexer.yy = this.yy, this.yy.lexer = this.lexer, typeof this.lexer.yylloc == "undefined" && (this.lexer.yylloc = {});
var n = this.lexer.yylloc;
f.push(n), typeof this.yy.parseError == "function" && (this.parseError = this.yy.parseError);
var q, r, s, t, u, v, w = {},
x, y, z, A;
for (;;) {
s = d[d.length - 1], this.defaultActions[s] ? t = this.defaultActions[s] : (q == null && (q = p()), t = g[s] && g[s][q]);
if (typeof t == "undefined" || !t.length || !t[0]) {
if (!k) {
A = [];
for (x in g[s]) this.terminals_[x] && x > 2 && A.push("'" + this.terminals_[x] + "'");
var B = "";
this.lexer.showPosition ? B = "在第"+ (i + 1)+"行发生解析错误 "+ ":<br/>" + this.lexer.showPosition() + "<br/>此处缺少" + A.join(", ") + "字符, 实际上是一个 '" + this.terminals_[q] + "'" : B = "在第"+ (i + 1)+"行发生解析错误 " + ": 本应该是 " + (q == 1 ? "结尾输入" : "'" + (this.terminals_[q] || q) + "'"), this.parseError(B, {
text: this.lexer.match,
token: this.terminals_[q] || q,
line: this.lexer.yylineno,
loc: n,
expected: A
})
}
if (k == 3) {
if (q == m) throw new Error(B || "解析意外终止.");
j = this.lexer.yyleng, h = this.lexer.yytext, i = this.lexer.yylineno, n = this.lexer.yylloc, q = p()
}
for (;;) {
if (l.toString() in g[s]) break;
if (s == 0) throw new Error(B || "解析意外终止.");
o(1), s = d[d.length - 1]
}
r = q, q = l, s = d[d.length - 1], t = g[s] && g[s][l], k = 3
}
if (t[0] instanceof Array && t.length > 1) throw new Error("解析错误: multiple actions possible at state: " + s + ", token: " + q);
switch (t[0]) {
case 1:
d.push(q), e.push(this.lexer.yytext), f.push(this.lexer.yylloc), d.push(t[1]), q = null, r ? (q = r, r = null) : (j = this.lexer.yyleng, h = this.lexer.yytext, i = this.lexer.yylineno, n = this.lexer.yylloc, k > 0 && k--);
break;
case 2:
y = this.productions_[t[1]][1], w.$ = e[e.length - y], w._$ = {
first_line: f[f.length - (y || 1)].first_line,
last_line: f[f.length - 1].last_line,
first_column: f[f.length - (y || 1)].first_column,
last_column: f[f.length - 1].last_column
}, v = this.performAction.call(w, h, j, i, this.yy, t[1], e, f);
if (typeof v != "undefined") return v;
y && (d = d.slice(0, -1 * y * 2), e = e.slice(0, -1 * y), f = f.slice(0, -1 * y)), d.push(this.productions_[t[1]][0]), e.push(w.$), f.push(w._$), z = g[d[d.length - 2]][d[d.length - 1]], d.push(z);
break;
case 3:
return !0
}
}
return !0
}
},
b = function() {
var a = {
EOF: 1,
parseError: function(b, c) {
if (!this.yy.parseError) throw new Error(b);
this.yy.parseError(b, c)
},
setInput: function(a) {
return this._input = a, this._more = this._less = this.done = !1, this.yylineno = this.yyleng = 0, this.yytext = this.matched = this.match = "", this.conditionStack = ["INITIAL"], this.yylloc = {
first_line: 1,
first_column: 0,
last_line: 1,
last_column: 0
}, this
},
input: function() {
var a = this._input[0];
this.yytext += a, this.yyleng++, this.match += a, this.matched += a;
var b = a.match(/\n/);
return b && this.yylineno++, this._input = this._input.slice(1), a
},
unput: function(a) {
return this._input = a + this._input, this
},
more: function() {
return this._more = !0, this
},
less: function(a) {
this._input = this.match.slice(a) + this._input
},
pastInput: function() {
var a = this.matched.substr(0, this.matched.length - this.match.length);
return (a.length > 20 ? "..." : "") + a.substr(-20).replace(/\n/g, "")
},
upcomingInput: function() {
var a = this.match;
return a.length < 20 && (a += this._input.substr(0, 20 - a.length)), (a.substr(0, 20) + (a.length > 20 ? "..." : "")).replace(/\n/g, "")
},
showPosition: function() {
var a = this.pastInput(),
b = (new Array(a.length + 1 - 5)).join("&nbsp;");
return "<code>"+ a + this.upcomingInput() + "</code><br/>" + b + '<i class="fa fa-arrow-up" style="color:green;"></i>'
},
next: function() {
if (this.done) return this.EOF;
this._input || (this.done = !0);
var a, b, c, d, e, f;
this._more || (this.yytext = "", this.match = "");
var g = this._currentRules();
for (var h = 0; h < g.length; h++) {
c = this._input.match(this.rules[g[h]]);
if (c && (!b || c[0].length > b[0].length)) {
b = c, d = h;
if (!this.options.flex) break
}
}
if (b) {
f = b[0].match(/\n.*/g), f && (this.yylineno += f.length), this.yylloc = {
first_line: this.yylloc.last_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.last_column,
last_column: f ? f[f.length - 1].length - 1 : this.yylloc.last_column + b[0].length
}, this.yytext += b[0], this.match += b[0], this.yyleng = this.yytext.length, this._more = !1, this._input = this._input.slice(b[0].length), this.matched += b[0], a = this.performAction.call(this, this.yy, this, g[d], this.conditionStack[this.conditionStack.length - 1]), this.done && this._input && (this.done = !1);
if (a) return a;
return
}
if (this._input === "") return this.EOF;
this.parseError("词汇错误发生在第" + (this.yylineno + 1) + "行. 不能识别的字符.<br/>" + this.showPosition(), {
text: "",
token: null,
line: this.yylineno
})
},
lex: function() {
var b = this.next();
return typeof b != "undefined" ? b : this.lex()
},
begin: function(b) {
this.conditionStack.push(b)
},
popState: function() {
return this.conditionStack.pop()
},
_currentRules: function() {
return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules
},
topState: function() {
return this.conditionStack[this.conditionStack.length - 2]
},
pushState: function(b) {
this.begin(b)
}
};
return a.options = {}, a.performAction = function(b, c, d, e) {
var f = e;
switch (d) {
case 0:
break;
case 1:
return 6;
case 2:
return c.yytext = c.yytext.substr(1, c.yyleng - 2), 4;
case 3:
return 17;
case 4:
return 18;
case 5:
return 23;
case 6:
return 24;
case 7:
return 22;
case 8:
return 21;
case 9:
return 10;
case 10:
return 11;
case 11:
return 8;
case 12:
return 14;
case 13:
return "INVALID"
}
}, a.rules = [/^(?:\s+)/, /^(?:(-?([0-9]|[1-9][0-9]+))(\.[0-9]+)?([eE][-+]?[0-9]+)?\b)/, /^(?:"(?:\\[\\"bfnrt/]|\\u[a-fA-F0-9]{4}|[^\\\0-\x09\x0a-\x1f"])*")/, /^(?:\{)/, /^(?:\})/, /^(?:\[)/, /^(?:\])/, /^(?:,)/, /^(?::)/, /^(?:true\b)/, /^(?:false\b)/, /^(?:null\b)/, /^(?:$)/, /^(?:.)/], a.conditions = {
INITIAL: {
rules: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
inclusive: !0
}
}, a
}();
return a.lexer = b, a
}();
return typeof a != "undefined" && typeof c != "undefined" && (c.parser = d, c.parse = function() {
return d.parse.apply(d, arguments)
}, c.main = function(d) {
if (!d[1]) throw new Error("Usage: " + d[0] + " FILE");
if (typeof process != "undefined") var e = a("fs").readFileSync(a("path").join(process.cwd(), d[1]), "utf8");
else var f = a("file").path(a("file").cwd()),
e = f.join(d[1]).read({
charset: "utf-8"
});
return c.parser.parse(e)
}, typeof b != "undefined" && a.main === b && c.main(typeof process != "undefined" ? process.argv.slice(1) : a("system").args)), c
}();
+71
View File
@@ -0,0 +1,71 @@
var current_json = '';
var current_json_str = '';
var xml_flag = false;
var zip_flag = false;
$('.tip').tooltip();
function init() {
xml_flag = false;
zip_flag = false;
}
$('#json-src').keyup(function () {
init();
var content = $.trim($(this).val());
var result = '';
if (content != '') {
//如果是xml,那么转换为json
if (content.substr(0, 1) === '<' && content.substr(-1, 1) === '>') {
try {
var json_obj = $.xml2json(content);
content = JSON.stringify(json_obj);
} catch (e) {
result = '解析错误:<span style="color: #f1592a;font-weight:bold;">' + e.message + '</span>';
current_json_str = result;
$('#json-target').html(result);
return false;
}
}
try {
current_json = jsonlint.parse(content);
current_json_str = JSON.stringify(current_json);
result = new Fjson(content, 4).toString();
} catch (e) {
result = '<span style="color: #f1592a;font-weight:bold;">' + e + '</span>';
current_json_str = result;
}
$('#json-target').html(result);
} else {
$('#json-target').html('');
}
});
$('#xml').click(function () {
if (xml_flag) {
$('#json-src').keyup();
} else {
var result = $.json2xml(current_json);
$('#json-target').html('<textarea style="width:100%;height:100%;border:0;resize:none;">' + result + '</textarea>');
xml_flag = true;
}
});
$('#zip').click(function () {
if (zip_flag) {
$('#json-src').keyup();
} else {
$('#json-target').html(current_json_str);
zip_flag = true;
}
});
$('#clear').click(function () {
$('#json-src').val('');
$('#json-target').html('');
});
$('.save').click(function () {
var content = JSON.stringify(current_json);
$('#txt-content').val(content);
$("#form-save").submit();
});
$('#json-src').keyup();
+66
View File
@@ -0,0 +1,66 @@
function jsonzip(ii) {
var txtA = document.getElementById("content");
var text = txtA.value;
if ((ii == 1 || ii == 3)) {
text = text.split("\n").join(" ");
var t = [];
var inString = false;
for (var i = 0, len = text.length; i < len; i++) {
var c = text.charAt(i);
if (inString && c === inString) {
if (text.charAt(i - 1) !== '\\') {
inString = false;
}
} else if (!inString && (c === '"' || c === "'")) {
inString = c;
} else if (!inString && (c === ' ' || c === "\t")) {
c = '';
}
t.push(c);
}
text = t.join('');
}
if ((ii == 2 || ii == 3)) {
text = text.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"");
}
if (ii == 4) {
text = text.replace(/\\\\/g, "\\").replace(/\\\"/g, '\"');
}
txtA.value = text;
}
String.prototype.trim = function () {
return this.replace(/(^\s*)|(\s*$)/g, '');
}
var GB2312UnicodeConverter = {
ToUnicode: function (str) {
var txt = escape(str).toLocaleLowerCase().replace(/%u/gi, '\\u');
return txt.replace(/%7b/gi, '{').replace(/%7d/gi, '}').replace(/%3a/gi, ':').replace(/%2c/gi, ',').replace(/%27/gi, '\'').replace(/%22/gi, '"').replace(/%5b/gi, '[').replace(/%5d/gi, ']');
}
, ToGB2312: function (str) {
return unescape(str.replace(/\\u/gi, '%u'));
}
};
function u2h() {
var txtA = document.getElementById("content");
var text = txtA.value;
text = text.trim();
txtA.value = GB2312UnicodeConverter.ToGB2312(text);
}
function h2u() {
var txtA = document.getElementById("content");
var text = txtA.value;
text = text.trim();
txtA.value = GB2312UnicodeConverter.ToUnicode(text);
}
function JsonToGet(type) {
var sstr = $("#content").val();
if (type == 1) {
sstr = sstr.replace(/\t/g, "");
sstr = sstr.replace(/\"/g, "").replace("{", "").replace("}", "").replace(",", "&").replace(":", "=");
sstr = sstr.replace(/\"/g, "").replace(/{/g, "").replace(/}/g, "").replace(/,/g, "&").replace(/:/g, "=");
} else {
sstr = sstr.replace(/&/g, '","').replace(/;/g, '","').replace(/=/g, '":"');
sstr = '{"' + sstr + '"}';
}
$("#content").val(sstr);
}
+61
View File
@@ -0,0 +1,61 @@
/*!
* jQuery Message Plugin (with Transition Definitions)
* Examples and documentation at: http://eadmarket.com/
* Copyright (c) 2012-2013 China.Ren.
* Version: 1.0.2 (19-OCT-2013)
* Dual licensed under the MIT and GPL licenses.
* http://jquery.malsup.com/license.html
* Requires: jQuery v1.3.1 or later
*/
var container = $('#jquery-beauty-msg');
if (container.length <= 0) {
$("body").append('<div style="clear:both;"></div><div id="jquery-beauty-msg"></div>');
container = $('#jquery-beauty-msg');
}
var containerStyle = 'color:#e1282b;font-family:"΢ÈíÑźÚ";font-weight:bold;font-size:20px;text-shadow:5px 5px 10px #bbb;'
+ 'text-align:center;margin:0;padding-top:20%;width:100%;word-break:break-all;z-index:100000;';
var closeFlag = false;
var timer = 0;
var msgContent = '';
$.msg = function (txt, style, obj, delay) {
msgContent = txt;
if (obj != "undefined" && obj != null) {
containerStyle += 'position:relative;top:' + $(obj).attr('top') + ';left:' + $(obj).attr('left') + ';';
}
else {
containerStyle += 'position:fixed;top:0;left:0;';
$(container).attr('style', containerStyle + style);
$(container).html(msgContent);
$(container).fadeIn(300, function () {
$(container).animate({ fontSize: '40px' }, '300');
$(container).delay(1000).fadeOut();
});
}
}
function addDot() {
msgContent = msgContent + ".";
$(container).html(msgContent);
timer = timer + 1;
if (!closeFlag && timer >= 5) {
$(container).html("²Ù×÷³¬Ê±£¡");
window.clearInterval();
}
}
$.loading = function (txt, action) {
msgContent = txt;
containerStyle += 'position:fixed;top:0;left:0;';
$(container).attr('style', containerStyle + "color:blue;");
$(container).html(msgContent);
if (action != "close") {
$(container).fadeIn(300, function () {
$(container).animate({ fontSize: '40px' }, '300');
});
window.setInterval("addDot", 1000);
} else {
window.clearInterval();
closeFlag = true;
$(container).fadeOut();
}
}
+57
View File
@@ -0,0 +1,57 @@
_uacct = "UA-2223138-1";
function onLoad() {
var version = getSilverlightVersion();
}
function getSilverlightVersion() {
var version = 'No Silverlight';
var container = null;
try {
var control = null;
if (window.ActiveXObject) {
control = new ActiveXObject('AgControl.AgControl');
}
else {
if (navigator.plugins['Silverlight Plug-In']) {
container = document.createElement('div');
document.body.appendChild(container);
container.innerHTML = '<embed type="application/x-silverlight" src="data:," />';
control = container.childNodes[0];
}
}
if (control) {
if (control.isVersionSupported('5.0')) { version = 'Silverlight/5.0'; }
else if (control.isVersionSupported('4.0')) { version = 'Silverlight/4.0'; }
else if (control.isVersionSupported('3.0')) { version = 'Silverlight/3.0'; }
else if (control.isVersionSupported('2.0')) { version = 'Silverlight/2.0'; }
else if (control.isVersionSupported('1.0')) { version = 'Silverlight/1.0'; }
}
}
catch (e) { }
if (container) {
document.body.removeChild(container);
}
return version;
}
onLoad();
+369
View File
@@ -0,0 +1,369 @@
/*
* format - jQuery plugin to pretty-print or minify text in XML, JSON, CSS and SQL formats.
* https://github.com/zachofalltrades/jquery.format
*
* Version - 0.1
* Copyright (c) 2013 Zach Shelton
* http://zachofalltrades.net
*
* Based on vkbeautify by Vadim Kiryukhin
* http://www.eslinstructor.net/vkbeautify/
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
(function( $ ) {
/**
* utility function called from constructor of Formatter
*/
function createShiftArr(step) {
var space = ' ';
if ( isNaN(parseInt(step)) ) { // argument is string
space = step;
} else { // argument is integer
space = new Array(step + 1).join(' '); //space is result of join (a string), not an array
}
var shift = ['\n']; // array of shifts
for(var ix=0;ix<100;ix++){
shift.push(shift[ix]+space);
}
return shift;
};
/**
*
*/
function isSubquery(str, parenthesisLevel) {
return parenthesisLevel - (str.replace(/\(/g,'').length - str.replace(/\)/g,'').length );
};
/**
*
*/
function split_sql(str, tab) {
return str.replace(/\s{1,}/g," ")
.replace(/ AND /ig,"~::~"+tab+tab+"AND ")
.replace(/ BETWEEN /ig,"~::~"+tab+"BETWEEN ")
.replace(/ CASE /ig,"~::~"+tab+"CASE ")
.replace(/ ELSE /ig,"~::~"+tab+"ELSE ")
.replace(/ END /ig,"~::~"+tab+"END ")
.replace(/ FROM /ig,"~::~FROM ")
.replace(/ GROUP\s{1,}BY/ig,"~::~GROUP BY ")
.replace(/ HAVING /ig,"~::~HAVING ")
//.replace(/ SET /ig," SET~::~")
.replace(/ IN /ig," IN ")
.replace(/ JOIN /ig,"~::~JOIN ")
.replace(/ CROSS~::~{1,}JOIN /ig,"~::~CROSS JOIN ")
.replace(/ INNER~::~{1,}JOIN /ig,"~::~INNER JOIN ")
.replace(/ LEFT~::~{1,}JOIN /ig,"~::~LEFT JOIN ")
.replace(/ RIGHT~::~{1,}JOIN /ig,"~::~RIGHT JOIN ")
.replace(/ ON /ig,"~::~"+tab+"ON ")
.replace(/ OR /ig,"~::~"+tab+tab+"OR ")
.replace(/ ORDER\s{1,}BY/ig,"~::~ORDER BY ")
.replace(/ OVER /ig,"~::~"+tab+"OVER ")
.replace(/\(\s{0,}SELECT /ig,"~::~(SELECT ")
.replace(/\)\s{0,}SELECT /ig,")~::~SELECT ")
.replace(/ THEN /ig," THEN~::~"+tab+"")
.replace(/ UNION /ig,"~::~UNION~::~")
.replace(/ USING /ig,"~::~USING ")
.replace(/ WHEN /ig,"~::~"+tab+"WHEN ")
.replace(/ WHERE /ig,"~::~WHERE ")
.replace(/ WITH /ig,"~::~WITH ")
//.replace(/\,\s{0,}\(/ig,",~::~( ")
//.replace(/\,/ig,",~::~"+tab+tab+"")
.replace(/ ALL /ig," ALL ")
.replace(/ AS /ig," AS ")
.replace(/ ASC /ig," ASC ")
.replace(/ DESC /ig," DESC ")
.replace(/ DISTINCT /ig," DISTINCT ")
.replace(/ EXISTS /ig," EXISTS ")
.replace(/ NOT /ig," NOT ")
.replace(/ NULL /ig," NULL ")
.replace(/ LIKE /ig," LIKE ")
.replace(/\s{0,}SELECT /ig,"SELECT ")
.replace(/\s{0,}UPDATE /ig,"UPDATE ")
.replace(/ SET /ig," SET ")
.replace(/~::~{1,}/g,"~::~")
.split('~::~');
};
var Formatter = function (options) {
this.init(options);
//TODO - if options object maps any functions, add them as appropriately named methods
var methodName = this.options.method;
if (!$.isFunction(this[methodName])) {
$.error("'" + methodName + "' is not a Formatter method.");
};
this.format = function(text) { //alias to currently selected method
return this[this.options.method].call(this, text);
};
};
/**
* putting the methods into the prototype instead of the constructor method
* enables more efficient on-the-fly creation of Formatter instances
*/
Formatter.prototype = {
options: {},
init: function(options) {
this.options = $.extend({}, $.fn.format.defaults, options);
this.step = this.options.step;
this.preserveComments = this.options.preserveComments;
this.shift = createShiftArr(this.step);
},
xml: function(text) {
var ar = text.replace(/>\s{0,}</g,"><")
.replace(/</g,"~::~<")
.replace(/\s*xmlns\:/g,"~::~xmlns:")
.replace(/\s*xmlns\=/g,"~::~xmlns=")
.split('~::~'),
len = ar.length,
inComment = false,
deep = 0,
str = '',
ix = 0;
for(ix=0;ix<len;ix++) {
// start comment or <![CDATA[...]]> or <!DOCTYPE //
if(ar[ix].search(/<!/) > -1) {
str += this.shift[deep]+ar[ix];
inComment = true;
// end comment or <![CDATA[...]]> //
if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1 || ar[ix].search(/!DOCTYPE/) > -1 ) {
inComment = false;
}
} else
// end comment or <![CDATA[...]]> //
if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1) {
str += ar[ix];
inComment = false;
} else
// <elm></elm> //
if( /^<\w/.exec(ar[ix-1]) && /^<\/\w/.exec(ar[ix]) &&
/^<[\w:\-\.\,]+/.exec(ar[ix-1]) == /^<\/[\w:\-\.\,]+/.exec(ar[ix])[0].replace('/','')) {
str += ar[ix];
if(!inComment) deep--;
} else
// <elm> //
if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) == -1 && ar[ix].search(/\/>/) == -1 ) {
str = !inComment ? str += this.shift[deep++]+ar[ix] : str += ar[ix];
} else
// <elm>...</elm> //
if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) > -1) {
str = !inComment ? str += this.shift[deep]+ar[ix] : str += ar[ix];
} else
// </elm> //
if(ar[ix].search(/<\//) > -1) {
str = !inComment ? str += this.shift[--deep]+ar[ix] : str += ar[ix];
} else
// <elm/> //
if(ar[ix].search(/\/>/) > -1 ) {
str = !inComment ? str += this.shift[deep]+ar[ix] : str += ar[ix];
} else
// <? xml ... ?> //
if(ar[ix].search(/<\?/) > -1) {
str += this.shift[deep]+ar[ix];
} else
// xmlns //
if( ar[ix].search(/xmlns\:/) > -1 || ar[ix].search(/xmlns\=/) > -1) {
str += this.shift[deep]+ar[ix];
}
else {
str += ar[ix];
}
}
return (str[0] == '\n') ? str.slice(1) : str;
},
xmlmin: function(text) {
var str = this.preserveComments ? text
: text.replace(/\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>/g,"")
.replace(/[ \r\n\t]{1,}xmlns/g, ' xmlns');
return str.replace(/>\s{0,}</g,"><");
},
json: function(text) {
if ( typeof JSON === 'undefined' ) return text;
if ( typeof text === "string" ) {
return JSON.stringify(JSON.parse(text), null, this.step);
}
if ( typeof text === "object" ) {
return JSON.stringify(text, null, this.step);
}
return text; // text is not string nor object
},
jsonmin: function(text) {
if (typeof JSON === 'undefined' ) {
return text;
}
return JSON.stringify(JSON.parse(text), null, 0);
},
css: function(text) {
var ar = text.replace(/\s{1,}/g,' ')
.replace(/\{/g,"{~::~")
.replace(/\}/g,"~::~}~::~")
.replace(/\;/g,";~::~")
.replace(/\/\*/g,"~::~/*")
.replace(/\*\//g,"*/~::~")
.replace(/~::~\s{0,}~::~/g,"~::~")
.split('~::~'),
len = ar.length,
deep = 0,
str = '',
ix = 0;
for(ix=0;ix<len;ix++) {
if( /\{/.exec(ar[ix])) {
str += this.shift[deep++]+ar[ix];
} else
if( /\}/.exec(ar[ix])) {
str += this.shift[--deep]+ar[ix];
} else
if( /\*\\/.exec(ar[ix])) {
str += this.shift[deep]+ar[ix];
}
else {
str += this.shift[deep]+ar[ix];
}
}
return str.replace(/^\n{1,}/,'');
},
cssmin: function(text) {
var str = this.preserveComments ? text : text.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\//g,"") ;
return str.replace(/\s{1,}/g,' ')
.replace(/\{\s{1,}/g,"{")
.replace(/\}\s{1,}/g,"}")
.replace(/\;\s{1,}/g,";")
.replace(/\/\*\s{1,}/g,"/*")
.replace(/\*\/\s{1,}/g,"*/");
},
sql: function(text) {
var ar_by_quote = text.replace(/\s{1,}/g," ")
.replace(/\'/ig,"~::~\'")
.split('~::~'),
len = ar_by_quote.length,
ar = [],
deep = 0,
tab = this.step,//+this.step,
parenthesisLevel = 0,
str = '',
ix = 0;
for(ix=0;ix<len;ix++) {
if(ix%2) {
ar = ar.concat(ar_by_quote[ix]);
} else {
ar = ar.concat(split_sql(ar_by_quote[ix], tab) );
}
}
len = ar.length;
for(ix=0;ix<len;ix++) {
parenthesisLevel = isSubquery(ar[ix], parenthesisLevel);
if( /\s{0,}\s{0,}SELECT\s{0,}/.exec(ar[ix])) {
ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"");
}
if( /\s{0,}\s{0,}SET\s{0,}/.exec(ar[ix])) {
ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"");
}
if( /\s{0,}\(\s{0,}SELECT\s{0,}/.exec(ar[ix])) {
deep++;
str += this.shift[deep]+ar[ix];
} else
if( /\'/.exec(ar[ix]) ) {
if(parenthesisLevel<1 && deep) {
deep--;
}
str += ar[ix];
}
else {
str += this.shift[deep]+ar[ix];
if(parenthesisLevel<1 && deep) {
deep--;
}
}
}
str = str.replace(/^\n{1,}/,'').replace(/\n{1,}/g,"\n");
return str;
},
sqlmin: function(text) {
return text.replace(/\s{1,}/g," ").replace(/\s{1,}\(/,"(").replace(/\s{1,}\)/,")");
}
};//end Formatter.prototype
/**
* DOM chaining version
*/
$.fn.format = function(options) {
var fmt = new Formatter(options);
// var methodName = fmt.options.method;
// if (!$.isFunction(fmt[methodName])) {
// $.error("'" + methodName + "' is not a Formatter method.")
// };
// console.log("call " + methodName + " on " + $.type(this));
// console.log(this);
return this.each(function() {
// console.log($.type(this));
// console.log(this);
var node = $(this);
// console.log($.type(node));
// console.log(node);
var text = node.val();
// console.log("text ==>\n" + text);
text = fmt.format(text);
hightout(text);
});
};
/**
* utility version
*/
$.format = function(text, options) {
var fmt = new Formatter(options);
// var methodName = fmt.options.method;
// if (!$.isFunction(fmt[methodName])) {
// $.error("'" + methodName + "' is not a Formatter method.")
// };
// console.log("call " + methodName + " on " + $.type(text));
// console.log(text);
// return fmt[methodName].call(fmt, text);
return fmt.format(text);
};
/**
* default configuration
*/
$.fn.format.defaults = {
method: 'xml', // the method to be called
step: ' ', // 4 spaces
preserveComments: false //applies to cssmin and xmlmin functions
};
})(jQuery);
function Empty() {
document.getElementById("content").value = "";
document.getElementById("content").select();
}
+517
View File
@@ -0,0 +1,517 @@
// ========================================================================
// XML.ObjTree -- XML source code from/to JavaScript object like E4X
// ========================================================================
if (typeof (XML) == 'undefined') XML = function () { };
// constructor
XML.ObjTree = function () {
return this;
};
// class variables
XML.ObjTree.VERSION = "0.23";
// object prototype
XML.ObjTree.prototype.xmlDecl = '<?xml version="1.0" encoding="UTF-8" ?>\n';
XML.ObjTree.prototype.attr_prefix = '-';
// method: parseXML( xmlsource )
XML.ObjTree.prototype.parseXML = function (xml) {
var root;
if (window.DOMParser) {
var xmldom = new DOMParser();
// xmldom.async = false; // DOMParser is always sync-mode
var dom = xmldom.parseFromString(xml, "application/xml");
if (!dom) return;
root = dom.documentElement;
} else if (window.ActiveXObject) {
xmldom = new ActiveXObject('Microsoft.XMLDOM');
xmldom.async = false;
xmldom.loadXML(xml);
root = xmldom.documentElement;
}
if (!root) return;
return this.parseDOM(root);
};
// method: parseHTTP( url, options, callback )
XML.ObjTree.prototype.parseHTTP = function (url, options, callback) {
var myopt = {};
for (var key in options) {
myopt[key] = options[key]; // copy object
}
if (!myopt.method) {
if (typeof (myopt.postBody) == "undefined" &&
typeof (myopt.postbody) == "undefined" &&
typeof (myopt.parameters) == "undefined") {
myopt.method = "get";
} else {
myopt.method = "post";
}
}
if (callback) {
myopt.asynchronous = true; // async-mode
var __this = this;
var __func = callback;
var __save = myopt.onComplete;
myopt.onComplete = function (trans) {
var tree;
if (trans && trans.responseXML && trans.responseXML.documentElement) {
tree = __this.parseDOM(trans.responseXML.documentElement);
}
__func(tree, trans);
if (__save) __save(trans);
};
} else {
myopt.asynchronous = false; // sync-mode
}
var trans;
if (typeof (HTTP) != "undefined" && HTTP.Request) {
myopt.uri = url;
var req = new HTTP.Request(myopt); // JSAN
if (req) trans = req.transport;
} else if (typeof (Ajax) != "undefined" && Ajax.Request) {
var req = new Ajax.Request(url, myopt); // ptorotype.js
if (req) trans = req.transport;
}
if (callback) return trans;
if (trans && trans.responseXML && trans.responseXML.documentElement) {
return this.parseDOM(trans.responseXML.documentElement);
}
}
// method: parseDOM( documentroot )
XML.ObjTree.prototype.parseDOM = function (root) {
if (!root) return;
this.__force_array = {};
if (this.force_array) {
for (var i = 0; i < this.force_array.length; i++) {
this.__force_array[this.force_array[i]] = 1;
}
}
var json = this.parseElement(root); // parse root node
if (this.__force_array[root.nodeName]) {
json = [json];
}
if (root.nodeType != 11) { // DOCUMENT_FRAGMENT_NODE
var tmp = {};
tmp[root.nodeName] = json; // root nodeName
json = tmp;
}
return json;
};
// method: parseElement( element )
XML.ObjTree.prototype.parseElement = function (elem) {
// COMMENT_NODE
if (elem.nodeType == 7) {
return;
}
// TEXT_NODE CDATA_SECTION_NODE
if (elem.nodeType == 3 || elem.nodeType == 4) {
var bool = elem.nodeValue.match(/[^\x00-\x20]/);
if (bool == null) return; // ignore white spaces
return elem.nodeValue;
}
var retval;
var cnt = {};
// parse attributes
if (elem.attributes && elem.attributes.length) {
retval = {};
for (var i = 0; i < elem.attributes.length; i++) {
var key = elem.attributes[i].nodeName;
if (typeof (key) != "string") continue;
var val = elem.attributes[i].nodeValue;
if (!val) continue;
key = this.attr_prefix + key;
if (typeof (cnt[key]) == "undefined") cnt[key] = 0;
cnt[key]++;
this.addNode(retval, key, cnt[key], val);
}
}
// parse child nodes (recursive)
if (elem.childNodes && elem.childNodes.length) {
var textonly = true;
if (retval) textonly = false; // some attributes exists
for (var i = 0; i < elem.childNodes.length && textonly; i++) {
var ntype = elem.childNodes[i].nodeType;
if (ntype == 3 || ntype == 4) continue;
textonly = false;
}
if (textonly) {
if (!retval) retval = "";
for (var i = 0; i < elem.childNodes.length; i++) {
retval += elem.childNodes[i].nodeValue;
}
} else {
if (!retval) retval = {};
for (var i = 0; i < elem.childNodes.length; i++) {
var key = elem.childNodes[i].nodeName;
if (typeof (key) != "string") continue;
var val = this.parseElement(elem.childNodes[i]);
if (!val) continue;
if (typeof (cnt[key]) == "undefined") cnt[key] = 0;
cnt[key]++;
this.addNode(retval, key, cnt[key], val);
}
}
}
return retval;
};
// method: addNode( hash, key, count, value )
XML.ObjTree.prototype.addNode = function (hash, key, cnts, val) {
if (this.__force_array[key]) {
if (cnts == 1) hash[key] = [];
hash[key][hash[key].length] = val; // push
} else if (cnts == 1) { // 1st sibling
hash[key] = val;
} else if (cnts == 2) { // 2nd sibling
hash[key] = [hash[key], val];
} else { // 3rd sibling and more
hash[key][hash[key].length] = val;
}
};
// method: writeXML( tree )
XML.ObjTree.prototype.writeXML = function (tree) {
var xml = this.hash_to_xml(null, tree);
return this.xmlDecl + xml;
};
// method: hash_to_xml( tagName, tree )
XML.ObjTree.prototype.hash_to_xml = function (name, tree) {
var elem = [];
var attr = [];
for (var key in tree) {
if (!tree.hasOwnProperty(key)) continue;
var val = tree[key];
if (key.charAt(0) != this.attr_prefix) {
if (typeof (val) == "undefined" || val == null) {
elem[elem.length] = "<" + key + " />";
} else if (typeof (val) == "object" && val.constructor == Array) {
elem[elem.length] = this.array_to_xml(key, val);
} else if (typeof (val) == "object") {
elem[elem.length] = this.hash_to_xml(key, val);
} else {
elem[elem.length] = this.scalar_to_xml(key, val);
}
} else {
attr[attr.length] = " " + (key.substring(1)) + '="' + (this.xml_escape(val)) + '"';
}
}
var jattr = attr.join("");
var jelem = elem.join("");
if (typeof (name) == "undefined" || name == null) {
// no tag
} else if (elem.length > 0) {
if (jelem.match(/\n/)) {
jelem = "<" + name + jattr + ">\n" + jelem + "</" + name + ">\n";
} else {
jelem = "<" + name + jattr + ">" + jelem + "</" + name + ">\n";
}
} else {
jelem = "<" + name + jattr + " />\n";
}
return jelem;
};
// method: array_to_xml( tagName, array )
XML.ObjTree.prototype.array_to_xml = function (name, array) {
var out = [];
for (var i = 0; i < array.length; i++) {
var val = array[i];
if (typeof (val) == "undefined" || val == null) {
out[out.length] = "<" + name + " />";
} else if (typeof (val) == "object" && val.constructor == Array) {
out[out.length] = this.array_to_xml(name, val);
} else if (typeof (val) == "object") {
out[out.length] = this.hash_to_xml(name, val);
} else {
out[out.length] = this.scalar_to_xml(name, val);
}
}
return out.join("");
};
// method: scalar_to_xml( tagName, text )
XML.ObjTree.prototype.scalar_to_xml = function (name, text) {
if (name == "#text") {
return this.xml_escape(text);
} else {
return "<" + name + ">" + this.xml_escape(text) + "</" + name + ">\n";
}
};
// method: xml_escape( text )
XML.ObjTree.prototype.xml_escape = function (text) {
return (text + '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
};
/*
// ========================================================================
=head1 NAME
XML.ObjTree -- XML source code from/to JavaScript object like E4X
=head1 SYNOPSIS
var xotree = new XML.ObjTree();
var tree1 = {
root: {
node: "Hello, World!"
}
};
var xml1 = xotree.writeXML( tree1 ); // object tree to XML source
alert( "xml1: "+xml1 );
var xml2 = '<?xml version="1.0"?><response><error>0</error></response>';
var tree2 = xotree.parseXML( xml2 ); // XML source to object tree
alert( "error: "+tree2.response.error );
=head1 DESCRIPTION
XML.ObjTree class is a parser/generater between XML source code
and JavaScript object like E4X, ECMAScript for XML.
This is a JavaScript version of the XML::TreePP module for Perl.
This also works as a wrapper for XMLHTTPRequest and successor to JKL.ParseXML class
when this is used with prototype.js or JSAN's HTTP.Request class.
=head2 JavaScript object tree format
A sample XML source:
<?xml version="1.0" encoding="UTF-8"?>
<family name="Kawasaki">
<father>Yasuhisa</father>
<mother>Chizuko</mother>
<children>
<girl>Shiori</girl>
<boy>Yusuke</boy>
<boy>Kairi</boy>
</children>
</family>
Its JavaScript object tree like JSON/E4X:
{
'family': {
'-name': 'Kawasaki',
'father': 'Yasuhisa',
'mother': 'Chizuko',
'children': {
'girl': 'Shiori'
'boy': [
'Yusuke',
'Kairi'
]
}
}
};
Each elements are parsed into objects:
tree.family.father; # the father's given name.
Prefix '-' is inserted before every attributes' name.
tree.family["-name"]; # this family's family name
A array is used because this family has two boys.
tree.family.children.boy[0]; # first boy's name
tree.family.children.boy[1]; # second boy's name
tree.family.children.girl; # (girl has no other sisiters)
=head1 METHODS
=head2 xotree = new XML.ObjTree()
This constructor method returns a new XML.ObjTree object.
=head2 xotree.force_array = [ "rdf:li", "item", "-xmlns" ];
This property allows you to specify a list of element names
which should always be forced into an array representation.
The default value is null, it means that context of the elements
will determine to make array or to keep it scalar.
=head2 xotree.attr_prefix = '@';
This property allows you to specify a prefix character which is
inserted before each attribute names.
Instead of default prefix '-', E4X-style prefix '@' is also available.
The default character is '-'.
Or set '@' to access attribute values like E4X, ECMAScript for XML.
The length of attr_prefix must be just one character and not be empty.
=head2 tree = xotree.parseXML( xmlsrc );
This method loads an XML document using the supplied string
and returns its JavaScript object converted.
=head2 tree = xotree.parseDOM( domnode );
This method parses a DOM tree (ex. responseXML.documentElement)
and returns its JavaScript object converted.
=head2 tree = xotree.parseHTTP( url, options );
This method loads a XML file from remote web server
and returns its JavaScript object converted.
XMLHTTPRequest's synchronous mode is always used.
This mode blocks the process until the response is completed.
First argument is a XML file's URL
which must exist in the same domain as parent HTML file's.
Cross-domain loading is not available for security reasons.
Second argument is options' object which can contains some parameters:
method, postBody, parameters, onLoading, etc.
This method requires JSAN's L<HTTP.Request> class or prototype.js's Ajax.Request class.
=head2 xotree.parseHTTP( url, options, callback );
If a callback function is set as third argument,
XMLHTTPRequest's asynchronous mode is used.
This mode calls a callback function with XML file's JavaScript object converted
after the response is completed.
=head2 xmlsrc = xotree.writeXML( tree );
This method parses a JavaScript object tree
and returns its XML source generated.
=head1 EXAMPLES
=head2 Text node and attributes
If a element has both of a text node and attributes
or both of a text node and other child nodes,
text node's value is moved to a special node named "#text".
var xotree = new XML.ObjTree();
var xmlsrc = '<span class="author">Kawasaki Yusuke</span>';
var tree = xotree.parseXML( xmlsrc );
var class = tree.span["-class"]; # attribute
var name = tree.span["#text"]; # text node
=head2 parseHTTP() method with HTTP-GET and sync-mode
HTTP/Request.js or prototype.js must be loaded before calling this method.
var xotree = new XML.ObjTree();
var url = "http://example.com/index.html";
var tree = xotree.parseHTTP( url );
xotree.attr_prefix = '@'; // E4X-style
alert( tree.html["@lang"] );
This code shows C<lang=""> attribute from a X-HTML source code.
=head2 parseHTTP() method with HTTP-POST and async-mode
Third argument is a callback function which is called on onComplete.
var xotree = new XML.ObjTree();
var url = "http://example.com/mt-tb.cgi";
var opts = {
postBody: "title=...&excerpt=...&url=...&blog_name=..."
};
var func = function ( tree ) {
alert( tree.response.error );
};
xotree.parseHTTP( url, opts, func );
This code send a trackback ping and shows its response code.
=head2 Simple RSS reader
This is a RSS reader which loads RDF file and displays all items.
var xotree = new XML.ObjTree();
xotree.force_array = [ "rdf:li", "item" ];
var url = "http://example.com/news-rdf.xml";
var func = function( tree ) {
var elem = document.getElementById("rss_here");
for( var i=0; i<tree["rdf:RDF"].item.length; i++ ) {
var divtag = document.createElement( "div" );
var atag = document.createElement( "a" );
atag.href = tree["rdf:RDF"].item[i].link;
var title = tree["rdf:RDF"].item[i].title;
var tnode = document.createTextNode( title );
atag.appendChild( tnode );
divtag.appendChild( atag );
elem.appendChild( divtag );
}
};
xotree.parseHTTP( url, {}, func );
=head2 XML-RPC using writeXML, prototype.js and parseDOM
If you wish to use prototype.js's Ajax.Request class by yourself:
var xotree = new XML.ObjTree();
var reqtree = {
methodCall: {
methodName: "weblogUpdates.ping",
params: {
param: [
{ value: "Kawa.Net xp top page" }, // 1st param
{ value: "http://www.kawa.net/" } // 2nd param
]
}
}
};
var reqxml = xotree.writeXML( reqtree ); // JS-Object to XML code
var url = "http://example.com/xmlrpc";
var func = function( req ) {
var resdom = req.responseXML.documentElement;
xotree.force_array = [ "member" ];
var restree = xotree.parseDOM( resdom ); // XML-DOM to JS-Object
alert( restree.methodResponse.params.param.value.struct.member[0].value.string );
};
var opt = {
method: "post",
postBody: reqxml,
asynchronous: true,
onComplete: func
};
new Ajax.Request( url, opt );
=head1 AUTHOR
Yusuke Kawasaki http://www.kawa.net/
=head1 COPYRIGHT AND LICENSE
Copyright (c) 2005-2006 Yusuke Kawasaki. All rights reserved.
This program is free software; you can redistribute it and/or
modify it under the Artistic license. Or whatever license I choose,
which I will do instead of keeping this documentation like it is.
=cut
// ========================================================================
*/
+53
View File
@@ -0,0 +1,53 @@
function demo_xml() {
var xml = "<books>\
<book>\
<author>Json</author>\
<title>Json Dev</title>\
<publisher>O'Reilly</publisher>\
</book>\
<book>\
<author>Json</author>\
<title>Podcasting Hacks</title>\
<publisher>O'Reilly</publisher>\
</book>\
</books>";
$('#input').val(xml);
}
function demo_json() {
var json = '{\
"tools": [\
{ "name":"css format" , "site":"http://www.pcjson.com/formatcss/" },\
{ "name":"json format" , "site":"http://www.pcjson.com/json/" },\
{ "name":"hash MD5" , "site":"http://www.pcjson.com/md5/" }\
]\
}';
$('#input').val(json);
}
function xml2json() {
var space = ($("#pretty_json").is(':checked')) ? " " : "";
var xotree = new XML.ObjTree();
var inputdata = $.trim($('#input').val());
var tree = xotree.parseXML(inputdata);
if (!tree.html) {
hightout(JSON.stringify(tree, null, space));
pcjson_com_msg($("#content"), "XML转JSON成功");return false;
} else {
pcjson_com_msg($("#content"), "XML格式错误");return false;
}
}
function json2xml() {
try {
var xotree = new XML.ObjTree();
var inputdata = $.trim($('#input').val());
hightout(xotree.writeXML(JSON.parse(inputdata)));
pcjson_com_msg($("#content"), "JSON转XML成功");return false;
} catch (e) {
pcjson_com_msg($("#content"), "JSON格式错误");return false;
}
}
function Empty() {
document.getElementById("input").value = "";
document.getElementById("output").value = "";
document.getElementById("input").select();
}