diff --git a/app/components/file-preview/component.js b/app/components/file-preview/component.js
index 8ce3c68..d94a7bd 100644
--- a/app/components/file-preview/component.js
+++ b/app/components/file-preview/component.js
@@ -1,6 +1,9 @@
import Component from '@ember/component';
import { inject as service } from '@ember/service';
+import { observer } from '@ember/object';
import { alias } from '@ember/object/computed';
+import { scheduleOnce } from '@ember/runloop';
+import JSONTreeView from 'npm:json-tree-view';
export default Component.extend({
@@ -12,13 +15,12 @@ export default Component.extend({
fileContent: null,
objectURL: null,
metaData: null,
- jsonView: null,
+ isJSON: null,
type: alias('metaData.type'),
isBinary: alias('metaData.isBinary'),
isImage: function() {
- return this.get('type').match(/^image\/.+$/);
- }.property('type'),
+ return this.get('type').match(/^image\/.+$/); }.property('type'),
isText: function() {
return !this.get('isBinary');
@@ -37,8 +39,65 @@ export default Component.extend({
} else {
this.set('fileContent', file.data);
}
+
this.set('fileLoaded', true);
});
- }.on('init')
+ }.on('didInsertElement'),
+
+ onFileLoaded: observer('fileLoaded', function(){
+ if (this.get('fileLoaded') && this.get('isJSON') && this.get('jsonShowTree')) {
+ scheduleOnce('afterRender', this, 'renderJsonTree');
+ }
+ }),
+
+ onJsonViewChanged: observer('jsonShowTree', function(){
+ if (this.get('fileLoaded') && this.get('isJSON') && this.get('jsonShowTree')) {
+ scheduleOnce('afterRender', this, 'renderJsonTree');
+ }
+ }),
+
+ renderJsonTree () {
+ let value = JSON.parse(this.get('fileContent'));
+
+ let view = new JSONTreeView('content', value);
+
+ // Listen for change events
+ view.on('change', function(self, key, oldValue, newValue){
+ console.log('change', key, oldValue, '=>', newValue);
+ });
+ view.on('rename', function(self, key, oldName, newName) {
+ console.log('rename', key, oldName, '=>', newName);
+ });
+ view.on('delete', function(self, key) {
+ console.log('delete', key);
+ });
+ view.on('append', function(self, key, nameOrValue, newValue) {
+ console.log('append', key, nameOrValue, '=>', newValue);
+ });
+ view.on('click', function(self, key, value) {
+ console.log('click', key, '=', value);
+ });
+ view.on('expand', function(self, key, value) {
+ console.log('expand', key, '=', value);
+ });
+ view.on('collapse', function(self, key, value) {
+ console.log('collapse', key, '=', value);
+ });
+ view.on('refresh', function(self, key, value) {
+ console.log('refresh', key, '=', value);
+ });
+
+ document.getElementById('json-tree-view')
+ .appendChild(view.dom);
+
+ window.jsonview = view;
+
+ view.expand(true);
+
+ view.withRootName = false;
+ view.readonly = true;
+
+ this.set('jsonTreeView', view);
+ }
});
diff --git a/app/components/file-preview/template.hbs b/app/components/file-preview/template.hbs
index 29dba52..1bd9acd 100644
--- a/app/components/file-preview/template.hbs
+++ b/app/components/file-preview/template.hbs
@@ -8,6 +8,14 @@
{{/if}}
{{#if isText}}
- {{fileContent}}
+ {{#if isJSON}}
+ {{#if jsonShowTree}}
+
{{fileContent}}
+ {{/if}}
+ {{else}}
+ {{fileContent}}
+ {{/if}}
{{/if}}
{{/if}}
\ No newline at end of file
diff --git a/app/controllers/inspect.js b/app/controllers/inspect.js
index b7c11e9..3e9681e 100644
--- a/app/controllers/inspect.js
+++ b/app/controllers/inspect.js
@@ -20,7 +20,7 @@ export default Controller.extend({
return !!this.get('model.documentMetaData.type').match(/application\/json/i);
}),
- jsonView: 'source',
+ jsonView: 'tree',
jsonShowTree: computed.equal('jsonView', 'tree'),
jsonShowSource: computed.equal('jsonView', 'source'),
diff --git a/app/styles/app.scss b/app/styles/app.scss
index 44e7a98..32460cc 100644
--- a/app/styles/app.scss
+++ b/app/styles/app.scss
@@ -24,3 +24,5 @@ body {
@import "components/directory-listing";
@import "components/file-preview";
@import "components/item-icon";
+
+@import "vendor/json-tree-view";
diff --git a/app/styles/vendor/_json-tree-view.scss b/app/styles/vendor/_json-tree-view.scss
new file mode 100644
index 0000000..d72fb77
--- /dev/null
+++ b/app/styles/vendor/_json-tree-view.scss
@@ -0,0 +1,149 @@
+.jsonView{
+ margin-left: 20px;
+ font-family: Consolas, "Lucida Console", Menlo, "dejavu sans mono", monospace;
+ font-size: 16px;
+ line-height: 16px;
+ padding: 2px;
+ cursor: default;
+ color: rgb(66, 66, 66);
+ white-space: nowrap;
+ -webkit-user-select: none;
+}
+
+.jsonView>div{
+ display: inline-block;
+}
+
+.jsonView.hidden{
+ display: none;
+}
+
+.jsonView>.children, .jsonView.insert{
+ display: block;
+}
+
+.jsonView>.name{
+ color: rgb(136, 19, 145);
+}
+
+.jsonView>.separator:before{
+ content: ":";
+}
+
+.jsonView>.separator{
+ padding-right: 5px;
+}
+
+.jsonView>.spacing{
+ display:inline-block;
+ width:15px;
+}
+.jsonView>.spacing::before{
+ content: '1';
+ visibility:hidden;
+}
+
+.jsonView>.value.null, .jsonView>.value.undefined{
+ color: rgb(128, 128, 128);
+}
+
+.jsonView>.value.boolean, .jsonView>.value.number{
+ color: rgb(28, 0, 207);
+}
+
+.jsonView>.value.string:not(.edit):before, .jsonView>.value.string:not(.edit):after{
+ content: "\"";
+}
+
+.jsonView>.value.string {
+ color: rgb(196, 26, 22);
+}
+
+.jsonView>.name:hover, .jsonView>.value:hover{
+ background-color: rgba(56, 121, 217, 0.1);
+}
+
+.jsonView>.expand, .jsonView>.collapse{
+ min-width: 20px;
+ margin-left: -20px;
+ cursor: pointer;
+}
+
+.jsonView>.expand:before{
+ content: '\25B6';
+}
+
+.jsonView>.collapse:before{
+ content: '\25BC';
+}
+
+.jsonView>.edit{
+ padding: 0px 5px 0px 5px;
+ white-space: nowrap;
+ overflow: hidden;
+ background-color: transparent;
+}
+
+.jsonView>.edit br{
+ display: none;
+}
+
+.jsonView>.edit *{
+ display: inline;
+ white-space: nowrap;
+}
+
+.jsonView>.value.edit{
+ color: rgb(0, 0, 0);
+}
+
+.jsonView>.delete:before{
+ content: '+';
+ transform: rotate(45deg);
+ -webkit-transform: rotate(45deg);
+ -o-transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ display: inline-block;
+}
+
+.jsonView>.delete{
+ opacity: 0;
+ display: inline;
+ padding: 3px;
+ cursor: pointer;
+ color: rgb(150, 150, 150);
+}
+
+.jsonView>.item:hover~.delete{
+ opacity: 1;
+ color: rgb(150, 150, 150);
+}
+.jsonView>.delete:hover{
+ opacity: 1;
+ color: rgb(0, 0, 0);
+ background: rgb(220, 220, 220);
+}
+
+.jsonView.readonly>.insert,.jsonView.readonly>.delete{
+ display: none !important;
+}
+.jsonView>.insert:before{
+ content: '+';
+}
+
+.jsonView>.insert{
+ display: none;
+ color: rgb(150, 150, 150);
+ cursor: pointer;
+}
+
+.jsonView.expanded>.insert, .jsonView.expanded>.insert{
+ display: inline-block;
+ margin-left: 20px;
+ padding: 3px;
+}
+
+.jsonView>.insert:hover{
+ color: rgb(0, 0, 0);
+ background: rgb(220, 220, 220);
+}
\ No newline at end of file
diff --git a/app/templates/inspect.hbs b/app/templates/inspect.hbs
index 3965205..b6bd452 100644
--- a/app/templates/inspect.hbs
+++ b/app/templates/inspect.hbs
@@ -14,10 +14,9 @@