From 5f26194f7a285a2743a84056deb3b494bde9f7f5 Mon Sep 17 00:00:00 2001 From: Hsieh Chin Fan Date: Mon, 30 Sep 2024 23:00:20 +0800 Subject: feat: improve menu items * fix editing mode, make it just like layout changes * add plain-modal for renderer results * check selection is within text range for geolink --- package.json | 4 +++- src/MenuItem.mjs | 35 +++++++++++++++++++++-------------- src/dumbymap.mjs | 25 +++++++++++++++++++------ src/editor.mjs | 18 ++++++++++-------- 4 files changed, 53 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index 9ee1a77..3af08b8 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "stylelint-order": "^6.0.4" }, "dependencies": { + "cssprefix": "^2.0.17", "easymde": "^2.18.0", "leader-line": "^1.0.7", "mapclay": "^0.8.3", @@ -58,7 +59,8 @@ "markdown-it-footnote": "^4.0.0", "markdown-it-front-matter": "^0.2.4", "markdown-it-toc-done-right": "^4.2.0", - "plain-draggable": "^2.5.14" + "plain-draggable": "^2.5.14", + "plain-modal": "^1.0.34" }, "author": "Hsiehg Chin Fan ", "homepage": "https://outdoorsafetylab.github.io/dumbymap", diff --git a/src/MenuItem.mjs b/src/MenuItem.mjs index 98f3bae..5604ef1 100644 --- a/src/MenuItem.mjs +++ b/src/MenuItem.mjs @@ -1,6 +1,5 @@ import { createGeoLink } from './dumbymap'; import { scrollToBlock } from './dumbyUtils'; -import { default as PlainModal } from 'plain-modal'; class Item extends HTMLDivElement { constructor({ text, innerHTML, onclick }) { @@ -38,7 +37,7 @@ window.customElements.define('menu-folder', Folder, { extends: 'div' }); export const pickMapItem = dumbymap => new Folder({ - innerHTML: 'Focus a Map(Tab)', + innerHTML: 'Maps(Tab)', items: dumbymap.utils.renderedMaps().map( map => new Item({ @@ -53,15 +52,16 @@ export const pickMapItem = dumbymap => export const pickBlockItem = dumbymap => new Folder({ - innerHTML: 'Focus Block(n/p)', + innerHTML: 'Blocks(n/p)', items: dumbymap.blocks.map( (block, index) => new Item({ text: + `(${index})` + block .querySelector('p') - ?.textContent.substring(0, 20) - .concat(' ...') ?? `Block ${index}`, + ?.textContent.substring(0, 15) + .concat(' ...'), onclick: () => { block.classList.add('focus'); scrollToBlock(block); @@ -72,13 +72,13 @@ export const pickBlockItem = dumbymap => export const pickLayoutItem = dumbymap => new Folder({ - innerHTML: 'Switch Layout(x)', + innerHTML: 'Layouts(x)', items: [ new Item({ text: 'EDIT', onclick: () => dumbymap.container - .closest('.playground') + .closest('[data-mode]') .setAttribute('data-mode', 'editing'), }), ...dumbymap.layouts.map( @@ -161,10 +161,17 @@ export class Suggestion { } } -export const modal = new Item({ - text: 'Render Results', - onclick: () => { - const modal = new PlainModal(); - modal.open(); - }, -}); +export const renderResults = (dumbymap, map) => + new Item({ + text: 'Render Results', + onclick: e => { + const modal = dumbymap.modal; + modal.open(); + modal.overlayBlur = 3; + modal.closeByEscKey = false; + // HACK find another way to override inline style + document.querySelector('.plainmodal-overlay-force').style.position = + 'static'; + console.log(map.renderer.results) + }, + }); diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs index d365712..b9b9fa2 100644 --- a/src/dumbymap.mjs +++ b/src/dumbymap.mjs @@ -9,6 +9,7 @@ import { onRemove, animateRectTransition, throttle } from './utils'; import { Layout, SideBySide, Overlay } from './Layout'; import * as utils from './dumbyUtils'; import * as menuItem from './MenuItem'; +import { default as PlainModal } from 'plain-modal'; const docLinkSelector = 'a[href^="#"][title^="=>"]'; const geoLinkSelector = 'a[href^="geo:"]'; @@ -155,6 +156,9 @@ export const generateMaps = (container, { delay, mapCallback }) => { container.appendChild(showcase); showcase.classList.add('Showcase'); const renderPromises = []; + const modalContent = document.createElement('div'); + container.appendChild(modalContent); + const modal = new PlainModal(modalContent); const dumbymap = { layouts, @@ -162,15 +166,15 @@ export const generateMaps = (container, { delay, mapCallback }) => { htmlHolder, showcase, blocks, + modal, utils: { + ...utils, renderedMaps: () => Array.from( container.querySelectorAll('.mapclay[data-render=fulfilled]'), ), focusNextMap: throttle(utils.focusNextMap, utils.focusDelay), switchToNextLayout: throttle(utils.switchToNextLayout, 300), - focusNextBlock: utils.focusNextBlock, - removeBlockFocus: utils.removeBlockFocus, }, }; Object.entries(dumbymap.utils).forEach(([util, func]) => { @@ -540,16 +544,25 @@ export const generateMaps = (container, { delay, mapCallback }) => { // Menu Items container.oncontextmenu = e => { + e.preventDefault(); + + // GeoLinks const selection = document.getSelection(); - const range = selection.getRangeAt(0); - if (selection) { - e.preventDefault(); + if (selection.type === 'Range') { + const range = selection.getRangeAt(0); menu.innerHTML = ''; const addGeoLink = new menuItem.GeoLink({ range }); menu.appendChild(addGeoLink.createElement()); } menu.style.cssText = `overflow: visible; display: block; left: ${e.clientX + 10}px; top: ${e.clientY + 5}px;`; - menu.appendChild(menuItem.modal); + + // Print Map Results + const map = e.target.closest('.mapclay'); + if (map) { + menu.appendChild(menuItem.renderResults(dumbymap, map)); + } + + // Dumby Utils menu.appendChild(menuItem.pickMapItem(dumbymap)); menu.appendChild(menuItem.pickBlockItem(dumbymap)); menu.appendChild(menuItem.pickLayoutItem(dumbymap)); diff --git a/src/editor.mjs b/src/editor.mjs index 760e2e1..a7bdd77 100644 --- a/src/editor.mjs +++ b/src/editor.mjs @@ -11,7 +11,10 @@ const textArea = document.querySelector('.editor textarea'); let dumbymap; new MutationObserver(() => { - if (document.body.getAttribute('data-mode') === 'editing') { + if ( + document.body.getAttribute('data-mode') === 'editing' && + HtmlContainer.getAttribute('data-layout') !== 'normal' + ) { HtmlContainer.setAttribute('data-layout', 'normal'); } }).observe(document.body, { @@ -276,7 +279,7 @@ window.onhashchange = () => { // Completion in Code Blok {{{ // Elements about suggestions {{{ const menu = document.createElement('div'); -menu.id = 'menu'; +menu.className = 'menu'; menu.onclick = () => (menu.style.display = 'none'); new MutationObserver(() => { if (menu.style.display === 'none') { @@ -648,14 +651,13 @@ document.onkeydown = e => { // }}} // }}} // Layout Switch {{{ -const layoutObserver = new MutationObserver(() => { +new MutationObserver(mutaions => { + const mutation = mutaions.at(-1); const layout = HtmlContainer.getAttribute('data-layout'); - if (layout !== 'normal') { - document.body.removeAttribute('data-mode'); + if (layout !== 'normal' || mutation.oldValue === 'normal') { + document.body.setAttribute('data-mode', ''); } -}); - -layoutObserver.observe(HtmlContainer, { +}).observe(HtmlContainer, { attributes: true, attributeFilter: ['data-layout'], attributeOldValue: true, -- cgit v1.2.3-70-g09d2