Highlight object when hovering, select node only when clicking inside one of the selectable areas
This commit is contained in:
parent
22845a0cc8
commit
1477aaaa4b
|
@ -12,10 +12,20 @@
|
|||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
&.selected .header,
|
||||
&.selected .contents,
|
||||
&.selected .footer {
|
||||
background-color: $selection-background;
|
||||
&.hovered {
|
||||
.header,
|
||||
.contents,
|
||||
.footer {
|
||||
background-color: $hovered-background;
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
.header,
|
||||
.contents,
|
||||
.footer {
|
||||
background-color: $selection-background;
|
||||
}
|
||||
}
|
||||
|
||||
$selector-height: 8px; // must be about half a line height
|
||||
|
|
|
@ -15,9 +15,8 @@
|
|||
} from '../constants.js'
|
||||
import {
|
||||
getPlainText,
|
||||
isAppendNodeSelector,
|
||||
isBeforeNodeSelector,
|
||||
isChildOfButton,
|
||||
isChildOfAttribute,
|
||||
isChildOfNodeName,
|
||||
isContentEditableDiv,
|
||||
setPlainText
|
||||
} from '../utils/domUtils.js'
|
||||
|
@ -51,6 +50,7 @@
|
|||
|
||||
let domKey
|
||||
let domValue
|
||||
let hovered = false
|
||||
|
||||
$: type = valueType (value)
|
||||
|
||||
|
@ -224,11 +224,11 @@
|
|||
}
|
||||
|
||||
// check if the mouse down is not happening in the key or value input fields or on a button
|
||||
if (isContentEditableDiv(event.target) || isChildOfButton(event.target)) {
|
||||
if (isContentEditableDiv(event.target) || isChildOfNodeName(event.target, 'BUTTON')) {
|
||||
return
|
||||
}
|
||||
|
||||
if (isBeforeNodeSelector(event.target)) {
|
||||
if (isChildOfAttribute(event.target, 'data-type', 'before-node-selector')) {
|
||||
singleton.mousedown = true
|
||||
singleton.selectionAnchor = path
|
||||
singleton.selectionFocus = null
|
||||
|
@ -236,7 +236,7 @@
|
|||
onSelect({
|
||||
beforePath: path
|
||||
})
|
||||
} else if (isAppendNodeSelector(event.target)) {
|
||||
} else if (isChildOfAttribute(event.target, 'data-type', 'append-node-selector')) {
|
||||
singleton.mousedown = true
|
||||
singleton.selectionAnchor = path
|
||||
singleton.selectionFocus = null
|
||||
|
@ -248,12 +248,15 @@
|
|||
// initialize dragging a selection
|
||||
singleton.mousedown = true
|
||||
singleton.selectionAnchor = path
|
||||
singleton.selectionFocus = path
|
||||
|
||||
onSelect({
|
||||
anchorPath: singleton.selectionAnchor,
|
||||
focusPath: singleton.selectionFocus
|
||||
})
|
||||
singleton.selectionFocus = null
|
||||
|
||||
if (isChildOfAttribute(event.target, 'data-type', 'selectable-area')) {
|
||||
// select current node
|
||||
onSelect({
|
||||
anchorPath: path,
|
||||
focusPath: path
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
event.stopPropagation()
|
||||
|
@ -299,21 +302,20 @@
|
|||
document.removeEventListener('mouseup', handleMouseUp)
|
||||
}
|
||||
|
||||
function handleSelectBefore (event) {
|
||||
function handleMouseOver (event) {
|
||||
event.stopPropagation()
|
||||
|
||||
onSelect({
|
||||
beforePath: path
|
||||
})
|
||||
if (
|
||||
isChildOfAttribute(event.target, 'data-type', 'selectable-area') &&
|
||||
!isContentEditableDiv(event.target)
|
||||
) {
|
||||
hovered = true
|
||||
}
|
||||
}
|
||||
|
||||
function handleSelectAfter (event) {
|
||||
event.preventDefault()
|
||||
function handleMouseOut (event) {
|
||||
event.stopPropagation()
|
||||
|
||||
onSelect({
|
||||
appendPath: path
|
||||
})
|
||||
hovered = false
|
||||
}
|
||||
|
||||
// FIXME: this is not efficient. Create a nested object with the selection and pass that
|
||||
|
@ -336,8 +338,11 @@
|
|||
class='json-node'
|
||||
class:root={path.length === 0}
|
||||
class:selected={selected}
|
||||
class:hovered={hovered}
|
||||
on:mousedown={handleMouseDown}
|
||||
on:mousemove={handleMouseMove}
|
||||
on:mouseover={handleMouseOver}
|
||||
on:mouseout={handleMouseOut}
|
||||
>
|
||||
<div
|
||||
data-type="before-node-selector"
|
||||
|
@ -348,7 +353,8 @@
|
|||
<div class="selector"></div>
|
||||
</div>
|
||||
{#if type === 'array'}
|
||||
<div class='header' style={indentationStyle}>
|
||||
<div
|
||||
data-type="selectable-area" class='header' style={indentationStyle} >
|
||||
<button
|
||||
class='expand'
|
||||
on:click={toggleExpand}
|
||||
|
@ -422,12 +428,12 @@
|
|||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="footer" style={indentationStyle}>
|
||||
<div data-type="selectable-area" class="footer" style={indentationStyle} >
|
||||
<span class="delimiter">]</span>
|
||||
</div>
|
||||
{/if}
|
||||
{:else if type === 'object'}
|
||||
<div class='header' style={indentationStyle}>
|
||||
<div data-type="selectable-area" class="header" style={indentationStyle} >
|
||||
<button
|
||||
class='expand'
|
||||
on:click={toggleExpand}
|
||||
|
@ -496,12 +502,12 @@
|
|||
<div class="selector"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer" style={indentationStyle}>
|
||||
<div data-type="selectable-area" class="footer" style={indentationStyle} >
|
||||
<span class="delimiter">}</span>
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="contents" style={indentationStyle}>
|
||||
<div data-type="selectable-area" class="contents" style={indentationStyle} >
|
||||
{#if typeof key === 'string'}
|
||||
<div
|
||||
class={keyClass}
|
||||
|
|
|
@ -25,6 +25,7 @@ $gray: #9d9d9d;
|
|||
$gray-icon: $gray;
|
||||
$light-gray: #c0c0c0;
|
||||
$selection-background: #e0e0e0;
|
||||
$hovered-background: #f0f0f0;
|
||||
$background-gray: #f5f5f5;
|
||||
|
||||
$line-height: 18px;
|
||||
|
|
|
@ -179,9 +179,12 @@ export function traverseInnerText (element, buffer) {
|
|||
return ''
|
||||
}
|
||||
|
||||
// test whether a DOM element is a child of a button
|
||||
export function isChildOfButton (element) {
|
||||
return isChildOf(element, e => e.nodeName === 'BUTTON')
|
||||
export function isChildOfNodeName (element, nodeName) {
|
||||
return isChildOf(element, e => e.nodeName.toUpperCase() === nodeName.toUpperCase())
|
||||
}
|
||||
|
||||
export function isChildOfAttribute (element, name, value) {
|
||||
return isChildOf(element, e => hasAttribute(e, name, value))
|
||||
}
|
||||
|
||||
// test whether a DOM element is a content editable div
|
||||
|
@ -189,18 +192,6 @@ export function isContentEditableDiv (element) {
|
|||
return (element.nodeName === 'DIV' && element.contentEditable === 'true')
|
||||
}
|
||||
|
||||
export function isBeforeNodeSelector (element) {
|
||||
return isChildOf(element, e => {
|
||||
return hasAttribute(e, 'data-type', 'before-node-selector')
|
||||
})
|
||||
}
|
||||
|
||||
export function isAppendNodeSelector (element) {
|
||||
return isChildOf(element, e => {
|
||||
return hasAttribute(e, 'data-type', 'append-node-selector')
|
||||
})
|
||||
}
|
||||
|
||||
function hasAttribute(element, name, value) {
|
||||
return typeof element.getAttribute === 'function' && element.getAttribute(name) === value
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue