Implemented top/bottom positioning of ActionMenu
This commit is contained in:
parent
ccf89162b7
commit
d73b79cb4e
|
@ -6,22 +6,46 @@ import FloatingMenu from './menu/FloatingMenu'
|
|||
import { escapeHTML, unescapeHTML } from '../utils/stringUtils'
|
||||
import { getInnerText, insideRect } from '../utils/domUtils'
|
||||
import { stringConvert, valueType, isUrl } from '../utils/typeUtils'
|
||||
import { compileJSONPointer, META, SELECTED, SELECTED_END, SELECTED_AFTER, SELECTED_BEFORE } from '../eson'
|
||||
import {
|
||||
compileJSONPointer,
|
||||
META,
|
||||
SELECTED, SELECTED_START, SELECTED_END, SELECTED_AFTER, SELECTED_BEFORE, SELECTED_FIRST, SELECTED_LAST
|
||||
} from '../eson'
|
||||
|
||||
// TODO: rename SELECTED, SELECTED_END, etc to AREA_*? It's used for both selection and hovering
|
||||
const SELECTED_CLASS_NAMES = {
|
||||
[SELECTED]: ' jsoneditor-selected',
|
||||
[SELECTED_END]: ' jsoneditor-selected jsoneditor-selected-end',
|
||||
[SELECTED_AFTER]: ' jsoneditor-selected jsoneditor-selected-insert-area',
|
||||
[SELECTED_BEFORE]: ' jsoneditor-selected jsoneditor-selected-insert-area',
|
||||
}
|
||||
const MENU_ITEMS_OBJECT = [
|
||||
{type: 'sort'},
|
||||
{type: 'duplicate'},
|
||||
{type: 'cut'},
|
||||
{type: 'copy'},
|
||||
{type: 'paste'},
|
||||
{type: 'remove'}
|
||||
]
|
||||
|
||||
const HOVERED_CLASS_NAMES = {
|
||||
[SELECTED]: ' jsoneditor-hover',
|
||||
[SELECTED_END]: ' jsoneditor-hover jsoneditor-hover-end',
|
||||
[SELECTED_AFTER]: ' jsoneditor-hover jsoneditor-hover-insert-area',
|
||||
[SELECTED_BEFORE]: ' jsoneditor-hover jsoneditor-hover-insert-area',
|
||||
}
|
||||
const MENU_ITEMS_ARRAY = [
|
||||
{type: 'sort'},
|
||||
{type: 'duplicate'},
|
||||
{type: 'cut'},
|
||||
{type: 'copy'},
|
||||
{type: 'paste'},
|
||||
{type: 'remove'}
|
||||
]
|
||||
|
||||
const MENU_ITEMS_VALUE = [
|
||||
// {text: 'String', onClick: this.props.emit('changeType', {type: 'checkbox', checked: false}}),
|
||||
{type: 'duplicate'},
|
||||
{type: 'cut'},
|
||||
{type: 'copy'},
|
||||
{type: 'paste'},
|
||||
{type: 'remove'}
|
||||
]
|
||||
|
||||
const MENU_ITEMS_INSERT_BEFORE = [
|
||||
{type: 'insertStructure'},
|
||||
{type: 'insertValue'},
|
||||
{type: 'insertObject'},
|
||||
{type: 'insertArray'},
|
||||
{type: 'paste'},
|
||||
]
|
||||
|
||||
export default class JSONNode extends PureComponent {
|
||||
static URL_TITLE = 'Ctrl+Click or Ctrl+Enter to open url'
|
||||
|
@ -46,7 +70,7 @@ export default class JSONNode extends PureComponent {
|
|||
state = {
|
||||
menu: null, // can contain object {anchor, root}
|
||||
appendMenu: null, // can contain object {anchor, root}
|
||||
hover: false
|
||||
hover: null
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
|
@ -104,17 +128,7 @@ export default class JSONNode extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
const floatingMenu = (meta.selected === SELECTED_END)
|
||||
? this.renderFloatingMenu([
|
||||
{type: 'sort'},
|
||||
{type: 'duplicate'},
|
||||
{type: 'cut'},
|
||||
{type: 'copy'},
|
||||
{type: 'paste'},
|
||||
{type: 'remove'}
|
||||
])
|
||||
: null
|
||||
|
||||
const floatingMenu = this.renderFloatingMenu(MENU_ITEMS_OBJECT, meta.selected)
|
||||
const insertArea = this.renderInsertBeforeArea()
|
||||
|
||||
return h('div', {
|
||||
|
@ -159,17 +173,7 @@ export default class JSONNode extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
const floatingMenu = (meta.selected === SELECTED_END)
|
||||
? this.renderFloatingMenu([
|
||||
{type: 'sort'},
|
||||
{type: 'duplicate'},
|
||||
{type: 'cut'},
|
||||
{type: 'copy'},
|
||||
{type: 'paste'},
|
||||
{type: 'remove'}
|
||||
])
|
||||
: null
|
||||
|
||||
const floatingMenu = this.renderFloatingMenu(MENU_ITEMS_ARRAY, meta.selected)
|
||||
const insertArea = this.renderInsertBeforeArea()
|
||||
|
||||
return h('div', {
|
||||
|
@ -194,16 +198,7 @@ export default class JSONNode extends PureComponent {
|
|||
this.renderError(meta.error)
|
||||
])
|
||||
|
||||
const floatingMenu = (meta.selected === SELECTED_END)
|
||||
? this.renderFloatingMenu([
|
||||
// {text: 'String', onClick: this.props.emit('changeType', {type: 'checkbox', checked: false}}),
|
||||
{type: 'duplicate'},
|
||||
{type: 'cut'},
|
||||
{type: 'copy'},
|
||||
{type: 'paste'},
|
||||
{type: 'remove'}
|
||||
])
|
||||
: null
|
||||
const floatingMenu = this.renderFloatingMenu(MENU_ITEMS_VALUE, meta.selected)
|
||||
|
||||
const insertArea = this.renderInsertBeforeArea()
|
||||
|
||||
|
@ -216,14 +211,9 @@ export default class JSONNode extends PureComponent {
|
|||
}
|
||||
|
||||
renderInsertBeforeArea () {
|
||||
const floatingMenu = (this.props.value[META].selected === SELECTED_BEFORE)
|
||||
? this.renderFloatingMenu([
|
||||
{type: 'insertStructure'},
|
||||
{type: 'insertValue'},
|
||||
{type: 'insertObject'},
|
||||
{type: 'insertArray'},
|
||||
{type: 'paste'},
|
||||
])
|
||||
const floatingMenu = ((this.props.value[META].selected & SELECTED_BEFORE) !== 0)
|
||||
? this.renderFloatingMenu(MENU_ITEMS_INSERT_BEFORE,
|
||||
SELECTED + SELECTED_END + SELECTED_FIRST)
|
||||
: null
|
||||
|
||||
return h('div', {
|
||||
|
@ -356,9 +346,23 @@ export default class JSONNode extends PureComponent {
|
|||
}
|
||||
|
||||
getContainerClassName (selected, hover) {
|
||||
return 'jsoneditor-node-container' +
|
||||
(hover ? (HOVERED_CLASS_NAMES[hover]) : '') +
|
||||
(selected ? (SELECTED_CLASS_NAMES[selected]) : '')
|
||||
let classNames = ['jsoneditor-node-container']
|
||||
|
||||
if ((selected & SELECTED) !== 0) { classNames.push('jsoneditor-selected') }
|
||||
if ((selected & SELECTED_START) !== 0) { classNames.push('jsoneditor-selected-start') }
|
||||
if ((selected & SELECTED_END) !== 0) { classNames.push('jsoneditor-selected-end') }
|
||||
if ((selected & SELECTED_FIRST) !== 0) { classNames.push('jsoneditor-selected-first') }
|
||||
if ((selected & SELECTED_LAST) !== 0) { classNames.push('jsoneditor-selected-last') }
|
||||
if ((selected & SELECTED_BEFORE) !== 0) { classNames.push('jsoneditor-selected-insert-area-before') }
|
||||
if ((selected & SELECTED_AFTER) !== 0) { classNames.push('jsoneditor-selected-insert-area-after') }
|
||||
|
||||
if ((hover & SELECTED) !== 0) { classNames.push('jsoneditor-hover') }
|
||||
if ((hover & SELECTED_START) !== 0) { classNames.push('jsoneditor-hover-start') }
|
||||
if ((hover & SELECTED_END) !== 0) { classNames.push('jsoneditor-hover-end') }
|
||||
if ((hover & SELECTED_BEFORE) !== 0) { classNames.push('jsoneditor-hover-insert-area-before') }
|
||||
if ((hover & SELECTED_AFTER) !== 0) { classNames.push('jsoneditor-hover-insert-area-after') }
|
||||
|
||||
return classNames.join(' ')
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -473,12 +477,20 @@ export default class JSONNode extends PureComponent {
|
|||
)
|
||||
}
|
||||
|
||||
renderFloatingMenu (items) {
|
||||
renderFloatingMenu (items, selected) {
|
||||
if ((selected & SELECTED_END) === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
const isLastOfMultiple = ((selected & SELECTED_LAST) !== 0) &&
|
||||
((selected & SELECTED_FIRST) === 0)
|
||||
|
||||
return h(FloatingMenu, {
|
||||
key: 'floating-menu',
|
||||
path: this.props.value[META].path,
|
||||
emit: this.props.emit,
|
||||
items
|
||||
items,
|
||||
position: isLastOfMultiple ? 'bottom' : 'top'
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -487,7 +499,7 @@ export default class JSONNode extends PureComponent {
|
|||
event.stopPropagation()
|
||||
|
||||
const hover = (event.target.className.indexOf('jsoneditor-insert-area') !== -1)
|
||||
? SELECTED_AFTER
|
||||
? (SELECTED + SELECTED_AFTER)
|
||||
: SELECTED
|
||||
|
||||
if (hoveredNode && hoveredNode !== this) {
|
||||
|
@ -505,7 +517,7 @@ export default class JSONNode extends PureComponent {
|
|||
handleMouseLeave = (event) => {
|
||||
event.stopPropagation()
|
||||
// FIXME: this gives issues when the hovered node doesn't exist anymore. check whether mounted?
|
||||
hoveredNode.setState({hover: false})
|
||||
hoveredNode.setState({hover: null})
|
||||
|
||||
this.setState({hover: null})
|
||||
}
|
||||
|
|
|
@ -529,35 +529,35 @@ div.jsoneditor-node-container {
|
|||
background-color: #ffed99; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-hover {
|
||||
background-color: #ffdb80; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-hover.jsoneditor-hover-insert-area {
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-hover.jsoneditor-hover-insert-area-after {
|
||||
background-color: #ffed99; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-hover.jsoneditor-hover-insert-area > div.jsoneditor-insert-area {
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-hover.jsoneditor-hover-insert-area-after > div.jsoneditor-insert-area {
|
||||
border: 1px dashed gray;
|
||||
background-color: #f2f2f2; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-hover.jsoneditor-hover-insert-area.jsoneditor-selected-insert-area > div.jsoneditor-insert-area {
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-hover.jsoneditor-hover-insert-area-after.jsoneditor-selected-insert-area-before > div.jsoneditor-insert-area {
|
||||
border: 1px dashed #f4af41;
|
||||
background-color: #ffdb80; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-selected-insert-area {
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-selected-insert-area-before {
|
||||
background-color: inherit; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-selected-insert-area.jsoneditor-hover {
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-selected-insert-area-before.jsoneditor-hover {
|
||||
background-color: #f2f2f2; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-selected-insert-area.jsoneditor-hover.jsoneditor-hover-insert-area {
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-selected-insert-area-before.jsoneditor-hover.jsoneditor-hover-insert-area-after {
|
||||
background-color: inherit; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-selected-insert-area > div.jsoneditor-insert-area {
|
||||
div.jsoneditor-node-container.jsoneditor-selected.jsoneditor-selected-insert-area-before > div.jsoneditor-insert-area {
|
||||
border: 1px dashed #f4af41;
|
||||
background: #ffed99; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected div.jsoneditor-hover {
|
||||
background-color: #ffdb80; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected div.jsoneditor-hover.jsoneditor-hover-insert-area {
|
||||
div.jsoneditor-node-container.jsoneditor-selected div.jsoneditor-hover.jsoneditor-hover-insert-area-after {
|
||||
background-color: inherit; }
|
||||
div.jsoneditor-node-container.jsoneditor-selected div.jsoneditor-hover.jsoneditor-hover-insert-area > div.jsoneditor-insert-area {
|
||||
div.jsoneditor-node-container.jsoneditor-selected div.jsoneditor-hover.jsoneditor-hover-insert-area-after > div.jsoneditor-insert-area {
|
||||
border: 1px dashed #f4af41;
|
||||
background: #ffdb80; }
|
||||
div.jsoneditor-node-container.jsoneditor-hover {
|
||||
background-color: #f2f2f2; }
|
||||
div.jsoneditor-node-container.jsoneditor-hover.jsoneditor-hover-insert-area {
|
||||
div.jsoneditor-node-container.jsoneditor-hover.jsoneditor-hover-insert-area-after {
|
||||
background-color: inherit; }
|
||||
div.jsoneditor-node-container.jsoneditor-hover.jsoneditor-hover-insert-area > div.jsoneditor-insert-area {
|
||||
div.jsoneditor-node-container.jsoneditor-hover.jsoneditor-hover-insert-area-after > div.jsoneditor-insert-area {
|
||||
border: 1px dashed gray;
|
||||
background-color: #f2f2f2; }
|
||||
div.jsoneditor-node-container div.jsoneditor-insert-area {
|
||||
|
@ -587,8 +587,17 @@ div.jsoneditor-node-container {
|
|||
width: 0;
|
||||
height: 0;
|
||||
border-top: solid 10px #4d4d4d;
|
||||
border-bottom: none;
|
||||
border-left: solid 10px transparent;
|
||||
border-right: solid 10px transparent; }
|
||||
div.jsoneditor-node-container div.jsoneditor-floating-menu.jsoneditor-floating-menu-bottom {
|
||||
bottom: auto;
|
||||
top: 100%; }
|
||||
div.jsoneditor-node-container div.jsoneditor-floating-menu.jsoneditor-floating-menu-bottom:after {
|
||||
top: -10px;
|
||||
margin-left: -10px;
|
||||
border-top: none;
|
||||
border-bottom: solid 10px #4d4d4d; }
|
||||
div.jsoneditor-node-container div.jsoneditor-floating-menu button.jsoneditor-floating-menu-item {
|
||||
color: #fff;
|
||||
background: #4d4d4d;
|
||||
|
|
|
@ -575,7 +575,7 @@ div.jsoneditor-node-container {
|
|||
&.jsoneditor-hover {
|
||||
background-color: $hoverAndSelectedColor;
|
||||
|
||||
&.jsoneditor-hover-insert-area {
|
||||
&.jsoneditor-hover-insert-area-after {
|
||||
background-color: $selectedColor;
|
||||
|
||||
> div.jsoneditor-insert-area {
|
||||
|
@ -583,7 +583,7 @@ div.jsoneditor-node-container {
|
|||
background-color: $hoverColor;
|
||||
}
|
||||
|
||||
&.jsoneditor-selected-insert-area {
|
||||
&.jsoneditor-selected-insert-area-before {
|
||||
> div.jsoneditor-insert-area {
|
||||
border: 1px dashed #f4af41;
|
||||
background-color: $hoverAndSelectedColor;
|
||||
|
@ -592,13 +592,13 @@ div.jsoneditor-node-container {
|
|||
}
|
||||
}
|
||||
|
||||
&.jsoneditor-selected-insert-area {
|
||||
&.jsoneditor-selected-insert-area-before {
|
||||
background-color: inherit;
|
||||
|
||||
&.jsoneditor-hover {
|
||||
background-color: $hoverColor;
|
||||
|
||||
&.jsoneditor-hover-insert-area {
|
||||
&.jsoneditor-hover-insert-area-after {
|
||||
background-color: inherit;
|
||||
}
|
||||
}
|
||||
|
@ -613,7 +613,7 @@ div.jsoneditor-node-container {
|
|||
div.jsoneditor-hover {
|
||||
background-color: $hoverAndSelectedColor;
|
||||
|
||||
&.jsoneditor-hover-insert-area {
|
||||
&.jsoneditor-hover-insert-area-after {
|
||||
background-color: inherit;
|
||||
|
||||
> div.jsoneditor-insert-area {
|
||||
|
@ -627,7 +627,7 @@ div.jsoneditor-node-container {
|
|||
&.jsoneditor-hover {
|
||||
background-color: $hoverColor;
|
||||
|
||||
&.jsoneditor-hover-insert-area {
|
||||
&.jsoneditor-hover-insert-area-after {
|
||||
background-color: inherit;
|
||||
|
||||
> div.jsoneditor-insert-area {
|
||||
|
@ -662,16 +662,29 @@ div.jsoneditor-node-container {
|
|||
box-shadow: 0 2px 6px 0 rgba(0,0,0,.24);
|
||||
|
||||
&:after {
|
||||
content:'';
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 35px;
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 35px;
|
||||
margin-left: -10px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: solid 10px $floating-menu-background;
|
||||
border-bottom: none;
|
||||
border-left: solid 10px transparent;
|
||||
border-right: solid 10px transparent;
|
||||
}
|
||||
|
||||
&.jsoneditor-floating-menu-bottom {
|
||||
bottom: auto;
|
||||
top: 100%;
|
||||
|
||||
&:after {
|
||||
top: -10px;
|
||||
margin-left: -10px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: solid 10px $floating-menu-background;
|
||||
border-left: solid 10px transparent;
|
||||
border-right: solid 10px transparent;
|
||||
border-top: none;
|
||||
border-bottom: solid 10px $floating-menu-background;
|
||||
}
|
||||
}
|
||||
|
||||
button.jsoneditor-floating-menu-item {
|
||||
|
|
|
@ -2,6 +2,7 @@ import { createElement as h, PureComponent } from 'react'
|
|||
import PropTypes from 'prop-types'
|
||||
|
||||
const MENU_CLASS_NAME = 'jsoneditor-floating-menu'
|
||||
const MENU_CLASS_NAME_BOTTOM = 'jsoneditor-floating-menu-bottom'
|
||||
const MENU_ITEM_CLASS_NAME = 'jsoneditor-floating-menu-item'
|
||||
|
||||
// Array: Sort | Map | Filter | Duplicate | Cut | Copy | Paste | Remove
|
||||
|
@ -134,7 +135,10 @@ export default class FloatingMenu extends PureComponent {
|
|||
type: PropTypes.string.isRequired
|
||||
})
|
||||
]).isRequired
|
||||
).isRequired
|
||||
).isRequired,
|
||||
path: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
emit: PropTypes.func.isRequired,
|
||||
position: PropTypes.string // 'top' or 'bottom'
|
||||
}
|
||||
|
||||
render () {
|
||||
|
@ -150,7 +154,8 @@ export default class FloatingMenu extends PureComponent {
|
|||
})
|
||||
|
||||
return h('div', {
|
||||
className: MENU_CLASS_NAME,
|
||||
className: MENU_CLASS_NAME +
|
||||
(this.props.position === 'bottom' ? (' ' + MENU_CLASS_NAME_BOTTOM) : ''),
|
||||
onMouseDown: this.handleTouchStart,
|
||||
onTouchStart: this.handleTouchStart,
|
||||
}, items)
|
||||
|
|
|
@ -13,9 +13,12 @@ import initial from 'lodash/initial'
|
|||
import last from 'lodash/last'
|
||||
|
||||
export const SELECTED = 1
|
||||
export const SELECTED_END = 2
|
||||
export const SELECTED_BEFORE = 3
|
||||
export const SELECTED_AFTER = 4
|
||||
export const SELECTED_START = 2
|
||||
export const SELECTED_END = 4
|
||||
export const SELECTED_FIRST = 8
|
||||
export const SELECTED_LAST = 16
|
||||
export const SELECTED_BEFORE = 32
|
||||
export const SELECTED_AFTER = 64
|
||||
|
||||
export const META = Symbol('meta')
|
||||
|
||||
|
@ -349,7 +352,7 @@ function setSearchStatus (eson, esonPointer, searchStatus) {
|
|||
/**
|
||||
* Merge selection status into the eson object, cleanup previous selection
|
||||
* @param {ESON} eson
|
||||
* @param {Selection} [selection]
|
||||
* @param {Selection | null} selection
|
||||
* @return {ESON} Returns updated eson object
|
||||
*/
|
||||
export function applySelection (eson, selection) {
|
||||
|
@ -357,11 +360,13 @@ export function applySelection (eson, selection) {
|
|||
return cleanupMetaData(eson, 'selected')
|
||||
}
|
||||
else if (selection.before) {
|
||||
const updatedEson = setIn(eson, selection.before.concat([META, 'selected']), SELECTED_BEFORE)
|
||||
const updatedEson = setIn(eson, selection.before.concat([META, 'selected']),
|
||||
SELECTED + SELECTED_BEFORE)
|
||||
return cleanupMetaData(updatedEson, 'selected', [selection.before])
|
||||
}
|
||||
else if (selection.after) {
|
||||
const updatedEson = setIn(eson, selection.after.concat([META, 'selected']), SELECTED_AFTER)
|
||||
const updatedEson = setIn(eson, selection.after.concat([META, 'selected']),
|
||||
SELECTED + SELECTED_AFTER)
|
||||
return cleanupMetaData(updatedEson, 'selected', [selection.after])
|
||||
}
|
||||
else { // selection.start and selection.end
|
||||
|
@ -379,15 +384,21 @@ export function applySelection (eson, selection) {
|
|||
const startIndex = root[META].props.indexOf(start)
|
||||
const endIndex = root[META].props.indexOf(end)
|
||||
|
||||
const minIndex = Math.min(startIndex, endIndex)
|
||||
const maxIndex = Math.max(startIndex, endIndex) + 1 // include max index itself
|
||||
const firstIndex = Math.min(startIndex, endIndex)
|
||||
const lastIndex = Math.max(startIndex, endIndex) + 1 // include max index itself
|
||||
const firstProp = root[META].props[firstIndex]
|
||||
const lastProp = root[META].props[lastIndex - 1]
|
||||
|
||||
const selectedProps = root[META].props.slice(minIndex, maxIndex)
|
||||
const selectedProps = root[META].props.slice(firstIndex, lastIndex)
|
||||
selectedPaths = selectedProps.map(prop => rootPath.concat(prop))
|
||||
let updatedObj = cloneWithSymbols(root)
|
||||
selectedProps.forEach(prop => {
|
||||
updatedObj[prop] = setIn(updatedObj[prop], [META, 'selected'],
|
||||
prop === end ? SELECTED_END : SELECTED)
|
||||
const selected = SELECTED +
|
||||
(prop === start ? SELECTED_START : 0) +
|
||||
(prop === end ? SELECTED_END : 0) +
|
||||
(prop === firstProp ? SELECTED_FIRST : 0) +
|
||||
(prop === lastProp ? SELECTED_LAST : 0)
|
||||
updatedObj[prop] = setIn(updatedObj[prop], [META, 'selected'], selected)
|
||||
})
|
||||
|
||||
return updatedObj
|
||||
|
@ -396,17 +407,21 @@ export function applySelection (eson, selection) {
|
|||
const startIndex = parseInt(start, 10)
|
||||
const endIndex = parseInt(end, 10)
|
||||
|
||||
const minIndex = Math.min(startIndex, endIndex)
|
||||
const maxIndex = Math.max(startIndex, endIndex) + 1 // include max index itself
|
||||
const firstIndex = Math.min(startIndex, endIndex)
|
||||
const lastIndex = Math.max(startIndex, endIndex) + 1 // include max index itself
|
||||
|
||||
const selectedIndices = range(minIndex, maxIndex)
|
||||
const selectedIndices = range(firstIndex, lastIndex)
|
||||
selectedPaths = selectedIndices.map(index => rootPath.concat(String(index)))
|
||||
|
||||
let updatedArr = root.slice()
|
||||
updatedArr = cloneWithSymbols(root)
|
||||
selectedIndices.forEach(index => {
|
||||
updatedArr[index] = setIn(updatedArr[index], [META, 'selected'],
|
||||
index === endIndex ? SELECTED_END : SELECTED)
|
||||
const selected = SELECTED +
|
||||
(index === start ? SELECTED_START : 0) +
|
||||
(index === end ? SELECTED_END : 0) +
|
||||
(index === firstIndex ? SELECTED_FIRST : 0) +
|
||||
(index === lastIndex ? SELECTED_LAST : 0)
|
||||
updatedArr[index] = setIn(updatedArr[index], [META, 'selected'], selected)
|
||||
})
|
||||
|
||||
return updatedArr
|
||||
|
|
Loading…
Reference in New Issue