{el.localName}${idents}>`; } function prettyWindowGlobal(win) { let proto = Object.prototype.toString.call(win); return `[${proto.substring(1, proto.length - 1)} ${win.location}]`; } function prettyAttr(obj) { return `[object Attr ${obj.name}="${obj.value}"]`; } function prettyObject(obj) { let proto = Object.prototype.toString.call(obj); let s = ""; try { s = JSON.stringify(obj); } catch (e) { if (e instanceof TypeError) { s = `<${e.message}>`; } else { throw e; } } return `${proto} ${s}`; } let res = []; for (let i = 0; i < ss.length; i++) { res.push(ss[i]); if (i < values.length) { let s; try { s = pretty(values[i]); } catch (e) { lazy.logger.warn("Problem pretty printing:", e); s = typeof values[i]; } res.push(s); } } return res.join(""); } /** * Template literal that truncates string values in arbitrary objects. * * Given any object, the template will walk the object and truncate * any strings it comes across to a reasonable limit. This is suitable * when you have arbitrary data and data integrity is not important. * * The strings are truncated in the middle so that the beginning and * the end is preserved. This will make a long, truncated string look * like "X <...> Y", where X and Y are half the number of characters * of the maximum string length from either side of the string. * * * Usage:: * * truncate`Hello ${"x".repeat(260)}!`; * // Hello xxx ... xxx! * * Functions named `toJSON` or `toString` on objects will be called. */ export function truncate(strings, ...values) { function walk(obj) { const typ = Object.prototype.toString.call(obj); switch (typ) { case "[object Undefined]": case "[object Null]": case "[object Boolean]": case "[object Number]": return obj; case "[object String]": if (lazy.truncateLog && obj.length > MAX_STRING_LENGTH) { let s1 = obj.substring(0, MAX_STRING_LENGTH / 2); let s2 = obj.substring(obj.length - MAX_STRING_LENGTH / 2); return `${s1} ... ${s2}`; } return obj; case "[object Array]": return obj.map(walk); // arbitrary object default: { if ( Object.getOwnPropertyNames(obj).includes("toString") && typeof obj.toString == "function" ) { return walk(obj.toString()); } let rv = {}; for (let prop in obj) { rv[prop] = walk(obj[prop]); } return rv; } } } let res = []; for (let i = 0; i < strings.length; ++i) { res.push(strings[i]); if (i < values.length) { let obj = walk(values[i]); let t = Object.prototype.toString.call(obj); if (t == "[object Array]" || t == "[object Object]") { res.push(JSON.stringify(obj)); } else { res.push(obj); } } } return res.join(""); } PK