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
JavaScript
/*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, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/api\./g, "") + " */";
} else {
pd.data.node.comment.innerHTML = "/*prettydiff.com " + pd
.data
.commentString
.join(", ")
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.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(