Add context menu allowing you to copy context path

This commit is contained in:
Misode
2020-12-19 03:24:15 +01:00
parent 6a3c7aac42
commit 6246e627b5
3 changed files with 117 additions and 6 deletions

View File

@@ -86,7 +86,9 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = {
${help(childPath, mounter)}
<button class="remove" data-id="${removeId}">${Octicon.trashcan}</button>
${cPrefix}
<label>${htmlEncode(pathLocale(path.contextPush('entry'), [`${index}`]))}</label>
<label ${contextMenu(childPath, mounter)}>
${htmlEncode(pathLocale(path.contextPush('entry'), [`${index}`]))}
</label>
${cSuffix}
</div>
${cBody ? `<div class="node-body">${cBody}</div>` : ''}
@@ -125,7 +127,9 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = {
${help(childPath, mounter)}
<button class="remove" data-id="${removeId}">${Octicon.trashcan}</button>
${cPrefix}
<label>${htmlEncode(key)}</label>
<label ${contextMenu(childPath, mounter)}>
${htmlEncode(key)}
</label>
${cSuffix}
</div>
${cBody ? `<div class="node-body">${cBody}</div>` : ''}
@@ -180,7 +184,9 @@ export const renderHtml: Hook<[any, Mounter], [string, string, string]> = {
${error(childPath, mounter)}
${help(childPath, mounter)}
${cPrefix}
<label>${htmlEncode(fieldSettings?.name ?? pathLocale(childPath))}</label>
<label ${contextMenu(childPath, mounter)}>
${htmlEncode(fieldSettings?.name ?? pathLocale(childPath))}
</label>
${cSuffix}
</div>
${cBody ? `<div class="node-body">${cBody}</div>` : ''}
@@ -259,7 +265,6 @@ function hashString(str: string) {
}
function pathLocale(path: Path, params?: string[]): string {
// return path.getContext().slice(-5).join('.')
return segmentedLocale(path.getContext(), params)
?? path.getContext()[path.getContext().length - 1] ?? ''
}
@@ -287,3 +292,57 @@ const popupIcon = (type: string, icon: keyof typeof Octicon, popup: string, moun
<span class="icon-popup">${popup}</span>${Octicon[icon]}
</div>`
}
const contextMenu = (path: ModelPath, mounter: Mounter) => {
const id = mounter.register(el => {
const openMenu = () => {
const popup = document.createElement('div')
popup.classList.add('node-menu')
const helpMessage = segmentedLocale(path.contextPush('help').getContext(), [], 6)
if (helpMessage) popup.insertAdjacentHTML('beforeend', `<span class="menu-item help-item">${helpMessage}</span>`)
const context = path.getContext().join('.')
popup.insertAdjacentHTML('beforeend', `
<div class="menu-item">
<span class="btn">${Octicon.clippy}</span>
Context:&nbsp
<span class="menu-item-context">${context}</span>
</div>`)
popup.querySelector('.menu-item .btn')?.addEventListener('click', () => {
const inputEl = document.createElement('input')
inputEl.value = context
el.appendChild(inputEl)
inputEl.select()
document.execCommand('copy')
el.removeChild(inputEl)
})
el.appendChild(popup)
document.body.addEventListener('click', () => {
try {el.removeChild(popup)} catch (e) {}
}, { capture: true, once: true })
document.body.addEventListener('contextmenu', () => {
try {el.removeChild(popup)} catch (e) {}
}, { capture: true, once: true })
}
el.addEventListener('contextmenu', evt => {
openMenu()
evt.preventDefault()
})
let timer: any = null
el.addEventListener('touchstart', () => {
timer = setTimeout(() => {
openMenu()
timer = null
}, 800)
})
el.addEventListener('touchend', () => {
if (timer) {
clearTimeout(timer)
timer = null
}
})
})
return `data-id="${id}"`
}

View File

@@ -12,6 +12,7 @@
--node-indent-border: #b9b9b9;
--node-popup-background: #1f2020e6;
--node-popup-text: #dadada;
--node-popup-text-dimmed: #b4b4b4;
--category-predicate: #65b5b8;
--category-predicate-border: #187e81;
--category-predicate-background: #95c5c7;
@@ -37,6 +38,7 @@
--node-indent-border: #454749;
--node-popup-background: #0a0a0ae6;
--node-popup-text: #dadada;
--node-popup-text-dimmed: #b4b4b4;
--category-predicate: #306163;
--category-predicate-border: #224849;
--category-predicate-background: #1d3333;
@@ -52,8 +54,9 @@
.node-header {
display: inline-flex;
position: relative;
align-items: center;
max-width: 100%;
width: 100%;
}
.node-header > * {
@@ -68,6 +71,7 @@
padding: 0 9px;
line-height: 1.94rem;
white-space: nowrap;
user-select: none;
background-color: var(--node-background-label);
}
@@ -221,6 +225,54 @@ button.remove {
fill: var(--node-remove);
}
.node-menu {
position: absolute;
left: 0;
top: 100%;
width: min-content;
margin-top: 4px;
margin-left: 4px;
z-index: 1;
color: var(--node-popup-text);
font-size: 16px;
border-radius: 3px;
background-color: var(--node-popup-background);
}
.node-menu::after {
content: "";
position: absolute;
bottom: 100%;
left: 0;
margin-left: 6px;
border-width: 5px;
border-style: solid;
border-color: transparent transparent var(--node-popup-background) transparent;
}
.menu-item {
padding: 4px;
display: flex;
align-items: center;
white-space: normal;
}
.menu-item > * {
margin-right: 4px;
}
.menu-item .btn {
padding: 8px;
}
span.menu-item {
padding: 4px 8px;
}
.menu-item-context {
color: var(--node-popup-text-dimmed);
}
/* Node body and list entry */
.node {