UNPKG

liberty-prettydiff

Version:

Language aware code comparison tool for several web based languages. It also beautifies, minifies, and a few other things.

1,190 lines (1,184 loc) 446 kB
/*prettydiff.com topcoms: true, inchar: " ", insize: 4, vertical: true */ /*global ace, ActiveXObject, ArrayBuffer, AudioContext, console, document, FileReader, global, localStorage, location, navigator, setTimeout, Uint8Array, window, XMLHttpRequest*/ /*jshint laxbreak: true*/ /*jslint for: true, this: true*/ /*********************************************************************** This is written by Austin Cheney on 3 Mar 2009. Anybody may use this code without permission so long as this comment exists verbatim in each instance of its use. http: //mailmarkup.org/ http: //prettydiff.com/ ***********************************************************************/ global.prettydiff.meta = { error: "", lang: ["", "", ""], time: "", insize: 0, outsize: 0, difftotal: 0, difflines: 0 }; (function dom__init() { "use strict"; var pd = global.prettydiff.pd, load = function dom__load_init() { return; }, loadPrep = function dom__loadPrep() { pd.data.node = { announce : pd.id("announcement"), beau : pd.id("Beautify"), beauOps : pd.id("beauops"), codeBeauIn : pd.id("beautyinput"), codeBeauOut : pd.id("beautyoutput"), codeDiffBase: pd.id("baseText"), codeDiffNew : pd.id("newText"), codeMinnIn : pd.id("minifyinput"), codeMinnOut : pd.id("minifyoutput"), codeParsIn : pd.id("parseinput"), codeParsOut : pd.id("parseoutput"), comment : pd.id("option_comment"), diffBase : pd.id("diffBase"), diffNew : pd.id("diffNew"), diffOps : pd.id("diffops"), headline : pd.id("headline"), jsscope : pd.id("jsscope-yes"), lang : pd.id("language"), langdefault : pd.id("lang-default"), maxInputs : pd.id("hideOptions"), minn : pd.id("Minify"), minnOps : pd.id("miniops"), modeBeau : pd.id("modebeautify"), modeDiff : pd.id("modediff"), modeMinn : pd.id("modeminify"), modePars : pd.id("modeparse"), page : (function dom__dataPage() { var divs = document.getElementsByTagName("div"); if (divs.length === 0) { return null; } return divs[0]; }()), pars : pd.id("Parse"), parsOps : pd.id("parseops"), report : { code: { box: pd.id("codereport") }, feed: { box: pd.id("feedreport") }, stat: { box: pd.id("statreport") } }, save : pd.id("diff-save") }; load(); }; if (location.href.indexOf("codemirror=") > 0) { (function dom__codemirror() { var loc = location .href .split("codemirror="), value = "", address = ""; if (loc[1].indexOf("&") > 0) { value = loc[1].slice(0, loc[1].indexOf("&")); address = loc[0] + loc[1].slice(loc[1].indexOf("&") + 1); } else { value = loc[1]; address = loc[0]; } if (address.indexOf("?ace=") > 0 || address.indexOf("&ace=") > 0) { if (address.charAt(address.length - 1) === "&") { return location.replace(address.slice(0, address.length - 1)); } return location.replace(address); } if (address.indexOf("?&") > 0) { return location.replace(address.replace("?&", "?ace=" + value + "&")); } if (address.indexOf("&&") > 0) { return location.replace(address.replace("&&", "&ace=" + value + "&")); } return location.replace(address + "ace=" + value); }()); } pd.id = function dom__id(x) { if (document.getElementById === undefined) { return; } return document.getElementById(x); }; //namespace to test for web browser features for progressive enhancement pd.test = { // accessibility analysis is locked behind a flag, this param will bypass the // flag accessibility : (location.href.toLowerCase().indexOf("accessibility=true") > 0), //delect if Ace Code Editor is supported ace : (location.href.toLowerCase().indexOf("ace=false") < 0 && typeof ace === "object"), //get the lowercase useragent string agent : (typeof navigator === "object") ? navigator .userAgent .toLowerCase() : "", //test for standard web audio support audio : ((typeof AudioContext === "function" || typeof AudioContext === "object") && AudioContext !== null) ? new AudioContext() : null, //delays the toggling of pd.test.load to false for asynchronous code sources delayExecution: false, //am I served from the Pretty Diff domain domain : (location.href.indexOf("prettydiff.com") < 15 && location.href.indexOf("prettydiff.com") > -1), //If the output is too large the report must open and minimize in a single step filled : { code: false, feed: false, stat: false }, //test for support of the file api fs : (typeof FileReader === "function"), //check for native JSON support json : (JSON !== undefined), // stores keypress state to avoid execution of pd.event.recycle from certain key // combinations keypress : false, keysequence : [], // supplement to ensure keypress is returned to false only after other keys // other than ctrl are released keystore : [], //some operations should not occur as the page is initially loading load : true, //test for localStorage and assign the result of the test ls : (typeof localStorage === "object" && localStorage !== null && typeof localStorage.getItem === "function" && typeof localStorage.hasOwnProperty === "function"), // Ace will only render correctly if the parent container is visible, this test // solves for this problem render : { anal: false, beau: false, diff: false, minn: false, pars: false }, //supplies alternate keyboard navigation to editable text areas tabesc : [], //check of native AJAX support xhr : (typeof XMLHttpRequest === "function" || typeof XMLHttpRequest === "object" || typeof ActiveXObject === "function") }; if (pd.test.agent.indexOf("msie 8.0;") > 0) { document.getElementsByTagName("body")[0].innerHTML = "<h1>Pretty Diff</h1> <p>Sorry, but Pretty Diff no longer supports IE8. <a href='" + "http://www.microsoft.com/en-us/download/internet-explorer.aspx'>Please upgrade</"; return; } //namespace for data points and dom nodes pd.data = { announcetext : "", audio : {}, builder : {}, color : "white", //for use with HTML themes commentString: [], diff : "", html : [], langvalue : [], mode : "diff", node : { anal : pd.id("Analysis"), analOps : pd.id("analysisops"), announce : pd.id("announcement"), beau : pd.id("Beautify"), beauOps : pd.id("beauops"), codeAnalIn : pd.id("analysisinput"), codeAnalOut : pd.id("analysisoutput"), codeBeauIn : pd.id("beautyinput"), codeBeauOut : pd.id("beautyoutput"), codeDiffBase: pd.id("baseText"), codeDiffNew : pd.id("newText"), codeMinnIn : pd.id("minifyinput"), codeMinnOut : pd.id("minifyoutput"), codeParsIn : pd.id("parseinput"), codeParsOut : pd.id("parseoutput"), comment : pd.id("option_comment"), diffBase : pd.id("diffBase"), diffNew : pd.id("diffNew"), diffOps : pd.id("diffops"), headline : pd.id("headline"), jsscope : pd.id("jsscope-yes"), lang : pd.id("language"), langdefault : pd.id("lang-default"), maxInputs : pd.id("hideOptions"), minn : pd.id("Minify"), minnOps : pd.id("miniops"), modeBeau : pd.id("modebeautify"), modeDiff : pd.id("modediff"), modeMinn : pd.id("modeminify"), modePars : pd.id("modeparse"), modeAnal : pd.id("modeanalysis"), page : (function dom__dataPage() { var divs = document.getElementsByTagName("div"); if (divs.length === 0) { return null; } return divs[0]; }()), pars : pd.id("Parse"), parsOps : pd.id("parseops"), report : { code: { box: pd.id("codereport") }, feed: { box: pd.id("feedreport") }, stat: { box: pd.id("statreport") } }, save : pd.id("diff-save") }, settings : {}, source : "", sourceLength : { anal : 0, beau : 0, diffBase: 0, diffNew : 0, minn : 0, pars : 0 }, stat : { avday : 1, anal : 0, beau : 0, css : 0, csv : 0, diff : 0, fdate : 0, js : 0, large : 0, markup: 0, minn : 0, pars : 0, pdate : "", text : 0, usage : 0, useday: 0, visit : 0 }, tabtrue : false, zIndex : 10 }; if (typeof global.prettydiff.finalFile === "object") { pd.data.finalFile = global.prettydiff.finalFile; } //namespace for Ace editors pd.ace = {}; //namespace for internal functions pd.app = { //builds the Ace editors aceApply : function dom__app_aceApply(nodeName, className, maxWidth) { var div = document.createElement("div"), span = document.createElement("span"), node = pd.data.node[nodeName], parent = node.parentNode.parentNode, attributes = node.attributes, len = attributes.length, a = 0, edit = {}, dollar = "$"; for (a = 0; a < len; a += 1) { if (attributes[a].name !== "rows" && attributes[a].name !== "cols" && attributes[a].name !== "wrap") { div.setAttribute(attributes[a].name, attributes[a].value); } } parent.appendChild(div); if (className === "output") { span.setAttribute("class", "clear"); parent.appendChild(span); } parent.removeChild(node.parentNode); div.setAttribute("class", className); if (maxWidth === true) { div.style.width = "100%"; } div.style.fontSize = "1.4em"; edit = ace.edit(div); pd.data.node[nodeName] = div.getElementsByTagName("textarea")[0]; edit[dollar + "blockScrolling"] = Infinity; return edit; }, // Readjusts the heights of the editors to compensate for various changes to the // interface, like screen resize fixHeight: function dom__app_fixHeight() { var baseText = pd.id("baseText"), newText = pd.id("newText"), beauIn = pd.id("beautyinput"), beauOut = pd.id("beautyoutput"), minnIn = pd.id("minifyinput"), minnOut = pd.id("minifyoutput"), parsIn = pd.id("parseinput"), parsOut = pd.id("parseoutput"), analIn = pd.id("analysisinput"), analOut = pd.id("analysisoutput"), math = 0, height = window.innerHeight || document.getElementsByTagName("body")[0].clientHeight, headline = 0; if (pd.data.node.headline !== null && pd.data.node.headline.style.display === "block") { headline = 3.8; } if (pd.test.ace === true) { if (baseText !== null && newText !== null) { math = (height / 14) - (16.5 + headline); baseText.style.height = math + "em"; newText.style.height = math + "em"; pd .ace .diffBase .setStyle("height:" + math + "em"); pd .ace .diffNew .setStyle("height:" + math + "em"); pd .ace .diffBase .resize(); pd .ace .diffNew .resize(); } math = (height / 14) - (14.31 + headline); if (pd.data.node.codeBeauIn !== null) { beauIn.style.height = math + "em"; pd .ace .beauIn .setStyle("height:" + math + "em"); pd .ace .beauIn .resize(); } if (pd.data.node.codeMinnIn !== null) { minnIn.style.height = math + "em"; pd .ace .minnIn .setStyle("height:" + math + "em"); pd .ace .minnIn .resize(); } if (pd.data.node.codeParsIn !== null) { parsIn.style.height = math + "em"; pd .ace .parsIn .setStyle("height:" + math + "em"); pd .ace .parsIn .resize(); } if (pd.data.node.codeAnalIn !== null) { analIn.style.height = math + "em"; pd .ace .analIn .setStyle("height:" + math + "em"); pd .ace .analIn .resize(); } if (pd.data.node.codeBeauOut !== null) { beauOut.style.height = math + "em"; pd .ace .beauOut .setStyle("height:" + math + "em"); pd .ace .beauOut .resize(); } if (pd.data.node.codeMinnOut !== null) { minnOut.style.height = math + "em"; pd .ace .minnOut .setStyle("height:" + math + "em"); pd .ace .minnOut .resize(); } if (pd.data.node.codeParsOut !== null) { parsOut.style.height = math + "em"; pd .ace .parsOut .setStyle("height:" + math + "em"); pd .ace .parsOut .resize(); } if (pd.data.node.codeAnalOut !== null) { analOut.style.height = math + "em"; pd .ace .analOut .setStyle("height:" + math + "em"); pd .ace .analOut .resize(); } } else { if (baseText !== null && newText !== null) { math = (height / 14.4) - (16.25 + headline); baseText.style.height = math + "em"; newText.style.height = math + "em"; } math = (height / 14.4) - (15.425 + headline); if (pd.data.node.codeBeauIn !== null) { pd.data.node.codeBeauIn.style.height = math + "em"; } if (pd.data.node.codeMinnIn !== null) { pd.data.node.codeMinnIn.style.height = math + "em"; } if (pd.data.node.codeParsIn !== null) { pd.data.node.codeParsIn.style.height = math + "em"; } if (pd.data.node.codeAnalIn !== null) { pd.data.node.codeAnalIn.style.height = math + "em"; } if (pd.data.node.codeBeauOut !== null) { pd.data.node.codeBeauOut.style.height = math + "em"; } if (pd.data.node.codeMinnOut !== null) { pd.data.node.codeMinnOut.style.height = math + "em"; } if (pd.data.node.codeParsOut !== null) { pd.data.node.codeParsOut.style.height = math + "em"; } if (pd.data.node.codeAnalOut !== null) { pd.data.node.codeAnalOut.style.height = math + "em"; } } }, //sets indentation size in Ace editors insize : function dom__app_insize() { var that = this, value = Number(that.value); if (that === pd.id("diff-quan")) { if (pd.data.node.codeDiffBase !== null) { pd .ace .diffBase .getSession() .setTabSize(value); } if (pd.data.node.codeDiffNew !== null) { pd .ace .diffNew .getSession() .setTabSize(value); } } else if (that === pd.id("beau-quan")) { if (pd.data.node.codeBeauIn !== null) { pd .ace .beauIn .getSession() .setTabSize(value); } if (pd.data.node.codeBeauOut !== null) { pd .ace .beauOut .getSession() .setTabSize(value); } } else if (that === pd.id("minn-quan")) { if (pd.data.node.codeMinnIn !== null) { pd .ace .minnIn .getSession() .setTabSize(value); } if (pd.data.node.codeMinnOut !== null) { pd .ace .minnOut .getSession() .setTabSize(value); } } else if (that === pd.id("pars-quan")) { if (pd.data.node.codeMinnIn !== null) { pd .ace .minnIn .getSession() .setTabSize(value); } if (pd.data.node.codeMinnOut !== null) { pd .ace .minnOut .getSession() .setTabSize(value); } } }, // determine the specific language if auto or unknown all - change all language // modes? comes from pd.codeops, which is fired on change of language // select list obj - the ace obj passed in. {} empty object if `all` is true // lang - a language passed in. "" empty string means auto detect langkey : function dom__app_langkey(all, obj, lang) { var value = [], sample = "", auto = function () { return; }, setlangmode = function () { return; }, nameproper = function () { return; }, language = global.prettydiff.language, // defaultt = actual default lang value from the select list defaultt = ""; if (typeof language !== "object") { return; } auto = language.auto; setlangmode = language.setlangmode; nameproper = language.nameproper; defaultt = (pd.data.node.langdefault === null || pd.data.node.langdefault.nodeName.toLowerCase() !== "select") ? "javascript" : setlangmode(pd.data.node.langdefault[pd.data.node.langdefault.selectedIndex].value); if (obj !== undefined && obj !== null) { if (pd.test.ace === true && obj.getValue !== undefined) { sample = obj.getValue(); if (sample.indexOf("http") === 0 || sample.indexOf("file:///") === 0) { if (obj === pd.ace.diffNew) { sample = pd.data.diff; } else { sample = pd.data.source; } } } else if (typeof obj.value === "string") { sample = obj.value; } } if (pd.data.node.lang !== null && pd.data.node.lang.selectedIndex > 0) { all = true; lang = pd.data.node.lang[pd.data.node.lang.selectedIndex].value; } if (lang === "csv") { pd.data.langvalue = ["plain_text", "csv", "CSV"]; } else if (lang === "text") { pd.data.langvalue = ["plain_text", "text", "Plain Text"]; } else if (lang !== "") { pd.data.langvalue = [lang, setlangmode(lang), nameproper(lang)]; } else if (sample !== "" || pd.test.ace === false) { pd.data.langvalue = auto(sample, defaultt); } else { pd.data.langvalue = [defaultt, setlangmode(defaultt), nameproper(defaultt)]; } value = pd.data.langvalue; if (pd.test.ace === true) { if (all === true || pd.data.mode === "anal") { if (all === true && lang === "") { value = auto(pd.ace.analIn.getValue(), defaultt); pd.data.langvalue = value; } if (value[0] === "tss") { value[0] = "javascript"; } else if (value[0] === "dustjs") { value[0] = "html"; } else if (value[0] === "markup") { value[0] = "xml"; } if (pd.data.node.codeAnalIn !== null) { pd .ace .analIn .getSession() .setMode("ace/mode/" + value[0]); } if (pd.data.node.codeAnalOut !== null) { pd .ace .analOut .getSession() .setMode("ace/mode/" + value[0]); } } if (all === true || pd.data.mode === "beau") { if (all === true && lang === "") { value = auto(pd.ace.beauIn.getValue(), defaultt); pd.data.langvalue = value; } if (value[0] === "tss") { value[0] = "javascript"; } else if (value[0] === "dustjs") { value[0] = "html"; } else if (value[0] === "markup") { value[0] = "xml"; } if (pd.data.node.codeBeauIn !== null) { pd .ace .beauIn .getSession() .setMode("ace/mode/" + value[0]); } if (pd.data.node.codeBeauOut !== null) { pd .ace .beauOut .getSession() .setMode("ace/mode/" + value[0]); } } if (all === true || pd.data.mode === "minn") { if (all === true && lang === "") { value = auto(pd.ace.minnIn.getValue(), defaultt); pd.data.langvalue = value; } if (value[0] === "tss") { value[0] = "javascript"; } else if (value[0] === "dustjs") { value[0] = "html"; } else if (value[0] === "markup") { value[0] = "xml"; } if (pd.data.node.codeMinnIn !== null) { pd .ace .minnIn .getSession() .setMode("ace/mode/" + value[0]); } if (pd.data.node.codeMinnOut !== null) { pd .ace .minnOut .getSession() .setMode("ace/mode/" + value[0]); } } if (all === true || pd.data.mode === "pars") { if (all === true && lang === "") { value = auto(pd.ace.parsIn.getValue(), defaultt); pd.data.langvalue = value; } if (value[0] === "tss") { value[0] = "javascript"; } else if (value[0] === "dustjs") { value[0] = "html"; } else if (value[0] === "markup") { value[0] = "xml"; } if (pd.data.node.codeParsIn !== null) { pd .ace .parsIn .getSession() .setMode("ace/mode/" + value[0]); } if (pd.data.node.codeParsOut !== null) { pd .ace .parsOut .getSession() .setMode("ace/mode/" + value[0]); } } if (all === true || pd.data.mode === "diff") { if (all === true && lang === "") { value = auto(pd.ace.diffBase.getValue(), defaultt); pd.data.langvalue = value; } if (value[0] === "tss") { value[0] = "javascript"; } else if (value[0] === "dustjs") { value[0] = "html"; } else if (value[0] === "markup") { value[0] = "xml"; } if (pd.data.node.codeDiffBase !== null) { pd .ace .diffBase .getSession() .setMode("ace/mode/" + value[0]); } if (pd.data.node.codeDiffNew !== null) { pd .ace .diffNew .getSession() .setMode("ace/mode/" + value[0]); } } } if (all === true && lang !== "") { return value[1]; } if (value.length < 1 && lang === "") { if (pd.data.mode === "beau" && pd.data.node.codeBeauIn !== null) { value = auto(pd.data.node.codeBeauIn.value, defaultt); } else if (pd.data.mode === "minn" && pd.data.node.codeMinnIn !== null) { value = auto(pd.data.node.codeMinnIn.value, defaultt); } else if (pd.data.mode === "pars" && pd.data.node.codeParsIn !== null) { value = auto(pd.data.node.codeParsIn.value, defaultt); } else { if (pd.data.node.codeDiffBase !== null) { value = auto(pd.data.node.codeDiffBase.value, defaultt); } else if (pd.data.node.codeDiffNew !== null) { value = auto(pd.data.node.codeDiffNew.value, defaultt); } } if (value.length < 1) { return "javascript"; } pd.data.langvalue = value; } if (lang === "text") { return "text"; } if (lang !== "") { return setlangmode(lang); } return pd.data.langvalue[1]; }, //store tool changes into localStorage to maintain state options : function dom__app_options(x) { var item = {}, node = "", name = "", type = "", id = "", classy = "", h3 = {}, body = {}; if (x !== undefined && x.nodeType === 1) { if (x.nodeName.toLowerCase() === "input" || x.nodeName.toLowerCase() === "select" || x.nodeName.toLowerCase() === "div") { item = x; } else { item = x.getElementsByTagName("input")[0]; if (item === undefined) { return; } } } else if (this.nodeName.toLowerCase() === "input" || this.nodeName.toLowerCase() === "select" || this.nodeName.toLowerCase() === "div") { item = this; } else { item = this.getElementsByTagName("input")[0]; } if (item.nodeType !== 1) { return; } if (item.nodeName.toLowerCase() !== "div" && pd.test.load === false && item !== pd.data.node.lang) { item.focus(); } node = item .nodeName .toLowerCase(); name = item.getAttribute("name"); type = item.getAttribute("type"); id = item.getAttribute("id"); classy = item.getAttribute("class"); if (pd.test.load === true) { return; } if (node === "input") { if (type === "radio") { if (id === "beau-other") { pd.data.settings.beauchar = pd .id("beau-char") .value; } else { pd.data.settings[name] = id; } if (id === "diff-other") { pd.data.settings.diffchar = pd .id("diff-char") .value; } else { pd.data.settings[name] = id; } } else if (type === "text") { if (id === "beau-char") { pd.data.settings.beauchar = item.value; } else if (id === "diff-char") { pd.data.settings.diffchar = item.value; } else { pd.data.settings[id] = item.value; } } } else if (node === "select") { pd.data.settings[id] = item.selectedIndex; } else if (node === "div" && classy === "box") { h3 = item.getElementsByTagName("h3")[0]; body = item.getElementsByTagName("div")[0]; if (pd.data.settings[id] === undefined) { pd.data.settings[id] = {}; } if (body.style.display === "none" && h3.clientWidth < 175) { pd.data.settings[id].min = true; pd.data.settings[id].max = false; } else if (pd.data.settings[id].max === false || pd.data.settings[id].max === undefined) { pd.data.settings[id].min = false; pd.data.settings[id].left = item.offsetLeft; pd.data.settings[id].top = item.offsetTop; if (pd.test.agent.indexOf("macintosh") > 0) { pd.data.settings[id].width = (body.clientWidth - 20); pd.data.settings[id].height = (body.clientHeight - 53); } else { pd.data.settings[id].width = (body.clientWidth - 4); pd.data.settings[id].height = (body.clientHeight - 36); } } } else if (node === "button" && id !== null) { pd.data.settings[id] = item .innerHTML .replace(/\s+/g, " "); } if (pd.test.json === true && pd.test.ls === true) { localStorage.settings = JSON.stringify(pd.data.settings); } if (pd.data.node.comment !== null && id !== null) { if (item.nodeName.toLowerCase() === "select") { node = item[item.selectedIndex].value; } else { node = item.value; } pd.data.commentString = global.prettydiff.options.functions.domops(id, node, pd.data.commentString); if (pd.data.node.comment !== null) { if (pd.data.commentString.length === 0) { pd.data.node.comment.innerHTML = "/*prettydiff.com */"; } else if (pd.data.commentString.length === 1) { pd.data.node.comment.innerHTML = "/*prettydiff.com " + pd .data .commentString[0] .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;") .replace(/api\./g, "") + " */"; } else { pd.data.node.comment.innerHTML = "/*prettydiff.com " + pd .data .commentString .join(", ") .replace(/&/g, "&amp;") .replace(/</g, "&lt;") .replace(/>/g, "&gt;") .replace(/api\./g, "") + " */"; } } if (pd.test.ls === true && pd.test.json === true) { localStorage.commentString = JSON .stringify(pd.data.commentString) .replace(/api\./g, ""); } } }, //intelligently raise the z-index of the report windows zTop : function dom__app_top(x) { var indexListed = pd.data.zIndex, indexes = [ (pd.data.node.report.feed.box === null) ? 0 : Number(pd.data.node.report.feed.box.style.zIndex), (pd.data.node.report.code.box === null) ? 0 : Number(pd.data.node.report.code.box.style.zIndex), (pd.data.node.report.stat.box === null) ? 0 : Number(pd.data.node.report.stat.box.style.zIndex) ], indexMax = Math.max(indexListed, indexes[0], indexes[1], indexes[2]) + 1; if (indexMax < 11) { indexMax = 11; } pd.data.zIndex = indexMax; if (x.nodeType === 1) { x.style.zIndex = indexMax; } } }; //namespace for event handlers pd.event = { //fixing areaTabOut in the case of unintentional back tabs areaShiftUp : function dom__event_areaShiftUp(e) { var event = e || window.event; if (event.keyCode === 16 && pd.test.tabesc.length > 0) { pd.test.tabesc = []; } if (event.keyCode === 17 || event.keyCode === 224) { pd.data.tabtrue = true; } }, //allows visual folding of function in the JSPretty jsscope HTML output beaufold : function dom__event_beaufold() { var self = this, title = self .getAttribute("title") .split("line "), min = Number(title[1].substr(0, title[1].indexOf(" "))), max = Number(title[2]), a = 0, b = "", list = [ self .parentNode .getElementsByTagName("li"), self .parentNode .nextSibling .getElementsByTagName("li") ]; if (self.innerHTML.charAt(0) === "-") { for (a = min; a < max; a += 1) { list[0][a].style.display = "none"; list[1][a].style.display = "none"; } self.innerHTML = "+" + self .innerHTML .substr(1); } else { for (a = min; a < max; a += 1) { list[0][a].style.display = "block"; list[1][a].style.display = "block"; if (list[0][a].getAttribute("class") === "fold" && list[0][a].innerHTML.charAt(0) === "+") { b = list[0][a].getAttribute("title"); b = b.substring(b.indexOf("to line ") + 1); a = Number(b) - 1; } } self.innerHTML = "-" + self .innerHTML .substr(1); } }, //clears the Pretty Diff comment string clearComment : function dom__event_clearComment() { localStorage.commentString = "[]"; pd.data.commentString = []; if (pd.data.node.comment !== null) { pd.data.node.comment.innerHTML = "/*prettydiff.com */"; } }, //change the color scheme of the web UI colorScheme : function dom__event_colorScheme(node) { var x = (node !== undefined && node.nodeType === 1) ? node : this, option = x.getElementsByTagName("option"), optionLen = option.length, index = (function dom__event_colorScheme_indexLen() { if (x.selectedIndex < 0 || x.selectedIndex > optionLen) { x.selectedIndex = optionLen - 1; return optionLen - 1; } return x.selectedIndex; }()), color = option[index] .innerHTML .toLowerCase() .replace(/\s+/g, ""), theme = "", logoColor = "", logo = pd.id("pdlogo"); document .getElementsByTagName("body")[0] .setAttribute("class", color); if (pd.test.ace === true) { if (color === "white") { theme = "ace/theme/textmate"; } if (color === "shadow") { theme = "ace/theme/idle_fingers"; } if (color === "canvas") { theme = "ace/theme/canvas"; } pd .ace .diffBase .setTheme(theme); pd .ace .diffNew .setTheme(theme); pd .ace .beauIn .setTheme(theme); pd .ace .beauOut .setTheme(theme); pd .ace .minnIn .setTheme(theme); pd .ace .minnOut .setTheme(theme); pd .ace .parsIn .setTheme(theme); pd .ace .parsOut .setTheme(theme); pd .ace .analIn .setTheme(theme); pd .ace .analOut .setTheme(theme); } pd.data.color = color; if (logo !== null) { if (color === "canvas") { logoColor = "664"; } else if (color === "shadow") { logoColor = "999"; } else { logoColor = "666"; } logo.style.borderColor = "#" + logoColor; logo .getElementsByTagName("g")[0] .setAttribute("fill", "#" + logoColor); } if (pd.test.load === false) { pd .app .options(x); } }, // allows grabbing and resizing columns (from the third column) in the diff // side-by-side report colSliderGrab: function dom__event_colSliderGrab(e) { var event = e || window.event, touch = (e !== null && e.type === "touchstart"), node = this, diffRight = node.parentNode, diff = diffRight.parentNode, subOffset = 0, lists = diff.getElementsByTagName("ol"), counter = lists[0].clientWidth, data = lists[1].clientWidth, width = lists[2].parentNode.clientWidth, total = lists[2].parentNode.parentNode.clientWidth, offset = lists[2].parentNode.offsetLeft - lists[2].parentNode.parentNode.offsetLeft, min = ((total - counter - data - 2) - width), max = (total - width - counter), status = "ew", minAdjust = min + 15, maxAdjust = max - 15, withinRange = false, diffLeft = diffRight.previousSibling, drop = function dom__event_colSliderGrab_drop(f) { f = f || window.event; f.preventDefault(); node.style.cursor = status + "-resize"; if (touch === true) { document.ontouchmove = null; document.ontouchend = null; } else { document.onmousemove = null; document.onmouseup = null; } }, boxmove = function dom__event_colSliderGrab_boxmove(f) { f = f || window.event; f.preventDefault(); if (touch === true) { subOffset = offset - f.touches[0].clientX; } else { subOffset = offset - f.clientX; } if (subOffset > minAdjust && subOffset < maxAdjust) { withinRange = true; } if (withinRange === true && subOffset > maxAdjust) { diffRight.style.width = ((total - counter - 2) / 10) + "em"; status = "e"; } else if (withinRange === true && subOffset < minAdjust) { diffRight.style.width = ((total - counter - data - 2) / 10) + "em"; status = "w"; } else if (subOffset < max && subOffset > min) { diffRight.style.width = ((width + subOffset) / 10) + "em"; status = "ew"; } if (touch === true) { document.ontouchend = drop; } else { document.onmouseup = drop; } }; event.preventDefault(); if (typeof pd.data.node === "object" && pd.data.node.report.code.box !== null) { offset += pd.data.node.report.code.box.offsetLeft; offset -= pd.data.node.report.code.body.scrollLeft; } else { subOffset = (document.body.parentNode.scrollLeft > document.body.scrollLeft) ? document.body.parentNode.scrollLeft : document.body.scrollLeft; offset -= subOffset; } offset += node.clientWidth; node.style.cursor = "ew-resize"; diff.style.width = (total / 10) + "em"; diff.style.display = "inline-block"; if (diffLeft.nodeType !== 1) { do { diffLeft = diffLeft.previousSibling; } while (diffLeft.nodeType !== 1); } diffLeft.style.display = "block"; diffRight.style.width = (diffRight.clientWidth / 10) + "em"; diffRight.style.position = "absolute"; if (touch === true) { document.ontouchmove = boxmove; document.ontouchstart = false; } else { document.onmousemove = boxmove; document.onmousedown = null; } return false; }, //allows visual folding of consecutive equal lines in a diff report difffold : function dom__event_difffold() { var a = 0, b = 0, self = this, title = self .getAttribute("title") .split("line "), min = Number(title[1].substr(0, title[1].indexOf(" "))), max = Number(title[2]), inner = self.innerHTML, lists = [], parent = self.parentNode.parentNode, listnodes = (parent.getAttribute("class") === "diff") ? parent.getElementsByTagName(