UNPKG

jodit

Version:

Jodit is an awesome and useful wysiwyg editor with filebrowser

138 lines (137 loc) 5.5 kB
/*! * Jodit Editor (https://xdsoft.net/jodit/) * Released under MIT see LICENSE.txt in the project root for license information. * Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net */ import { pluginSystem } from "../../core/global.js"; import { splitArray, toArray } from "../../core/helpers/index.js"; import { flatButtonsSet, isButtonGroup } from "../../core/ui/helpers/buttons.js"; import "./config.js"; const isButtonSeparator = (item) => item === '|' || item === '---' || item === '\n'; /** * Constrain a responsive breakpoint set (`buttonsMD/SM/XS`) to the buttons the * user actually asked for via `buttons`. Those breakpoint defaults are * group-based supersets, so a custom (smaller) `buttons` list would otherwise * see *extra* buttons appear on resize when the toolbar switched to a breakpoint * set — resizing must only ever drop buttons, never add ones outside `buttons`. * * When the breakpoint set introduces nothing outside `buttons` (the default * case, where `buttons` is the full superset), the list is returned untouched so * the standard grouped mobile layout — groups, separators and `dots` — is * preserved. See #1389. */ function fitToButtons(list, editor) { var _a; const allowed = flatButtonsSet(splitArray(editor.o.buttons), editor); const groups = editor.getRegisteredButtonGroups(); let changed = false; let hadDots = false; const flat = []; for (const item of list) { if (isButtonGroup(item)) { const members = [...item.buttons, ...((_a = groups[item.group]) !== null && _a !== void 0 ? _a : [])]; const kept = members.filter(button => allowed.has(button)); if (kept.length !== members.length) { changed = true; } flat.push(...kept); } else if (isButtonSeparator(item)) { flat.push(item); } else if (item === 'dots') { hadDots = true; } else if (allowed.has(item)) { flat.push(item); } else { changed = true; } } if (!changed) { return list; } // Drop separators left dangling once the buttons around them were removed. const cleaned = []; for (const item of flat) { if (isButtonSeparator(item) && (cleaned.length === 0 || isButtonSeparator(cleaned[cleaned.length - 1]))) { continue; } cleaned.push(item); } while (cleaned.length && isButtonSeparator(cleaned[cleaned.length - 1])) { cleaned.pop(); } // Keep the "show all" overflow button only if some requested button is still // hidden at this breakpoint. if (hadDots) { const shown = flatButtonsSet(cleaned, editor); if (toArray(allowed).some(button => !shown.has(button))) { cleaned.push('dots'); } } return cleaned; } /** * Rebuild toolbar in depends on editor's width */ export function mobile(editor) { let timeout = 0, store = splitArray(editor.o.buttons); if (editor.o.mobileTapTimeout) { // Emulate double tap editor.e.on('touchend', (e) => { if (e.changedTouches && e.changedTouches.length) { const now = new Date().getTime(), diff = now - timeout; if (diff > editor.o.mobileTapTimeout) { timeout = now; if (diff < editor.o.mobileTapTimeout * 1.5) { editor.s.insertCursorAtPoint(e.clientX, e.clientY); } } } }); } editor.e.on('getDiffButtons.mobile', (toolbar) => { if (toolbar === editor.toolbar) { const buttons = flatButtonsSet(splitArray(editor.o.buttons), editor), flatStore = flatButtonsSet(store, editor); return toArray(buttons).reduce((acc, item) => { if (!flatStore.has(item)) { acc.push(item); } return acc; }, []); } }); if (editor.o.toolbarAdaptive) { editor.e .on('resize afterInit recalcAdaptive changePlace afterAddPlace', () => { var _a, _b; if (!editor.o.toolbar) { return; } const width = ((_a = editor.container.parentElement) !== null && _a !== void 0 ? _a : editor.container).offsetWidth; const newStore = (() => { if (editor.isFullSize || width >= editor.o.sizeLG) { return splitArray(editor.o.buttons); } if (width >= editor.o.sizeMD) { return fitToButtons(splitArray(editor.o.buttonsMD), editor); } if (width >= editor.o.sizeSM) { return fitToButtons(splitArray(editor.o.buttonsSM), editor); } return fitToButtons(splitArray(editor.o.buttonsXS), editor); })(); if (newStore.toString() !== store.toString()) { store = newStore; editor.e.fire('closeAllPopups'); (_b = editor.toolbar) === null || _b === void 0 ? void 0 : _b.setRemoveButtons(editor.o.removeButtons).build(store.concat(editor.o.extraButtons)); } }) .on(editor.ow, 'load resize', () => editor.e.fire('recalcAdaptive')); } } pluginSystem.add('mobile', mobile);