Implemented selecting nodes

This commit is contained in:
jos 2017-09-29 10:06:14 +02:00
parent eee0b55636
commit 52ec02e3e1
7 changed files with 87 additions and 31 deletions

31
package-lock.json generated
View File

@ -3422,6 +3422,11 @@
"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": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
@ -6205,6 +6210,14 @@
"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": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz",
@ -7050,15 +7063,6 @@
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
"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": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
@ -7070,6 +7074,15 @@
"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": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/stringifier/-/stringifier-1.3.0.tgz",

View File

@ -29,7 +29,8 @@
"brace": "0.9.1",
"javascript-natural-sort": "0.7.1",
"lodash": "4.17.4",
"prop-types": "15.5.10"
"prop-types": "15.5.10",
"react-hammerjs": "0.5.0"
},
"devDependencies": {
"ava": "0.17.0",

View File

@ -145,7 +145,7 @@ export default class JSONNode extends Component {
*/
renderAppend (text) {
return h('div', {
'data-path': compileJSONPointer(this.props.path) + '/#',
'data-path': compileJSONPointer(this.props.path) + '/-',
className: 'jsoneditor-node',
onKeyDown: this.handleKeyDownAppend
}, [

View File

@ -1,6 +1,8 @@
// @flow weak
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 Ajv from 'ajv'
@ -13,7 +15,7 @@ import {
expand, expandPath, addErrors,
search, applySearchResults, nextSearchResult, previousSearchResult,
applySelection,
compileJSONPointer
compileJSONPointer, parseJSONPointer
} from '../eson'
import { patchEson } from '../patchEson'
import {
@ -32,7 +34,7 @@ import {
import { createFindKeyBinding } from '../utils/keyBindings'
import { KEY_BINDINGS } from '../constants'
import type { ESON, ESONPatch } from '../types'
import type { ESON, ESONPatch, JSONPath } from '../types'
const AJV_OPTIONS = {
allErrors: true,
@ -182,19 +184,26 @@ export default class TreeMode extends Component {
this.renderMenu(searchResults),
h('div', {
key: 'contents',
ref: 'contents',
className: 'jsoneditor-contents jsoneditor-tree-contents',
id: this.id
key: 'contents',
ref: 'contents',
className: 'jsoneditor-contents jsoneditor-tree-contents'
},
h('ul', {className: 'jsoneditor-list jsoneditor-root' + (data.selected ? ' jsoneditor-selected' : '')},
h(Node, {
data,
events: state.events,
options: props,
path: [],
prop: null
})
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(Node, {
data,
events: state.events,
options: props,
path: [],
prop: null
})
)
)
)
])
@ -494,6 +503,42 @@ export default class TreeMode extends Component {
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
* @param {Path} path

View File

@ -12,6 +12,7 @@ div.jsoneditor-search {
form.jsoneditor-search-box {
display: inline-flex;
position: relative;
max-width: 100%;
background-color: white;
border: 2px solid @theme-color;
@ -80,4 +81,4 @@ div.jsoneditor-search {
background-position: -148px -49px;
}
}
}
}

View File

@ -442,6 +442,7 @@ div.jsoneditor-menu-separator {
div.jsoneditor-menu-panel-right {
float: right;
max-width: 100%;
}
button.jsoneditor-remove span.jsoneditor-icon {

View File

@ -8,11 +8,6 @@ import {
applySelection
} 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 ESON1 = loadJSON('./resources/eson1.json')
const ESON2 = loadJSON('./resources/eson2.json')