9 lines
11 KiB
JavaScript
9 lines
11 KiB
JavaScript
/*
|
|
* Defiant.js v1.2.5
|
|
* Serch JSON structures plus smart templating with XSLT and XPath.
|
|
* http://defiantjs.com
|
|
*
|
|
* Copyright (c) 2013-2015, Hakan Bilgin <hbi@longscript.com>
|
|
* Licensed under the MIT License
|
|
*/
|
|
if("undefined"==typeof module)var module={exports:void 0};if(module.exports=Defiant=function(){"use strict";var a={is_ie:/msie/i.test(navigator.userAgent),is_safari:/safari/i.test(navigator.userAgent),env:"production",xml_decl:'<?xml version="1.0" encoding="utf-8"?>',namespace:'xmlns:d="defiant-namespace"',tabsize:4,render:function(a,b){var c,d,e,f,g=new XSLTProcessor,h=document.createElement("span"),i={match:"/"};switch(typeof a){case"object":this.extend(i,a),i.data||(i.data=b);break;case"string":i.template=a,i.data=b;break;default:throw"error"}if(i.data=JSON.toXML(i.data),c='//xsl:template[@name="'+i.template+'"]',this.xsl_template||this.gatherTemplates(),i.sorter&&(f=this.node.selectSingleNode(this.xsl_template,c+"//xsl:for-each//xsl:sort"),f&&(i.sorter.order&&f.setAttribute("order",i.sorter.order),i.sorter.select&&f.setAttribute("select",i.sorter.select),f.setAttribute("data-type",i.sorter.type||"text"))),e=this.node.selectSingleNode(this.xsl_template,c),e.setAttribute("match",i.match),g.importStylesheet(this.xsl_template),h.appendChild(g.transformToFragment(i.data,document)),e.removeAttribute("match"),this.is_safari){d=h.getElementsByTagName("script");for(var j=0,k=d.length;k>j;j++)d[j].defer=!0}return h.innerHTML},gatherTemplates:function(){for(var a=document.getElementsByTagName("script"),b="",c=0,d=a.length;d>c;c++)"defiant/xsl-template"===a[c].type&&(b+=a[c].innerHTML);this.xsl_template=this.xmlFromString('<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" '+this.namespace+">"+b.replace(/defiant:(\w+)/g,"$1")+"</xsl:stylesheet>")},getSnapshot:function(a){return JSON.toXML(a,!0)},xmlFromString:function(a){var b,c;return a=a.replace(/>\s{1,}</g,"><"),null===a.trim().match(/<\?xml/)&&(a=this.xml_decl+a),this.is_ie?(c=new ActiveXObject("Msxml2.DOMDocument"),c.loadXML(a),-1===a.indexOf("xsl:stylesheet")&&c.setProperty("SelectionLanguage","XPath")):(b=new DOMParser,c=b.parseFromString(a,"text/xml")),c},extend:function(a,b){for(var c in b)a[c]&&"object"==typeof b[c]?this.extend(a[c],b[c]):a[c]=b[c];return a},node:{}};return a}(this),"undefined"==typeof XSLTProcessor){var XSLTProcessor=function(){};XSLTProcessor.prototype={importStylesheet:function(a){this.xsldoc=a},transformToFragment:function(a){var b=a.transformNode(this.xsldoc),c=document.createElement("span");return c.innerHTML=b,c}}}String.prototype.fill||(String.prototype.fill=function(a,b){var c=this;for(b=b||" ";c.length<a;c+=b);return c}),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/gm,"")}),String.prototype.xTransform||(String.prototype.xTransform=function(){var a=this;return-1===this.indexOf("translate(")&&(a=this.replace(/contains\(([^,]+),([^\\)]+)\)/,function(a,b,c){var d="abcdefghijklmnopqrstuvwxyz",e=c.trim().slice(-1);return"contains(translate("+b+", "+e+d.toUpperCase()+e+", "+e+d+e+"),"+c.toLowerCase()+")"})),a.toString()}),"undefined"==typeof JSON&&(window.JSON={parse:function(sJSON){return eval("("+sJSON+")")},stringify:function(a){if(a instanceof Object){var b="";if(a.constructor===Array){for(var c=0;c<a.length;b+=this.stringify(a[c])+",",c++);return"["+b.substr(0,b.length-1)+"]"}if(a.toString!==Object.prototype.toString)return'"'+a.toString().replace(/"/g,"\\$&")+'"';for(var d in a)b+='"'+d.replace(/"/g,"\\$&")+'":'+this.stringify(a[d])+",";return"{"+b.substr(0,b.length-1)+"}"}return"string"==typeof a?'"'+a.replace(/"/g,"\\$&")+'"':String(a)}}),JSON.toXML||(JSON.toXML=function(a,b){"use strict";var c={map:[],rx_validate_name:/^(?!xml)[a-z_][\w\d.:]*$/i,rx_node:/<(.+?)( .*?)>/,rx_constructor:/<(.+?)( d:contr=".*?")>/,rx_namespace:/ xmlns\:d="defiant\-namespace"/,rx_data:/(<.+?>)(.*?)(<\/d:data>)/i,rx_function:/function (\w+)/i,to_xml:function(a){var b=this.hash_to_xml(null,a);return Defiant.xmlFromString(b)},hash_to_xml:function(a,b,c){var d,e,f,g,h,i,j,k,l=b.constructor===Array,m=[],n=[];for(d in b)if(e=b[d],(null===e||void 0===e||"NaN"===e.toString())&&(e=null),g="@"===d.slice(0,1),h=c?a:d,h==+h&&b.constructor!==Object&&(h="d:item"),null===e?(i=null,j=!1):(i=e.constructor,j=i.toString().match(this.rx_function)[1]),g)n.push(h.slice(1)+'="'+this.escape_xml(e)+'"'),"String"!==j&&n.push("d:"+h.slice(1)+'="'+j+'"');else if(null===e)m.push(this.scalar_to_xml(h,e));else switch(i){case Function:break;case Object:m.push(this.hash_to_xml(h,e));break;case Array:if(d===h){if(f=e.constructor===Array)for(k=e.length;k--;)e[k].constructor===Array&&(f=!0),f||e[k].constructor!==Object||(f=!0);m.push(this.scalar_to_xml(h,e,f));break}case String:if("string"==typeof e&&(e=e.toString().replace(/\&/g,"&").replace(/\r|\n/g," ")),"#text"===h){this.map.push(b),n.push('d:mi="'+this.map.length+'"'),n.push('d:constr="'+j+'"'),m.push(this.escape_xml(e));break}case Number:case Boolean:if("#text"===h&&"String"!==j){this.map.push(b),n.push('d:mi="'+this.map.length+'"'),n.push('d:constr="'+j+'"'),m.push(this.escape_xml(e));break}m.push(this.scalar_to_xml(h,e))}return a||(a="d:data",n.push(Defiant.namespace),l&&n.push('d:constr="Array"')),null===a.match(this.rx_validate_name)&&(n.push('d:name="'+a+'"'),a="d:name"),c?m.join(""):(this.map.push(b),n.push('d:mi="'+this.map.length+'"'),"<"+a+(n.length?" "+n.join(" "):"")+(m.length?">"+m.join("")+"</"+a+">":"/>"))},scalar_to_xml:function(a,b,c){var d,e,f,g="";if(null===a.match(this.rx_validate_name)&&(g+=' d:name="'+a+'"',a="d:name",c=!1),(null===b||"NaN"===b.toString())&&(b=null),null===b)return"<"+a+' d:constr="null"/>';if(1===b.length&&b[0].constructor===Object){d=this.hash_to_xml(!1,b[0]);var h=d.match(this.rx_node),i=d.match(this.rx_constructor);return h=null!==h?h[2].replace(this.rx_namespace,"").replace(/>/,"").replace(/"\/$/,'"'):"",i=null!==i?i[2]:"",d=d.match(this.rx_data),d=null!==d?d[2]:"","<"+a+h+" "+i+' d:type="ArrayItem">'+d+"</"+a+">"}return 0===b.length&&b.constructor===Array?"<"+a+' d:constr="Array"/>':c?this.hash_to_xml(a,b,!0):(e=b.constructor,f=e.toString().match(this.rx_function)[1],d=e===Array?this.hash_to_xml("d:item",b,!0):this.escape_xml(b),g+=' d:constr="'+f+'"',this.map.push(b),g+=' d:mi="'+this.map.length+'"',"#text"===a?this.escape_xml(b):"<"+a+g+">"+d+"</"+a+">")},escape_xml:function(a){return String(a).replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/ /g," ")}},d=c.to_xml.call(c,a);return b?{doc:d,src:a,map:c.map}:(this.search.map=c.map,d)}),JSON.search||(JSON.search=function(a,b,c){"use strict";var d,e,f=a.doc&&a.doc.nodeType,g=f?a.doc:JSON.toXML(a),h=f?a.map:this.search.map,i=f?a.src:a,j=Defiant.node[c?"selectSingleNode":"selectNodes"](g,b.xTransform()),k=[];for(c&&(j=[j]),e=j.length;e--;)switch(j[e].nodeType){case 2:case 3:k.unshift(j[e].nodeValue);break;default:d=+j[e].getAttribute("d:mi"),h[d-1]&&k.unshift(h[d-1])}return"development"===Defiant.env&&(this.trace=JSON.mtrace(i,k,j)),k}),JSON.mtrace||(JSON.mtrace=function(a,b,c){"use strict";for(var d,e,f,g,h,i=window,j=JSON.stringify,k=j(a,null," ").replace(/\t/g,""),l=[],m=0,n=c.length,o=n?c[m].ownerDocument.documentElement:!1,p=(this.search.map,0);n>m;m++){switch(c[m].nodeType){case 2:e=c[m].ownerElement?c[m].ownerElement.getAttribute("d:"+c[m].nodeName):"String",d='"@'+c[m].nodeName+'": '+i[e](b[m]),f=k.indexOf(d),h=0;break;case 3:e=c[m].parentNode.getAttribute("d:constr"),d=i[e](b[m]),d='"'+c[m].parentNode.nodeName+'": '+("Number"===d?d:'"'+d+'"'),f=k.indexOf(d),h=0;break;default:if(c[m]===o)continue;"String"===c[m].getAttribute("d:constr")?(e=c[m].getAttribute("d:constr"),d=i[e](b[m]),d='"'+c[m].nodeName+'": '+("Number"===d?d:'"'+d+'"'),f=k.indexOf(d,p),h=0,p=f+1):(d=j(b[m],null," ").replace(/\t/g,""),f=k.indexOf(d),h=d.match(/\n/g).length)}g=k.substring(0,f).match(/\n/g).length+1,l.push([g,h])}return l}),Defiant.node.selectNodes=function(a,b){if(a.evaluate){for(var c=a.createNSResolver(a.documentElement),d=a.evaluate(b,a,c,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null),e=[],f=0,g=d.snapshotLength;g>f;f++)e.push(d.snapshotItem(f));return e}return a.selectNodes(b)},Defiant.node.selectSingleNode=function(a,b){if(a.evaluate){var c=this.selectNodes(a,b);return c.length>0?c[0]:null}return a.selectSingleNode(b)},Defiant.node.prettyPrint=function(a){var b,c,d=Defiant,e=d.tabsize,f=d.xml_decl.toLowerCase();d.is_ie?c=a.xml:(b=new XMLSerializer,c=b.serializeToString(a)),"development"!==d.env&&(c=c.replace(/ \w+\:d=".*?"| d\:\w+=".*?"/g,""));for(var g,h,i=c.trim().replace(/(>)\s*(<)(\/*)/g,"$1\n$2$3"),j=i.split("\n"),k=-1,l=0,m=j.length;m>l;l++)(0!==l||j[l].toLowerCase()!==f)&&(g=null!==j[l].match(/<[A-Za-z_\:]+.*?>/g),h=null!==j[l].match(/<\/[\w\:]+>/g),null!==j[l].match(/<.*?\/>/g)&&(g=h=!0),g&&k++,j[l]=String().fill(k," ")+j[l],g&&h&&k--,!g&&h&&k--);return j.join("\n").replace(/\t/g,String().fill(e," "))},Defiant.node.toJSON=function(a,b){"use strict";var c=function(a){var b,d,e,f,g,h,i,j,k,l,m={},n=window;switch(a.nodeType){case 1:for(g=a.getAttribute("d:constr"),"Array"===g?m=[]:"String"===g&&""===a.textContent&&(m=""),b=a.attributes,j=0,k=b.length;k>j;j++)l=b.item(j),null===l.nodeName.match(/\:d|d\:/g)&&(g=a.getAttribute("d:"+l.nodeName),h=g&&"undefined"!==g?"null"===l.nodeValue?null:n[g]("false"===l.nodeValue?"":l.nodeValue):l.nodeValue,m["@"+l.nodeName]=h);break;case 3:d=a.parentNode.getAttribute("d:type"),h=d?n[d]("false"===a.nodeValue?"":a.nodeValue):a.nodeValue,m=h}if(a.hasChildNodes())for(j=0,k=a.childNodes.length;k>j;j++)if(e=a.childNodes.item(j),f=e.nodeName,b=a.attributes,"d:name"===f&&(f=e.getAttribute("d:name")),"#text"===f)g=a.getAttribute("d:constr"),"undefined"===g&&(g=void 0),i=e.textContent||e.text,h="Boolean"===g&&"false"===i?"":i,g||b.length?g&&1===k?m=n[g](h):a.hasChildNodes()&&b.length<3?m=g?n[g](h):h:m[f]=g?n[g](h):h:m=h;else{if(m[f]){m[f].push?m[f].push(c(e)):m[f]=[m[f],c(e)];continue}switch(g=e.getAttribute("d:constr")){case"null":m.push?m.push(null):m[f]=null;break;case"Array":e.parentNode.firstChild===e&&"Array"===g&&"d:item"!==f?"d:item"===f||"Array"===g?(h=c(e),m[f]=h.length?[h]:h):m[f]=c(e):m.push?m.push(c(e)):m[f]=c(e);break;case"String":case"Number":case"Boolean":i=e.textContent||e.text,h="Boolean"===g&&"false"===i?"":i,m.push?m.push(n[g](h)):m[f]=c(e);break;default:m.push?m.push(c(e)):m[f]=c(e)}}return 1===a.nodeType&&"ArrayItem"===a.getAttribute("d:type")&&(m=[m]),m},d=9===a.nodeType?a.documentElement:a,e=c(d),f=e[d.nodeName];return d===d.ownerDocument.documentElement&&f&&f.constructor===Array&&(e=f),b&&"true"===b.toString()&&(b=" "),b?JSON.stringify(e,null,b):e},"undefined"!=typeof jQuery&&!function(a){"use strict";a.fn.defiant=function(a,b){return this.html(Defiant.render(a,b)),this}}(jQuery); |