@themarioga/grid-editor 9.0.0-beta.2 → 9.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +76 -8
- package/dist/grideditor.bundle.min.js +2 -2
- package/dist/grideditor.css +187 -0
- package/dist/grideditor.d.ts +75 -0
- package/dist/grideditor.esm.js +38 -11
- package/dist/grideditor.js +38 -11
- package/dist/grideditor.min.css +1 -1
- package/dist/grideditor.min.css.map +1 -1
- package/dist/grideditor.min.js +1 -1
- package/dist/grideditor.min.js.map +3 -3
- package/dist/locales/grideditor.es.esm.js +22 -0
- package/dist/locales/grideditor.es.js +22 -0
- package/dist/locales/grideditor.es.min.js +2 -2
- package/dist/locales/grideditor.es.min.js.map +2 -2
- package/dist/plugins/grideditor.history.esm.js +360 -0
- package/dist/plugins/grideditor.history.js +365 -0
- package/dist/plugins/grideditor.history.min.js +1 -0
- package/dist/plugins/grideditor.history.min.js.map +7 -0
- package/dist/plugins/grideditor.offcanvas.esm.js +551 -0
- package/dist/plugins/grideditor.offcanvas.js +556 -0
- package/dist/plugins/grideditor.offcanvas.min.js +1 -0
- package/dist/plugins/grideditor.offcanvas.min.js.map +7 -0
- package/dist/plugins/grideditor.popup.esm.js +90 -37
- package/dist/plugins/grideditor.popup.js +90 -37
- package/dist/plugins/grideditor.popup.min.js +1 -1
- package/dist/plugins/grideditor.popup.min.js.map +4 -4
- package/docs/events.md +7 -3
- package/docs/locale-keys.md +32 -1
- package/docs/plugins.md +19 -5
- package/example/clipboard.html +22 -0
- package/example/containers.html +22 -4
- package/example/history.html +94 -0
- package/example/index.html +9 -1
- package/package.json +1 -1
- package/src/js/grideditor.js +37 -9
- package/src/js/locales/grideditor.es.js +22 -0
- package/src/js/plugins/grideditor.history.js +367 -0
- package/src/js/plugins/grideditor.offcanvas.js +420 -0
- package/src/js/plugins/grideditor.popup.js +8 -70
- package/src/js/triggers/triggers.js +121 -0
- package/src/less/grideditor.less +60 -0
- package/types/grideditor.d.ts +75 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/js/register.js", "../../src/js/dom.js", "../../src/js/triggers/triggers.js", "../../src/js/plugins/grideditor.offcanvas.js"],
|
|
4
|
+
"sourcesContent": ["/**\n * What a plugin's or a locale's classic script imports in place of the\n * editor: the GridEditor the page already loaded.\n *\n * The build points `import { GridEditor } from '../grideditor.js'` here for\n * the classic scripts, so each registers on the editor the page has rather\n * than bringing its own. Loaded before the editor there is nothing to\n * register on, and saying so is better than a TypeError three calls later.\n */\nvar GridEditor = window.GridEditor;\n\nif (!GridEditor || typeof GridEditor.get !== 'function') {\n throw new Error('grid-editor: load grideditor.js (or grideditor.bundle.min.js) before its plugins, ' +\n 'its locales and grideditor.jquery.js');\n}\n\nexport { GridEditor };\nexport default GridEditor;\n", "/**\n * The DOM, the way grid-editor uses it.\n *\n * Small helpers over the browser's own API, for the core and the shipped\n * plugins. Not a public API: a plugin of a host's own is free to write its\n * DOM code however it likes, and this file makes no promise to it.\n *\n * Stateless on purpose. The build puts a copy of this file in each plugin's\n * classic script, so anything kept here would be kept once per copy; a\n * module that needs to remember something about a node keeps its own\n * WeakMap.\n */\n\n/** Every element under `root` matching `selector`, as an array. */\nexport function all(root, selector) {\n return root ? Array.prototype.slice.call(root.querySelectorAll(selector)) : [];\n}\n\n/** The first element under `root` matching `selector`, or null. */\nexport function one(root, selector) {\n return root ? root.querySelector(selector) : null;\n}\n\n/** `root` itself when it matches, then every element under it that does. */\nexport function selfAndAll(root, selector) {\n if (!root) { return []; }\n\n var found = all(root, selector);\n if (root.nodeType === 1 && root.matches(selector)) { found.unshift(root); }\n return found;\n}\n\n/** The element children of `node`, those matching `selector` if one is given. */\nexport function children(node, selector) {\n if (!node) { return []; }\n\n return Array.prototype.filter.call(node.children, function(each) {\n return !selector || each.matches(selector);\n });\n}\n\n/** The first element child matching `selector`, or null. */\nexport function child(node, selector) {\n return children(node, selector)[0] || null;\n}\n\n/** The nearest ancestor-or-self matching `selector` below `stopAt`, or null. */\nexport function closest(node, selector, stopAt) {\n var found = node && node.nodeType === 1 ? node.closest(selector) : null;\n\n if (found && stopAt && found !== stopAt && !stopAt.contains(found)) { return null; }\n return found;\n}\n\n/** Whether `node` is an element matching `selector`. */\nexport function is(node, selector) {\n return !!node && node.nodeType === 1 && node.matches(selector);\n}\n\n/** Whether `node` is in the document. */\nexport function attached(node) {\n return !!node && document.documentElement.contains(node);\n}\n\n/** The element siblings after `node` that match `selector`. */\nexport function nextAll(node, selector) {\n var found = [];\n\n for (var next = node.nextElementSibling; next; next = next.nextElementSibling) {\n if (!selector || next.matches(selector)) { found.push(next); }\n }\n return found;\n}\n\n/** The ancestors of `node` up to, and not including, `stop`, nearest first. */\nexport function parentsUntil(node, stop) {\n var found = [];\n\n for (var parent = node.parentElement; parent && parent !== stop; parent = parent.parentElement) {\n found.push(parent);\n }\n return found;\n}\n\n/**\n * The nodes the html parses into, detached. Parsed the way innerHTML parses,\n * so a <script> in it never runs, here or once it is in the page.\n */\nexport function parse(html) {\n var template = document.createElement('template');\n template.innerHTML = html;\n return Array.prototype.slice.call(template.content.childNodes);\n}\n\n/** The one element the html is, detached. */\nexport function create(html) {\n var nodes = parse(html.trim());\n\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i].nodeType === 1) { return nodes[i]; }\n }\n return null;\n}\n\n/** An element of `tag`, with `attributes` and `text`. */\nexport function element(tag, attributes, text) {\n var node = document.createElement(tag);\n\n Object.keys(attributes || {}).forEach(function(name) {\n var value = attributes[name];\n if (value !== null && value !== undefined && value !== false) { node.setAttribute(name, value); }\n });\n if (text !== undefined && text !== null) { node.textContent = text; }\n\n return node;\n}\n\n/** Replace what `node` holds with `html`. A <script> in it does not run. */\nexport function setHtml(node, html) {\n node.innerHTML = html === undefined || html === null ? '' : String(html);\n return node;\n}\n\n/** Add one or several space separated classes. */\nexport function addClass(node, names) {\n split(names).forEach(function(name) { node.classList.add(name); });\n return node;\n}\n\nexport function removeClass(node, names) {\n split(names).forEach(function(name) { node.classList.remove(name); });\n return node;\n}\n\n/** Each class on, or off, or flipped when `on` is not given. */\nexport function toggleClass(node, names, state) {\n split(names).forEach(function(name) {\n if (state === undefined) {\n node.classList.toggle(name);\n } else {\n node.classList.toggle(name, !!state);\n }\n });\n return node;\n}\n\nexport function hasClass(node, name) {\n return !!node && node.nodeType === 1 && node.classList.contains(name);\n}\n\nfunction split(names) {\n return String(names || '').split(/\\s+/).filter(Boolean);\n}\n\n/** Take the class attribute off when there is nothing left in it. */\nexport function dropEmptyClass(node) {\n if (!node.getAttribute('class')) { node.removeAttribute('class'); }\n return node;\n}\n\n/** Take the style attribute off when there is nothing left in it. */\nexport function dropEmptyStyle(node) {\n if (!node.getAttribute('style')) { node.removeAttribute('style'); }\n return node;\n}\n\n/** Set attributes; a null or undefined value takes the attribute off. */\nexport function attr(node, attributes) {\n Object.keys(attributes).forEach(function(name) {\n var value = attributes[name];\n\n if (value === null || value === undefined) {\n node.removeAttribute(name);\n } else {\n node.setAttribute(name, value);\n }\n });\n return node;\n}\n\n/**\n * Inline styles, by css property name. A number is pixels for the properties\n * that take a length, as jQuery had it; an empty string takes one off.\n */\nexport function css(node, styles) {\n Object.keys(styles).forEach(function(property) {\n var value = styles[property];\n\n if (typeof value === 'number' && !UNITLESS[property]) { value = value + 'px'; }\n node.style.setProperty(property, value === null || value === undefined ? '' : String(value));\n });\n return node;\n}\n\nvar UNITLESS = { opacity: true, 'z-index': true, 'flex-grow': true, 'flex-shrink': true, order: true };\n\n/** What an element of this tag shows as when nothing hides it. */\nvar defaultDisplays = {};\n\nfunction defaultDisplay(node) {\n var tag = node.nodeName;\n\n if (!defaultDisplays[tag]) {\n var probe = document.body.appendChild(document.createElement(tag));\n defaultDisplays[tag] = getComputedStyle(probe).display;\n probe.remove();\n if (defaultDisplays[tag] === 'none') { defaultDisplays[tag] = 'block'; }\n }\n return defaultDisplays[tag];\n}\n\n/** Show a node: its inline display:none off, and a display of its own if a stylesheet hides it. */\nexport function show(node) {\n node.style.removeProperty('display');\n if (getComputedStyle(node).display === 'none') { node.style.display = defaultDisplay(node); }\n return node;\n}\n\nexport function hide(node) {\n node.style.display = 'none';\n return node;\n}\n\n/** Show or hide; flip when `on` is not given. */\nexport function toggle(node, state) {\n if (state === undefined) { state = !visible(node); }\n return state ? show(node) : hide(node);\n}\n\n/** Whether a node takes up room: what jQuery's :visible meant. */\nexport function visible(node) {\n return !!(node.offsetWidth || node.offsetHeight || node.getClientRects().length);\n}\n\n/** The border box's width, fractions included. */\nexport function outerWidth(node) {\n return node.getBoundingClientRect().width;\n}\n\nexport function outerHeight(node) {\n return node.getBoundingClientRect().height;\n}\n\n/** The content box's height, which is what jQuery's height() gave. */\nexport function contentHeight(node) {\n var style = getComputedStyle(node);\n return node.clientHeight - parseFloat(style.paddingTop) - parseFloat(style.paddingBottom);\n}\n\n/** Where a node is on the page, not in the window. */\nexport function offset(node) {\n var box = node.getBoundingClientRect();\n return { top: box.top + window.pageYOffset, left: box.left + window.pageXOffset };\n}\n\n/** Its index among its parent's element children, those matching `selector` if given. */\nexport function indexIn(node, selector) {\n return children(node.parentElement, selector).indexOf(node);\n}\n\n/** Put `node` right after `reference`. */\nexport function insertAfter(node, reference) {\n reference.parentNode.insertBefore(node, reference.nextSibling);\n return node;\n}\n\n/** Replace `node` with what it holds. */\nexport function unwrap(node) {\n var parent = node.parentNode;\n\n while (node.firstChild) { parent.insertBefore(node.firstChild, node); }\n node.remove();\n}\n\n/** Put `node` inside `wrapper`, where `node` was. */\nexport function wrap(node, wrapper) {\n node.parentNode.insertBefore(wrapper, node);\n wrapper.appendChild(node);\n return wrapper;\n}\n\n/**\n * Listen on `root` for `types` (space separated) on descendants that match\n * `selector`, with `this` the matched element, as jQuery's delegated\n * handlers had it. Hands back the listener, for removeEventListener; a\n * signal in `options` removes it too.\n */\nexport function delegate(root, types, selector, handler, options) {\n var listener = function(event) {\n var match = closest(event.target, selector, root);\n if (match && root.contains(match)) { return handler.call(match, event); }\n return undefined;\n };\n\n split(types).forEach(function(type) { root.addEventListener(type, listener, options); });\n return listener;\n}\n\n/** Listen for several space separated event types with one handler. */\nexport function on(target, types, handler, options) {\n split(types).forEach(function(type) { target.addEventListener(type, handler, options); });\n return handler;\n}\n\nexport function off(target, types, handler, options) {\n split(types).forEach(function(type) { target.removeEventListener(type, handler, options); });\n}\n\n/** A mouse event of `type` sent to `node`, the way a pointer would. */\nexport function fire(node, type) {\n node.dispatchEvent(new MouseEvent(type, { bubbles: type !== 'mouseenter' && type !== 'mouseleave' }));\n}\n\n/* ------------------------------------------------------------------\n * Taking a node away, visibly.\n *\n * The durations are jQuery's: 400 ms unless the caller says otherwise. `done` runs once the node is out of sight, which is\n * when the caller removes it; a node that is already out of sight is done at\n * once, on the next task, as jQuery had it.\n * ------------------------------------------------------------------ */\n\nvar DEFAULT_DURATION = 400;\n\nfunction animateAway(node, frames, duration, done) {\n duration = duration === undefined ? DEFAULT_DURATION : duration;\n\n var finish = function() {\n hide(node);\n if (done) { done(); }\n };\n\n if (!visible(node) || !node.animate || duration <= 0) {\n window.setTimeout(finish, 0);\n return;\n }\n\n var animation = node.animate(frames(getComputedStyle(node)), {\n duration: duration,\n easing: 'ease-in-out',\n });\n var called = false;\n var once = function() {\n if (called) { return; }\n called = true;\n finish();\n };\n\n animation.onfinish = once;\n animation.oncancel = once;\n}\n\n/** Fold a node up to nothing, then hide it. */\nexport function slideUp(node, duration, done) {\n if (typeof duration === 'function') {\n done = duration;\n duration = undefined;\n }\n\n node.style.overflow = 'hidden';\n animateAway(node, function(style) {\n return [\n {\n height: style.height,\n paddingTop: style.paddingTop,\n paddingBottom: style.paddingBottom,\n marginTop: style.marginTop,\n marginBottom: style.marginBottom,\n },\n { height: '0px', paddingTop: '0px', paddingBottom: '0px', marginTop: '0px', marginBottom: '0px' },\n ];\n }, duration, function() {\n node.style.removeProperty('overflow');\n if (done) { done(); }\n });\n}\n\n/** Fade a node out, then hide it. */\nexport function fadeOut(node, duration, done) {\n animateAway(node, function(style) {\n return [{ opacity: style.opacity }, { opacity: 0 }];\n }, duration, done);\n}\n\n/** Fade and fold a node, in height and, with `width`, sideways too, then hide it. */\nexport function shrinkAway(node, duration, done, width) {\n node.style.overflow = 'hidden';\n animateAway(node, function(style) {\n var from = { opacity: style.opacity, height: style.height };\n var to = { opacity: 0, height: '0px' };\n\n if (width) {\n from.width = style.width;\n to.width = '0px';\n }\n return [from, to];\n }, duration, function() {\n node.style.removeProperty('overflow');\n if (done) { done(); }\n });\n}\n", "/**\n * What the popup and the offcanvas plugins share: the host's triggers.\n *\n * A trigger is markup the host owns - a button, a link - anywhere in the\n * canvas, that points at a container by id. While editing it must not reach\n * Bootstrap, and one that points at nothing is warned about. Not a public\n * API: the build puts a copy of this file in each plugin that imports it,\n * so it keeps nothing of its own between plugins.\n */\nimport * as dom from '../dom.js';\n\n/**\n * The trigger handling of one kind of container.\n *\n * `kind` names the container (`popup`), its classes (`ge-popup-trigger`,\n * `ge-popup-orphan`) and the event for a trigger left pointing at nothing\n * (`popup-orphan`). `idAttribute` is the attribute a container has its id in,\n * `targetAttribute` the one a trigger names it with, and `toggle` is\n * Bootstrap's `data-bs-toggle` for it, written on the way out.\n *\n * Gives back `onInit` and `onDeinit`, for the plugin to hand the editor as\n * its own, and `write(root)`, what onDeinit does to the canvas, for\n * cleanMarkup to do to a copy.\n */\nexport function triggersFor(ge, kind, idAttribute, targetAttribute, toggle) {\n var triggerClass = 'ge-' + kind + '-trigger';\n var orphanClass = 'ge-' + kind + '-orphan';\n var listening = null;\n\n function idOf(container) {\n return container.getAttribute(idAttribute);\n }\n\n /** Whether a container with this id is on the canvas. */\n function exists(id, root) {\n return dom.all(root || ge.canvas, '[' + idAttribute + ']').some(function(container) {\n return idOf(container) === id;\n });\n }\n\n function wire() {\n dom.all(ge.canvas, '[' + targetAttribute + ']').forEach(function(trigger) {\n dom.addClass(trigger, triggerClass);\n var wanted = trigger.getAttribute(targetAttribute);\n\n // Bootstrap's own attributes are written at getHtml time, not\n // while editing, so a click here cannot open a real container\n trigger.removeAttribute('data-bs-toggle');\n trigger.removeAttribute('data-bs-target');\n\n if (exists(wanted)) {\n dom.removeClass(trigger, orphanClass);\n return;\n }\n\n var column = trigger.closest('.column');\n var nearby = column ? dom.all(column, '[' + idAttribute + ']') : [];\n\n if (nearby.length === 1) {\n trigger.setAttribute(targetAttribute, idOf(nearby[0]));\n dom.removeClass(trigger, orphanClass);\n return;\n }\n\n dom.addClass(trigger, orphanClass);\n\n ge.operate(function() {\n ge.emit(kind + '-orphan', ge.payloadFor(kind, trigger, {\n parent: trigger.parentElement,\n source: 'api',\n missing: wanted,\n }));\n });\n });\n }\n\n function write(root) {\n root = root || ge.canvas;\n\n dom.all(root, '[' + targetAttribute + ']').forEach(function(trigger) {\n var wanted = trigger.getAttribute(targetAttribute);\n\n // The warning marking is editing furniture, whether or not\n // the trigger can be wired up\n dom.removeClass(trigger, orphanClass);\n dom.dropEmptyClass(trigger);\n\n if (!exists(wanted, root)) { return; }\n\n trigger.setAttribute('data-bs-toggle', toggle);\n trigger.setAttribute('data-bs-target', '#' + wanted);\n });\n }\n\n return {\n write: write,\n\n // Triggers are markup the host owns, anywhere in the canvas, so they\n // are looked at whenever the canvas is initialized rather than only\n // when a container is touched\n onInit: function() {\n wire();\n\n if (listening) { listening.abort(); }\n listening = new AbortController();\n\n // A trigger is often a link, and a link still navigates even\n // with its Bootstrap attributes suspended\n dom.delegate(ge.canvas, 'click', '.' + triggerClass + ', [' + targetAttribute + ']', function(e) {\n if (dom.hasClass(ge.canvas, 'ge-editing')) { e.preventDefault(); }\n }, { signal: listening.signal });\n },\n\n onDeinit: function() {\n if (listening) { listening.abort(); }\n listening = null;\n\n write();\n },\n };\n}\n", "/**\n * Offcanvases for grid-editor.\n *\n * A container plugin: load this file after the editor and the toolbar offers\n * an offcanvas, a bootstrap panel that slides in from an edge of the window,\n * and its trigger. What it can ask the editor for is the handle its factory\n * is called with, described in docs/plugins.md.\n *\n * <script src=\"dist/grideditor.min.js\"></script>\n * <script src=\"dist/plugins/grideditor.offcanvas.min.js\"></script>\n *\n * While editing the panel is rendered unfolded and in place, with its body as\n * an ordinary region, and nothing in it reaches Bootstrap's javascript. Its\n * options - placement, backdrop, body scroll, keyboard, responsive and dark\n * theme - are Bootstrap's classes and attributes and nothing else: they are\n * read from the markup, chosen in the container's settings panel, or given to\n * createContainer and the offcanvas setting for the ones made new.\n */\nimport { GridEditor } from '../grideditor.js';\nimport * as dom from '../dom.js';\nimport { triggersFor } from '../triggers/triggers.js';\n\nObject.assign(GridEditor.locales.en, {\n 'container.add_offcanvas': 'Offcanvas',\n 'container.offcanvas_title': 'Title',\n 'container.offcanvas_trigger': 'Open',\n 'tool.toggle_offcanvas': 'Fold this offcanvas away while editing',\n 'container.offcanvas_section': 'Offcanvas',\n 'container.offcanvas_placement': 'Placement',\n 'container.offcanvas_start': 'Start',\n 'container.offcanvas_end': 'End',\n 'container.offcanvas_top': 'Top',\n 'container.offcanvas_bottom': 'Bottom',\n 'container.offcanvas_backdrop': 'Backdrop',\n 'container.offcanvas_backdrop_yes': 'Yes',\n 'container.offcanvas_backdrop_no': 'No',\n 'container.offcanvas_backdrop_static': 'Static',\n 'container.offcanvas_scroll': 'Allow body scroll',\n 'container.offcanvas_keyboard': 'Close with Esc',\n 'container.offcanvas_responsive': 'Responsive',\n 'container.offcanvas_responsive_never': 'Always offcanvas',\n 'container.offcanvas_responsive_from': 'Inline from {breakpoint}',\n 'container.offcanvas_dark': 'Dark theme',\n});\n\n/** What an offcanvas made new has when neither the call nor the setting says. */\nvar DEFAULTS = {\n placement: 'start',\n backdrop: true,\n scroll: false,\n keyboard: true,\n responsive: null,\n dark: false,\n};\n\nvar KEYS = ['placement', 'backdrop', 'scroll', 'keyboard', 'responsive', 'dark'];\nvar PLACEMENTS = ['start', 'end', 'top', 'bottom'];\nvar BACKDROPS = [true, false, 'static'];\n\n/** Each field's label, and each choice's, as keys the locale test can find. */\nvar LABELS = {\n placement: { labelKey: 'container.offcanvas_placement' },\n backdrop: { labelKey: 'container.offcanvas_backdrop' },\n responsive: { labelKey: 'container.offcanvas_responsive' },\n scroll: { labelKey: 'container.offcanvas_scroll' },\n keyboard: { labelKey: 'container.offcanvas_keyboard' },\n dark: { labelKey: 'container.offcanvas_dark' },\n};\nvar PLACEMENT_CHOICES = [\n { value: 'start', labelKey: 'container.offcanvas_start' },\n { value: 'end', labelKey: 'container.offcanvas_end' },\n { value: 'top', labelKey: 'container.offcanvas_top' },\n { value: 'bottom', labelKey: 'container.offcanvas_bottom' },\n];\nvar BACKDROP_CHOICES = [\n { value: 'true', labelKey: 'container.offcanvas_backdrop_yes' },\n { value: 'false', labelKey: 'container.offcanvas_backdrop_no' },\n { value: 'static', labelKey: 'container.offcanvas_backdrop_static' },\n];\n\nvar fieldCounter = 0;\n\nGridEditor.containers.offcanvas = function(ge) {\n\n // Bootstrap has no offcanvas-xs: below the smallest breakpoint is always a panel\n var RESPONSIVE = ge.breakpoints.filter(function(key) { return key !== 'xs'; });\n var sections = []; // { node, element, render } for every panel section built\n\n var triggers = triggersFor(ge, 'offcanvas', 'data-ge-offcanvas-id', 'data-ge-offcanvas-target', 'offcanvas');\n\n var CHECKS = {\n placement: function(value) { return PLACEMENTS.indexOf(value) !== -1; },\n backdrop: function(value) { return BACKDROPS.indexOf(value) !== -1; },\n responsive: function(value) { return value === null || RESPONSIVE.indexOf(value) !== -1; },\n };\n\n function isValid(key, value) {\n return CHECKS[key] ? CHECKS[key](value) : typeof value === 'boolean';\n }\n\n /** The values an option takes, as the warning lists them. */\n function takes(key) {\n if (key === 'placement') { return JSON.stringify(PLACEMENTS); }\n if (key === 'backdrop') { return JSON.stringify(BACKDROPS); }\n if (key === 'responsive') { return JSON.stringify([null].concat(RESPONSIVE)); }\n\n return '[true,false]';\n }\n\n /**\n * A value for a new offcanvas: the option, or the offcanvas setting, or\n * the default. One the option does not take is warned about and the\n * default used.\n */\n function chosen(options, key) {\n var setting = ge.settings.offcanvas || {};\n var value = options[key] !== undefined ? options[key] : setting[key];\n\n if (value === undefined) { return DEFAULTS[key]; }\n if (isValid(key, value)) { return value; }\n\n ge.warn('offcanvas: ' + JSON.stringify(value) + ' is not a ' + key + ', which takes ' +\n takes(key) + ': ' + JSON.stringify(DEFAULTS[key]) + ' is used');\n return DEFAULTS[key];\n }\n\n /** The class that makes a node a panel: `offcanvas`, or `offcanvas-{breakpoint}` for a responsive one. */\n function isPanelClass(name) {\n return name === 'offcanvas' || (/^offcanvas-/.test(name) && RESPONSIVE.indexOf(name.slice(10)) !== -1);\n }\n\n function isPanel(node) {\n return Array.prototype.some.call(node.classList, isPanelClass);\n }\n\n /** The panel, found by the id the container carries: with responsive it has no .offcanvas class. */\n function panelOf(container) {\n var id = container.getAttribute('data-ge-offcanvas-id');\n var own = dom.children(container);\n\n return own.filter(function(node) { return id && node.id === id; })[0] || own.filter(isPanel)[0] || null;\n }\n\n function triggerOf(container) {\n return dom.child(container, '[data-ge-offcanvas-target]');\n }\n\n /** The class that marks a trigger while editing is furniture: the page has no use for it. */\n function dropTriggerMarks(root) {\n dom.all(root, '.ge-offcanvas-trigger').forEach(function(trigger) {\n dom.removeClass(trigger, 'ge-offcanvas-trigger');\n dom.dropEmptyClass(trigger);\n });\n }\n\n function hideClass(responsive) {\n return 'd-' + responsive + '-none';\n }\n\n /** What a panel's classes and attributes say it is. */\n function read(container) {\n var panel = panelOf(container);\n var backdrop = panel.getAttribute('data-bs-backdrop');\n var responsive = null;\n\n Array.prototype.forEach.call(panel.classList, function(name) {\n if (name !== 'offcanvas' && isPanelClass(name)) { responsive = name.slice(10); }\n });\n\n return {\n placement: PLACEMENTS.filter(function(place) { return dom.hasClass(panel, 'offcanvas-' + place); })[0] || 'start',\n backdrop: backdrop === 'false' ? false : backdrop === 'static' ? 'static' : true,\n scroll: panel.getAttribute('data-bs-scroll') === 'true',\n keyboard: panel.getAttribute('data-bs-keyboard') !== 'false',\n responsive: responsive,\n dark: panel.getAttribute('data-bs-theme') === 'dark',\n };\n }\n\n function setAttribute(panel, name, value) {\n if (value === null) {\n panel.removeAttribute(name);\n } else {\n panel.setAttribute(name, value);\n }\n }\n\n function write(container, key, value) {\n var panel = panelOf(container);\n\n if (key === 'placement') {\n PLACEMENTS.forEach(function(place) { dom.removeClass(panel, 'offcanvas-' + place); });\n dom.addClass(panel, 'offcanvas-' + value);\n }\n\n if (key === 'backdrop') { setAttribute(panel, 'data-bs-backdrop', value === true ? null : String(value)); }\n if (key === 'scroll') { setAttribute(panel, 'data-bs-scroll', value ? 'true' : null); }\n if (key === 'keyboard') { setAttribute(panel, 'data-bs-keyboard', value ? null : 'false'); }\n\n if (key === 'responsive') {\n var before = read(container).responsive;\n var trigger = triggerOf(container);\n var rest = Array.prototype.filter.call(panel.classList, function(name) { return !isPanelClass(name); });\n\n // The one class that makes it a panel comes first, as Bootstrap writes it\n panel.className = [value === null ? 'offcanvas' : 'offcanvas-' + value].concat(rest).join(' ');\n\n if (trigger) {\n if (before !== null) { dom.removeClass(trigger, hideClass(before)); }\n if (value !== null) { dom.addClass(trigger, hideClass(value)); }\n dom.dropEmptyClass(trigger);\n }\n }\n\n if (key === 'dark') {\n if (value) {\n panel.setAttribute('data-bs-theme', 'dark');\n } else if (panel.getAttribute('data-bs-theme') === 'dark') {\n panel.removeAttribute('data-bs-theme');\n }\n }\n }\n\n function nextId() {\n return 'ge-offcanvas-option-' + (++fieldCounter);\n }\n\n function field(labelKey, control, id) {\n var box = dom.element('div', { 'class': 'ge-offcanvas-option mb-2' });\n\n box.appendChild(dom.element('label', { 'class': 'form-label', 'for': id }, ge.t(labelKey)));\n box.appendChild(control);\n\n return box;\n }\n\n function checkbox(labelKey, onChange) {\n var id = nextId();\n var box = dom.element('div', { 'class': 'form-check' });\n var input = box.appendChild(dom.element('input', { 'class': 'form-check-input', type: 'checkbox', id: id }));\n\n box.appendChild(dom.element('label', { 'class': 'form-check-label', 'for': id }, ge.t(labelKey)));\n input.addEventListener('change', function() { onChange(input.checked); });\n\n return { box: box, input: input };\n }\n\n /** A select over `choices`, each { value, label }, that calls `onChange` with the value chosen. */\n function select(choices, onChange) {\n var id = nextId();\n var control = dom.element('select', { 'class': 'form-select form-select-sm', id: id });\n\n choices.forEach(function(choice) {\n control.appendChild(dom.element('option', { value: choice.value }, choice.label));\n });\n control.addEventListener('change', function() { onChange(control.value); });\n\n return { id: id, control: control };\n }\n\n /** The Offcanvas section of an offcanvas's settings panel. */\n function createSection(container) {\n var body = dom.element('div', { 'class': 'ge-offcanvas-options' });\n\n function change(key, value) {\n write(container, key, value);\n render();\n }\n\n var translated = function(choice) { return { value: choice.value, label: ge.t(choice.labelKey) }; };\n\n var selects = {\n placement: select(PLACEMENT_CHOICES.map(translated), function(value) { change('placement', value); }),\n backdrop: select(BACKDROP_CHOICES.map(translated), function(value) {\n change('backdrop', value === 'static' ? 'static' : value === 'true');\n }),\n responsive: select([{ value: '', label: ge.t('container.offcanvas_responsive_never') }].concat(\n RESPONSIVE.map(function(key) {\n return { value: key, label: ge.t('container.offcanvas_responsive_from', { breakpoint: key }) };\n })\n ), function(value) { change('responsive', value === '' ? null : value); }),\n };\n\n Object.keys(selects).forEach(function(key) {\n var box = field(LABELS[key].labelKey, selects[key].control, selects[key].id);\n\n box.setAttribute('data-ge-offcanvas-option', key);\n body.appendChild(box);\n });\n\n var inputs = {};\n ['scroll', 'keyboard', 'dark'].forEach(function(key) {\n var each = checkbox(LABELS[key].labelKey, function(on) { change(key, on); });\n\n inputs[key] = each.input;\n each.box.setAttribute('data-ge-offcanvas-option', key);\n body.appendChild(each.box);\n });\n\n /** Fill the fields from the markup. */\n function render() {\n var values = read(container);\n\n selects.placement.control.value = values.placement;\n selects.backdrop.control.value = String(values.backdrop);\n selects.responsive.control.value = values.responsive === null ? '' : values.responsive;\n Object.keys(inputs).forEach(function(key) { inputs[key].checked = values[key]; });\n }\n\n render();\n sections.push({ node: container, element: body, render: render });\n\n return body;\n }\n\n return {\n labelKey: 'container.add_offcanvas',\n paneKind: 'offcanvas',\n\n // The ids a copy of an offcanvas has to rename together\n references: ['data-ge-offcanvas-id', 'data-ge-offcanvas-target'],\n\n onInit: triggers.onInit,\n\n onDeinit: function() {\n sections = [];\n triggers.onDeinit();\n dropTriggerMarks(ge.canvas);\n },\n\n // What onDeinit and unmark do, on a copy of the canvas\n cleanMarkup: function(root) {\n var definition = this;\n triggers.write(root);\n dropTriggerMarks(root);\n dom.all(root, '[data-ge-container=\"offcanvas\"]').forEach(function(container) { definition.unmark(container); });\n },\n\n create: function(options) {\n options = options || {};\n\n var id = ge.containerId('offcanvas');\n var container = dom.element('div', { 'data-ge-container': 'offcanvas', 'data-ge-offcanvas-id': id });\n\n if (options.trigger !== false) {\n container.appendChild(dom.element('button', {\n type: 'button',\n 'class': 'btn btn-primary ge-offcanvas-trigger',\n 'data-ge-offcanvas-target': id,\n }, options.trigger_label || ge.t('container.offcanvas_trigger')));\n }\n\n var panel = container.appendChild(dom.element('div', {\n 'class': 'offcanvas',\n tabindex: '-1',\n id: id,\n 'aria-labelledby': id + '-label',\n }));\n var header = panel.appendChild(dom.element('div', { 'class': 'offcanvas-header' }));\n\n header.appendChild(dom.element('h5', { 'class': 'offcanvas-title', id: id + '-label' }))\n .appendChild(dom.element('span', { 'class': 'ge-pane-label' },\n options.title || ge.t('container.offcanvas_title')));\n header.appendChild(dom.create('<button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"offcanvas\" aria-label=\"Close\"></button>'));\n panel.appendChild(dom.element('div', { 'class': 'offcanvas-body' })).appendChild(ge.defaultRegion());\n\n KEYS.forEach(function(key) { write(container, key, chosen(options, key)); });\n\n return container;\n },\n\n mark: function(container) {\n var header = dom.child(panelOf(container), '.offcanvas-header');\n\n // Nothing in an offcanvas may reach Bootstrap while editing:\n // the panel is rendered unfolded and static, and a real\n // one sliding in over it would be the editor fighting itself\n dom.all(header, '[data-bs-dismiss]').forEach(function(dismiss) {\n ge.suspendToggles(dismiss);\n });\n dom.all(header, '.offcanvas-title').forEach(function(title) {\n ge.makeLabelEditable(ge.labelIn(title));\n });\n },\n\n unmark: function(container) {\n var header = dom.child(panelOf(container), '.offcanvas-header');\n\n if (header) {\n ge.resumeToggles(header);\n ge.unwrapLabels(header);\n }\n dom.removeClass(container, 'ge-offcanvas-collapsed');\n },\n\n /** A page of unfolded panels stays workable if they can be folded away. */\n tools: function(drawer, container) {\n ge.createTool(drawer, ge.t('tool.toggle_offcanvas'), 'ge-toggle-offcanvas', 'bi bi-chevron-bar-contract',\n function() {\n dom.toggleClass(container, 'ge-offcanvas-collapsed');\n });\n },\n\n panelSection: function(node, kind) {\n if (kind === 'offcanvas' && panelOf(node)) {\n return { labelKey: 'container.offcanvas_section', body: createSection(node) };\n }\n\n return null;\n },\n\n // After a view change or a change of classes: the sections follow\n onRefresh: function(scope) {\n sections = sections.filter(function(entry) { return entry.element.isConnected; });\n sections.forEach(function(entry) {\n if (entry.node === scope || scope.contains(entry.node)) { entry.render(); }\n });\n },\n };\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["GridEditor", "all", "root", "selector", "children", "node", "selector", "each", "child", "closest", "stopAt", "found", "parse", "html", "template", "create", "nodes", "i", "element", "tag", "attributes", "text", "node", "name", "value", "addClass", "node", "names", "split", "name", "removeClass", "toggleClass", "state", "hasClass", "dropEmptyClass", "delegate", "root", "types", "selector", "handler", "options", "listener", "event", "match", "closest", "split", "type", "triggersFor", "ge", "kind", "idAttribute", "targetAttribute", "toggle", "triggerClass", "orphanClass", "listening", "idOf", "container", "exists", "id", "root", "all", "wire", "trigger", "addClass", "wanted", "removeClass", "column", "nearby", "write", "dropEmptyClass", "delegate", "e", "hasClass", "GridEditor", "DEFAULTS", "KEYS", "PLACEMENTS", "BACKDROPS", "LABELS", "PLACEMENT_CHOICES", "BACKDROP_CHOICES", "fieldCounter", "ge", "RESPONSIVE", "key", "sections", "triggers", "triggersFor", "CHECKS", "value", "isValid", "takes", "chosen", "options", "setting", "isPanelClass", "name", "isPanel", "node", "panelOf", "container", "id", "own", "children", "triggerOf", "child", "dropTriggerMarks", "root", "all", "trigger", "removeClass", "dropEmptyClass", "hideClass", "responsive", "read", "panel", "backdrop", "place", "hasClass", "setAttribute", "write", "addClass", "before", "rest", "nextId", "field", "labelKey", "control", "box", "element", "checkbox", "onChange", "input", "select", "choices", "choice", "createSection", "body", "change", "render", "translated", "selects", "inputs", "each", "on", "values", "definition", "header", "create", "dismiss", "title", "drawer", "toggleClass", "kind", "scope", "entry"]
|
|
7
|
+
}
|
|
@@ -5,6 +5,13 @@ import { GridEditor } from "../grideditor.esm.js";
|
|
|
5
5
|
function all(root, selector) {
|
|
6
6
|
return root ? Array.prototype.slice.call(root.querySelectorAll(selector)) : [];
|
|
7
7
|
}
|
|
8
|
+
function closest(node, selector, stopAt) {
|
|
9
|
+
var found = node && node.nodeType === 1 ? node.closest(selector) : null;
|
|
10
|
+
if (found && stopAt && found !== stopAt && !stopAt.contains(found)) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return found;
|
|
14
|
+
}
|
|
8
15
|
function parse(html) {
|
|
9
16
|
var template = document.createElement("template");
|
|
10
17
|
template.innerHTML = html;
|
|
@@ -54,6 +61,9 @@ function toggleClass(node, names, state) {
|
|
|
54
61
|
});
|
|
55
62
|
return node;
|
|
56
63
|
}
|
|
64
|
+
function hasClass(node, name) {
|
|
65
|
+
return !!node && node.nodeType === 1 && node.classList.contains(name);
|
|
66
|
+
}
|
|
57
67
|
function split(names) {
|
|
58
68
|
return String(names || "").split(/\s+/).filter(Boolean);
|
|
59
69
|
}
|
|
@@ -63,43 +73,53 @@ function dropEmptyClass(node) {
|
|
|
63
73
|
}
|
|
64
74
|
return node;
|
|
65
75
|
}
|
|
76
|
+
function delegate(root, types, selector, handler, options) {
|
|
77
|
+
var listener = function(event) {
|
|
78
|
+
var match = closest(event.target, selector, root);
|
|
79
|
+
if (match && root.contains(match)) {
|
|
80
|
+
return handler.call(match, event);
|
|
81
|
+
}
|
|
82
|
+
return void 0;
|
|
83
|
+
};
|
|
84
|
+
split(types).forEach(function(type) {
|
|
85
|
+
root.addEventListener(type, listener, options);
|
|
86
|
+
});
|
|
87
|
+
return listener;
|
|
88
|
+
}
|
|
66
89
|
|
|
67
|
-
// src/js/
|
|
68
|
-
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
GridEditor.containers.popup = function(ge) {
|
|
75
|
-
function popupIdOf(container) {
|
|
76
|
-
return container.getAttribute("data-ge-popup-id");
|
|
90
|
+
// src/js/triggers/triggers.js
|
|
91
|
+
function triggersFor(ge, kind, idAttribute, targetAttribute, toggle) {
|
|
92
|
+
var triggerClass = "ge-" + kind + "-trigger";
|
|
93
|
+
var orphanClass = "ge-" + kind + "-orphan";
|
|
94
|
+
var listening = null;
|
|
95
|
+
function idOf(container) {
|
|
96
|
+
return container.getAttribute(idAttribute);
|
|
77
97
|
}
|
|
78
|
-
function
|
|
79
|
-
return all(root || ge.canvas, "[
|
|
80
|
-
return
|
|
98
|
+
function exists(id, root) {
|
|
99
|
+
return all(root || ge.canvas, "[" + idAttribute + "]").some(function(container) {
|
|
100
|
+
return idOf(container) === id;
|
|
81
101
|
});
|
|
82
102
|
}
|
|
83
|
-
function
|
|
84
|
-
all(ge.canvas, "[
|
|
85
|
-
addClass(trigger,
|
|
86
|
-
var wanted = trigger.getAttribute(
|
|
103
|
+
function wire() {
|
|
104
|
+
all(ge.canvas, "[" + targetAttribute + "]").forEach(function(trigger) {
|
|
105
|
+
addClass(trigger, triggerClass);
|
|
106
|
+
var wanted = trigger.getAttribute(targetAttribute);
|
|
87
107
|
trigger.removeAttribute("data-bs-toggle");
|
|
88
108
|
trigger.removeAttribute("data-bs-target");
|
|
89
|
-
if (
|
|
90
|
-
removeClass(trigger,
|
|
109
|
+
if (exists(wanted)) {
|
|
110
|
+
removeClass(trigger, orphanClass);
|
|
91
111
|
return;
|
|
92
112
|
}
|
|
93
113
|
var column = trigger.closest(".column");
|
|
94
|
-
var nearby = column ? all(column, "[
|
|
114
|
+
var nearby = column ? all(column, "[" + idAttribute + "]") : [];
|
|
95
115
|
if (nearby.length === 1) {
|
|
96
|
-
trigger.setAttribute(
|
|
97
|
-
removeClass(trigger,
|
|
116
|
+
trigger.setAttribute(targetAttribute, idOf(nearby[0]));
|
|
117
|
+
removeClass(trigger, orphanClass);
|
|
98
118
|
return;
|
|
99
119
|
}
|
|
100
|
-
addClass(trigger,
|
|
120
|
+
addClass(trigger, orphanClass);
|
|
101
121
|
ge.operate(function() {
|
|
102
|
-
ge.emit("
|
|
122
|
+
ge.emit(kind + "-orphan", ge.payloadFor(kind, trigger, {
|
|
103
123
|
parent: trigger.parentElement,
|
|
104
124
|
source: "api",
|
|
105
125
|
missing: wanted
|
|
@@ -107,33 +127,66 @@ GridEditor.containers.popup = function(ge) {
|
|
|
107
127
|
});
|
|
108
128
|
});
|
|
109
129
|
}
|
|
110
|
-
function
|
|
130
|
+
function write(root) {
|
|
111
131
|
root = root || ge.canvas;
|
|
112
|
-
all(root, "[
|
|
113
|
-
var wanted = trigger.getAttribute(
|
|
114
|
-
removeClass(trigger,
|
|
132
|
+
all(root, "[" + targetAttribute + "]").forEach(function(trigger) {
|
|
133
|
+
var wanted = trigger.getAttribute(targetAttribute);
|
|
134
|
+
removeClass(trigger, orphanClass);
|
|
115
135
|
dropEmptyClass(trigger);
|
|
116
|
-
if (!
|
|
136
|
+
if (!exists(wanted, root)) {
|
|
117
137
|
return;
|
|
118
138
|
}
|
|
119
|
-
trigger.setAttribute("data-bs-toggle",
|
|
139
|
+
trigger.setAttribute("data-bs-toggle", toggle);
|
|
120
140
|
trigger.setAttribute("data-bs-target", "#" + wanted);
|
|
121
141
|
});
|
|
122
142
|
}
|
|
123
143
|
return {
|
|
124
|
-
|
|
125
|
-
paneKind: "popup",
|
|
144
|
+
write,
|
|
126
145
|
// Triggers are markup the host owns, anywhere in the canvas, so they
|
|
127
146
|
// are looked at whenever the canvas is initialized rather than only
|
|
128
|
-
// when a
|
|
129
|
-
onInit:
|
|
130
|
-
|
|
131
|
-
|
|
147
|
+
// when a container is touched
|
|
148
|
+
onInit: function() {
|
|
149
|
+
wire();
|
|
150
|
+
if (listening) {
|
|
151
|
+
listening.abort();
|
|
152
|
+
}
|
|
153
|
+
listening = new AbortController();
|
|
154
|
+
delegate(ge.canvas, "click", "." + triggerClass + ", [" + targetAttribute + "]", function(e) {
|
|
155
|
+
if (hasClass(ge.canvas, "ge-editing")) {
|
|
156
|
+
e.preventDefault();
|
|
157
|
+
}
|
|
158
|
+
}, { signal: listening.signal });
|
|
132
159
|
},
|
|
160
|
+
onDeinit: function() {
|
|
161
|
+
if (listening) {
|
|
162
|
+
listening.abort();
|
|
163
|
+
}
|
|
164
|
+
listening = null;
|
|
165
|
+
write();
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// src/js/plugins/grideditor.popup.js
|
|
171
|
+
Object.assign(GridEditor.locales.en, {
|
|
172
|
+
"container.add_popup": "Popup",
|
|
173
|
+
"container.popup_title": "Title",
|
|
174
|
+
"container.popup_trigger": "Open",
|
|
175
|
+
"tool.toggle_popup": "Fold this popup away while editing"
|
|
176
|
+
});
|
|
177
|
+
GridEditor.containers.popup = function(ge) {
|
|
178
|
+
var triggers = triggersFor(ge, "popup", "data-ge-popup-id", "data-ge-popup-target", "modal");
|
|
179
|
+
return {
|
|
180
|
+
labelKey: "container.add_popup",
|
|
181
|
+
paneKind: "popup",
|
|
182
|
+
// The ids a copy of a popup has to rename together
|
|
183
|
+
references: ["data-ge-popup-id", "data-ge-popup-target"],
|
|
184
|
+
onInit: triggers.onInit,
|
|
185
|
+
onDeinit: triggers.onDeinit,
|
|
133
186
|
// What onDeinit and unmark do, on a copy of the canvas
|
|
134
187
|
cleanMarkup: function(root) {
|
|
135
188
|
var definition = this;
|
|
136
|
-
|
|
189
|
+
triggers.write(root);
|
|
137
190
|
all(root, '[data-ge-container="popup"]').forEach(function(container) {
|
|
138
191
|
definition.unmark(container);
|
|
139
192
|
});
|
|
@@ -9,6 +9,13 @@
|
|
|
9
9
|
function all(root, selector) {
|
|
10
10
|
return root ? Array.prototype.slice.call(root.querySelectorAll(selector)) : [];
|
|
11
11
|
}
|
|
12
|
+
function closest(node, selector, stopAt) {
|
|
13
|
+
var found = node && node.nodeType === 1 ? node.closest(selector) : null;
|
|
14
|
+
if (found && stopAt && found !== stopAt && !stopAt.contains(found)) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return found;
|
|
18
|
+
}
|
|
12
19
|
function parse(html) {
|
|
13
20
|
var template = document.createElement("template");
|
|
14
21
|
template.innerHTML = html;
|
|
@@ -58,6 +65,9 @@
|
|
|
58
65
|
});
|
|
59
66
|
return node;
|
|
60
67
|
}
|
|
68
|
+
function hasClass(node, name) {
|
|
69
|
+
return !!node && node.nodeType === 1 && node.classList.contains(name);
|
|
70
|
+
}
|
|
61
71
|
function split(names) {
|
|
62
72
|
return String(names || "").split(/\s+/).filter(Boolean);
|
|
63
73
|
}
|
|
@@ -67,43 +77,53 @@
|
|
|
67
77
|
}
|
|
68
78
|
return node;
|
|
69
79
|
}
|
|
80
|
+
function delegate(root, types, selector, handler, options) {
|
|
81
|
+
var listener = function(event) {
|
|
82
|
+
var match = closest(event.target, selector, root);
|
|
83
|
+
if (match && root.contains(match)) {
|
|
84
|
+
return handler.call(match, event);
|
|
85
|
+
}
|
|
86
|
+
return void 0;
|
|
87
|
+
};
|
|
88
|
+
split(types).forEach(function(type) {
|
|
89
|
+
root.addEventListener(type, listener, options);
|
|
90
|
+
});
|
|
91
|
+
return listener;
|
|
92
|
+
}
|
|
70
93
|
|
|
71
|
-
// src/js/
|
|
72
|
-
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
GridEditor.containers.popup = function(ge) {
|
|
79
|
-
function popupIdOf(container) {
|
|
80
|
-
return container.getAttribute("data-ge-popup-id");
|
|
94
|
+
// src/js/triggers/triggers.js
|
|
95
|
+
function triggersFor(ge, kind, idAttribute, targetAttribute, toggle) {
|
|
96
|
+
var triggerClass = "ge-" + kind + "-trigger";
|
|
97
|
+
var orphanClass = "ge-" + kind + "-orphan";
|
|
98
|
+
var listening = null;
|
|
99
|
+
function idOf(container) {
|
|
100
|
+
return container.getAttribute(idAttribute);
|
|
81
101
|
}
|
|
82
|
-
function
|
|
83
|
-
return all(root || ge.canvas, "[
|
|
84
|
-
return
|
|
102
|
+
function exists(id, root) {
|
|
103
|
+
return all(root || ge.canvas, "[" + idAttribute + "]").some(function(container) {
|
|
104
|
+
return idOf(container) === id;
|
|
85
105
|
});
|
|
86
106
|
}
|
|
87
|
-
function
|
|
88
|
-
all(ge.canvas, "[
|
|
89
|
-
addClass(trigger,
|
|
90
|
-
var wanted = trigger.getAttribute(
|
|
107
|
+
function wire() {
|
|
108
|
+
all(ge.canvas, "[" + targetAttribute + "]").forEach(function(trigger) {
|
|
109
|
+
addClass(trigger, triggerClass);
|
|
110
|
+
var wanted = trigger.getAttribute(targetAttribute);
|
|
91
111
|
trigger.removeAttribute("data-bs-toggle");
|
|
92
112
|
trigger.removeAttribute("data-bs-target");
|
|
93
|
-
if (
|
|
94
|
-
removeClass(trigger,
|
|
113
|
+
if (exists(wanted)) {
|
|
114
|
+
removeClass(trigger, orphanClass);
|
|
95
115
|
return;
|
|
96
116
|
}
|
|
97
117
|
var column = trigger.closest(".column");
|
|
98
|
-
var nearby = column ? all(column, "[
|
|
118
|
+
var nearby = column ? all(column, "[" + idAttribute + "]") : [];
|
|
99
119
|
if (nearby.length === 1) {
|
|
100
|
-
trigger.setAttribute(
|
|
101
|
-
removeClass(trigger,
|
|
120
|
+
trigger.setAttribute(targetAttribute, idOf(nearby[0]));
|
|
121
|
+
removeClass(trigger, orphanClass);
|
|
102
122
|
return;
|
|
103
123
|
}
|
|
104
|
-
addClass(trigger,
|
|
124
|
+
addClass(trigger, orphanClass);
|
|
105
125
|
ge.operate(function() {
|
|
106
|
-
ge.emit("
|
|
126
|
+
ge.emit(kind + "-orphan", ge.payloadFor(kind, trigger, {
|
|
107
127
|
parent: trigger.parentElement,
|
|
108
128
|
source: "api",
|
|
109
129
|
missing: wanted
|
|
@@ -111,33 +131,66 @@
|
|
|
111
131
|
});
|
|
112
132
|
});
|
|
113
133
|
}
|
|
114
|
-
function
|
|
134
|
+
function write(root) {
|
|
115
135
|
root = root || ge.canvas;
|
|
116
|
-
all(root, "[
|
|
117
|
-
var wanted = trigger.getAttribute(
|
|
118
|
-
removeClass(trigger,
|
|
136
|
+
all(root, "[" + targetAttribute + "]").forEach(function(trigger) {
|
|
137
|
+
var wanted = trigger.getAttribute(targetAttribute);
|
|
138
|
+
removeClass(trigger, orphanClass);
|
|
119
139
|
dropEmptyClass(trigger);
|
|
120
|
-
if (!
|
|
140
|
+
if (!exists(wanted, root)) {
|
|
121
141
|
return;
|
|
122
142
|
}
|
|
123
|
-
trigger.setAttribute("data-bs-toggle",
|
|
143
|
+
trigger.setAttribute("data-bs-toggle", toggle);
|
|
124
144
|
trigger.setAttribute("data-bs-target", "#" + wanted);
|
|
125
145
|
});
|
|
126
146
|
}
|
|
127
147
|
return {
|
|
128
|
-
|
|
129
|
-
paneKind: "popup",
|
|
148
|
+
write,
|
|
130
149
|
// Triggers are markup the host owns, anywhere in the canvas, so they
|
|
131
150
|
// are looked at whenever the canvas is initialized rather than only
|
|
132
|
-
// when a
|
|
133
|
-
onInit:
|
|
134
|
-
|
|
135
|
-
|
|
151
|
+
// when a container is touched
|
|
152
|
+
onInit: function() {
|
|
153
|
+
wire();
|
|
154
|
+
if (listening) {
|
|
155
|
+
listening.abort();
|
|
156
|
+
}
|
|
157
|
+
listening = new AbortController();
|
|
158
|
+
delegate(ge.canvas, "click", "." + triggerClass + ", [" + targetAttribute + "]", function(e) {
|
|
159
|
+
if (hasClass(ge.canvas, "ge-editing")) {
|
|
160
|
+
e.preventDefault();
|
|
161
|
+
}
|
|
162
|
+
}, { signal: listening.signal });
|
|
136
163
|
},
|
|
164
|
+
onDeinit: function() {
|
|
165
|
+
if (listening) {
|
|
166
|
+
listening.abort();
|
|
167
|
+
}
|
|
168
|
+
listening = null;
|
|
169
|
+
write();
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// src/js/plugins/grideditor.popup.js
|
|
175
|
+
Object.assign(GridEditor.locales.en, {
|
|
176
|
+
"container.add_popup": "Popup",
|
|
177
|
+
"container.popup_title": "Title",
|
|
178
|
+
"container.popup_trigger": "Open",
|
|
179
|
+
"tool.toggle_popup": "Fold this popup away while editing"
|
|
180
|
+
});
|
|
181
|
+
GridEditor.containers.popup = function(ge) {
|
|
182
|
+
var triggers = triggersFor(ge, "popup", "data-ge-popup-id", "data-ge-popup-target", "modal");
|
|
183
|
+
return {
|
|
184
|
+
labelKey: "container.add_popup",
|
|
185
|
+
paneKind: "popup",
|
|
186
|
+
// The ids a copy of a popup has to rename together
|
|
187
|
+
references: ["data-ge-popup-id", "data-ge-popup-target"],
|
|
188
|
+
onInit: triggers.onInit,
|
|
189
|
+
onDeinit: triggers.onDeinit,
|
|
137
190
|
// What onDeinit and unmark do, on a copy of the canvas
|
|
138
191
|
cleanMarkup: function(root) {
|
|
139
192
|
var definition = this;
|
|
140
|
-
|
|
193
|
+
triggers.write(root);
|
|
141
194
|
all(root, '[data-ge-container="popup"]').forEach(function(container) {
|
|
142
195
|
definition.unmark(container);
|
|
143
196
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var
|
|
1
|
+
(()=>{var h=window.GridEditor;if(!h||typeof h.get!="function")throw new Error("grid-editor: load grideditor.js (or grideditor.bundle.min.js) before its plugins, its locales and grideditor.jquery.js");function f(t,n){return t?Array.prototype.slice.call(t.querySelectorAll(n)):[]}function O(t,n,e){var r=t&&t.nodeType===1?t.closest(n):null;return r&&e&&r!==e&&!e.contains(r)?null:r}function _(t){var n=document.createElement("template");return n.innerHTML=t,Array.prototype.slice.call(n.content.childNodes)}function C(t){for(var n=_(t.trim()),e=0;e<n.length;e++)if(n[e].nodeType===1)return n[e];return null}function s(t,n,e){var r=document.createElement(t);return Object.keys(n||{}).forEach(function(a){var l=n[a];l!=null&&l!==!1&&r.setAttribute(a,l)}),e!=null&&(r.textContent=e),r}function g(t,n){return v(n).forEach(function(e){t.classList.add(e)}),t}function d(t,n){return v(n).forEach(function(e){t.classList.remove(e)}),t}function E(t,n,e){return v(n).forEach(function(r){e===void 0?t.classList.toggle(r):t.classList.toggle(r,!!e)}),t}function w(t,n){return!!t&&t.nodeType===1&&t.classList.contains(n)}function v(t){return String(t||"").split(/\s+/).filter(Boolean)}function T(t){return t.getAttribute("class")||t.removeAttribute("class"),t}function A(t,n,e,r,a){var l=function(u){var i=O(u.target,e,t);if(i&&t.contains(i))return r.call(i,u)};return v(n).forEach(function(u){t.addEventListener(u,l,a)}),l}function B(t,n,e,r,a){var l="ge-"+n+"-trigger",u="ge-"+n+"-orphan",i=null;function m(o){return o.getAttribute(e)}function x(o,p){return f(p||t.canvas,"["+e+"]").some(function(c){return m(c)===o})}function L(){f(t.canvas,"["+r+"]").forEach(function(o){g(o,l);var p=o.getAttribute(r);if(o.removeAttribute("data-bs-toggle"),o.removeAttribute("data-bs-target"),x(p)){d(o,u);return}var c=o.closest(".column"),b=c?f(c,"["+e+"]"):[];if(b.length===1){o.setAttribute(r,m(b[0])),d(o,u);return}g(o,u),t.operate(function(){t.emit(n+"-orphan",t.payloadFor(n,o,{parent:o.parentElement,source:"api",missing:p}))})})}function y(o){o=o||t.canvas,f(o,"["+r+"]").forEach(function(p){var c=p.getAttribute(r);d(p,u),T(p),x(c,o)&&(p.setAttribute("data-bs-toggle",a),p.setAttribute("data-bs-target","#"+c))})}return{write:y,onInit:function(){L(),i&&i.abort(),i=new AbortController,A(t.canvas,"click","."+l+", ["+r+"]",function(o){w(t.canvas,"ge-editing")&&o.preventDefault()},{signal:i.signal})},onDeinit:function(){i&&i.abort(),i=null,y()}}}Object.assign(h.locales.en,{"container.add_popup":"Popup","container.popup_title":"Title","container.popup_trigger":"Open","tool.toggle_popup":"Fold this popup away while editing"});h.containers.popup=function(t){var n=B(t,"popup","data-ge-popup-id","data-ge-popup-target","modal");return{labelKey:"container.add_popup",paneKind:"popup",references:["data-ge-popup-id","data-ge-popup-target"],onInit:n.onInit,onDeinit:n.onDeinit,cleanMarkup:function(e){var r=this;n.write(e),f(e,'[data-ge-container="popup"]').forEach(function(a){r.unmark(a)})},create:function(e){var r=t.containerId("popup"),a=s("div",{"data-ge-container":"popup","data-ge-popup-id":r});e.trigger!==!1&&a.appendChild(s("button",{type:"button",class:"btn btn-primary ge-popup-trigger","data-ge-popup-target":r},e.trigger_label||t.t("container.popup_trigger")));var l=a.appendChild(s("div",{class:"modal fade",tabindex:"-1","aria-hidden":"true",id:r})),u=l.appendChild(s("div",{class:"modal-dialog"}));e.size&&g(u,"modal-"+e.size);var i=u.appendChild(s("div",{class:"modal-content"})),m=i.appendChild(s("div",{class:"modal-header"}));return m.appendChild(s("h5",{class:"modal-title"})).appendChild(s("span",{class:"ge-pane-label"},e.title||t.t("container.popup_title"))),m.appendChild(C('<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>')),i.appendChild(s("div",{class:"modal-body"})).appendChild(t.defaultRegion()),a},mark:function(e){f(e,"[data-bs-dismiss]").forEach(function(r){t.suspendToggles(r)}),f(e,".modal-title").forEach(function(r){t.makeLabelEditable(t.labelIn(r))})},unmark:function(e){t.resumeToggles(e),d(e,"ge-popup-collapsed"),t.unwrapLabels(e)},tools:function(e,r){t.createTool(e,t.t("tool.toggle_popup"),"ge-toggle-popup","bi bi-chevron-bar-contract",function(){E(r,"ge-popup-collapsed")})}}};})();
|