Implemented `findSelectionPointerFromEvent`
This commit is contained in:
parent
6c17d6256c
commit
aaa498b4ec
|
@ -2,6 +2,9 @@ body, input, select {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
font-size: 11pt; }
|
font-size: 11pt; }
|
||||||
|
|
||||||
|
body {
|
||||||
|
height: 2000px; }
|
||||||
|
|
||||||
.demo .menu {
|
.demo .menu {
|
||||||
margin: 20px 0; }
|
margin: 20px 0; }
|
||||||
.demo .menu button, .demo .menu label {
|
.demo .menu button, .demo .menu label {
|
||||||
|
|
|
@ -4,6 +4,10 @@ body, input, select {
|
||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
height: 2000px;
|
||||||
|
}
|
||||||
|
|
||||||
.demo {
|
.demo {
|
||||||
.menu {
|
.menu {
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
|
|
|
@ -89,10 +89,11 @@ export default class JSONNode extends PureComponent {
|
||||||
const jsonPropsCount = jsonProps.length
|
const jsonPropsCount = jsonProps.length
|
||||||
|
|
||||||
const nodeStart = h('div', {
|
const nodeStart = h('div', {
|
||||||
key: 'node',
|
key: 'node',
|
||||||
onKeyDown: this.handleKeyDown,
|
onKeyDown: this.handleKeyDown,
|
||||||
className: 'jsoneditor-node jsoneditor-object'
|
'data-selection-area': 'contents',
|
||||||
}, [
|
className: 'jsoneditor-node jsoneditor-object'
|
||||||
|
}, [
|
||||||
this.renderExpandButton(),
|
this.renderExpandButton(),
|
||||||
// this.renderDelimiter('\u2610'),
|
// this.renderDelimiter('\u2610'),
|
||||||
this.renderProperty(),
|
this.renderProperty(),
|
||||||
|
@ -121,24 +122,39 @@ export default class JSONNode extends PureComponent {
|
||||||
options: this.props.options
|
options: this.props.options
|
||||||
}))
|
}))
|
||||||
|
|
||||||
childs = h('div', {key: 'childs', className: 'jsoneditor-list'}, propsChilds)
|
childs = h('div', {
|
||||||
|
key: 'childs',
|
||||||
|
'data-selection-area': 'left',
|
||||||
|
className: 'jsoneditor-list'
|
||||||
|
}, propsChilds)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
childs = h('div', {key: 'childs', className: 'jsoneditor-list', 'data-area': 'emptyBefore'},
|
childs = h('div', {
|
||||||
this.renderAppend('(empty object)')
|
key: 'childs',
|
||||||
|
className: 'jsoneditor-list',
|
||||||
|
'data-area': 'emptyBefore', // TODO: remove
|
||||||
|
'data-selection-area': 'left'
|
||||||
|
},
|
||||||
|
this.renderEmpty('(empty object)')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodeEnd = this.props.eson[EXPANDED]
|
const nodeEnd = this.props.eson[EXPANDED]
|
||||||
? h('div', {key: 'node-end', className: 'jsoneditor-node-end', 'data-area': 'empty'}, [
|
? h('div', {
|
||||||
this.renderDelimiter('}', 'jsoneditor-delimiter-end')
|
key: 'node-end',
|
||||||
|
className: 'jsoneditor-node-end',
|
||||||
|
'data-selection-area': 'right',
|
||||||
|
'data-area': 'empty', // TODO: remove
|
||||||
|
}, [
|
||||||
|
this.renderDelimiter('}', 'jsoneditor-delimiter-end', 'left')
|
||||||
])
|
])
|
||||||
: null
|
: null
|
||||||
|
|
||||||
return h('div', {
|
return h('div', {
|
||||||
'data-path': compileJSONPointer(this.state.path),
|
'data-path': compileJSONPointer(this.state.path),
|
||||||
'data-area': 'empty',
|
'data-area': 'empty', // TODO: remove
|
||||||
|
'data-selection-area': 'right',
|
||||||
className: this.getContainerClassName(this.props.eson[SELECTION], this.state.hover),
|
className: this.getContainerClassName(this.props.eson[SELECTION], this.state.hover),
|
||||||
// onMouseOver: this.handleMouseOver,
|
// onMouseOver: this.handleMouseOver,
|
||||||
// onMouseLeave: this.handleMouseLeave
|
// onMouseLeave: this.handleMouseLeave
|
||||||
|
@ -151,6 +167,7 @@ export default class JSONNode extends PureComponent {
|
||||||
const nodeStart = h('div', {
|
const nodeStart = h('div', {
|
||||||
key: 'node',
|
key: 'node',
|
||||||
onKeyDown: this.handleKeyDown,
|
onKeyDown: this.handleKeyDown,
|
||||||
|
'data-selection-area': 'contents',
|
||||||
className: 'jsoneditor-node jsoneditor-array'
|
className: 'jsoneditor-node jsoneditor-array'
|
||||||
}, [
|
}, [
|
||||||
this.renderExpandButton(),
|
this.renderExpandButton(),
|
||||||
|
@ -180,24 +197,34 @@ export default class JSONNode extends PureComponent {
|
||||||
findKeyBinding: this.props.findKeyBinding
|
findKeyBinding: this.props.findKeyBinding
|
||||||
}))
|
}))
|
||||||
|
|
||||||
childs = h('div', {key: 'childs', className: 'jsoneditor-list'}, items)
|
childs = h('div', {
|
||||||
|
key: 'childs',
|
||||||
|
'data-selection-area': 'left',
|
||||||
|
className: 'jsoneditor-list'
|
||||||
|
}, items)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
childs = h('div', {key: 'childs', className: 'jsoneditor-list', 'data-area': 'emptyBefore'},
|
childs = h('div', {
|
||||||
this.renderAppend('(empty array)')
|
key: 'childs',
|
||||||
|
className: 'jsoneditor-list',
|
||||||
|
'data-selection-area': 'left',
|
||||||
|
'data-area': 'emptyBefore' // TODO: remove data-area
|
||||||
|
},
|
||||||
|
this.renderEmpty('(empty array)')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodeEnd = this.props.eson[EXPANDED]
|
const nodeEnd = this.props.eson[EXPANDED]
|
||||||
? h('div', {key: 'node-end', className: 'jsoneditor-node-end', 'data-area': 'empty'}, [
|
? h('div', {key: 'node-end', className: 'jsoneditor-node-end', 'data-area': 'empty'}, [ // TODO: remove data-area
|
||||||
this.renderDelimiter(']', 'jsoneditor-delimiter-end')
|
this.renderDelimiter(']', 'jsoneditor-delimiter-end', 'left')
|
||||||
])
|
])
|
||||||
: null
|
: null
|
||||||
|
|
||||||
return h('div', {
|
return h('div', {
|
||||||
'data-path': compileJSONPointer(this.state.path),
|
'data-path': compileJSONPointer(this.state.path),
|
||||||
'data-area': 'empty',
|
'data-area': 'empty', // TODO: remove data-area
|
||||||
|
'data-selection-area': 'right',
|
||||||
className: this.getContainerClassName(this.props.eson[SELECTION], this.state.hover),
|
className: this.getContainerClassName(this.props.eson[SELECTION], this.state.hover),
|
||||||
// onMouseOver: this.handleMouseOver,
|
// onMouseOver: this.handleMouseOver,
|
||||||
// onMouseLeave: this.handleMouseLeave
|
// onMouseLeave: this.handleMouseLeave
|
||||||
|
@ -208,6 +235,7 @@ export default class JSONNode extends PureComponent {
|
||||||
const node = h('div', {
|
const node = h('div', {
|
||||||
key: 'node',
|
key: 'node',
|
||||||
onKeyDown: this.handleKeyDown,
|
onKeyDown: this.handleKeyDown,
|
||||||
|
'data-selection-area': 'contents',
|
||||||
className: 'jsoneditor-node'
|
className: 'jsoneditor-node'
|
||||||
}, [
|
}, [
|
||||||
this.renderPlaceholder(),
|
this.renderPlaceholder(),
|
||||||
|
@ -221,7 +249,8 @@ export default class JSONNode extends PureComponent {
|
||||||
|
|
||||||
return h('div', {
|
return h('div', {
|
||||||
'data-path': compileJSONPointer(this.state.path),
|
'data-path': compileJSONPointer(this.state.path),
|
||||||
'data-area': 'empty',
|
'data-area': 'empty', // TODO: remove
|
||||||
|
'data-selection-area': 'right',
|
||||||
className: this.getContainerClassName(this.props.eson[SELECTION], this.state.hover),
|
className: this.getContainerClassName(this.props.eson[SELECTION], this.state.hover),
|
||||||
// onMouseOver: this.handleMouseOver,
|
// onMouseOver: this.handleMouseOver,
|
||||||
// onMouseLeave: this.handleMouseLeave
|
// onMouseLeave: this.handleMouseLeave
|
||||||
|
@ -233,22 +262,27 @@ export default class JSONNode extends PureComponent {
|
||||||
* @param {string} text
|
* @param {string} text
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
renderAppend (text) {
|
renderEmpty (text) {
|
||||||
return h('div', {
|
return h('div', {
|
||||||
'data-path': compileJSONPointer(this.state.path) + '/-',
|
'data-path': compileJSONPointer(this.state.path) + '/-',
|
||||||
'data-area': 'empty',
|
'data-area': 'empty', // TODO: remove
|
||||||
className: 'jsoneditor-node',
|
'data-selection-area': 'right',
|
||||||
onKeyDown: this.handleKeyDownAppend
|
className: 'jsoneditor-node-container'
|
||||||
}, [
|
}, h('div', {
|
||||||
this.renderPlaceholder('inside'),
|
className: 'jsoneditor-node',
|
||||||
|
'data-selection-area': 'contents',
|
||||||
|
onKeyDown: this.handleKeyDownAppend
|
||||||
|
}, [
|
||||||
|
this.renderPlaceholder(),
|
||||||
this.renderReadonly(text)
|
this.renderReadonly(text)
|
||||||
])
|
]))
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPlaceholder (dataArea = 'value') {
|
renderPlaceholder () {
|
||||||
return h('div', {
|
return h('div', {
|
||||||
key: 'placeholder',
|
key: 'placeholder',
|
||||||
'data-area': dataArea,
|
// 'data-area': dataArea, // TODO: remove
|
||||||
|
'data-selection-area': 'left',
|
||||||
className: 'jsoneditor-button-placeholder'
|
className: 'jsoneditor-button-placeholder'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -256,7 +290,7 @@ export default class JSONNode extends PureComponent {
|
||||||
renderReadonly (text, title = null, dataArea = 'inside') {
|
renderReadonly (text, title = null, dataArea = 'inside') {
|
||||||
return h('div', {
|
return h('div', {
|
||||||
key: 'readonly',
|
key: 'readonly',
|
||||||
'data-area': dataArea,
|
'data-area': dataArea, // TODO: remove
|
||||||
className: 'jsoneditor-readonly',
|
className: 'jsoneditor-readonly',
|
||||||
title
|
title
|
||||||
}, text)
|
}, text)
|
||||||
|
@ -320,14 +354,15 @@ export default class JSONNode extends PureComponent {
|
||||||
return h('div', {
|
return h('div', {
|
||||||
key: 'separator',
|
key: 'separator',
|
||||||
className: 'jsoneditor-delimiter',
|
className: 'jsoneditor-delimiter',
|
||||||
'data-area': 'value'
|
'data-area': 'value' // TODO: remove
|
||||||
}, ':')
|
}, ':')
|
||||||
}
|
}
|
||||||
|
|
||||||
renderDelimiter (text, className = '') {
|
renderDelimiter (text, className = '', dataArea) {
|
||||||
return h('div', {
|
return h('div', {
|
||||||
key: text,
|
key: text,
|
||||||
'data-area': 'value',
|
'data-area': 'value', // TODO: remove
|
||||||
|
'data-selection-area': dataArea,
|
||||||
className: 'jsoneditor-delimiter ' + className
|
className: 'jsoneditor-delimiter ' + className
|
||||||
}, text)
|
}, text)
|
||||||
}
|
}
|
||||||
|
@ -520,6 +555,7 @@ export default class JSONNode extends PureComponent {
|
||||||
|
|
||||||
return h('div', {key: 'expand', className: 'jsoneditor-button-container'},
|
return h('div', {key: 'expand', className: 'jsoneditor-button-container'},
|
||||||
h('button', {
|
h('button', {
|
||||||
|
'data-selection-area': 'left',
|
||||||
className: className,
|
className: className,
|
||||||
onClick: this.handleExpand,
|
onClick: this.handleExpand,
|
||||||
title:
|
title:
|
||||||
|
@ -561,12 +597,6 @@ export default class JSONNode extends PureComponent {
|
||||||
this.setState({hover: null})
|
this.setState({hover: null})
|
||||||
}
|
}
|
||||||
|
|
||||||
static getRootName (value, options) {
|
|
||||||
return typeof options.name === 'string'
|
|
||||||
? options.name
|
|
||||||
: value[TYPE]
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
handleChangeProperty = (event) => {
|
handleChangeProperty = (event) => {
|
||||||
const parentPath = initial(this.state.path)
|
const parentPath = initial(this.state.path)
|
||||||
|
|
|
@ -57,10 +57,12 @@ import {
|
||||||
pathsFromSelection,
|
pathsFromSelection,
|
||||||
previousSearchResult,
|
previousSearchResult,
|
||||||
search,
|
search,
|
||||||
|
SELECTION,
|
||||||
syncEson
|
syncEson
|
||||||
} from '../eson'
|
} from '../eson'
|
||||||
import TreeModeMenu from './menu/TreeModeMenu'
|
import TreeModeMenu from './menu/TreeModeMenu'
|
||||||
import Search from './menu/Search'
|
import Search from './menu/Search'
|
||||||
|
import { findParentWithAttribute } from '../utils/domUtils'
|
||||||
|
|
||||||
const AJV_OPTIONS = {
|
const AJV_OPTIONS = {
|
||||||
allErrors: true,
|
allErrors: true,
|
||||||
|
@ -254,9 +256,9 @@ export default class TreeMode extends PureComponent {
|
||||||
onMouseDown: this.handleTouchStart,
|
onMouseDown: this.handleTouchStart,
|
||||||
onTouchStart: this.handleTouchStart,
|
onTouchStart: this.handleTouchStart,
|
||||||
className: 'jsoneditor-list jsoneditor-root' +
|
className: 'jsoneditor-list jsoneditor-root' +
|
||||||
(/*eson[META].selected*/ false ? ' jsoneditor-selected' : '')}, // FIXME
|
(eson[SELECTION] !== false ? ' jsoneditor-selected' : '')},
|
||||||
h(Node, {
|
h(Node, {
|
||||||
path: [],
|
parentPath: null,
|
||||||
eson,
|
eson,
|
||||||
emit: this.emitter.emit,
|
emit: this.emitter.emit,
|
||||||
findKeyBinding: this.findKeyBinding,
|
findKeyBinding: this.findKeyBinding,
|
||||||
|
@ -781,6 +783,10 @@ export default class TreeMode extends PureComponent {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selectionPointer = this.findSelectionPointerFromEvent(event)
|
||||||
|
|
||||||
|
console.log('touchStart selectionPointer=', selectionPointer)
|
||||||
|
|
||||||
const pointer = this.findJSONPointerFromElement(event.target)
|
const pointer = this.findJSONPointerFromElement(event.target)
|
||||||
const clickedOnEmptySpace = (event.target.nodeName === 'DIV') &&
|
const clickedOnEmptySpace = (event.target.nodeName === 'DIV') &&
|
||||||
(event.target.contentEditable !== 'true') &&
|
(event.target.contentEditable !== 'true') &&
|
||||||
|
@ -856,6 +862,25 @@ export default class TreeMode extends PureComponent {
|
||||||
return path ? { path, area } : null
|
return path ? { path, area } : null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find JSON pointer from an HTML element
|
||||||
|
* @param {Event} event
|
||||||
|
* @return {SelectionPointer | null}
|
||||||
|
*/
|
||||||
|
findSelectionPointerFromEvent (event) {
|
||||||
|
const areaParent = findParentWithAttribute(event.target, 'data-selection-area')
|
||||||
|
const area = areaParent ? areaParent.getAttribute('data-selection-area') : undefined
|
||||||
|
|
||||||
|
const base = (area === 'left')
|
||||||
|
? document.elementFromPoint(event.target.getBoundingClientRect().right - 1, event.clientY)
|
||||||
|
: event.target
|
||||||
|
|
||||||
|
const pathParent = findParentWithAttribute(base, 'data-path')
|
||||||
|
const path = pathParent ? pathParent.getAttribute('data-path') : undefined
|
||||||
|
|
||||||
|
return (area !== undefined && path !== undefined) ? { area, path } : null
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get selection from an JSONPointer
|
* Get selection from an JSONPointer
|
||||||
* @param {ESONPointer} pointer
|
* @param {ESONPointer} pointer
|
||||||
|
|
|
@ -37,6 +37,13 @@
|
||||||
* }} Selection
|
* }} Selection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{
|
||||||
|
* area: 'left' | 'contents' | 'after',
|
||||||
|
* path: Path
|
||||||
|
* }} SelectionPointer
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{matches: ESONPointer[], active: ESONPointer, text: String}} SearchResult
|
* @typedef {{matches: ESONPointer[], active: ESONPointer, text: String}} SearchResult
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue