diff --git a/src/Console/Log.es6 b/src/Console/Log.es6
index 8ed30d9..0673dd0 100644
--- a/src/Console/Log.es6
+++ b/src/Console/Log.es6
@@ -1,4 +1,5 @@
import util from '../lib/util'
+import stringify from '../lib/stringify.es6'
import highlight from '../lib/highlight.es6'
import beautify from 'js-beautify'
@@ -365,168 +366,6 @@ function extractSrc(args)
var extractObj = (obj, simple) => JSON.parse(stringify(obj, null, obj, simple));
-// Modified from: https://jsconsole.com/
-function stringify(obj, visited, topObj, simple)
-{
- let json = '',
- type = '',
- parts = [],
- names = [],
- proto,
- circular = false;
-
- visited = visited || [];
- topObj = topObj || obj;
-
- try {
- type = ({}).toString.call(obj);
- } catch (e)
- {
- type = '[object Object]';
- }
-
- var isFn = (type == '[object Function]'),
- isStr = (type == '[object String]'),
- isArr = (type == '[object Array]'),
- isObj = (type == '[object Object]'),
- isNum = (type == '[object Number]'),
- isSymbol = (type == '[object Symbol]'),
- isBool = (type == '[object Boolean]');
-
- for (let i = 0, len = visited.length; i < len; i++)
- {
- if (obj === visited[i])
- {
- circular = true;
- break;
- }
- }
-
- if (circular)
- {
- json = '"[circular]"';
- } else if (isStr)
- {
- json = `"${escapeJsonStr(obj)}"`;
- } else if (isArr)
- {
- visited.push(obj);
-
- json = '[';
- util.each(obj, val => parts.push(`${stringify(val, visited, null, simple)}`));
- json += parts.join(', ') + ']';
- } else if (isObj || isFn)
- {
- visited.push(obj);
-
- names = Object.getOwnPropertyNames(obj);
- proto = Object.getPrototypeOf(obj);
- if (proto === Object.prototype || isFn || simple) proto = null;
- if (proto) proto = `"erudaProto": ${stringify(proto, visited, topObj)}`;
- names.sort(sortObjName);
- if (isFn)
- {
- // We don't these properties to be display for functions.
- names = names.filter(val => ['arguments', 'caller', 'name', 'length', 'prototype'].indexOf(val) < 0);
- }
- if (names.length === 0 && isFn)
- {
- json = `"${escapeJsonStr(obj.toString())}"`;
- } else
- {
- json = '{';
- if (isFn)
- {
- // Function length is restricted to 500 for performance reason.
- var fnStr = obj.toString();
- if (fnStr.length > 500) fnStr = fnStr.slice(0, 500) + '...';
- parts.push(`"erudaObjAbstract": "${escapeJsonStr(fnStr)}"`);
- }
- util.each(names, name =>
- {
- parts.push(`"${escapeJsonStr(name)}": ${stringify(obj[name], visited, null, simple)}`);
- });
- if (proto) parts.push(proto);
- json += parts.join(', ') + '}';
- }
- } else if (isNum)
- {
- json = obj + '';
- if (util.endWith(json, 'Infinity') || json === 'NaN') json = `"${json}"`;
- } else if (isBool)
- {
- json = obj ? 'true' : 'false';
- } else if (obj === null)
- {
- json = 'null';
- } else if (isSymbol)
- {
- json = '"Symbol"';
- } else if (obj === undefined)
- {
- json = '"undefined"';
- } else
- {
- try
- {
- visited.push(obj);
-
- json = '{\n';
- if (!simple) parts.push(`"erudaObjAbstract": "${type.replace(/(\[object )|]/g, '')}"`);
- names = Object.getOwnPropertyNames(obj);
- proto = Object.getPrototypeOf(obj);
- if (proto === Object.prototype || simple) proto = null;
- if (proto)
- {
- try
- {
- proto = `"erudaProto": ${stringify(proto, visited, topObj)}`;
- } catch(e)
- {
- proto = `"erudaProto": "${escapeJsonStr(e.message)}"`;
- }
- }
- names.sort(sortObjName);
- util.each(names, name =>
- {
- let val = topObj[name];
-
- try
- {
- parts.push(`"${escapeJsonStr(name)}": ${stringify(val, visited, null, simple)}`);
- } catch (e)
- {
- parts.push(`"${escapeJsonStr(name)}": "${escapeJsonStr(e.message)}"`);
- }
- });
- if (proto) parts.push(proto);
- json += parts.join(',\n') + '\n}';
- } catch (e) {
- json = `"${obj}"`;
- }
- }
-
- return json;
-}
-
-var escapeJsonStr = str => str.replace(/\\/g, '\\\\')
- .replace(/"/g, '\\"')
- .replace(/\f|\n|\r|\t/g, '');
-
-var sortObjName = (a, b) =>
-{
- let codeA = a.charCodeAt(0),
- codeB = b.charCodeAt(0);
-
- if (isLetter(codeA) && !isLetter(codeB)) return -1;
- if (!isLetter(codeA) && isLetter(codeB)) return 1;
-
- return a > b ? 1 : -1;
-};
-
-var isLetter = code => (code > 64 && code < 90) || (code > 96 && code < 123);
-
-
var transMultipleMsg = args => args.map(val => transMsg(val)).join(' ');
var txtToHtml = str => str.replace(/\n/g, '
')
diff --git a/src/Elements/Elements.es6 b/src/Elements/Elements.es6
index c30bc1b..88dde63 100644
--- a/src/Elements/Elements.es6
+++ b/src/Elements/Elements.es6
@@ -1,5 +1,6 @@
import Tool from '../DevTools/Tool.es6'
import CssStore from './CssStore.es6'
+import stringify from '../lib/stringify.es6'
import Highlight from './Highlight.es6'
import Select from './Select.es6'
import util from '../lib/util'
@@ -126,6 +127,18 @@ export default class Elements extends Tool
sources.set('js', text);
parent.showTool('sources');
}
+ }).on('click', '.eruda-breadcrumb', () =>
+ {
+ let data = this._elData || JSON.parse(stringify(this._curEl, null, this._curEl, false)),
+ sources = parent.get('sources');
+
+ this._elData = data;
+
+ if (sources)
+ {
+ sources.set('json', data);
+ parent.showTool('sources');
+ }
}).on('click', '.toggle-all-computed-style', () => this._toggleAllComputedStyle());
var $bottomBar = this._$el.find('.eruda-bottom-bar');
@@ -173,6 +186,7 @@ export default class Elements extends Tool
_setEl(el)
{
this._curEl = el;
+ this._elData = null;
this._curCssStore = new CssStore(el);
this._highlight.setEl(el);
this._rmDefComputedStyle = true;
diff --git a/src/Elements/Elements.hbs b/src/Elements/Elements.hbs
index bc45674..499ed83 100644
--- a/src/Elements/Elements.hbs
+++ b/src/Elements/Elements.hbs
@@ -1,4 +1,4 @@
-