/devtoolsformatter-example.js Secret
Last active
January 11, 2021 21:26
-
-
Save paulirish/ac138a480ac971a0b500 to your computer and use it in GitHub Desktop.
examples for devtoolsFormatter for custom object display in Chrome DevTools
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// see examples in https://docs.google.com/document/d/1FTascZXT9cxfetuPRT2eXPQKXui4nWFivUnS_335T3U/edit# | |
Formatter = function(simpleFormatter) | |
{ | |
this._simpleFormatter = simpleFormatter; | |
} | |
Formatter.prototype = { | |
header: function(object) | |
{ | |
if ((object instanceof Node)) | |
return null; | |
var header = new JsonMLElement("span"); | |
header.createTextChild(this._simpleFormatter.description(object)); | |
return header.toJsonML(); | |
}, | |
hasBody: function(object) | |
{ | |
if (object instanceof Array) | |
return false; | |
return this._simpleFormatter.hasChildren(object); | |
}, | |
body: function(object) | |
{ | |
var body = new JsonMLElement("ol"); | |
body.setStyle("list-style-type:none; padding-left: 0px; margin-top: 0px; margin-bottom: 0px; margin-left: 12px"); | |
var children = this._simpleFormatter.children(object); | |
for (var i = 0; i < children.length; ++i) { | |
var child = children[i]; | |
var li = body.createChild("li"); | |
var objectTag; | |
if (typeof child.value === "object") | |
objectTag = li.createObjectTag(child.value); | |
else | |
objectTag = li.createChild("span"); | |
var nameSpan = objectTag.createChild("span"); | |
nameSpan.createTextChild(child.key + ": "); | |
nameSpan.setStyle("color: rgb(136, 19, 145);"); | |
if (child.value instanceof Node) { | |
var node = child.value; | |
objectTag.createTextChild(node.nodeName.toLowerCase()); | |
if (node.id) | |
objectTag.createTextChild("#" + node.id) | |
else | |
objectTag.createTextChild("." + node.className) | |
} | |
if (typeof child.value !== "object") | |
objectTag.createTextChild("" + child.value); | |
} | |
return body.toJsonML(); | |
}, | |
_arrayFormatter: function(array) | |
{ | |
var j = new JsonMLElement(); | |
j.createTextChild("["); | |
for (var i = 0; i < array.length; ++i) { | |
if (i != 0) | |
j.createTextChild(", ") | |
j.createObjectTag(array[i]); | |
} | |
j.createTextChild("]"); | |
return j; | |
} | |
} | |
JsonMLElement = function(tagName) | |
{ | |
this._attributes = {}; | |
this._jsonML = [tagName, this._attributes]; | |
} | |
JsonMLElement.prototype = { | |
createChild: function(tagName) | |
{ | |
var c = new JsonMLElement(tagName); | |
this._jsonML.push(c.toJsonML()); | |
return c; | |
}, | |
createObjectTag: function(object) | |
{ | |
var tag = this.createChild("object"); | |
tag.addAttribute("object", object); | |
return tag; | |
}, | |
setStyle: function(style) | |
{ | |
this._attributes["style"] = style; | |
}, | |
addAttribute: function(key, value) | |
{ | |
this._attributes[key] = value; | |
}, | |
createTextChild: function(text) | |
{ | |
this._jsonML.push(text + ""); | |
}, | |
toJsonML: function() | |
{ | |
return this._jsonML; | |
} | |
} | |
function SimpleFormatter() | |
{ | |
} | |
SimpleFormatter.prototype = { | |
description: function(object) | |
{ | |
if ((typeof object === "object") && object) | |
return object.constructor.name; | |
return object; | |
}, | |
hasChildren: function(object) | |
{ | |
return (typeof object === "object"); | |
}, | |
children: function(object) | |
{ | |
var result = []; | |
for (var key in object) | |
result.push({key: key, value: object[key]}); | |
return result; | |
} | |
} | |
window["devtoolsFormatter"] = new Formatter(new SimpleFormatter()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// see examples in https://docs.google.com/document/d/1FTascZXT9cxfetuPRT2eXPQKXui4nWFivUnS_335T3U/edit# | |
JsonMLFormatter = function(simpleFormatter) | |
{ | |
this._simpleFormatter = simpleFormatter; | |
} | |
JsonMLFormatter.prototype = { | |
header: function(object) | |
{ | |
var c = this._simpleFormatter.preview(object); | |
if (c === null) | |
return null; | |
var header = new JsonMLElement('span'); | |
header.createTextChild(c); | |
return header.toJsonML(); | |
}, | |
hasBody: function(object) | |
{ | |
return this._simpleFormatter.hasChildren(object); | |
}, | |
body: function(object) | |
{ | |
var body = new JsonMLElement('ol'); | |
body.setStyle('list-style-type:none; padding-left: 0px; margin-top: 0px; margin-bottom: 0px; margin-left: 12px'); | |
var children = this._simpleFormatter.children(object); | |
for (var i = 0; i < children.length; ++i) { | |
var child = children[i]; | |
var li = body.createChild('li'); | |
var nameSpan = new JsonMLElement('span'); | |
nameSpan.createTextChild(child.name + ': '); | |
nameSpan.setStyle('color: rgb(136, 19, 145);'); | |
if (typeof child.value === 'object') { | |
var objectTag = li.createObjectTag(child.value); | |
objectTag.appendChild(nameSpan); | |
if (!this._simpleFormatter.hasChildren(child.value)) | |
li.setStyle("padding-left: 13px;"); | |
} else { | |
li.setStyle("padding-left: 13px;"); | |
var objectTag = li.createChild('span'); | |
objectTag.appendChild(nameSpan); | |
objectTag.createTextChild('' + child.value); | |
} | |
} | |
return body.toJsonML(); | |
} | |
} | |
JsonMLElement = function(tagName) | |
{ | |
this._attributes = {}; | |
this._jsonML = [tagName, this._attributes]; | |
} | |
JsonMLElement.prototype = { | |
appendChild: function(element) | |
{ | |
this._jsonML.push(element.toJsonML()); | |
}, | |
createChild: function(tagName) | |
{ | |
var c = new JsonMLElement(tagName); | |
this._jsonML.push(c.toJsonML()); | |
return c; | |
}, | |
createObjectTag: function(object) | |
{ | |
var tag = this.createChild('object'); | |
tag.addAttribute('object', object); | |
return tag; | |
}, | |
setStyle: function(style) | |
{ | |
this._attributes['style'] = style; | |
}, | |
addAttribute: function(key, value) | |
{ | |
this._attributes[key] = value; | |
}, | |
createTextChild: function(text) | |
{ | |
this._jsonML.push(text + ''); | |
}, | |
toJsonML: function() | |
{ | |
return this._jsonML; | |
} | |
} | |
GwtSimpleFormatter = function () | |
{ | |
this._formatters = [new MapFormatter(), new SetFormatter(), new ArrayFormatter(), new EntryFormatter(), new ObjectFormatter()]; | |
} | |
GwtSimpleFormatter.__INTERNAL_TYPE = '__formatter_internal_type'; | |
GwtSimpleFormatter.__INTERNAL_TYPES = { | |
Entry: 'entry' | |
}; | |
GwtSimpleFormatter.prototype = { | |
preview: function(object) | |
{ | |
if (typeof object === 'undefined') | |
return 'undefined'; | |
if (typeof object === 'number') | |
return object + ''; | |
if (typeof object === 'string') | |
return object; | |
if (!object) | |
return 'null'; | |
for (var i = 0; i < this._formatters.length; ++i) { | |
var formatter = this._formatters[i]; | |
if (formatter.accept(object)) | |
return formatter.preview(object); | |
} | |
return null; | |
}, | |
hasChildren: function(object) | |
{ | |
if (!object) | |
return false; | |
for (var i = 0; i < this._formatters.length; ++i) { | |
var formatter = this._formatters[i]; | |
if (formatter.accept(object)) | |
return formatter.hasChildren(object); | |
} | |
return false; | |
}, | |
children: function(object) | |
{ | |
if (!object) | |
return []; | |
for (var i = 0; i < this._formatters.length; ++i) { | |
var formatter = this._formatters[i]; | |
if (formatter.accept(object)) | |
return formatter.children(object); | |
} | |
return []; | |
} | |
}; | |
ObjectFormatter = function() {}; | |
ObjectFormatter.prototype = { | |
accept: function(object) | |
{ | |
return !!object.getClass$ | |
}, | |
preview: function(object) | |
{ | |
var type = object.getClass$().compoundName_1_g$; | |
return type; | |
}, | |
hasChildren: function(object) | |
{ | |
return !!Object.keys(object).length; | |
}, | |
children: function(object) | |
{ | |
var keys= Object.keys(object); | |
var properties = []; | |
for (var i = 0; i < keys.length; ++i) | |
properties.push(this._createPropertyPreview(keys[i], object[keys[i]])); | |
return properties; | |
}, | |
_createPropertyPreview: function(key, value) | |
{ | |
var result = {}; | |
result.name = this._tryToCutKey(key) || key; | |
result.value = value; | |
return result; | |
}, | |
_tryToCutKey: function(key) | |
{ | |
var ind = key.lastIndexOf('_'); | |
if (ind === -1) | |
return null; | |
var len = key.lastIndexOf('_', ind - 1); | |
if (len === -1) | |
return null; | |
return key.substring(0, len); | |
} | |
}; | |
MapFormatter = function() {}; | |
MapFormatter.prototype = { | |
accept: function(object) | |
{ | |
if (!object.getClass$) | |
return false; | |
var clazz = object.getClass$(); | |
return clazz.compoundName_1_g$ === 'HashMap'; | |
}, | |
hasChildren: function(object) | |
{ | |
return !!object.size_2_g$; | |
}, | |
preview: function(object) | |
{ | |
var type = object.getClass$().compoundName_1_g$; | |
var size = object.size_2_g$; | |
return type + ' size = ' + size; | |
}, | |
children: function(object) | |
{ | |
var stringChildren = this._retrieveStringEntries(object); | |
if (stringChildren.length) | |
return stringChildren; | |
return this._retrieveObjectEntries(object); | |
}, | |
_retrieveStringEntries: function(object) | |
{ | |
var mapObject = object.stringMap_0_g$.backingMap_2_g$; | |
var entries = []; | |
var keys = Object.keys(mapObject); | |
for (var i = 0; i < keys.length; ++i) { | |
var entry = {name: keys[i], value: mapObject[keys[i]]}; | |
entries.push(entry); | |
} | |
return entries; | |
}, | |
_retrieveObjectEntries: function(object) | |
{ | |
var mapObject = object.hashCodeMap_0_g$.backingMap_1_g$ | |
var entries = []; | |
var keys = Object.keys(mapObject); | |
for (var i = 0; i < keys.length; ++i) { | |
var bucket = mapObject[keys[i]]; | |
for (var j = 0; j < bucket.length; ++j) { | |
var entry = bucket[j]; | |
var entryWrapper = {key: entry.key_1_g$, value: entry.value_15_g$}; | |
entryWrapper[GwtSimpleFormatter.__INTERNAL_TYPE] = 'entry'; | |
entries.push({name: entries.length + '', value: entryWrapper}); | |
} | |
} | |
return entries; | |
} | |
} | |
ArrayFormatter = function() {}; | |
ArrayFormatter.prototype = { | |
accept: function(object) | |
{ | |
if (!object.___clazz$ || !(object instanceof Array)) | |
return false; | |
return true; | |
}, | |
preview: function(object) | |
{ | |
var type = object.___clazz$.componentType_1_g$.compoundName_1_g$; | |
return type + '[] size = ' + object.length; | |
}, | |
hasChildren: function(object) | |
{ | |
return !!object.length; | |
}, | |
children: function(object) | |
{ | |
var result = []; | |
for (var i = 0; i < object.length; ++i) { | |
result.push({name: i + '', value: object[i]}); | |
} | |
return result; | |
} | |
} | |
EntryFormatter = function() {}; | |
EntryFormatter.prototype = { | |
accept: function(object) | |
{ | |
return object[GwtSimpleFormatter.__INTERNAL_TYPE] === GwtSimpleFormatter.__INTERNAL_TYPES.Entry; | |
}, | |
preview: function(object) | |
{ | |
var keyPreview = window.devtoolsFormatter._simpleFormatter.preview(object.key); | |
var valuePreview = window.devtoolsFormatter._simpleFormatter.preview(object.value); | |
return keyPreview + ' => ' + valuePreview; | |
}, | |
hasChildren: function(object) | |
{ | |
return true; | |
}, | |
children: function(object) | |
{ | |
var keyProperty = {name: 'key', value: object.key}; | |
var valueProperty = {name: 'value', value: object.value}; | |
return [keyProperty, valueProperty]; | |
} | |
}; | |
SetFormatter = function() {}; | |
SetFormatter.prototype = { | |
accept: function(object) | |
{ | |
if (!object.getClass$) | |
return false; | |
var clazz = object.getClass$(); | |
return clazz.compoundName_1_g$ === 'HashSet'; | |
}, | |
preview: function(object) | |
{ | |
var type = object.getClass$().compoundName_1_g$; | |
var size = object.map_1_g$.size_2_g$; | |
return type + ' size = ' + size; | |
}, | |
hasChildren: function(object) | |
{ | |
return !!object.map_1_g$.size_2_g$; | |
}, | |
children: function(object) | |
{ | |
var map = object.map_1_g$; | |
var mapObject = map.stringMap_0_g$.backingMap_2_g$; | |
var entries = []; | |
var keys = Object.keys(mapObject); | |
for (var i = 0; i < keys.length; ++i) { | |
var entry = {name: i + '', value: keys[i]}; | |
entries.push(entry); | |
} | |
return entries; | |
} | |
}; | |
window['devtoolsFormatter'] = new JsonMLFormatter(new GwtSimpleFormatter()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment