Some fixes in styling empty key/value
This commit is contained in:
parent
3517d185f9
commit
2b73c6e6bf
|
@ -7,6 +7,7 @@
|
|||
import { escapeHTML } from './utils/stringUtils.js'
|
||||
import { updateProps } from './utils/updateProps.js'
|
||||
import { unescapeHTML } from './utils/stringUtils'
|
||||
import { getInnerText } from './utils/domUtils'
|
||||
|
||||
export let key = undefined
|
||||
export let value
|
||||
|
@ -41,6 +42,13 @@
|
|||
$: escapedValue = escapeHTML(value, escapeUnicode)
|
||||
$: valueIsUrl = isUrl(value)
|
||||
|
||||
$: keyClass = classnames('key', {
|
||||
empty: escapedKey.length === 0,
|
||||
search: searchResult
|
||||
? !!searchResult[SEARCH_PROPERTY]
|
||||
: false
|
||||
})
|
||||
|
||||
$: valueClass = classnames('value', type, {
|
||||
url: valueIsUrl,
|
||||
empty: escapedValue.length === 0,
|
||||
|
@ -54,12 +62,12 @@
|
|||
}
|
||||
|
||||
function handleKeyInput (event) {
|
||||
const newKey = unescapeHTML(event.target.innerText)
|
||||
const newKey = unescapeHTML(getInnerText(event.target))
|
||||
onChangeKey(newKey, key)
|
||||
}
|
||||
|
||||
function handleValueInput (event) {
|
||||
const valueText = unescapeHTML(event.target.innerText)
|
||||
const valueText = unescapeHTML(getInnerText(event.target))
|
||||
const newValue = stringConvert(valueText) // TODO: implement support for type "string"
|
||||
onChangeValue(newValue, key)
|
||||
}
|
||||
|
@ -140,7 +148,7 @@
|
|||
</button>
|
||||
{#if typeof key === 'string'}
|
||||
<div
|
||||
class="key {searchResult && searchResult[SEARCH_PROPERTY] ? 'search' : ''}"
|
||||
class={keyClass}
|
||||
contenteditable="true"
|
||||
spellcheck="false"
|
||||
on:input={handleKeyInput}
|
||||
|
@ -189,7 +197,7 @@
|
|||
</button>
|
||||
{#if typeof key === 'string'}
|
||||
<div
|
||||
class="key {searchResult && searchResult[SEARCH_PROPERTY] ? 'search' : ''}"
|
||||
class={keyClass}
|
||||
contenteditable="true"
|
||||
spellcheck="false"
|
||||
on:input={handleKeyInput}
|
||||
|
@ -226,7 +234,7 @@
|
|||
<div class="contents">
|
||||
{#if typeof key === 'string'}
|
||||
<div
|
||||
class="key {searchResult && searchResult[SEARCH_PROPERTY] ? 'search' : ''}"
|
||||
class={keyClass}
|
||||
contenteditable="true"
|
||||
spellcheck="false"
|
||||
on:input={handleKeyInput}
|
||||
|
@ -268,6 +276,10 @@
|
|||
flex-direction: row;
|
||||
|
||||
line-height: $line-height;
|
||||
|
||||
> * {
|
||||
display: table-cell;
|
||||
}
|
||||
}
|
||||
|
||||
.contents {
|
||||
|
@ -296,8 +308,6 @@
|
|||
|
||||
.key,
|
||||
.value {
|
||||
display: table-cell;
|
||||
|
||||
line-height: $line-height;
|
||||
min-width: 16px;
|
||||
word-break: normal;
|
||||
|
@ -314,13 +324,11 @@
|
|||
|
||||
.separator,
|
||||
.delimiter {
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
color: $gray;
|
||||
}
|
||||
|
||||
.tag {
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
border: none;
|
||||
font-size: $font-size-small;
|
||||
|
@ -388,10 +396,9 @@
|
|||
div.empty::after {
|
||||
pointer-events: none;
|
||||
color: lightgray;
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
div.property.empty::after {
|
||||
div.key.empty::after {
|
||||
content: 'key';
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* Get the inner text of an HTML element (for example a div element)
|
||||
* @param {Element} element
|
||||
* @param {Object} [buffer]
|
||||
* @return {String} innerText
|
||||
*/
|
||||
export function getInnerText (element, buffer) {
|
||||
const first = (buffer === undefined)
|
||||
if (first) {
|
||||
buffer = {
|
||||
'text': '',
|
||||
'flush': function () {
|
||||
const text = this.text
|
||||
this.text = ''
|
||||
return text
|
||||
},
|
||||
'set': function (text) {
|
||||
this.text = text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// text node
|
||||
if (element.nodeValue) {
|
||||
return buffer.flush() + element.nodeValue
|
||||
}
|
||||
|
||||
// divs or other HTML elements
|
||||
if (element.hasChildNodes()) {
|
||||
const childNodes = element.childNodes
|
||||
let innerText = ''
|
||||
|
||||
for (let i = 0, iMax = childNodes.length; i < iMax; i++) {
|
||||
const child = childNodes[i]
|
||||
|
||||
if (child.nodeName === 'DIV' || child.nodeName === 'P') {
|
||||
const prevChild = childNodes[i - 1]
|
||||
const prevName = prevChild ? prevChild.nodeName : undefined
|
||||
if (prevName && prevName !== 'DIV' && prevName !== 'P' && prevName !== 'BR') {
|
||||
innerText += '\n'
|
||||
buffer.flush()
|
||||
}
|
||||
innerText += getInnerText(child, buffer)
|
||||
buffer.set('\n')
|
||||
}
|
||||
else if (child.nodeName === 'BR') {
|
||||
innerText += buffer.flush()
|
||||
buffer.set('\n')
|
||||
}
|
||||
else {
|
||||
innerText += getInnerText(child, buffer)
|
||||
}
|
||||
}
|
||||
|
||||
return innerText
|
||||
}
|
||||
else {
|
||||
if (element.nodeName === 'P' && getInternetExplorerVersion() !== -1) {
|
||||
// On Internet Explorer, a <p> with hasChildNodes()==false is
|
||||
// rendered with a new line. Note that a <p> with
|
||||
// hasChildNodes()==true is rendered without a new line
|
||||
// Other browsers always ensure there is a <br> inside the <p>,
|
||||
// and if not, the <p> does not render a new line
|
||||
return buffer.flush()
|
||||
}
|
||||
}
|
||||
|
||||
// br or unknown
|
||||
return ''
|
||||
}
|
||||
|
Loading…
Reference in New Issue