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 --- src/MenuItem.mjs | 35 +++++++++++++++++++++-------------- src/dumbymap.mjs | 25 +++++++++++++++++++------ src/editor.mjs | 18 ++++++++++-------- 3 files changed, 50 insertions(+), 28 deletions(-) (limited to 'src') 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