Implemented mode form

This commit is contained in:
jos 2016-10-14 17:10:09 +02:00
parent 482720b28c
commit 6cf85d2ce9
7 changed files with 69 additions and 45 deletions

View File

@ -2,21 +2,25 @@ import { h } from 'preact'
import { escapeHTML } from './utils/stringUtils' import { escapeHTML } from './utils/stringUtils'
import JSONNode from './JSONNode' import JSONNode from './JSONNode'
import { valueType, isUrl } from './utils/typeUtils'
export default class JSONNodeViewer extends JSONNode { /**
constructor (props) { * JSONNodeForm
super(props) *
} * Creates JSONNodes without action menus and with readonly properties
*/
export default class JSONNodeForm extends JSONNode {
// render no action menu...
renderActionMenuButton () { renderActionMenuButton () {
return null return null
} }
// render no append menu...
renderAppendMenuButton () { renderAppendMenuButton () {
return null return null
} }
// render a readonly property
renderProperty (prop, data, options) { renderProperty (prop, data, options) {
if (prop !== null) { if (prop !== null) {
const isIndex = typeof prop === 'number' // FIXME: pass an explicit prop isIndex const isIndex = typeof prop === 'number' // FIXME: pass an explicit prop isIndex
@ -43,35 +47,4 @@ export default class JSONNodeViewer extends JSONNode {
}, content) }, content)
} }
} }
renderValue (value) {
const escapedValue = escapeHTML(value)
const type = valueType (value)
const isEmpty = escapedValue.length === 0
const itsAnUrl = isUrl(value)
const className = JSONNode.getValueClass(type, itsAnUrl, isEmpty)
if (itsAnUrl) {
return h('a', {
class: className,
href: escapedValue
}, escapedValue)
}
else {
return h('div', {
class: className,
contentEditable: 'false',
spellCheck: 'false',
onClick: this.handleClickValue
}, escapedValue)
}
}
handleClickValue = (event) => {
if (event.button === 0) { // Left click
this.openLinkIfUrl(event)
}
}
} }

42
src/JSONNodeView.js Normal file
View File

@ -0,0 +1,42 @@
import { h } from 'preact'
import { escapeHTML } from './utils/stringUtils'
import JSONNode from './JSONNode'
import JSONNodeForm from './JSONNodeForm'
import { valueType, isUrl } from './utils/typeUtils'
/**
* JSONNodeView
*
* Creates JSONNodes without action menus and with readonly properties and values
*/
export default class JSONNodeView extends JSONNodeForm {
// render a readonly value
renderValue (value) {
const escapedValue = escapeHTML(value)
const type = valueType (value)
const isEmpty = escapedValue.length === 0
const itsAnUrl = isUrl(value)
const className = JSONNode.getValueClass(type, itsAnUrl, isEmpty)
if (itsAnUrl) {
return h('a', {
class: className,
href: escapedValue
}, escapedValue)
}
else {
return h('div', {
class: className,
onClick: this.handleClickValue
}, escapedValue)
}
}
handleClickValue = (event) => {
if (event.button === 0) { // Left click
this.openLinkIfUrl(event)
}
}
}

View File

@ -6,7 +6,8 @@ import {
duplicate, insert, append, remove, changeType, changeValue, changeProperty, sort duplicate, insert, append, remove, changeType, changeValue, changeProperty, sort
} from './actions' } from './actions'
import JSONNode from './JSONNode' import JSONNode from './JSONNode'
import JSONNodeViewer from './JSONNodeViewer' import JSONNodeView from './JSONNodeView'
import JSONNodeForm from './JSONNodeForm'
import ModeButton from './menu/ModeButton' import ModeButton from './menu/ModeButton'
import { parseJSON } from './utils/jsonUtils' import { parseJSON } from './utils/jsonUtils'
@ -47,9 +48,10 @@ export default class TreeMode extends Component {
} }
render (props, state) { render (props, state) {
console.log('mode', props.mode) const Node = (props.mode === 'view')
const Node = props.mode === 'view' ? JSONNodeView
? JSONNodeViewer : (props.mode === 'form')
? JSONNodeForm
: JSONNode : JSONNode
return h('div', { return h('div', {

View File

@ -23,9 +23,10 @@
<label for="mode">mode: <label for="mode">mode:
<select id="mode"> <select id="mode">
<option value="code">code</option>
<option value="text">text</option> <option value="text">text</option>
<option value="code">code</option>
<option value="tree" selected>tree</option> <option value="tree" selected>tree</option>
<option value="form">form</option>
<option value="view">view</option> <option value="view">view</option>
</select> </select>
</label> </label>
@ -54,7 +55,7 @@
alert(err) alert(err)
}, },
mode: mode, mode: mode,
modes: ['text', 'code', 'tree', 'view'], modes: ['text', 'code', 'tree', 'form', 'view'],
indentation: 4 indentation: 4
} }
const editor = jsoneditor(container, options) const editor = jsoneditor(container, options)

View File

@ -5,9 +5,9 @@ import TreeMode from './TreeMode'
import '!style!css!less!./jsoneditor.less' import '!style!css!less!./jsoneditor.less'
// TODO: allow adding new modes
const modes = { const modes = {
code: CodeMode, code: CodeMode,
form: TreeMode,
text: TextMode, text: TextMode,
tree: TreeMode, tree: TreeMode,
view: TreeMode view: TreeMode

View File

@ -169,6 +169,12 @@ ul.jsoneditor-list {
background-color: #f5f5f5; background-color: #f5f5f5;
} }
.jsoneditor-mode-form {
.jsoneditor-property:hover {
background-color: inherit;
}
}
.jsoneditor-mode-view { .jsoneditor-mode-view {
.jsoneditor-property:hover, .jsoneditor-property:hover,
.jsoneditor-value:hover { .jsoneditor-value:hover {

View File

@ -31,7 +31,7 @@
* }} JSONPatchResult * }} JSONPatchResult
* *
* @typedef {{ * @typedef {{
* mode: 'code' | 'text' | 'tree' | 'view', * mode: 'code' | 'form' | 'text' | 'tree' | 'view',
* modes: string[], * modes: string[],
* indentation: number | string, * indentation: number | string,
* onChange: function (patch: JSONPatch, revert: JSONPatch), * onChange: function (patch: JSONPatch, revert: JSONPatch),