"use strict"; var samsam = require("@sinonjs/samsam"); var formatio = { excludeConstructors: ["Object", /^.$/], quoteStrings: true, limitChildrenCount: 0 }; var specialObjects = []; if (typeof global !== "undefined") { specialObjects.push({ object: global, value: "[object global]" }); } if (typeof document !== "undefined") { specialObjects.push({ object: document, value: "[object HTMLDocument]" }); } if (typeof window !== "undefined") { specialObjects.push({ object: window, value: "[object Window]" }); } function functionName(func) { if (!func) { return ""; } if (func.displayName) { return func.displayName; } if (func.name) { return func.name; } var matches = func.toString().match(/function\s+([^\(]+)/m); return (matches && matches[1]) || ""; } function constructorName(f, object) { var name = functionName(object && object.constructor); var excludes = f.excludeConstructors || formatio.excludeConstructors || []; var i, l; for (i = 0, l = excludes.length; i < l; ++i) { if (typeof excludes[i] === "string" && excludes[i] === name) { return ""; } else if (excludes[i].test && excludes[i].test(name)) { return ""; } } return name; } function isCircular(object, objects) { if (typeof object !== "object") { return false; } var i, l; for (i = 0, l = objects.length; i < l; ++i) { if (objects[i] === object) { return true; } } return false; } function ascii(f, object, processed, indent) { if (typeof object === "string") { if (object.length === 0) { return "(empty string)"; } var qs = f.quoteStrings; var quote = typeof qs !== "boolean" || qs; return processed || quote ? "\"" + object + "\"" : object; } if (typeof object === "function" && !(object instanceof RegExp)) { return ascii.func(object); } processed = processed || []; if (isCircular(object, processed)) { return "[Circular]"; } if (Object.prototype.toString.call(object) === "[object Array]") { return ascii.array.call(f, object, processed); } if (!object) { return String((1 / object) === -Infinity ? "-0" : object); } if (samsam.isElement(object)) { return ascii.element(object); } if (typeof object.toString === "function" && object.toString !== Object.prototype.toString) { return object.toString(); } var i, l; for (i = 0, l = specialObjects.length; i < l; i++) { if (object === specialObjects[i].object) { return specialObjects[i].value; } } if (typeof Set !== "undefined" && object instanceof Set) { return ascii.set.call(f, object, processed); } return ascii.object.call(f, object, processed, indent); } ascii.func = function (func) { return "function " + functionName(func) + "() {}"; }; function delimit(str, delimiters) { delimiters = delimiters || ["[", "]"]; return delimiters[0] + str + delimiters[1]; } ascii.array = function (array, processed, delimiters) { processed = processed || []; processed.push(array); var pieces = []; var i, l; l = (this.limitChildrenCount > 0) ? Math.min(this.limitChildrenCount, array.length) : array.length; for (i = 0; i < l; ++i) { pieces.push(ascii(this, array[i], processed)); } if (l < array.length) { pieces.push("[... " + (array.length - l) + " more elements]"); } return delimit(pieces.join(", "), delimiters); }; ascii.set = function (set, processed) { return ascii.array.call(this, Array.from(set), processed, ["Set {", "}"]); }; ascii.object = function (object, processed, indent) { processed = processed || []; processed.push(object); indent = indent || 0; var pieces = []; var properties = Object.keys(object).sort(); var length = 3; var prop, str, obj, i, k, l; l = (this.limitChildrenCount > 0) ? Math.min(this.limitChildrenCount, properties.length) : properties.length; for (i = 0; i < l; ++i) { prop = properties[i]; obj = object[prop]; if (isCircular(obj, processed)) { str = "[Circular]"; } else { str = ascii(this, obj, processed, indent + 2); } str = (/\s/.test(prop) ? "\"" + prop + "\"" : prop) + ": " + str; length += str.length; pieces.push(str); } var cons = constructorName(this, object); var prefix = cons ? "[" + cons + "] " : ""; var is = ""; for (i = 0, k = indent; i < k; ++i) { is += " "; } if (l < properties.length) {pieces.push("[... " + (properties.length - l) + " more elements]");} if (length + indent > 80) { return prefix + "{\n " + is + pieces.join(",\n " + is) + "\n" + is + "}"; } return prefix + "{ " + pieces.join(", ") + " }"; }; ascii.element = function (element) { var tagName = element.tagName.toLowerCase(); var attrs = element.attributes; var pairs = []; var attr, attrName, i, l, val; for (i = 0, l = attrs.length; i < l; ++i) { attr = attrs.item(i); attrName = attr.nodeName.toLowerCase().replace("html:", ""); val = attr.nodeValue; if (attrName !== "contenteditable" || val !== "inherit") { if (val) { pairs.push(attrName + "=\"" + val + "\""); } } } var formatted = "<" + tagName + (pairs.length > 0 ? " " : ""); // SVG elements have undefined innerHTML var content = element.innerHTML || ""; if (content.length > 20) { content = content.substr(0, 20) + "[...]"; } var res = formatted + pairs.join(" ") + ">" + content + ""; return res.replace(/ contentEditable="inherit"/, ""); }; function Formatio(options) { // eslint-disable-next-line guard-for-in for (var opt in options) { this[opt] = options[opt]; } } Formatio.prototype = { functionName: functionName, configure: function (options) { return new Formatio(options); }, constructorName: function (object) { return constructorName(this, object); }, ascii: function (object, processed, indent) { return ascii(this, object, processed, indent); } }; module.exports = Formatio.prototype;