Implemented selecting nodes
This commit is contained in:
parent
eee0b55636
commit
52ec02e3e1
|
@ -3422,6 +3422,11 @@
|
||||||
"glogg": "1.0.0"
|
"glogg": "1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"hammerjs": {
|
||||||
|
"version": "2.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
|
||||||
|
"integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE="
|
||||||
|
},
|
||||||
"har-validator": {
|
"har-validator": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
|
||||||
|
@ -6205,6 +6210,14 @@
|
||||||
"object-assign": "4.1.1"
|
"object-assign": "4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-hammerjs": {
|
||||||
|
"version": "0.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-hammerjs/-/react-hammerjs-0.5.0.tgz",
|
||||||
|
"integrity": "sha1-qiDlxfRNZg8+joftESgvEhc+d64=",
|
||||||
|
"requires": {
|
||||||
|
"hammerjs": "2.0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"read-all-stream": {
|
"read-all-stream": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz",
|
||||||
|
@ -7050,15 +7063,6 @@
|
||||||
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
|
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"string_decoder": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"safe-buffer": "5.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"string-width": {
|
"string-width": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||||
|
@ -7070,6 +7074,15 @@
|
||||||
"strip-ansi": "3.0.1"
|
"strip-ansi": "3.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"string_decoder": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "5.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"stringifier": {
|
"stringifier": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/stringifier/-/stringifier-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/stringifier/-/stringifier-1.3.0.tgz",
|
||||||
|
|
|
@ -29,7 +29,8 @@
|
||||||
"brace": "0.9.1",
|
"brace": "0.9.1",
|
||||||
"javascript-natural-sort": "0.7.1",
|
"javascript-natural-sort": "0.7.1",
|
||||||
"lodash": "4.17.4",
|
"lodash": "4.17.4",
|
||||||
"prop-types": "15.5.10"
|
"prop-types": "15.5.10",
|
||||||
|
"react-hammerjs": "0.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"ava": "0.17.0",
|
"ava": "0.17.0",
|
||||||
|
|
|
@ -145,7 +145,7 @@ export default class JSONNode extends Component {
|
||||||
*/
|
*/
|
||||||
renderAppend (text) {
|
renderAppend (text) {
|
||||||
return h('div', {
|
return h('div', {
|
||||||
'data-path': compileJSONPointer(this.props.path) + '/#',
|
'data-path': compileJSONPointer(this.props.path) + '/-',
|
||||||
className: 'jsoneditor-node',
|
className: 'jsoneditor-node',
|
||||||
onKeyDown: this.handleKeyDownAppend
|
onKeyDown: this.handleKeyDownAppend
|
||||||
}, [
|
}, [
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
// @flow weak
|
// @flow weak
|
||||||
|
|
||||||
import { createElement as h, Component } from 'react'
|
import { createElement as h, Component } from 'react'
|
||||||
|
import isEqual from 'lodash/isEqual'
|
||||||
|
import Hammer from 'react-hammerjs'
|
||||||
import jump from '../assets/jump.js/src/jump'
|
import jump from '../assets/jump.js/src/jump'
|
||||||
import Ajv from 'ajv'
|
import Ajv from 'ajv'
|
||||||
|
|
||||||
|
@ -13,7 +15,7 @@ import {
|
||||||
expand, expandPath, addErrors,
|
expand, expandPath, addErrors,
|
||||||
search, applySearchResults, nextSearchResult, previousSearchResult,
|
search, applySearchResults, nextSearchResult, previousSearchResult,
|
||||||
applySelection,
|
applySelection,
|
||||||
compileJSONPointer
|
compileJSONPointer, parseJSONPointer
|
||||||
} from '../eson'
|
} from '../eson'
|
||||||
import { patchEson } from '../patchEson'
|
import { patchEson } from '../patchEson'
|
||||||
import {
|
import {
|
||||||
|
@ -32,7 +34,7 @@ import {
|
||||||
import { createFindKeyBinding } from '../utils/keyBindings'
|
import { createFindKeyBinding } from '../utils/keyBindings'
|
||||||
import { KEY_BINDINGS } from '../constants'
|
import { KEY_BINDINGS } from '../constants'
|
||||||
|
|
||||||
import type { ESON, ESONPatch } from '../types'
|
import type { ESON, ESONPatch, JSONPath } from '../types'
|
||||||
|
|
||||||
const AJV_OPTIONS = {
|
const AJV_OPTIONS = {
|
||||||
allErrors: true,
|
allErrors: true,
|
||||||
|
@ -184,8 +186,14 @@ export default class TreeMode extends Component {
|
||||||
h('div', {
|
h('div', {
|
||||||
key: 'contents',
|
key: 'contents',
|
||||||
ref: 'contents',
|
ref: 'contents',
|
||||||
className: 'jsoneditor-contents jsoneditor-tree-contents',
|
className: 'jsoneditor-contents jsoneditor-tree-contents'
|
||||||
id: this.id
|
},
|
||||||
|
h(Hammer, {
|
||||||
|
id: this.id,
|
||||||
|
direction: 'DIRECTION_VERTICAL',
|
||||||
|
onTap: this.handleTap,
|
||||||
|
onPanStart: this.handlePanStart,
|
||||||
|
onPan: this.handlePan
|
||||||
},
|
},
|
||||||
h('ul', {className: 'jsoneditor-list jsoneditor-root' + (data.selected ? ' jsoneditor-selected' : '')},
|
h('ul', {className: 'jsoneditor-list jsoneditor-root' + (data.selected ? ' jsoneditor-selected' : '')},
|
||||||
h(Node, {
|
h(Node, {
|
||||||
|
@ -197,6 +205,7 @@ export default class TreeMode extends Component {
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,6 +503,42 @@ export default class TreeMode extends Component {
|
||||||
this.emitOnChange (actions, result.revert, result.data)
|
this.emitOnChange (actions, result.revert, result.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleTap = (event) => {
|
||||||
|
if (this.state.selection) {
|
||||||
|
this.setState({ selection: null })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePanStart = (event) => {
|
||||||
|
const path = this.findDataPathFromElement(event.target.firstChild)
|
||||||
|
if (path) {
|
||||||
|
this.setState({
|
||||||
|
selection: {
|
||||||
|
start: {path},
|
||||||
|
end: {path}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePan = (event) => {
|
||||||
|
const path = this.findDataPathFromElement(event.target.firstChild)
|
||||||
|
if (path && this.state.selection && !isEqual(path, this.state.selection.end.path)) {
|
||||||
|
this.setState({
|
||||||
|
selection: {
|
||||||
|
start: this.state.selection.start,
|
||||||
|
end: {path}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
findDataPathFromElement (element: Element) : JSONPath | null {
|
||||||
|
// The .replace is to change paths like `/myarray/-` into `/myarray`
|
||||||
|
const attr = element && element.getAttribute && element.getAttribute('data-path').replace(/\/-$/, '')
|
||||||
|
return attr ? parseJSONPointer(attr) : null
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scroll the window vertically to the node with given path
|
* Scroll the window vertically to the node with given path
|
||||||
* @param {Path} path
|
* @param {Path} path
|
||||||
|
|
|
@ -12,6 +12,7 @@ div.jsoneditor-search {
|
||||||
form.jsoneditor-search-box {
|
form.jsoneditor-search-box {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
max-width: 100%;
|
||||||
|
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border: 2px solid @theme-color;
|
border: 2px solid @theme-color;
|
||||||
|
|
|
@ -442,6 +442,7 @@ div.jsoneditor-menu-separator {
|
||||||
|
|
||||||
div.jsoneditor-menu-panel-right {
|
div.jsoneditor-menu-panel-right {
|
||||||
float: right;
|
float: right;
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.jsoneditor-remove span.jsoneditor-icon {
|
button.jsoneditor-remove span.jsoneditor-icon {
|
||||||
|
|
|
@ -8,11 +8,6 @@ import {
|
||||||
applySelection
|
applySelection
|
||||||
} from '../src/eson'
|
} from '../src/eson'
|
||||||
|
|
||||||
|
|
||||||
// TODO: move all JSON documents in separate json files to keep the test readable?
|
|
||||||
|
|
||||||
// TODO: instead of all slightly different copies of ESON, built them up via setIn, updateIn based on ESON
|
|
||||||
|
|
||||||
const JSON1 = loadJSON('./resources/json1.json')
|
const JSON1 = loadJSON('./resources/json1.json')
|
||||||
const ESON1 = loadJSON('./resources/eson1.json')
|
const ESON1 = loadJSON('./resources/eson1.json')
|
||||||
const ESON2 = loadJSON('./resources/eson2.json')
|
const ESON2 = loadJSON('./resources/eson2.json')
|
||||||
|
|
Loading…
Reference in New Issue