|
Server : Apache/2.4.58 (Win64) OpenSSL/3.1.3 PHP/8.2.12 System : Windows NT SERVER-PC 10.0 build 26200 (Windows 11) AMD64 User : ServerPC ( 0) PHP Version : 8.2.12 Disable Function : NONE Directory : C:/Windows/SystemApps/Microsoft.Windows.CloudExperienceHost_cw5n1h2txyewy/js/ |
Upload File : |
window.DebugJS = window.DebugJS || {};
function DebugJSConsole() {
this._registers = [];
this._pendingOutput = [];
this._pendingOutputTimer = null;
this._createUI();
this._catchErrors();
this._loadCommandHistory();
this._eval = eval; // calling eval indirectly (through a reference) will cause it to execute in the global scope
var that = this;
function interceptKey(ev) {
if (that._isVisible() && !ev.key.match("F\\d")) {
ev.stopPropagation();
ev.stopImmediatePropagation();
return true;
}
return false;
}
window.addEventListener("keydown", function (ev) {
if (ev.keyCode === 74 && ev.shiftKey && ev.ctrlKey) {
ev.preventDefault();
that._toggleLayerVisibility();
} else if (interceptKey(ev)) {
var controlKeys = [ "ArrowUp", "Up", "ArrowDown", "Down", "PageUp", "PageDown", "Home", "End" ];
if (controlKeys.indexOf(ev.key) === -1 &&
!ev.ctrlKey && !ev.altKey) {
that._textInputElement.focus();
}
if (ev.key === "Esc" || ev.key === "Escape") {
that._toggleLayerVisibility();
}
if (document.activeElement === that._textInputElement) {
that._onTextInput(ev);
}
}
}, true);
window.addEventListener("keyup", interceptKey, true);
window.addEventListener("keypress", interceptKey, true);
this._textInputFlipElement.addEventListener("click", function () {
if (that._isSingleLineMode()) {
this.innerText = "<";
that._textInputElement.className = "debugConsoleMultiLine";
} else {
this.innerText = ">";
that._textInputElement.className = "debugConsoleSingleLine";
}
that._setCommand(that._textInputElement.value);
that._textInputElement.focus();
}, false);
}
DebugJSConsole.prototype._onTextInput = function (ev) {
this._textInputElement.scrollIntoView();
if (ev.key === "Enter" && (ev.ctrlKey || this._isSingleLineMode())) {
ev.preventDefault();
var command = this._textInputElement.value.trim();
this._textInputElement.value = "";
if (command !== "") {
this._appendText("", "> " + toSingleLine(command));
var index = -1;
this._commandHistory.forEach(function (previousCommand, i) {
if (toSingleLine(command) === toSingleLine(previousCommand)) {
index = i;
}
});
if (index !== -1) {
var other = this._commandHistory.splice(index, 1)[0];
if (this._isSingleLineMode()) {
command = other;
}
}
this._commandHistory.unshift(command);
this._commandHistory.length = Math.min(this._commandHistory.length, 20);
this._commandHistoryPosition = -1;
this._saveCommandHistory();
this._eval(
"with (DebugJS.console._getCommands()) {\n" +
(this._safety ? " try {\n" : "") +
" dump(stash(eval(" + JSON.stringify(command) + ")));\n" +
(this._safety ? " } catch (ex) {\n" : "") +
(this._safety ? " err(ex);\n" : "") +
(this._safety ? " }\n" : "") +
"}"
);
this._textInputElement.scrollIntoView();
}
} else if ((ev.key === "Up" || ev.key === "ArrowUp") && (ev.ctrlKey || this._isSingleLineMode())) {
ev.preventDefault();
if (this._commandHistoryPosition < this._commandHistory.length - 1) {
this._setCommand(this._commandHistory[++this._commandHistoryPosition]);
}
} else if ((ev.key === "Down" || ev.key === "ArrowDown") && (ev.ctrlKey || this._isSingleLineMode())) {
ev.preventDefault();
if (this._commandHistoryPosition > 0) {
this._setCommand(this._commandHistory[--this._commandHistoryPosition]);
} else {
this._commandHistoryPosition = -1;
this._setCommand("");
}
} else if (ev.key === "Tab") {
ev.preventDefault();
this._tabComplete();
}
};
function nub (sequence) {
var members = {};
sequence.forEach(function (item) { this[item] = null; }, members);
return Object.keys(members);
}
DebugJSConsole.prototype._tabComplete = function () {
var cursorPosition = this._textInputElement.selectionStart,
fullText = this._textInputElement.value,
preCursorText = fullText.slice(0, cursorPosition),
postCursorText = fullText.slice(cursorPosition);
var match = preCursorText.match(/[^=\s\(\){}\+\-\*\/,;&|!"']+$/);
if (match !== null && match.length === 1 && match[0] !== ".") {
var candidate = match[0].trim();
var lastDot = candidate.lastIndexOf(".");
var isGlobal = false;
var realPart = "";
var queryPart = "";
if (lastDot === -1) {
isGlobal = true;
realPart = "window";
queryPart = candidate;
} else {
isGlobal = false;
realPart = candidate.substr(0, lastDot);
queryPart = candidate.substr(lastDot + 1);
}
var realValue = this._eval(
"var __tabCompleteResult = null;" +
"with (DebugJS.console._getCommands()) {" +
" try {" +
" __tabCompleteResult = eval(" + JSON.stringify(realPart) + ");" +
" } catch (ex) { }" +
"}" +
"__tabCompleteResult;"
);
var matchingFields = {};
for (var field in realValue) {
if (field.substr(0, queryPart.length).toLowerCase() === queryPart.toLowerCase()) {
matchingFields[field] = null;
}
}
var matchingFieldsArray = Object.keys(matchingFields);
var newQueryPart = null;
if (matchingFieldsArray.length === 1) {
newQueryPart = matchingFieldsArray[0];
} else if (matchingFieldsArray.length > 1) {
matchingFields.toString = function () { return matchingFieldsArray.length.toString() + " matches"; };
var commonPrefix = matchingFieldsArray.reduce(function (prev, next) {
var i = 0;
for (var len = Math.min(prev.length, next.length); i < len; i++) {
if (prev[i].toLowerCase() !== next[i].toLowerCase()) {
break;
}
}
return next.substring(0, i);
});
var differentQuery = this._lastRealPart !== realPart || this._lastQuery.toLowerCase() !== queryPart.toLowerCase();
if (differentQuery) {
this._appendTreeView(new DataTreeView(candidate + "*", realValue, matchingFields, ["toString"]), true);
} else if (commonPrefix.length === queryPart.length) {
var trimmedFields = nub(matchingFieldsArray.map(function (s) { return s.slice(0, queryPart.length); }));
newQueryPart = trimmedFields[(trimmedFields.indexOf(queryPart) + 1) % trimmedFields.length];
}
if (commonPrefix.length > queryPart.length) {
var distance = function (s) {
return Array.prototype.reduce.call(queryPart, function (total, c, i) {
return (c === s[i] ? 0 : 1) + total;
}, 0);
};
newQueryPart = matchingFieldsArray.sort(function (a,b) { return distance(a) - distance(b); })[0].slice(0, commonPrefix.length);
}
}
if (newQueryPart !== null) {
var newPreCursorText = preCursorText.substr(0, match.index) + (isGlobal ? "" : (realPart + ".")) + newQueryPart;
this._textInputElement.value = newPreCursorText + postCursorText;
this._textInputElement.setSelectionRange(newPreCursorText.length, newPreCursorText.length);
}
this._lastQuery = newQueryPart !== null ? newQueryPart : queryPart;
this._lastRealPart = realPart;
}
};
DebugJSConsole.prototype._createUI = function () {
this._styleElement = document.createElement("style");
this._styleElement.id = "debugConsoleStyles";
this._styleElement.type = "text/css";
this._styleElement.innerText = DebugJSConsole.CSS;
this._rootElement = createElement("div", "debugConsoleRoot", null);
this._rootElement.innerHTML =
"<div id=debugConsoleBackground>" +
"<div id=debugConsoleLayer>" +
"<div id=debugConsoleOutput></div>" +
"<div>" +
"<span id=debugConsoleInputFlip title='Click here to switch between single and multi-line input'>></span> " +
"<textarea id=debugConsoleInput class=debugConsoleSingleLine></textarea>" +
"</div>" +
"</div>" +
"</div>";
this._layerElement = this._rootElement.querySelector("#debugConsoleLayer");
this._outputElement = this._rootElement.querySelector("#debugConsoleOutput");
this._textInputElement = this._rootElement.querySelector("#debugConsoleInput");
this._textInputElement.spellcheck = false;
this._lastQuery = "";
this._lastRealPart = "";
this._textInputFlipElement = this._rootElement.querySelector("#debugConsoleInputFlip");
};
DebugJSConsole.prototype.writeHTML = function (html) {
var div = document.createElement("div");
div.innerHTML = html;
this._appendOutput(div);
};
DebugJSConsole.outputBufferLimit = 1000;
DebugJSConsole.prototype._appendOutput = function (div, parentElement) {
if (parentElement !== this._outputElement && parentElement !== undefined) {
parentElement.appendChild(div);
} else {
this._pendingOutput.push(div);
if (this._pendingOutput.length > DebugJSConsole.outputBufferLimit) {
this._pendingOutput.shift();
}
if (this._isVisible() && !this._pendingOutputTimer) {
this._pendingOutputTimer = setTimeout(this._applyPendingOutput.bind(this), 250);
}
}
};
DebugJSConsole.prototype._applyPendingOutput = function () {
this._pendingOutputTimer = null;
var parentElement = this._outputElement;
var maintainScrollPosition = false;
var stuckToBottom = false;
var scrollTop;
if (this._rootElement.parentNode !== null) {
maintainScrollPosition = true;
scrollTop = this._layerElement.scrollTop;
var scrollHeight = this._layerElement.scrollHeight;
var clientHeight = this._layerElement.clientHeight;
stuckToBottom = (scrollHeight - scrollTop <= clientHeight + 10);
}
var pendingOutput = this._pendingOutput;
this._pendingOutput = [];
pendingOutput.forEach(function (div) {
parentElement.appendChild(div);
});
var newHeight;
if (maintainScrollPosition && !stuckToBottom) {
newHeight = this._layerElement.scrollHeight;
}
for (var excess = parentElement.childNodes.length - DebugJSConsole.outputBufferLimit; excess > 0; excess--) {
parentElement.removeChild(parentElement.firstChild);
}
if (stuckToBottom) {
this._layerElement.scrollTop = this._layerElement.scrollHeight - this._layerElement.clientHeight;
} else if (maintainScrollPosition) {
this._layerElement.scrollTop = scrollTop - (newHeight - this._layerElement.scrollHeight);
}
};
DebugJSConsole.prototype._clearOutput = function () {
this._outputElement.innerHTML = "";
};
DebugJSConsole.prototype._appendText = function (className, text, parentElement) {
this._appendOutput(createElement("div", className, text), parentElement);
};
DebugJSConsole.prototype._appendData = function (label, data, shouldExpand) {
this._appendTreeView(new DataTreeView(label, data, data, []), shouldExpand);
};
DebugJSConsole.prototype._appendHTML = function (node, shouldExpand) {
this._appendTreeView(new HtmlTreeView(node), shouldExpand);
};
DebugJSConsole.prototype._appendCSS = function (element) {
this._appendTreeView(new CssTraceTreeView(element), true);
};
DebugJSConsole.prototype._appendSheet = function (sheet, shouldExpand) {
this._appendTreeView(new CssTreeView(sheet), shouldExpand);
};
DebugJSConsole.prototype._appendRule = function (rule, shouldExpand) {
this._appendTreeView(new CssRuleTreeView(rule, null), shouldExpand);
};
DebugJSConsole.prototype._appendStyle = function (style, shouldExpand) {
this._appendTreeView(new CssStyleTreeView(style, null), shouldExpand);
};
DebugJSConsole.prototype._appendTreeView = function (treeView, shouldExpand, parentElement) {
var canExpand = treeView.length > 0;
if (treeView.isExpanded === undefined) {
treeView.isExpanded = canExpand && shouldExpand && treeView.length <= 20;
}
var div = createElement("div", "debugConsoleOutputText", null);
var expanderRegion = createElement("span", "debugConsolePropertyName", null, div);
var expanderElement = createElement("span", "debugConsolePropertyExpander debugConsoleOutputText", "+", expanderRegion);
if (treeView.label) {
createElement("span", null, treeView.label + ": ", expanderRegion);
}
var valueElement = createElement("span", null, treeView.value, div);
if (treeView.html) {
valueElement.innerHTML = treeView.html.outerHTML;
} else if (treeView.className) {
valueElement.className = treeView.className;
}
var that = this;
var register = createElement("span", "debugConsoleRegister",
(treeView.label !== "prototype") ? this._getRegisterName(treeView.register) : null, valueElement);
valueElement.addEventListener("click", function (ev) {
that._toggleRegister(treeView.register);
}, false);
register.onRegisterChange = function (registerValue, registerName) {
if (registerValue === treeView.register && treeView.label !== "prototype") {
this.innerText = registerName;
}
};
var detailsElement = createElement("div", "debugConsoleObjectProperties", null, div);
if (canExpand) {
expanderRegion.addEventListener("click", function (ev) {
if (detailsElement.innerHTML !== "") {
detailsElement.innerHTML = "";
expanderElement.innerText = "+";
treeView.isExpanded = false;
} else {
expanderElement.innerText = "-";
that._expandTreeView(treeView, detailsElement);
}
}, false);
if (treeView.isExpanded) {
expanderElement.innerText = "-";
that._expandTreeView(treeView, detailsElement);
}
} else {
expanderElement.style.visibility = "hidden";
}
this._appendOutput(div, parentElement);
};
DebugJSConsole.prototype._expandTreeView = function (treeView, detailsElement) {
if (treeView.children === undefined) {
treeView.children = [];
for (var i = 0, len = treeView.length; i < len; i++) {
treeView.children.push(treeView.createChild(i));
}
}
treeView.isExpanded = true;
treeView.children.forEach(function (child) {
this._appendTreeView(child, false, detailsElement);
}, this);
};
function TreeView() { }
TreeView.prototype.label = "";
TreeView.prototype.value = "";
TreeView.prototype.className = "";
TreeView.prototype.html = null;
TreeView.prototype.register = null;
TreeView.prototype.length = 0;
TreeView.prototype.isExpanded = false;
TreeView.prototype.children = [];
TreeView.prototype.createChild = function (index) { return null; };
function DataTreeView(label, data, proto, excluded) {
this.label = label;
this._data = this.register = data;
this.value = valueToString(proto);
if (this.value) {
var maxLength = 1000;
this.value = this.value.trim();
if (label) {
this.value = this.value.replace(/\s+/g, " ");
maxLength = 100;
}
if (this.value.length > maxLength) {
this.value = this.value.substr(0, maxLength) + "...";
}
}
this._fields = getProperties(proto, true, excluded).sort(function (a, b) {
if ((typeof data[a] === "function") !== (typeof data[b] === "function")) {
return (typeof data[a] === "function") ? 1 : -1;
}
var aAsNumber = Number(a);
var bAsNumber = Number(b);
var aIsNumber = aAsNumber !== null && !isNaN(aAsNumber);
var bIsNumber = bAsNumber !== null && !isNaN(bAsNumber);
if (aIsNumber && bIsNumber) {
return aAsNumber - bAsNumber;
}
if (aIsNumber !== bIsNumber) {
return aIsNumber ? 1 : -1;
}
if ((a[0] === "_") !== (b[0] === "_")) {
return (a[0] === "_") ? 1 : -1;
}
return a.localeCompare(b);
});
if (typeof data === "function" && !isEmpty(data.prototype, [])) {
this._prototype = { data: data.prototype, proto: data.prototype, excluded: [] };
this._fields.splice(0, 0, this._prototype);
} else if (!isEmpty(proto, excluded)) {
var nextPrototype = Object.getPrototypeOf(proto);
var nextExcluded = excluded.concat(this._fields);
if (!isEmpty(nextPrototype, nextExcluded)) {
this._prototype = { data: data, proto: nextPrototype, excluded: nextExcluded };
this._fields.splice(0, 0, this._prototype);
}
}
this.length = this._fields.length;
}
DataTreeView.prototype.createChild = function (index) {
if (this._prototype !== undefined && index === 0) {
return new DataTreeView("prototype", this._prototype.data, this._prototype.proto, this._prototype.excluded);
} else {
var field = this._fields[index], value, className;
try {
value = this._data[field];
className = "debugConsoleOutputText";
} catch (ex) {
value = ex;
className = "debugConsoleErrorText";
}
var treeView = new DataTreeView(field, value, value, []);
treeView.className = className;
return treeView;
}
};
function HtmlTreeView(node) {
var i, len;
this._element = this.register = node;
if (instanceOf(node, HTMLStyleElement)) {
var style = node;
this._displayable = style.sheet.cssRules;
} else if (instanceOf(node, HTMLLinkElement) && node.type === "text/css") {
var link = node;
this._displayable = link.sheet.cssRules;
} else {
this._displayable = [];
for (i = 0, len = node.childNodes.length; i < len; i++) {
if (isDisplayableHtmlNode(node.childNodes[i])) {
this._displayable.push(node.childNodes[i]);
}
}
}
this.length = this._displayable.length;
if (node.nodeType === Node.TEXT_NODE) {
this.className = "debugConsoleHtmlText";
var textNode = node;
this.value = toSingleLine(textNode.textContent.trim());
} else if (node.nodeType === Node.COMMENT_NODE) {
this.className = "debugConsoleHtmlComment";
this.value = toSingleLine(node.text);
} else {
var htmlNode = node;
this.html = createElement("span", null, null);
createElement("span", "debugConsoleHtmlBracket", "<", this.html);
createElement("span", "debugConsolePropertyName", htmlNode.nodeName.toLowerCase(), this.html);
if (htmlNode.id) {
this._appendHtmlAttribute("id", htmlNode.id);
}
if (htmlNode.className) {
this._appendHtmlAttribute("class", htmlNode.className);
}
for (i = 0, len = htmlNode.attributes.length; i < len; i++) {
var attribute = htmlNode.attributes[i];
if (attribute.name !== "id" && attribute.name !== "class") {
this._appendHtmlAttribute(attribute.name, attribute.value);
}
}
createElement("span", "debugConsoleHtmlBracket", ">", this.html);
}
}
HtmlTreeView.prototype.createChild = function (index) {
var child = this._displayable[index];
if (instanceOf(child, CSSRule)) {
return new CssRuleTreeView(this._displayable[index]);
} else {
return new HtmlTreeView(this._displayable[index]);
}
};
HtmlTreeView.prototype._appendHtmlAttribute = function (attrName, attrValue) {
createElement("span", null, " ", this.html);
createElement("span", "debugConsoleHtmlAttrName", attrName, this.html);
createElement("span", null, "=\"", this.html);
createElement("span", "debugConsoleHtmlAttrValue", attrValue, this.html);
createElement("span", null, "\"", this.html);
};
function CssTraceTreeView(element) {
this._element = element;
this._matches = [];
if (element.style.length > 0) {
this._matches.push(new CssStyleTreeView(element.style, "<inline-styles>", element));
}
Array.prototype.forEach.call(document.styleSheets, function (sheet) {
this._addMatches(sheet.cssRules, element);
}, this);
this.label = "trace";
this.value = this.register = element;
this.length = this._matches.length;
}
CssTraceTreeView.prototype._addMatches = function (rules, element, prefix) {
Array.prototype.forEach.call(rules, function (rule) {
if (rule.type === rule.MEDIA_RULE) {
var mql = window.matchMedia ? window.matchMedia(rule.media) : window.msMatchMedia(rule.media);
if (mql.matches) {
this._addMatches(rule.cssRules, element, (prefix || "") + "@media (" + rule.media + ") ");
}
} else if (element.matches ? element.matches(rule.selectorText) : element.msMatchesSelector(rule.selectorText)) {
this._matches.push(new CssRuleTreeView(rule, element, prefix));
}
}, this);
};
CssTraceTreeView.prototype.createChild = function (index) {
return this._matches[index];
};
function CssTreeView(sheet) {
if (sheet.href) {
this.value = sheet.href;
} else if (sheet.id) {
this.value = sheet.id;
} else if (sheet.title) {
this.value = sheet.title;
}
this.register = this._sheet = sheet;
this.label = "css";
this.length = sheet.cssRules.length;
}
CssTreeView.prototype.createChild = function (index) {
return new CssRuleTreeView(this._sheet.cssRules[index]);
};
function CssRuleTreeView(rule, match, prefix) {
if (rule.type === rule.STYLE_RULE) {
var styleTree = this._styleTree = new CssStyleTreeView(rule.style, rule.selectorText, match);
this.value = (prefix || "") + styleTree.value;
this.label = match ? "match" : "rule";
this.length = styleTree.length;
} else if (rule.type === rule.IMPORT_RULE) {
this.label = "@import";
this.value = rule.href;
this.length = rule.styleSheet.cssRules.length;
} else if (rule.type === rule.MEDIA_RULE) {
this.label = "@media";
this.value = rule.media;
this.length = rule.cssRules.length;
} else {
this.label = "rule";
this.value = rule.cssText;
this.length = 0;
}
this._rule = this.register = rule;
this._match = match;
}
CssRuleTreeView.prototype.createChild = function (index) {
var styleTree = this._styleTree;
if (styleTree) {
return styleTree.createChild(index);
}
var rule = this._rule;
if (rule.type === rule.IMPORT_RULE) {
return new CssRuleTreeView(rule.styleSheet.cssRules[index], this._match);
}
if (rule.type === rule.MEDIA_RULE) {
return new CssRuleTreeView(rule.cssRules[index], this._match);
}
return null;
};
function CssStyleTreeView(style, value, match) {
this._style = this.register = style;
this._match = match;
this.label = "style";
this.value = value;
this._children = [];
for (var i = 0, len = style.length; i < len; i++) {
if (this.cssIgnoreName[style[i]] === undefined) {
var parts = style[i].split("-");
if (/^-ms-/.test(style[i])) {
parts.splice(0, 3, "-ms-" + parts[2]);
}
this._insertChild(parts);
}
}
this.length = this._children.length;
}
CssStyleTreeView.prototype._insertChild = function (parts) {
for (var i = 0, len = this._children.length; i < len; i++) {
if (this._children[i].insert(parts)) {
return;
}
}
this._children.push(new CssPropertyTreeView(this._style, null, parts, this._match));
};
CssStyleTreeView.prototype.createChild = function (index) {
return this._children[index].getLeaf();
};
CssStyleTreeView.prototype.cssIgnoreName = {};
CssStyleTreeView.prototype.cssIgnoreName["-ms-text-size-adjust"] = true;
function CssPropertyTreeView(style, base, remaining, match) {
this._style = style;
this._match = match;
this.part = remaining.splice(0, 1)[0];
this.label = base ? base + "-" + this.part : this.part;
this._children = [];
if (remaining.length > 0) {
this._children.push(new CssPropertyTreeView(style, this.label, remaining, match));
}
var indexer = this.cssFixedName[this.label];
if (!indexer) {
indexer = this.label.replace(/^-ms/, "ms");
indexer = indexer.replace(/-\w/g, function (m) { return m[1].toUpperCase(); });
}
this.value = this._style[indexer];
if (this.value === undefined) {
indexer = indexer.replace(/^ms\w/, function (m) { return m[2].toLowerCase(); });
this.value = this._style[indexer];
}
if (this.value !== undefined) {
this.register = this.value;
if (this._match && this._match.currentStyle && !areCssValuesEqual(this.value, this._match.currentStyle[indexer])) {
this.html = createElement("span", "debugConsoleCssOverriden", null);
createElement("span", "debugConsoleOutputText", this.value, this.html);
}
}
}
CssPropertyTreeView.prototype.createChild = function (index) {
return this._children[index].getLeaf();
};
Object.defineProperty(CssPropertyTreeView.prototype, "length", { get: function () {
return this._children.length;
}});
CssPropertyTreeView.prototype.insert = function (parts) {
if (this.part === parts[0]) {
parts.splice(0, 1);
if (parts.length > 0) {
for (var i = 0, len = this._children.length; i < len; i++) {
if (this._children[i].insert(parts)) {
return true;
}
}
this._children.push(new CssPropertyTreeView(this._style, this.label, parts, this._match));
}
return true;
} else {
return false;
}
};
CssPropertyTreeView.prototype.getLeaf = function () {
if (this._children.length === 1) {
return this._children[0].getLeaf();
} else {
return this;
}
};
CssPropertyTreeView.prototype.cssFixedName = {
"-ms-scrollbar-3dlight-color": "scrollbar3dLightColor",
"scrollbar-3dlight-color": "scrollbar3dLightColor",
"-ms-scrollbar-darkshadow-color": "scrollbarDarkShadowColor",
"scrollbar-darkshadow-color": "scrollbarDarkShadowColor",
"-ms-transform-origin-x": "msTransformOrigin",
"-ms-transform-origin-y": "msTransformOrigin"
};
function ElementEvents(callback, context) {
var domEvents = {}, body = document.body, selection = body, border = 2,
root = createElement("div", "debugConsoleRoot", null, body),
overlayLeft = createElement("div", "debugConsoleVerticalOverlay", null, root).style,
overlayRight = createElement("div", "debugConsoleVerticalOverlay", null, root).style,
overlayTop = createElement("div", "debugConsoleHorizontalOverlay", null, root).style,
overlayBottom = createElement("div", "debugConsoleHorizontalOverlay", null, root).style;
overlayLeft.width = overlayRight.width = overlayTop.height = overlayBottom.height = String(border) + "px";
function restoreConsole() {
for (var evName in domEvents) {
document.removeEventListener(evName, domEvents[evName], true);
}
body.removeChild(root);
callback.call(context, selection);
}
function positionOverlay() {
var rect = selection.getBoundingClientRect(),
offsetLeft = rect.left + body.scrollLeft - body.clientLeft,
offsetTop = rect.top + body.scrollTop - body.clientTop,
selectionWidth = selection.offsetWidth,
selectionHeight = selection.offsetHeight;
overlayLeft.left = overlayTop.left = overlayBottom.left = String(offsetLeft) + "px";
overlayRight.left = String(offsetLeft + selectionWidth - border) + "px";
overlayLeft.top = overlayRight.top = overlayTop.top = String(offsetTop) + "px";
overlayBottom.top = String(offsetTop + selectionHeight - border) + "px";
overlayLeft.height = overlayRight.height = String(selectionHeight) + "px";
overlayTop.width = overlayBottom.width = String(selectionWidth) + "px";
}
domEvents.mousemove = function (ev) {
var target = document.elementFromPoint(ev.clientX, ev.clientY);
if (/^debugConsole/.test(target.className)) {
return;
}
if (target !== selection) {
selection = target;
positionOverlay();
}
};
domEvents.click = function (ev) {
ev.preventDefault();
ev.stopPropagation();
restoreConsole();
};
domEvents.keydown = function (ev) {
if (ev.keyCode === 192 && ev.shiftKey) {
restoreConsole();
}
if (ev.key === "Esc" || ev.key === "Escape") {
ev.preventDefault();
ev.stopPropagation();
selection = null;
restoreConsole();
}
};
for (var eventName in domEvents) {
document.addEventListener(eventName, domEvents[eventName], true);
}
positionOverlay();
}
DebugJSConsole.prototype.stashHtml = function (element) {
this._rootElement.style.display = "";
if (element) {
this._toggleRegister(element);
this._appendHTML(element, true);
}
this._textInputElement.focus();
};
DebugJSConsole.prototype._selectHtml = function () {
this._rootElement.style.display = "none";
new ElementEvents(this.stashHtml, this);
};
DebugJSConsole.prototype.log = function (level, text) {
var secondsSinceStart = (Date.now() - this._startTime) / 1000;
var messageStyle;
switch (level) {
case "error":
messageStyle = "debugConsoleErrorText";
break;
case "warning":
messageStyle = "debugConsoleWarningText";
break;
default:
messageStyle = "debugConsoleLogText";
break;
}
this._appendText(messageStyle, "Log@" + secondsSinceStart.toFixed(3) + ": " + text);
};
DebugJSConsole.prototype._isVisible = function () {
return (this._rootElement.parentNode !== null);
};
DebugJSConsole.prototype._toggleLayerVisibility = function () {
if (!this._isVisible()) {
if (this._styleElement.parentNode === null) {
document.getElementsByTagName("head")[0].appendChild(this._styleElement);
}
this._applyPendingOutput();
document.body.appendChild(this._rootElement);
this._textInputElement.focus();
} else {
document.body.removeChild(this._rootElement);
clearTimeout(this._pendingOutputTimer);
this._pendingOutputTimer = null;
}
};
DebugJSConsole.prototype._catchErrors = function () {
var that = this;
window.onerror = function (msg, file, line) {
that._appendText("debugConsoleExceptionText", "Unhandled exception: " + msg + "\n file: " + file + "\n line: " + line);
return false;
};
};
DebugJSConsole.prototype._loadCommandHistory = function () {
this._commandHistory = DebugJS.getCookie("consoleCommandHistory", []);
};
DebugJSConsole.prototype._saveCommandHistory = function () {
DebugJS.setCookie("consoleCommandHistory", this._commandHistory);
};
DebugJSConsole.prototype._setCommand = function (value) {
if (this._isSingleLineMode()) {
value = toSingleLine(value);
} else if (this._commandHistoryPosition >= 0 && this._commandHistoryPosition < this._commandHistory.length &&
toSingleLine(this._textInputElement.value) === toSingleLine(this._commandHistory[this._commandHistoryPosition])) {
value = this._commandHistory[this._commandHistoryPosition];
}
this._textInputElement.value = value;
};
DebugJSConsole.prototype._isSingleLineMode = function () {
return (this._textInputElement.className.split(" ").indexOf("debugConsoleSingleLine") !== -1);
};
DebugJSConsole.prototype._setSafety = function (enableSafety) {
this._safety = enableSafety;
this._appendText("debugConsoleOutputText", "Safety " + (enableSafety ? "enabled" : "disabled"));
};
DebugJSConsole.prototype._stash = function (value) {
this._registers[0] = value;
};
DebugJSConsole.prototype._toggleRegister = function (value) {
for (var i = 1, len = this._registers.length; i < len; i++) {
if (this._registers[i] === value) {
delete this._registers[i];
this._updateRegisterElements(value, "");
return;
}
}
for (i = 1, len = this._registers.length; i < len; i++) {
if (this._registers[i] === undefined) {
break;
}
}
this._registers[i] = value;
this._updateRegisterElements(value, "$" + i.toString());
};
DebugJSConsole.prototype._getRegisterName = function (value) {
var registerName = "";
if (value !== undefined) {
var registerIndex = this._registers.indexOf(value, 1);
if (registerIndex !== -1) {
registerName = "$" + registerIndex.toString();
}
}
return registerName;
};
DebugJSConsole.prototype._updateRegisterElements = function (value, registerName) {
var registerElements = document.querySelectorAll(".debugConsoleRegister");
for (var i = 0, len = registerElements.length; i < len; i++) {
registerElements[i].onRegisterChange(value, registerName);
}
};
DebugJSConsole.prototype._loadScriptFile = function (path) {
var scriptElement = document.createElement("script");
var that = this;
scriptElement.onload = function () {
that._appendText("debugConsoleOutputText", "Script file loaded: " + path);
};
scriptElement.onerror = function () {
that._appendText("debugConsoleErrorText", "Error loading script file: " + path);
};
scriptElement.type = "text/javascript";
scriptElement.src = path;
document.getElementsByTagName("head")[0].appendChild(scriptElement);
};
DebugJSConsole.prototype._getCommands = function () {
return new ConsoleCommands(this, this._registers);
};
DebugJSConsole.prototype._startTime = Date.now();
DebugJSConsole.prototype._styleElement = null;
DebugJSConsole.prototype._rootElement = null;
DebugJSConsole.prototype._layerElement = null;
DebugJSConsole.prototype._outputElement = null;
DebugJSConsole.prototype._textInputElement = null;
DebugJSConsole.prototype._textInputFlipElement = null;
DebugJSConsole.prototype._commandHistory = null;
DebugJSConsole.prototype._commandHistoryPosition = -1;
DebugJSConsole.prototype._safety = true;
function ConsoleCommands(debugConsole, registers) {
this._console = debugConsole;
for (var i = 0, len = registers.length; i < len; i++) {
Object.defineProperty(this, "$" + i.toString(), { value: registers[i] });
}
}
ConsoleCommands.prototype.clip = function (text) {
window.clipboardData.setData("Text", text);
};
ConsoleCommands.prototype.dump = function (data, label) {
if (data !== undefined || label !== undefined) {
this._console._appendData(label, data, true);
}
};
ConsoleCommands.prototype.log = function (data) {
if (data !== undefined) {
this._console._appendData(null, data, true);
}
};
ConsoleCommands.prototype.html = function (data) {
if (data === undefined) {
data = document.documentElement;
}
if (instanceOf(data, Node)) {
this._console._appendHTML(data, true);
} else {
this.err("Not an HTML node");
}
};
ConsoleCommands.prototype.css = function (data) {
if (instanceOf(data, HTMLElement)) {
this._console._appendCSS(data);
} else if (instanceOf(data, CSSStyleDeclaration)) {
this._console._appendStyle(data, true);
} else if (instanceOf(data, CSSRule)) {
this._console._appendRule(data, true);
} else if (instanceOf(data, CSSStyleSheet)) {
this._console._appendSheet(data, true);
} else if (data === undefined) {
Array.prototype.forEach.call(document.styleSheets, function (sheet) {
if (sheet.id !== "debugConsoleStyles") {
this._console._appendSheet(sheet, false);
}
}, this);
} else {
this.err("Not a valid object type");
}
};
ConsoleCommands.prototype.err = function (msg) {
this._console._appendText("debugConsoleErrorText", msg);
};
ConsoleCommands.prototype.load = function (path) {
this._console._loadScriptFile(path);
};
ConsoleCommands.prototype.hook = function (source, eventName) {
var that = this;
function listener() {
that.dump({source: source, eventName: eventName, args: arguments }, "Event fired");
}
if (source) {
if (source.addEventListener !== undefined) {
source.addEventListener(eventName, listener, false);
} else if (source.addListener !== undefined) {
source.addListener(eventName, listener);
} else if (source.on !== undefined) {
source.on(eventName, listener);
}
}
};
ConsoleCommands.prototype.promise = function (p) {
var that = this;
p.then(
function () { that.dump({ promise: p, args: arguments }, "Promise complete"); },
function () { that.dump({ promise: p, args: arguments }, "Promise error"); },
function () { that.dump({ promise: p, args: arguments }, "Promise progress"); }
);
};
ConsoleCommands.prototype.safety = function (enableSafety) {
this._console._setSafety(enableSafety);
};
Object.defineProperty(ConsoleCommands.prototype, "cls", { get: function () {
this._console._clearOutput();
}});
Object.defineProperty(ConsoleCommands.prototype, "select", { get: function () {
this._console._selectHtml();
}});
Object.defineProperty(ConsoleCommands.prototype, "help", { get: function () {
this._console._appendText(
"debugConsoleOutputText",
"The console command-line accepts any javascript code and dumps the result.\n" +
"Built-in commands:\n" +
" cls - clears the output area\n" +
" log(string) - outputs a string\n" +
" clip(string) - copies the string to the clipboard\n" +
" dump(obj [, label]) - dumps an object with an optional label\n" +
" html([node]) - dumps the HTML tree, optionally rooted to a specific node\n" +
" select - stash an HTML element by selecting it in the actual UI\n" +
" css([element|sheet|rule|style]) - dumps CSS, optionally matching a provided object\n" +
" hook(obj, event) - hooks an event on an object and dumps when it fires\n" +
" promise(p) - listens to the complete/error/progress events on a promise\n" +
" load(string) - loads the specified javascript file\n" +
" safety(bool) - enables/disables catching errors thrown from console evaluation\n" +
"\n" +
"You can click the > next to the input area to toggle between single-line and multi-line input modes. The console supports a persistent command history, use the arrow keys (or Ctrl+arrow keys in multi-line mode) to repeat past commands.\n" +
"\n" +
"The result of the last evaluation is stored in a stash register. You can access with the $0 symbol. Clicking on any value in the output will store that value into a numbered register, like $1 or $2. All of these registers can be used anywhere in an expression. Note that a register is a value, not an alias to a property. If the property that the register was created from changes, the register will not.\n" +
"\n" +
"In depth usage instructions can be found at http://codebox/jsconsole"
);
}});
ConsoleCommands.prototype.stash = function (value) {
this._console._stash(value);
return value;
};
function getProperties(data, own, excluded) {
var props = [];
if (data) {
var hasProps = false;
if (typeof data === "function") {
hasProps = true;
Array.prototype.push.apply(excluded, Object.getOwnPropertyNames(Function));
} else if (typeof data === "object") {
hasProps = true;
}
if (hasProps) {
var proto = data;
do {
if (proto === Object.prototype || proto === Array.prototype || proto === Function.prototype) {
break;
}
var prototypeProperties;
try {
prototypeProperties = Object.getOwnPropertyNames(proto);
} catch (ex) {
break; // XSS on iframes can prevent enumeration
}
for (var i = 0, len = prototypeProperties.length; i < len; i++) {
var propertyName = prototypeProperties[i];
if (props.indexOf(propertyName) === -1 &&
excluded.indexOf(propertyName) === -1 &&
propertyName !== "constructor") {
props.push(propertyName);
}
}
proto = Object.getPrototypeOf(proto);
} while (!own && proto);
}
}
return props;
}
function isEmpty(data, excluded) {
var empty = getProperties(data, false, excluded).length === 0;
if (typeof data === "function") {
empty = empty && isEmpty(data.prototype, []);
}
return empty;
}
var constructorCache = [];
function getConstructorName(constructorFunction) {
var constructorName;
var cached = false;
var len = constructorCache.length;
for (var i = 0; i < len; ++i) {
if (constructorCache[i].fn === constructorFunction) {
cached = true;
constructorName = constructorCache[i].name;
break;
}
}
if (!cached) {
constructorName = DebugJS.scanTypes(function (testConstructorFunction, testConstructorName) {
if (testConstructorFunction === constructorFunction) {
return testConstructorName;
}
});
if (!constructorName) {
var code = constructorFunction.toString();
if (code.substr(0, 9) === "function ") {
var parenthesisIndex = code.indexOf("(");
if (parenthesisIndex !== -1) {
var possibleName = code.substr(9, parenthesisIndex - 9).trim();
if (possibleName.match(/^[\w$]+$/) !== null) {
constructorName = possibleName;
}
}
}
}
constructorCache.push({ fn: constructorFunction, name: constructorName });
}
return constructorName;
}
function toSingleLine(value) {
return value.replace(/(\/\/[^\r\n]*)|(\/\*(.|[\r\n])*\*\/)/g, "$2").replace(/\s*[\r\n]\s*/g, " ");
}
function valueToString(data, isRecursive) {
var string = "{...}";
try {
switch (typeof data) {
case "undefined":
case "string":
string = JSON.stringify(data);
break;
case "number":
case "boolean":
string = data.toString();
break;
default:
if (data === null) {
string = "null";
} else {
if (Array.isArray(data)) {
string = "length=" + data.length.toString();
if (data.length < 20 && !isRecursive) {
string += " [" + data.map(function (item) { return valueToString(item, true); }).join(", ") + "]";
}
} else {
if (data.toString) {
string = data.toString();
} else {
string = "" + data;
}
}
if (string === "[object Object]") {
var constructorName = getConstructorName(data.constructor);
if (constructorName) {
string = "[object " + constructorName + "]";
}
}
if (data.name) {
string = string + " " + data.name;
}
if (data._debugObjectName) {
string = string + " " + data._debugObjectName;
}
if (data.id) {
string = string + " #" + data.id;
}
if (data.className) {
string = string + " " + data.className.trim().split(/\s+/).map(function (className) { return "." + className; }).join(" ");
}
if (data.objectId) {
string = string + " " + data.objectId;
}
}
break;
}
} catch (ex) { }
return string;
}
function instanceOf(obj, proto) {
return obj instanceof proto;
/* This version no longer works and I cannot remember what madness inspired it. We'll just use the default version
of instanceof, which will probably fail on iframed content.
var toProtoName = {}.toString;
var protoString = toProtoName.call(proto);
while (obj && toProtoName.call(obj) !== protoString && toProtoName.call(obj.constructor) !== protoString) {
obj = Object.getPrototypeOf(obj);
}
return obj;*/
}
function isDisplayableHtmlNode(node) {
switch (node.nodeType) {
case Node.TEXT_NODE:
case Node.COMMENT_NODE:
var textNode = node;
return textNode.textContent.trim().length > 0;
}
return true;
}
function createElement(nodeType, className, innerText, parentElement) {
var element = document.createElement(nodeType);
if (className) {
element.className = className;
}
if (innerText) {
element.innerText = innerText;
}
if (parentElement) {
parentElement.appendChild(element);
}
return element;
}
function areCssValuesEqual(valueA, valueB) {
if ((valueA + "").trim() === (valueB + "").trim()) {
return true;
}
var aAsNumber = Number(valueA);
var bAsNumber = Number(valueB);
return aAsNumber !== null && !isNaN(aAsNumber) && aAsNumber === bAsNumber;
}
DebugJS.getCookie = function (valueName, defaultValue) {
var result = defaultValue;
try {
document.cookie.split(";").forEach(function (cookie) {
var split = cookie.split("=");
var cookieName = split[0].trim();
if (cookieName === valueName) {
result = JSON.parse(unescape(split[1]));
}
});
} catch (ex) { }
return result;
};
DebugJS.setCookie = function (valueName, value) {
var date = new Date();
date.setFullYear(date.getFullYear() + 1);
document.cookie = valueName + "=" + escape(JSON.stringify(value)) + "; expires=" + date.toUTCString();
};
DebugJS.scanTypes = function (fn, namespace, namespaceName, alreadyChecked, depth) {
DebugJS.scanningTypes++;
try {
namespace = namespace || window;
namespaceName = namespaceName || "";
alreadyChecked = alreadyChecked || [ window.Windows, window.Microsoft ]; // don't bother searching these namespaces
depth = depth || 0;
if (depth < 10 && alreadyChecked.length < 1000) {
for (var field in namespace) {
if ((field[0] >= "A" && field[0] <= "Z") || field[0] === "$") { // namespaces and constructors start with a capital letter
try {
var objectToCheck = namespace[field];
var isNamespace = typeof objectToCheck === "object" && objectToCheck !== null && objectToCheck.constructor === Object;
var isFunction = typeof objectToCheck === "function" && objectToCheck !== Function;
if ((isNamespace || isFunction) && alreadyChecked.indexOf(objectToCheck) === -1) {
alreadyChecked.push(objectToCheck);
var objectName = (namespaceName ? namespaceName + "." : "") + field;
var result;
if (isFunction) {
result = fn(objectToCheck, objectName, namespace, field);
}
if (!result) {
result = DebugJS.scanTypes(fn, objectToCheck, objectName, alreadyChecked, depth + 1);
}
if (result) {
return result;
}
}
} catch (ex) {
}
}
}
}
} finally {
DebugJS.scanningTypes--;
}
};
DebugJSConsole.CSS =
".debugConsoleRoot {" +
"width:0;" +
"height:0;" +
"direction: ltr;" +
"-ms-user-select: element;" +
"cursor: text; " +
"}" +
"#debugConsoleBackground {" +
"text-overflow:clip;" +
"position:fixed;" +
"top:0;" +
"left:0;" +
"width:100%;" +
"height:100%;" +
"z-index:2000;" +
"background-color:rgba(0,0,0,0.8);" +
"overflow:hidden;" +
"}" +
"#debugConsoleLayer {" +
"width:98%;" +
"height:100%;" +
"padding:0 1%;" +
"color:white;" +
"font-family:'Segoe UI', 'Segoe UI Symbol';" +
"font-size:10pt;" +
"overflow-x:hidden;" +
"overflow-y:scroll;" +
"}" +
"#debugConsoleOutput {" +
"width:100%;" +
"overflow-x: hidden;" +
"white-space: nowrap;" +
"}" +
"#debugConsole div {" +
"width:100%;" +
"overflow:hidden;" +
"}" +
".debugConsoleVerticalOverlay {" +
"background-color:blue;" +
"position:absolute;" +
"z-index:100000;" +
"}" +
".debugConsoleHorizontalOverlay {" +
"background-color:blue;" +
"position:absolute;" +
"z-index:100000;" +
"}" +
".debugConsoleLogText {" +
"color:lightgreen;" +
"font-style:italic;" +
"}" +
".debugConsoleExceptionText {" +
"color:red;" +
"font-weight:bold;" +
"}" +
".debugConsoleOutputText {" +
"color:rgba(200,200,200,1);" +
"}" +
".debugConsoleErrorText {" +
"color:red;" +
"}" +
".debugConsoleWarningText {" +
"color:yellow;" +
"}" +
".debugConsolePropertyExpander { " +
"cursor:pointer;" +
"margin-right:5px;" +
"font-family:Consolas;" +
"}" +
".debugConsolePropertyName {" +
"color:rgba(200,100,200,1);" +
"}" +
".debugConsoleObjectProperties {" +
"margin-left:15px;" +
"}" +
"#debugConsoleInput {" +
"font-family:inherit;" +
"font-size:inherit;" +
"border:none;" +
"width:95%;" +
"color:inherit;" +
"padding:0px;" +
"margin:0px;" +
"}" +
"#debugConsoleInput.debugConsoleSingleLine {" +
"height: 1.5em;" +
"overflow: hidden;" +
"background:none;" +
"}" +
"#debugConsoleInput.debugConsoleMultiLine {" +
"height: 10em;" +
"overflow: auto;" +
"background-color: rgba(0,0,0,0.4);" +
"}" +
"#debugConsoleInputFlip { " +
"vertical-align:top;" +
"cursor:pointer;" +
"}" +
".debugConsoleRegister {" +
"margin-left:5px;" +
"color:cyan;" +
"text-decoration:none;" +
"}" +
".debugConsoleHtmlComment {" +
"color:#d0d090;" +
"font-style:italic;" +
"}" +
".debugConsoleHtmlAttrName {" +
"color:#b0d0f0;" +
"}" +
".debugConsoleHtmlAttrValue {" +
"color:#80c0e0;" +
"}" +
".debugConsoleHtmlBracket {" +
"color:#f0c0f0;" +
"}" +
".debugConsoleHtmlText {" +
"color:#d0d0d0;" +
"font-style:italic;" +
"}" +
".debugConsoleCssOverriden {" +
"color:red;" +
"text-decoration:line-through;" +
"}" +
"@media screen and (max-width:340px) {" +
"#debugConsoleLayer {" +
"font-size: 8pt" +
"}" +
"}";
DebugJS.console = new DebugJSConsole();