Implemented mode `text`
This commit is contained in:
parent
84031dc3ef
commit
b44a465207
|
@ -0,0 +1,101 @@
|
||||||
|
import { h, Component } from 'preact'
|
||||||
|
import { parseJSON } from './utils/jsonUtils'
|
||||||
|
|
||||||
|
export default class TextMode extends Component {
|
||||||
|
// TODO: define propTypes
|
||||||
|
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
text: '{}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render (props, state) {
|
||||||
|
return h('div', {class: 'jsoneditor jsoneditor-mode-text'}, [
|
||||||
|
h('div', {class: 'jsoneditor-menu'}, [
|
||||||
|
h('button', {
|
||||||
|
class: 'jsoneditor-format',
|
||||||
|
title: 'Format the JSON document',
|
||||||
|
onClick: this.format
|
||||||
|
}),
|
||||||
|
h('button', {
|
||||||
|
class: 'jsoneditor-compact',
|
||||||
|
title: 'Compact the JSON document',
|
||||||
|
onClick: this.compact
|
||||||
|
})
|
||||||
|
// TODO: implement a button "Fix JSON"
|
||||||
|
]),
|
||||||
|
|
||||||
|
h('div', {class: 'jsoneditor-contents'}, [
|
||||||
|
h('textarea', {class: 'jsoneditor-text', value: this.state.text})
|
||||||
|
])
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the configured indentation
|
||||||
|
* @return {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
getIndentation () {
|
||||||
|
return this.props.options && this.props.options.indentation || 2
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the json
|
||||||
|
*/
|
||||||
|
format = () => {
|
||||||
|
var json = this.get()
|
||||||
|
var text = JSON.stringify(json, null, this.getIndentation())
|
||||||
|
this.setText(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compact the json
|
||||||
|
*/
|
||||||
|
compact = () => {
|
||||||
|
var json = this.get()
|
||||||
|
var text = JSON.stringify(json)
|
||||||
|
this.setText(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply a JSONPatch to the current JSON document
|
||||||
|
* @param {JSONPatch} actions JSONPatch actions
|
||||||
|
* @return {JSONPatch} Returns a JSONPatch to revert the applied patch
|
||||||
|
*/
|
||||||
|
patch (actions) {
|
||||||
|
// TODO: implement patch
|
||||||
|
throw new Error('Patch not yet implemented')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set JSON object in editor
|
||||||
|
* @param {Object | Array | string | number | boolean | null} json JSON data
|
||||||
|
*/
|
||||||
|
set (json) {
|
||||||
|
this.setState({
|
||||||
|
text: JSON.stringify(json, null, this.getIndentation())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get JSON from the editor
|
||||||
|
* @returns {Object | Array | string | number | boolean | null} json
|
||||||
|
*/
|
||||||
|
get () {
|
||||||
|
return parseJSON(this.state.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: comment
|
||||||
|
setText (text) {
|
||||||
|
this.setState({ text })
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: comment
|
||||||
|
getText () {
|
||||||
|
return this.state.text
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,7 +48,8 @@ export default class TreeMode extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render (props, state) {
|
render (props, state) {
|
||||||
return h('div', {class: 'jsoneditor'}, [
|
// TODO: make mode tree dynamic
|
||||||
|
return h('div', {class: 'jsoneditor jsoneditor-mode-tree'}, [
|
||||||
h('div', {class: 'jsoneditor-menu'}, [
|
h('div', {class: 'jsoneditor-menu'}, [
|
||||||
h('button', {
|
h('button', {
|
||||||
class: 'jsoneditor-expand-all',
|
class: 'jsoneditor-expand-all',
|
||||||
|
@ -75,8 +76,8 @@ export default class TreeMode extends Component {
|
||||||
})
|
})
|
||||||
]),
|
]),
|
||||||
|
|
||||||
h('div', {class: 'jsoneditor-treemode', contentEditable: 'false', onClick: JSONNode.hideContextMenu}, [
|
h('div', {class: 'jsoneditor-contents jsoneditor-tree-contents', onClick: JSONNode.hideContextMenu}, [
|
||||||
h('ul', {class: 'jsoneditor-list', contentEditable: 'false'}, [
|
h('ul', {class: 'jsoneditor-list'}, [
|
||||||
h(JSONNode, {
|
h(JSONNode, {
|
||||||
data: state.data,
|
data: state.data,
|
||||||
events: state.events,
|
events: state.events,
|
||||||
|
|
|
@ -29,7 +29,9 @@
|
||||||
console.log('onChange patch=', patch, ', revert=', revert)
|
console.log('onChange patch=', patch, ', revert=', revert)
|
||||||
window.patch = patch
|
window.patch = patch
|
||||||
window.revert = revert
|
window.revert = revert
|
||||||
}
|
},
|
||||||
|
mode: 'text',
|
||||||
|
indentation: 4
|
||||||
};
|
};
|
||||||
const editor = jsoneditor(container, options);
|
const editor = jsoneditor(container, options);
|
||||||
const json = {
|
const json = {
|
||||||
|
|
14
src/index.js
14
src/index.js
|
@ -1,8 +1,16 @@
|
||||||
import { h, render } from 'preact'
|
import { h, render } from 'preact'
|
||||||
import TreeMode from './TreeMode'
|
import TreeMode from './TreeMode'
|
||||||
|
import TextMode from './TextMode'
|
||||||
|
|
||||||
import '!style!css!less!./jsoneditor.less'
|
import '!style!css!less!./jsoneditor.less'
|
||||||
|
|
||||||
|
// TODO: allow adding new modes
|
||||||
|
const modes = {
|
||||||
|
tree: TreeMode,
|
||||||
|
text: TextMode,
|
||||||
|
default: TreeMode
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new json editor
|
* Create a new json editor
|
||||||
* @param {HTMLElement} container
|
* @param {HTMLElement} container
|
||||||
|
@ -11,7 +19,10 @@ import '!style!css!less!./jsoneditor.less'
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function jsoneditor (container, options) {
|
function jsoneditor (container, options) {
|
||||||
const elem = render(h(TreeMode, {options}), container)
|
const mode = options && options.mode
|
||||||
|
const constructor = modes[mode] || modes['default']
|
||||||
|
|
||||||
|
const elem = render(h(constructor, {options}), container)
|
||||||
const component = elem._component
|
const component = elem._component
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -20,6 +31,7 @@ function jsoneditor (container, options) {
|
||||||
_container: container,
|
_container: container,
|
||||||
_options: options,
|
_options: options,
|
||||||
_component: component,
|
_component: component,
|
||||||
|
_modes: modes,
|
||||||
|
|
||||||
// TODO: implement setMode
|
// TODO: implement setMode
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
|
@fontFamily: droid sans mono, consolas, monospace, courier new, courier, sans-serif;
|
||||||
|
@fontSize: 10pt;
|
||||||
|
@black: #1A1A1A;
|
||||||
|
|
||||||
.jsoneditor {
|
.jsoneditor {
|
||||||
border: 1px solid #3883fa;
|
border: 1px solid #3883fa;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 150px;
|
|
||||||
|
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -69,16 +72,30 @@
|
||||||
background-position: -48px -120px;
|
background-position: -48px -120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button.jsoneditor-compact {
|
||||||
|
background-position: -72px -96px;
|
||||||
|
}
|
||||||
|
button.jsoneditor-format {
|
||||||
|
background-position: -72px -120px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.jsoneditor-treemode {
|
.jsoneditor-contents {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto;
|
min-height: 150px;
|
||||||
padding: 2px 0;
|
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.jsoneditor-tree-contents {
|
||||||
|
padding: 2px 0;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.jsoneditor-node {
|
.jsoneditor-node {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
@ -110,8 +127,8 @@ ul.jsoneditor-list {
|
||||||
.jsoneditor-separator {
|
.jsoneditor-separator {
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
|
|
||||||
font-family: droid sans mono, consolas, monospace, courier new, courier, sans-serif;
|
font-family: @fontFamily;
|
||||||
font-size: 10pt;
|
font-size: @fontSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jsoneditor-property,
|
.jsoneditor-property,
|
||||||
|
@ -122,7 +139,7 @@ ul.jsoneditor-list {
|
||||||
|
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
|
|
||||||
color: #1A1A1A;
|
color: @black;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +332,7 @@ button.jsoneditor-menu-button {
|
||||||
|
|
||||||
button.jsoneditor-menu-button:hover,
|
button.jsoneditor-menu-button:hover,
|
||||||
button.jsoneditor-menu-button:focus {
|
button.jsoneditor-menu-button:focus {
|
||||||
color: #1a1a1a;
|
color: @black;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
@ -481,3 +498,21 @@ button.jsoneditor-type-Array:focus span.jsoneditor-icon,
|
||||||
button.jsoneditor-type-Array.jsoneditor-selected span.jsoneditor-icon {
|
button.jsoneditor-type-Array.jsoneditor-selected span.jsoneditor-icon {
|
||||||
background-position: -96px 0;
|
background-position: -96px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
textarea.jsoneditor-text {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 150px;
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
outline-width: 0;
|
||||||
|
border: none;
|
||||||
|
background-color: #fff;
|
||||||
|
resize: none;
|
||||||
|
|
||||||
|
font-family: @fontFamily;
|
||||||
|
font-size: @fontSize;
|
||||||
|
color: @black;
|
||||||
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
* @typedef {Array.<{op: string, path?: string, from?: string, value?: *}>} JSONPatch
|
* @typedef {Array.<{op: string, path?: string, from?: string, value?: *}>} JSONPatch
|
||||||
*
|
*
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
*
|
* mode: 'tree' | 'text'
|
||||||
* }} Options
|
* }} Options
|
||||||
*
|
*
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
|
|
Loading…
Reference in New Issue