mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-23 23:27:09 +00:00
Add context menu allowing you to copy context path
This commit is contained in:
@@ -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: 
|
||||
<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}"`
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user