@themarioga/grid-editor 7.2.0 → 8.0.0-beta.2

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.
Files changed (97) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/README.md +96 -30
  3. package/UPGRADING.md +86 -0
  4. package/dist/grideditor.bundle.min.js +3 -3
  5. package/dist/grideditor.css +149 -6
  6. package/dist/grideditor.d.ts +18 -0
  7. package/dist/grideditor.esm.js +257 -48
  8. package/dist/grideditor.jquery.js +0 -13
  9. package/dist/grideditor.jquery.min.js +1 -1
  10. package/dist/grideditor.jquery.min.js.map +3 -3
  11. package/dist/grideditor.js +257 -48
  12. package/dist/grideditor.min.css +1 -1
  13. package/dist/grideditor.min.css.map +1 -1
  14. package/dist/grideditor.min.js +2 -2
  15. package/dist/grideditor.min.js.map +3 -3
  16. package/dist/locales/grideditor.es.esm.js +80 -6
  17. package/dist/locales/grideditor.es.js +80 -6
  18. package/dist/locales/grideditor.es.min.js +1 -1
  19. package/dist/locales/grideditor.es.min.js.map +2 -2
  20. package/dist/plugins/grideditor.accordion.min.js.map +2 -2
  21. package/dist/plugins/grideditor.alignment.esm.js +11 -38
  22. package/dist/plugins/grideditor.alignment.js +11 -38
  23. package/dist/plugins/grideditor.alignment.min.js +1 -1
  24. package/dist/plugins/grideditor.alignment.min.js.map +3 -3
  25. package/dist/plugins/grideditor.card.min.js.map +1 -1
  26. package/dist/plugins/grideditor.ckeditor.esm.js +0 -5
  27. package/dist/plugins/grideditor.ckeditor.js +0 -5
  28. package/dist/plugins/grideditor.ckeditor.min.js +1 -1
  29. package/dist/plugins/grideditor.ckeditor.min.js.map +3 -3
  30. package/dist/plugins/grideditor.clipboard.min.js.map +1 -1
  31. package/dist/plugins/grideditor.codemirror-inline.min.js.map +1 -1
  32. package/dist/plugins/grideditor.codemirror.min.js.map +1 -1
  33. package/dist/plugins/grideditor.elements.min.js.map +2 -2
  34. package/dist/plugins/grideditor.gutters.min.js.map +1 -1
  35. package/dist/plugins/grideditor.order.min.js.map +1 -1
  36. package/dist/plugins/grideditor.popup.min.js.map +1 -1
  37. package/dist/plugins/grideditor.sections.min.js.map +2 -2
  38. package/dist/plugins/grideditor.style.esm.js +1926 -0
  39. package/dist/plugins/grideditor.style.js +1923 -0
  40. package/dist/plugins/grideditor.style.min.js +4 -0
  41. package/dist/plugins/grideditor.style.min.js.map +7 -0
  42. package/dist/plugins/grideditor.summernote.min.js.map +2 -2
  43. package/dist/plugins/grideditor.tabs.min.js.map +2 -2
  44. package/dist/plugins/grideditor.tinymce.esm.js +1 -8
  45. package/dist/plugins/grideditor.tinymce.js +1 -8
  46. package/dist/plugins/grideditor.tinymce.min.js +1 -1
  47. package/dist/plugins/grideditor.tinymce.min.js.map +3 -3
  48. package/docs/events.md +4 -6
  49. package/docs/locale-keys.md +99 -15
  50. package/docs/plugins.md +47 -23
  51. package/example/ckeditor.html +0 -5
  52. package/example/index.html +17 -2
  53. package/example/style.html +163 -0
  54. package/example/utilities.html +21 -16
  55. package/package.json +1 -1
  56. package/src/js/dom.js +1 -2
  57. package/src/js/grideditor.jquery.js +7 -28
  58. package/src/js/grideditor.js +336 -67
  59. package/src/js/locales/grideditor.es.js +80 -6
  60. package/src/js/plugins/grideditor.alignment.js +21 -50
  61. package/src/js/plugins/grideditor.ckeditor.js +10 -23
  62. package/src/js/plugins/grideditor.style.js +185 -0
  63. package/src/js/plugins/grideditor.summernote.js +4 -5
  64. package/src/js/plugins/grideditor.tinymce.js +4 -17
  65. package/src/js/style/accordion.js +168 -0
  66. package/src/js/style/catalog.js +76 -0
  67. package/src/js/style/custom.js +84 -0
  68. package/src/js/style/display.js +229 -0
  69. package/src/js/style/drawerflow.js +118 -0
  70. package/src/js/style/fields.js +382 -0
  71. package/src/js/style/flex.js +156 -0
  72. package/src/js/{plugins/grideditor.float.js → style/float.js} +6 -16
  73. package/src/js/style/options.js +60 -0
  74. package/src/js/style/sections.js +298 -0
  75. package/src/js/{plugins/grideditor.spacing.js → style/spacing.js} +7 -19
  76. package/src/js/style/sticky.js +39 -0
  77. package/src/js/{plugins/grideditor.textalign.js → style/textalign.js} +6 -14
  78. package/src/js/text/grideditor.text.js +1 -1
  79. package/src/less/grideditor.less +151 -10
  80. package/types/grideditor.d.ts +18 -0
  81. package/dist/plugins/grideditor.float.esm.js +0 -34
  82. package/dist/plugins/grideditor.float.js +0 -41
  83. package/dist/plugins/grideditor.float.min.js +0 -1
  84. package/dist/plugins/grideditor.float.min.js.map +0 -7
  85. package/dist/plugins/grideditor.spacing.esm.js +0 -318
  86. package/dist/plugins/grideditor.spacing.js +0 -323
  87. package/dist/plugins/grideditor.spacing.min.js +0 -1
  88. package/dist/plugins/grideditor.spacing.min.js.map +0 -7
  89. package/dist/plugins/grideditor.textalign.esm.js +0 -40
  90. package/dist/plugins/grideditor.textalign.js +0 -47
  91. package/dist/plugins/grideditor.textalign.min.js +0 -1
  92. package/dist/plugins/grideditor.textalign.min.js.map +0 -7
  93. package/dist/plugins/grideditor.visibility.esm.js +0 -158
  94. package/dist/plugins/grideditor.visibility.js +0 -163
  95. package/dist/plugins/grideditor.visibility.min.js +0 -1
  96. package/dist/plugins/grideditor.visibility.min.js.map +0 -7
  97. package/src/js/plugins/grideditor.visibility.js +0 -171
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/js/register.js", "../../src/js/dom.js", "../../src/js/text/grideditor.text.js", "../../src/js/plugins/grideditor.tinymce.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 the ones 6.x had through jQuery: 400 ms unless the\n * 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 * Text for grid-editor: what the text editor plugins share.\n *\n * Not a file a page loads. The build puts it at the top of each text editor\n * plugin - grideditor.tinymce.js, grideditor.ckeditor.js,\n * grideditor.summernote.js - and whichever of them loads first installs it:\n * a page with two editors has one of these.\n *\n * It is a feature plugin, `text`, that the `plugins` setting does not choose\n * (content_types does), and it is everything a text is to the editor: the\n * text block's drawer, the Text buttons in the toolbar, createText, opening\n * an editor on a click and closing it again with the host's attributes put\n * back, and making the host's plain content a text through the core's\n * `textTypes` hook.\n *\n * Each editor registers under GridEditor.texts, which is this file's own\n * registry and not a contract: an editor of a host's own is a feature plugin\n * of its own, as example/custom_editor.html shows.\n */\nimport { GridEditor } from '../grideditor.js';\nimport * as dom from '../dom.js';\n\n// However many editors a page loads, each with a copy of this file in its\n// classic script: the first one installs it\nif (!GridEditor.features.text) {\n\n Object.assign(GridEditor.locales.en, {\n 'text.add': 'Text',\n 'text.add_type': 'Text ({editor})',\n 'panel.editor': 'Editor',\n 'panel.kind_text': 'Text',\n });\n\n /**\n * What a content area's attributes were before its editor opened, and\n * once it had: the two readings closeText plays the host's changes\n * back from. Shared by every editor on the page, like the nodes.\n */\n var readBefore = new WeakMap();\n var readReady = new WeakMap();\n\n /** What a text editor puts on a content area while it is open, whenever it likes. */\n var EDITOR_CLASS = /^(mce-|cke|ck-|note-)|^(ck|active|ge-rte-active)$/;\n var EDITOR_ATTRIBUTE = /^(data-mce-|contenteditable$|spellcheck$)/;\n\n function attributesOf(element) {\n var found = {};\n Array.prototype.slice.call(element.attributes).forEach(function(attribute) {\n found[attribute.name] = attribute.value;\n });\n return found;\n }\n\n function classesIn(value) {\n return (value || '').split(/\\s+/).filter(function(name) {\n return name !== '' && !EDITOR_CLASS.test(name);\n });\n }\n\n /** The host's markup, with what changed from `ready` to `open` played back onto it. */\n function restoreAttributes(block, before, ready, open) {\n var result = Object.assign({}, before);\n\n Object.keys(Object.assign({}, ready, open)).forEach(function(name) {\n if (name === 'class' || EDITOR_ATTRIBUTE.test(name) || ready[name] === open[name]) { return; }\n\n if (open[name] === undefined) {\n delete result[name];\n } else {\n result[name] = open[name];\n }\n });\n\n var readyClasses = classesIn(ready['class']);\n var openClasses = classesIn(open['class']);\n var classes = classesIn(before['class']).filter(function(name) {\n return openClasses.indexOf(name) !== -1 || readyClasses.indexOf(name) === -1;\n });\n openClasses.forEach(function(name) {\n if (readyClasses.indexOf(name) === -1 && classes.indexOf(name) === -1) { classes.push(name); }\n });\n\n // In the host's order, class where it was: getHtml should not\n // shuffle a node's attributes because it was edited\n if (classes.length) { result['class'] = classes.join(' '); } else { delete result['class']; }\n\n Object.keys(attributesOf(block)).forEach(function(name) { block.removeAttribute(name); });\n Object.keys(result).forEach(function(name) { block.setAttribute(name, result[name]); });\n }\n\n function textFeature(ge) {\n\n var settings = ge.settings;\n var TEXTS = {};\n var warned = {};\n\n Object.keys(GridEditor.texts).forEach(function(type) {\n TEXTS[type] = GridEditor.texts[type](ge);\n });\n\n // Every editor loaded, in the order the page loaded them, unless the\n // host names the ones it wants\n if (!Array.isArray(settings.content_types)) { settings.content_types = Object.keys(TEXTS); }\n if (!Array.isArray(settings.text_tools)) { settings.text_tools = []; }\n if (!Array.isArray(settings.text_classes)) { settings.text_classes = []; }\n\n /** The text editors this editor offers, in content_types order: the ones loaded. */\n function offeredTexts() {\n return settings.content_types.filter(function(type) { return !!TEXTS[type]; });\n }\n\n /** What a text editor is called: its plugin's label, or its type. */\n function textLabel(type) {\n var text = TEXTS[type];\n return text && text.labelKey ? ge.t(text.labelKey) : type;\n }\n\n /** A detached content area of `type`, holding `content` or the editor's initial content. */\n function makeText(type, content) {\n var text = TEXTS[type];\n var block = dom.element('div', {\n 'class': 'ge-content ge-content-type-' + type,\n 'data-ge-content-type': type,\n });\n\n if (content && content.nodeType) {\n block.appendChild(content);\n } else {\n dom.setHtml(block, content !== undefined ? content : (text && text.initialContent) || '');\n }\n return block;\n }\n\n /**\n * createText(type?, options?): a content area of a text editor's,\n * detached unless a placement is given. The type is the first one\n * offered by default. `options.content` is its html.\n */\n function apiCreateText(type, options) {\n if (type && typeof type === 'object') {\n options = type;\n type = undefined;\n }\n options = options || {};\n type = type || offeredTexts()[0];\n\n if (!type || !TEXTS[type]) {\n if (!warned['createText:' + type]) {\n warned['createText:' + type] = true;\n ge.warn('createText: no text editor \"' + type + '\" is loaded; ' +\n 'load its plugin and name it in content_types');\n }\n return null;\n }\n\n return ge.place(makeText(type, options.content), 'text', options);\n }\n\n /** Whether a content area is a text of one of the editors loaded here. */\n function isOurs(block) {\n return !!TEXTS[block.getAttribute('data-ge-content-type')];\n }\n\n /** Open the editor on a text, once: until it is closed again. */\n function startText(block) {\n if (dom.hasClass(block, 'ge-rte-active')) { return; }\n\n // A content area nobody can see - a tab that is not the open one,\n // a closed accordion item - has no geometry for an editor to lay\n // its toolbar out against, and nothing anyone can type into\n if (!dom.visible(block)) { return; }\n\n // The attribute: it is markup, and the drawer reads it the same way\n var text = TEXTS[block.getAttribute('data-ge-content-type')];\n if (!text) { return; }\n\n // Not marked active, so the next click tries again: the library\n // may be loaded by then\n if (text.available && !text.available()) {\n if (text.missingKey) { console.error(ge.t(text.missingKey)); }\n return;\n }\n\n readBefore.set(block, attributesOf(block));\n readReady.delete(block);\n dom.addClass(block, 'ge-rte-active');\n text.start([block]);\n }\n\n function onClick() {\n startText(this);\n }\n\n /**\n * Close the text editor on one content area, and leave the content\n * area's own attributes as the host left them.\n *\n * An editor adds attributes of its own while it is open, and takes\n * them off again, more or less: CKEditor leaves aria-readonly behind.\n * tinyMCE does worse, and puts back every attribute as it was when it\n * opened, so an id, a class or a plugin's attribute given while it was\n * open is lost. So the attributes are read three times - before the\n * editor opens, once it has opened, and before it closes - and what\n * changed between the second and the third, the host's doing, is\n * played back onto the first, the host's markup. What the editor did\n * is left out either way.\n */\n function closeText(block) {\n var text = TEXTS[block.getAttribute('data-ge-content-type')];\n var before = readBefore.get(block);\n var open = before ? attributesOf(block) : null;\n\n // Every content area is told, as in 5.x: one whose editor never\n // started is the plugin's to ignore\n if (text) { text.stop([block]); }\n\n // After stop, not before: an editor that restores the class\n // attribute it snapshotted would put ge-rte-active back\n dom.removeClass(block, 'ge-rte-active');\n\n if (before) {\n restoreAttributes(block, before, readReady.get(block) || before, open);\n readBefore.delete(block);\n readReady.delete(block);\n }\n }\n\n function createTextControls(textBlock) {\n var block = dom.child(textBlock, '.ge-content');\n var type = block.getAttribute('data-ge-content-type');\n var drawer = dom.element('div', { 'class': 'ge-tools-drawer ge-text-drawer' });\n textBlock.insertBefore(drawer, textBlock.firstChild);\n\n ge.createMoveTool(drawer);\n\n var details = ge.addSettingsTool(drawer, block, settings.text_classes);\n\n // Which editor edits it, first in its settings: something to\n // know about it, not something to do with it\n var general = dom.child(details, '.ge-details-general');\n var editor = dom.element('div', { 'class': 'ge-field ge-text-editor' });\n editor.appendChild(dom.element('span', { 'class': 'ge-field-label' }, ge.t('panel.editor')));\n editor.appendChild(dom.element('span', { 'class': 'ge-field-value' }, textLabel(type)));\n general.insertBefore(editor, general.firstChild);\n\n settings.text_tools.forEach(function(hostTool) {\n ge.createTool(drawer, hostTool.title || '', hostTool.className || '',\n hostTool.iconClass || 'bi bi-wrench', hostTool.on);\n });\n\n ge.createTool(drawer, ge.t('tool.delete_text'), 'ge-delete-text', 'bi bi-trash', function() {\n ge.deleteNode('text', block, ge.t('confirm.delete_text'), function(removed) {\n // Its editor lets go first: removed while open, it would\n // be left behind, attached to nothing\n closeText(block);\n dom.slideUp(textBlock, function() {\n textBlock.remove();\n removed();\n });\n });\n });\n }\n\n /** A drawer for each text of ours in a text block that has none yet. */\n function markTexts() {\n dom.all(ge.canvas, '.ge-text-block').forEach(function(textBlock) {\n if (dom.child(textBlock, '.ge-tools-drawer')) { return; }\n\n var block = dom.child(textBlock, '.ge-content');\n if (!block || !isOurs(block)) { return; }\n\n createTextControls(textBlock);\n });\n }\n\n var texts = offeredTexts();\n var clicks = null; // The delegated click listener, while editing\n\n return {\n methods: {\n createText: apiCreateText,\n },\n\n /**\n * The types this plugin edits, for the core: every editor loaded\n * is the owner of its texts, and the ones offered are what the\n * host's plain content can be made.\n */\n textTypes: function() {\n var offered = offeredTexts();\n var others = Object.keys(TEXTS).filter(function(type) { return offered.indexOf(type) === -1; });\n\n return offered.concat(others).map(function(type) {\n var text = TEXTS[type];\n\n return {\n type: type,\n label: textLabel(type),\n offered: offered.indexOf(type) !== -1,\n available: text.available ? function() { return text.available(); } : null,\n missingKey: text.missingKey,\n edit: function(block) {\n var textBlock = block.parentElement;\n if (dom.hasClass(textBlock, 'ge-text-block') && !dom.child(textBlock, '.ge-tools-drawer')) {\n createTextControls(textBlock);\n }\n\n startText(block);\n },\n };\n });\n },\n\n // A text block of each editor offered. Like a container, it goes\n // into a row of its own when clicked, or where it is dropped\n toolbar: texts.map(function(type) {\n return {\n label: function() {\n return texts.length > 1 ? ge.t('text.add_type', { editor: textLabel(type) }) : ge.t('text.add');\n },\n iconClass: TEXTS[type].iconClass,\n className: 'ge-add-text-button',\n kind: 'text',\n inColumn: true,\n create: function() { return makeText(type); },\n };\n }),\n\n onInit: function() {\n markTexts();\n\n if (clicks) { ge.canvas.removeEventListener('click', clicks); }\n clicks = dom.delegate(ge.canvas, 'click', '.ge-content', onClick);\n },\n\n // While the drawers and the text blocks are still there, as the\n // editors left them\n onBeforeDeinit: function() {\n dom.all(ge.canvas, '.ge-content').forEach(function(block) {\n if (isOurs(block)) { closeText(block); }\n });\n },\n\n onDeinit: function() {\n if (clicks) { ge.canvas.removeEventListener('click', clicks); }\n clicks = null;\n },\n\n // The first time only: an undo says ready again, and by then the\n // host may have changed the content area itself\n onContentReady: function(area) {\n if (readBefore.has(area) && !readReady.has(area)) {\n readReady.set(area, attributesOf(area));\n }\n },\n };\n }\n\n // Whatever the plugins setting says: content_types chooses the editors\n textFeature.always = true;\n\n GridEditor.features.text = textFeature;\n\n}\n", "/**\n * tinyMCE for grid-editor's content areas.\n *\n * A text editor plugin: load this file after the editor, and tinyMCE 7\n * after or before it, and a text of the tinymce type is edited with an\n * inline tinyMCE. What it can ask the editor for is the handle its\n * factory is called with, described in docs/plugins.md.\n *\n * <script src=\"tinymce/tinymce.min.js\"></script>\n * <script src=\"dist/grideditor.min.js\"></script>\n * <script src=\"dist/plugins/grideditor.tinymce.min.js\"></script>\n *\n * Up to 5.x the main bundle carried a copy of this file; since 6.0 it is\n * loaded on its own, like every plugin. It imports what every text editor\n * shares - text blocks, the Text button, createText, making the host's plain\n * content a text - from src/js/text/grideditor.text.js, which the build puts\n * in its classic script, installed once however many editors a page loads.\n */\nimport { GridEditor } from '../grideditor.js';\nimport * as dom from '../dom.js';\nimport '../text/grideditor.text.js';\n\nObject.assign(GridEditor.locales.en, {\n 'text.tinymce': 'tinyMCE',\n 'warning.oninit_removed': 'tinyMCE\\'s oninit option was removed in 7.0 and is ignored: use init_instance_callback.',\n});\n\n// tinyMCE snapshots the target element's attributes when an inline editor is\n// created and restores them on remove(), so this has to run *after* remove()\n// to keep the grid editor's own class and tinyMCE's leftovers off the element.\nfunction cleanUp(contentArea) {\n dom.removeClass(contentArea, 'active ge-rte-active');\n ['id', 'style', 'spellcheck', 'contenteditable', 'data-mce-style'].forEach(function(name) {\n contentArea.removeAttribute(name);\n });\n}\n\nvar INITIAL_CONTENT = '<p>Lorem ipsum dolores</p>';\n\n// What this file remembers about a content area: its editor, and whether a\n// deinit came before that editor was ready\nvar editors = new WeakMap();\nvar pendingRemove = new WeakSet();\n\n// Said once per page, however many editors are on it\nvar warnedOninit = false;\n\nGridEditor.texts.tinymce = function(ge) {\n return {\n labelKey: 'text.tinymce',\n initialContent: INITIAL_CONTENT,\n missingKey: 'error.tinymce_missing',\n\n available: function() { return !!window.tinymce; },\n\n start: function(contentAreas) {\n var settings = ge.settings;\n var userConfig = (settings.tinymce && settings.tinymce.config) ? settings.tinymce.config : {};\n\n // 'oninit' was the pre-6 name for init_instance_callback, honoured\n // through 6.x and gone in 7.0\n if (userConfig.oninit && !warnedOninit) {\n warnedOninit = true;\n ge.warn(ge.t('warning.oninit_removed'));\n }\n\n contentAreas.forEach(function(contentArea) {\n if (dom.hasClass(contentArea, 'active')) { return; }\n\n if (contentArea.innerHTML == INITIAL_CONTENT) {\n contentArea.innerHTML = '';\n }\n dom.addClass(contentArea, 'active');\n\n var configuration = Object.assign({\n // tinyMCE's own \"Upgrade\" badge in the menubar. Off by\n // default because an inline editor here is a column of\n // someone's page, not tinyMCE's own interface; a host that\n // wants it back passes promotion: true.\n promotion: false,\n }, userConfig, {\n target: contentArea,\n inline: true,\n init_instance_callback: function(editor) {\n // deinit ran before this init finished, so tear it down again\n if (pendingRemove.has(contentArea)) {\n pendingRemove.delete(contentArea);\n editor.remove();\n // deinit already ran and cannot clean up after this\n // late remove(), so do it here instead\n cleanUp(contentArea);\n return;\n }\n\n editors.set(contentArea, editor);\n\n // The editor rewrote what is inside this content area\n // while it took it over, so whatever the grid editor\n // had in there is gone. Saying so lets it put its own\n // furniture back.\n ge.textReady(contentArea);\n\n // Undo and redo rewrite it too, from snapshots that\n // leave out whatever is marked data-mce-bogus - an\n // element's drawer among them - so it goes back in\n // after each of those as well\n editor.on('Undo Redo', function() {\n ge.textReady(contentArea);\n });\n\n // The inline toolbar is laid out against the element's\n // geometry at the moment tinyMCE draws it, and an\n // element that has just appeared - a tab pane, an\n // accordion body, a column whose width is still\n // settling - may not have its own width yet. Asking\n // for the ui again once the browser has laid the frame\n // out measures it as it now is, instead of leaving a\n // toolbar wrapped into a narrow column.\n window.requestAnimationFrame(function() {\n if (editor.removed || !editor.ui || !editor.ui.show) { return; }\n\n editor.ui.show();\n });\n\n // And again whenever the user comes back to this\n // editor: by then the element may have been resized,\n // hidden and shown again - a tab switched away from\n // and back, a column made narrower - and the toolbar\n // is only ever as right as its last measurement.\n editor.on('focus', function() {\n window.requestAnimationFrame(function() {\n if (editor.removed || !editor.ui || !editor.ui.show) { return; }\n\n editor.ui.show();\n });\n });\n\n // Bring focus to text field\n editor.focus();\n\n // Call the original callback, if one was passed in the config\n if (userConfig.init_instance_callback) {\n userConfig.init_instance_callback.call(this, editor);\n }\n }\n });\n // We always edit the element we were handed, so a selector in the\n // user config would only fight with target\n delete configuration.selector;\n delete configuration.oninit;\n\n window.tinymce.init(configuration);\n });\n },\n\n stop: function(contentAreas) {\n contentAreas.filter(function(contentArea) {\n return dom.hasClass(contentArea, 'active');\n }).forEach(function(contentArea) {\n var editor = editors.get(contentArea);\n\n if (editor) {\n editors.delete(contentArea);\n editor.remove();\n } else {\n // tinymce.init() is asynchronous, so the editor may not exist\n // yet. Leave a note for init_instance_callback to remove it.\n pendingRemove.add(contentArea);\n }\n\n cleanUp(contentArea);\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", "element", "tag", "attributes", "text", "node", "name", "value", "setHtml", "html", "addClass", "names", "split", "removeClass", "hasClass", "node", "name", "split", "names", "hide", "node", "visible", "node", "delegate", "root", "types", "selector", "handler", "options", "listener", "event", "match", "closest", "split", "type", "DEFAULT_DURATION", "animateAway", "node", "frames", "duration", "done", "finish", "hide", "visible", "animation", "called", "once", "slideUp", "style", "GridEditor", "attributesOf", "element", "found", "attribute", "classesIn", "value", "name", "EDITOR_CLASS", "restoreAttributes", "block", "before", "ready", "open", "result", "EDITOR_ATTRIBUTE", "readyClasses", "openClasses", "classes", "textFeature", "ge", "settings", "TEXTS", "warned", "type", "offeredTexts", "textLabel", "text", "makeText", "content", "setHtml", "apiCreateText", "options", "isOurs", "startText", "hasClass", "visible", "readBefore", "readReady", "addClass", "onClick", "closeText", "removeClass", "createTextControls", "textBlock", "child", "drawer", "details", "general", "editor", "hostTool", "removed", "slideUp", "markTexts", "all", "texts", "clicks", "offered", "others", "delegate", "area", "GridEditor", "cleanUp", "contentArea", "removeClass", "name", "INITIAL_CONTENT", "editors", "pendingRemove", "warnedOninit", "ge", "contentAreas", "settings", "userConfig", "hasClass", "addClass", "configuration", "editor"]
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 * Text for grid-editor: what the text editor plugins share.\n *\n * Not a file a page loads. The build puts it at the top of each text editor\n * plugin - grideditor.tinymce.js, grideditor.ckeditor.js,\n * grideditor.summernote.js - and whichever of them loads first installs it:\n * a page with two editors has one of these.\n *\n * It is a feature plugin, `text`, that the `plugins` setting does not choose\n * (content_types does), and it is everything a text is to the editor: the\n * text block's drawer, the Text buttons in the toolbar, createText, opening\n * an editor on a click and closing it again with the host's attributes put\n * back, and making the host's plain content a text through the core's\n * `textTypes` hook.\n *\n * Each editor registers under GridEditor.texts, which is this file's own\n * registry and not a contract: an editor of a host's own is a feature plugin\n * of its own, as example/custom_editor.html shows.\n */\nimport { GridEditor } from '../grideditor.js';\nimport * as dom from '../dom.js';\n\n// However many editors a page loads, each with a copy of this file in its\n// classic script: the first one installs it\nif (!GridEditor.features.text) {\n\n Object.assign(GridEditor.locales.en, {\n 'text.add': 'Text',\n 'text.add_type': 'Text ({editor})',\n 'panel.editor': 'Editor',\n 'panel.kind_text': 'Text',\n });\n\n /**\n * What a content area's attributes were before its editor opened, and\n * once it had: the two readings closeText plays the host's changes\n * back from. Shared by every editor on the page, like the nodes.\n */\n var readBefore = new WeakMap();\n var readReady = new WeakMap();\n\n /** What a text editor puts on a content area while it is open, whenever it likes. */\n var EDITOR_CLASS = /^(mce-|cke|ck-|note-)|^(ck|active|ge-rte-active)$/;\n var EDITOR_ATTRIBUTE = /^(data-mce-|contenteditable$|spellcheck$)/;\n\n function attributesOf(element) {\n var found = {};\n Array.prototype.slice.call(element.attributes).forEach(function(attribute) {\n found[attribute.name] = attribute.value;\n });\n return found;\n }\n\n function classesIn(value) {\n return (value || '').split(/\\s+/).filter(function(name) {\n return name !== '' && !EDITOR_CLASS.test(name);\n });\n }\n\n /** The host's markup, with what changed from `ready` to `open` played back onto it. */\n function restoreAttributes(block, before, ready, open) {\n var result = Object.assign({}, before);\n\n Object.keys(Object.assign({}, ready, open)).forEach(function(name) {\n if (name === 'class' || EDITOR_ATTRIBUTE.test(name) || ready[name] === open[name]) { return; }\n\n if (open[name] === undefined) {\n delete result[name];\n } else {\n result[name] = open[name];\n }\n });\n\n var readyClasses = classesIn(ready['class']);\n var openClasses = classesIn(open['class']);\n var classes = classesIn(before['class']).filter(function(name) {\n return openClasses.indexOf(name) !== -1 || readyClasses.indexOf(name) === -1;\n });\n openClasses.forEach(function(name) {\n if (readyClasses.indexOf(name) === -1 && classes.indexOf(name) === -1) { classes.push(name); }\n });\n\n // In the host's order, class where it was: getHtml should not\n // shuffle a node's attributes because it was edited\n if (classes.length) { result['class'] = classes.join(' '); } else { delete result['class']; }\n\n Object.keys(attributesOf(block)).forEach(function(name) { block.removeAttribute(name); });\n Object.keys(result).forEach(function(name) { block.setAttribute(name, result[name]); });\n }\n\n function textFeature(ge) {\n\n var settings = ge.settings;\n var TEXTS = {};\n var warned = {};\n\n Object.keys(GridEditor.texts).forEach(function(type) {\n TEXTS[type] = GridEditor.texts[type](ge);\n });\n\n // Every editor loaded, in the order the page loaded them, unless the\n // host names the ones it wants\n if (!Array.isArray(settings.content_types)) { settings.content_types = Object.keys(TEXTS); }\n if (!Array.isArray(settings.text_tools)) { settings.text_tools = []; }\n if (!Array.isArray(settings.text_classes)) { settings.text_classes = []; }\n\n /** The text editors this editor offers, in content_types order: the ones loaded. */\n function offeredTexts() {\n return settings.content_types.filter(function(type) { return !!TEXTS[type]; });\n }\n\n /** What a text editor is called: its plugin's label, or its type. */\n function textLabel(type) {\n var text = TEXTS[type];\n return text && text.labelKey ? ge.t(text.labelKey) : type;\n }\n\n /** A detached content area of `type`, holding `content` or the editor's initial content. */\n function makeText(type, content) {\n var text = TEXTS[type];\n var block = dom.element('div', {\n 'class': 'ge-content ge-content-type-' + type,\n 'data-ge-content-type': type,\n });\n\n if (content && content.nodeType) {\n block.appendChild(content);\n } else {\n dom.setHtml(block, content !== undefined ? content : (text && text.initialContent) || '');\n }\n return block;\n }\n\n /**\n * createText(type?, options?): a content area of a text editor's,\n * detached unless a placement is given. The type is the first one\n * offered by default. `options.content` is its html.\n */\n function apiCreateText(type, options) {\n if (type && typeof type === 'object') {\n options = type;\n type = undefined;\n }\n options = options || {};\n type = type || offeredTexts()[0];\n\n if (!type || !TEXTS[type]) {\n if (!warned['createText:' + type]) {\n warned['createText:' + type] = true;\n ge.warn('createText: no text editor \"' + type + '\" is loaded; ' +\n 'load its plugin and name it in content_types');\n }\n return null;\n }\n\n return ge.place(makeText(type, options.content), 'text', options);\n }\n\n /** Whether a content area is a text of one of the editors loaded here. */\n function isOurs(block) {\n return !!TEXTS[block.getAttribute('data-ge-content-type')];\n }\n\n /** Open the editor on a text, once: until it is closed again. */\n function startText(block) {\n if (dom.hasClass(block, 'ge-rte-active')) { return; }\n\n // A content area nobody can see - a tab that is not the open one,\n // a closed accordion item - has no geometry for an editor to lay\n // its toolbar out against, and nothing anyone can type into\n if (!dom.visible(block)) { return; }\n\n // The attribute: it is markup, and the drawer reads it the same way\n var text = TEXTS[block.getAttribute('data-ge-content-type')];\n if (!text) { return; }\n\n // Not marked active, so the next click tries again: the library\n // may be loaded by then\n if (text.available && !text.available()) {\n if (text.missingKey) { console.error(ge.t(text.missingKey)); }\n return;\n }\n\n readBefore.set(block, attributesOf(block));\n readReady.delete(block);\n dom.addClass(block, 'ge-rte-active');\n text.start([block]);\n }\n\n function onClick() {\n startText(this);\n }\n\n /**\n * Close the text editor on one content area, and leave the content\n * area's own attributes as the host left them.\n *\n * An editor adds attributes of its own while it is open, and takes\n * them off again, more or less: CKEditor leaves aria-readonly behind.\n * tinyMCE does worse, and puts back every attribute as it was when it\n * opened, so an id, a class or a plugin's attribute given while it was\n * open is lost. So the attributes are read three times - before the\n * editor opens, once it has opened, and before it closes - and what\n * changed between the second and the third, the host's doing, is\n * played back onto the first, the host's markup. What the editor did\n * is left out either way.\n */\n function closeText(block) {\n var text = TEXTS[block.getAttribute('data-ge-content-type')];\n var before = readBefore.get(block);\n var open = before ? attributesOf(block) : null;\n\n // Every content area is told: one whose editor never\n // started is the plugin's to ignore\n if (text) { text.stop([block]); }\n\n // After stop, not before: an editor that restores the class\n // attribute it snapshotted would put ge-rte-active back\n dom.removeClass(block, 'ge-rte-active');\n\n if (before) {\n restoreAttributes(block, before, readReady.get(block) || before, open);\n readBefore.delete(block);\n readReady.delete(block);\n }\n }\n\n function createTextControls(textBlock) {\n var block = dom.child(textBlock, '.ge-content');\n var type = block.getAttribute('data-ge-content-type');\n var drawer = dom.element('div', { 'class': 'ge-tools-drawer ge-text-drawer' });\n textBlock.insertBefore(drawer, textBlock.firstChild);\n\n ge.createMoveTool(drawer);\n\n var details = ge.addSettingsTool(drawer, block, settings.text_classes);\n\n // Which editor edits it, first in its settings: something to\n // know about it, not something to do with it\n var general = dom.child(details, '.ge-details-general');\n var editor = dom.element('div', { 'class': 'ge-field ge-text-editor' });\n editor.appendChild(dom.element('span', { 'class': 'ge-field-label' }, ge.t('panel.editor')));\n editor.appendChild(dom.element('span', { 'class': 'ge-field-value' }, textLabel(type)));\n general.insertBefore(editor, general.firstChild);\n\n settings.text_tools.forEach(function(hostTool) {\n ge.createTool(drawer, hostTool.title || '', hostTool.className || '',\n hostTool.iconClass || 'bi bi-wrench', hostTool.on);\n });\n\n ge.createTool(drawer, ge.t('tool.delete_text'), 'ge-delete-text', 'bi bi-trash', function() {\n ge.deleteNode('text', block, ge.t('confirm.delete_text'), function(removed) {\n // Its editor lets go first: removed while open, it would\n // be left behind, attached to nothing\n closeText(block);\n dom.slideUp(textBlock, function() {\n textBlock.remove();\n removed();\n });\n });\n });\n }\n\n /** A drawer for each text of ours in a text block that has none yet. */\n function markTexts() {\n dom.all(ge.canvas, '.ge-text-block').forEach(function(textBlock) {\n if (dom.child(textBlock, '.ge-tools-drawer')) { return; }\n\n var block = dom.child(textBlock, '.ge-content');\n if (!block || !isOurs(block)) { return; }\n\n createTextControls(textBlock);\n });\n }\n\n var texts = offeredTexts();\n var clicks = null; // The delegated click listener, while editing\n\n return {\n methods: {\n createText: apiCreateText,\n },\n\n /**\n * The types this plugin edits, for the core: every editor loaded\n * is the owner of its texts, and the ones offered are what the\n * host's plain content can be made.\n */\n textTypes: function() {\n var offered = offeredTexts();\n var others = Object.keys(TEXTS).filter(function(type) { return offered.indexOf(type) === -1; });\n\n return offered.concat(others).map(function(type) {\n var text = TEXTS[type];\n\n return {\n type: type,\n label: textLabel(type),\n offered: offered.indexOf(type) !== -1,\n available: text.available ? function() { return text.available(); } : null,\n missingKey: text.missingKey,\n edit: function(block) {\n var textBlock = block.parentElement;\n if (dom.hasClass(textBlock, 'ge-text-block') && !dom.child(textBlock, '.ge-tools-drawer')) {\n createTextControls(textBlock);\n }\n\n startText(block);\n },\n };\n });\n },\n\n // A text block of each editor offered. Like a container, it goes\n // into a row of its own when clicked, or where it is dropped\n toolbar: texts.map(function(type) {\n return {\n label: function() {\n return texts.length > 1 ? ge.t('text.add_type', { editor: textLabel(type) }) : ge.t('text.add');\n },\n iconClass: TEXTS[type].iconClass,\n className: 'ge-add-text-button',\n kind: 'text',\n inColumn: true,\n create: function() { return makeText(type); },\n };\n }),\n\n onInit: function() {\n markTexts();\n\n if (clicks) { ge.canvas.removeEventListener('click', clicks); }\n clicks = dom.delegate(ge.canvas, 'click', '.ge-content', onClick);\n },\n\n // While the drawers and the text blocks are still there, as the\n // editors left them\n onBeforeDeinit: function() {\n dom.all(ge.canvas, '.ge-content').forEach(function(block) {\n if (isOurs(block)) { closeText(block); }\n });\n },\n\n onDeinit: function() {\n if (clicks) { ge.canvas.removeEventListener('click', clicks); }\n clicks = null;\n },\n\n // The first time only: an undo says ready again, and by then the\n // host may have changed the content area itself\n onContentReady: function(area) {\n if (readBefore.has(area) && !readReady.has(area)) {\n readReady.set(area, attributesOf(area));\n }\n },\n };\n }\n\n // Whatever the plugins setting says: content_types chooses the editors\n textFeature.always = true;\n\n GridEditor.features.text = textFeature;\n\n}\n", "/**\n * tinyMCE for grid-editor's content areas.\n *\n * A text editor plugin: load this file after the editor, and tinyMCE 7\n * after or before it, and a text of the tinymce type is edited with an\n * inline tinyMCE. What it can ask the editor for is the handle its\n * factory is called with, described in docs/plugins.md.\n *\n * <script src=\"tinymce/tinymce.min.js\"></script>\n * <script src=\"dist/grideditor.min.js\"></script>\n * <script src=\"dist/plugins/grideditor.tinymce.min.js\"></script>\n *\n * It imports what every text editor shares - text blocks, the Text button,\n * createText, making the host's plain content a text - from\n * src/js/text/grideditor.text.js, which the build puts in its classic\n * script, installed once however many editors a page loads.\n */\nimport { GridEditor } from '../grideditor.js';\nimport * as dom from '../dom.js';\nimport '../text/grideditor.text.js';\n\nObject.assign(GridEditor.locales.en, {\n 'text.tinymce': 'tinyMCE',\n});\n\n// tinyMCE snapshots the target element's attributes when an inline editor is\n// created and restores them on remove(), so this has to run *after* remove()\n// to keep the grid editor's own class and tinyMCE's leftovers off the element.\nfunction cleanUp(contentArea) {\n dom.removeClass(contentArea, 'active ge-rte-active');\n ['id', 'style', 'spellcheck', 'contenteditable', 'data-mce-style'].forEach(function(name) {\n contentArea.removeAttribute(name);\n });\n}\n\nvar INITIAL_CONTENT = '<p>Lorem ipsum dolores</p>';\n\n// What this file remembers about a content area: its editor, and whether a\n// deinit came before that editor was ready\nvar editors = new WeakMap();\nvar pendingRemove = new WeakSet();\n\nGridEditor.texts.tinymce = function(ge) {\n return {\n labelKey: 'text.tinymce',\n initialContent: INITIAL_CONTENT,\n missingKey: 'error.tinymce_missing',\n\n available: function() { return !!window.tinymce; },\n\n start: function(contentAreas) {\n var settings = ge.settings;\n var userConfig = (settings.tinymce && settings.tinymce.config) ? settings.tinymce.config : {};\n\n contentAreas.forEach(function(contentArea) {\n if (dom.hasClass(contentArea, 'active')) { return; }\n\n if (contentArea.innerHTML == INITIAL_CONTENT) {\n contentArea.innerHTML = '';\n }\n dom.addClass(contentArea, 'active');\n\n var configuration = Object.assign({\n // tinyMCE's own \"Upgrade\" badge in the menubar. Off by\n // default because an inline editor here is a column of\n // someone's page, not tinyMCE's own interface; a host that\n // wants it back passes promotion: true.\n promotion: false,\n }, userConfig, {\n target: contentArea,\n inline: true,\n init_instance_callback: function(editor) {\n // deinit ran before this init finished, so tear it down again\n if (pendingRemove.has(contentArea)) {\n pendingRemove.delete(contentArea);\n editor.remove();\n // deinit already ran and cannot clean up after this\n // late remove(), so do it here instead\n cleanUp(contentArea);\n return;\n }\n\n editors.set(contentArea, editor);\n\n // The editor rewrote what is inside this content area\n // while it took it over, so whatever the grid editor\n // had in there is gone. Saying so lets it put its own\n // furniture back.\n ge.textReady(contentArea);\n\n // Undo and redo rewrite it too, from snapshots that\n // leave out whatever is marked data-mce-bogus - an\n // element's drawer among them - so it goes back in\n // after each of those as well\n editor.on('Undo Redo', function() {\n ge.textReady(contentArea);\n });\n\n // The inline toolbar is laid out against the element's\n // geometry at the moment tinyMCE draws it, and an\n // element that has just appeared - a tab pane, an\n // accordion body, a column whose width is still\n // settling - may not have its own width yet. Asking\n // for the ui again once the browser has laid the frame\n // out measures it as it now is, instead of leaving a\n // toolbar wrapped into a narrow column.\n window.requestAnimationFrame(function() {\n if (editor.removed || !editor.ui || !editor.ui.show) { return; }\n\n editor.ui.show();\n });\n\n // And again whenever the user comes back to this\n // editor: by then the element may have been resized,\n // hidden and shown again - a tab switched away from\n // and back, a column made narrower - and the toolbar\n // is only ever as right as its last measurement.\n editor.on('focus', function() {\n window.requestAnimationFrame(function() {\n if (editor.removed || !editor.ui || !editor.ui.show) { return; }\n\n editor.ui.show();\n });\n });\n\n // Bring focus to text field\n editor.focus();\n\n // Call the original callback, if one was passed in the config\n if (userConfig.init_instance_callback) {\n userConfig.init_instance_callback.call(this, editor);\n }\n }\n });\n // We always edit the element we were handed, so a selector in the\n // user config would only fight with target\n delete configuration.selector;\n\n window.tinymce.init(configuration);\n });\n },\n\n stop: function(contentAreas) {\n contentAreas.filter(function(contentArea) {\n return dom.hasClass(contentArea, 'active');\n }).forEach(function(contentArea) {\n var editor = editors.get(contentArea);\n\n if (editor) {\n editors.delete(contentArea);\n editor.remove();\n } else {\n // tinymce.init() is asynchronous, so the editor may not exist\n // yet. Leave a note for init_instance_callback to remove it.\n pendingRemove.add(contentArea);\n }\n\n cleanUp(contentArea);\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", "element", "tag", "attributes", "text", "node", "name", "value", "setHtml", "html", "addClass", "names", "split", "removeClass", "hasClass", "node", "name", "split", "names", "hide", "node", "visible", "node", "delegate", "root", "types", "selector", "handler", "options", "listener", "event", "match", "closest", "split", "type", "DEFAULT_DURATION", "animateAway", "node", "frames", "duration", "done", "finish", "hide", "visible", "animation", "called", "once", "slideUp", "style", "GridEditor", "attributesOf", "element", "found", "attribute", "classesIn", "value", "name", "EDITOR_CLASS", "restoreAttributes", "block", "before", "ready", "open", "result", "EDITOR_ATTRIBUTE", "readyClasses", "openClasses", "classes", "textFeature", "ge", "settings", "TEXTS", "warned", "type", "offeredTexts", "textLabel", "text", "makeText", "content", "setHtml", "apiCreateText", "options", "isOurs", "startText", "hasClass", "visible", "readBefore", "readReady", "addClass", "onClick", "closeText", "removeClass", "createTextControls", "textBlock", "child", "drawer", "details", "general", "editor", "hostTool", "removed", "slideUp", "markTexts", "all", "texts", "clicks", "offered", "others", "delegate", "area", "GridEditor", "cleanUp", "contentArea", "removeClass", "name", "INITIAL_CONTENT", "editors", "pendingRemove", "ge", "contentAreas", "settings", "userConfig", "hasClass", "addClass", "configuration", "editor"]
7
7
  }
package/docs/events.md CHANGED
@@ -38,11 +38,10 @@ listener and every callback hears each notification, whatever the ones before
38
38
  it did.
39
39
 
40
40
  A listener that throws is the browser's to report, as any listener's error
41
- is: the other listeners, the callbacks and the operation go on. Up to 6.x an
42
- error thrown in a jQuery handler stopped the operation where it was.
41
+ is: the other listeners, the callbacks and the operation go on.
43
42
 
44
- The payload's nodes are elements. Up to 6.x they were jQuery objects, and
45
- they still are for a page that loads `grideditor.jquery.js`: through the
43
+ The payload's nodes are elements. They are jQuery objects for a page that
44
+ loads `grideditor.jquery.js`: through the
46
45
  adapter, a jQuery listener - bound on the canvas or delegated from an
47
46
  ancestor - runs once per notification with `(event, payload)`, the payload's
48
47
  nodes wrapped, and `preventDefault()` on its event cancels as before. The
@@ -168,8 +167,7 @@ the clipboard plugin put in, from a paste tool or the toolbar. A paste is an add
168
167
  like any other, so canceling its `before-add-*` turns it away.
169
168
 
170
169
  A text block is `kind: 'text'`, with its content area as the node, when it is
171
- added, deleted or moved, and in `drawerTools`. Up to 5.x a content area
172
- dragged between columns was `kind: 'content'`. The host's plain content - a
170
+ added, deleted or moved, and in `drawerTools`. The host's plain content - a
173
171
  content area with no text type on it - is `kind: 'plain'` when it is deleted,
174
172
  moved or converted; the convert pair's `source` is `tool`, and canceling
175
173
  `before-convert` leaves it plain, with no editor opened. The kinds for containers are
@@ -133,7 +133,7 @@ editor's label, one of the `text.<type>` keys below or, for a plugin with no
133
133
  label, its type.
134
134
 
135
135
  The keys a text needs once an editor is loaded - `text.add`, `text.add_type`,
136
- `panel.editor` and `panel.kind_text` - are the text editor plugins' since 6.0, and come with any of them. The rest
136
+ `panel.editor` and `panel.kind_text` - are the text editor plugins', and come with any of them. The rest
137
137
  are the main bundle's: what the editor shows with no text editor loaded.
138
138
 
139
139
  | Key | English | Where |
@@ -221,8 +221,9 @@ key, so a locale covers a new breakpoint by adding `view.<key>`. Short strings
221
221
  utility.*
222
222
  ---------
223
223
 
224
- The Responsive section of a settings panel, which the utility plugins fill.
225
- The labels of each utility and its values are the plugins' own keys.
224
+ The Responsive section of a settings panel, which the utility plugins fill,
225
+ and the per breakpoint fields of the style plugin's sections. The labels of
226
+ each utility and its values are the plugins' own keys.
226
227
 
227
228
  | Key | English | Where |
228
229
  | --- | --- | --- |
@@ -235,23 +236,20 @@ The labels of each utility and its values are the plugins' own keys.
235
236
  | `utility.default` | Default | The empty choice of a field when nothing below the view sets the utility, and always in the all view |
236
237
  | `utility.inherit` | Inherit: {value} (from {breakpoint}) | The empty choice in a breakpoint view when a smaller breakpoint sets the utility. `{breakpoint}` is its key, `sm` |
237
238
  | `utility.varies` | Changes at {breakpoints}; choosing here replaces that | Note under a field in the all view when breakpoints set their own value. `{breakpoints}` is a list of keys |
238
- | `utility.visibility` | Visibility | Label of the visibility plugin's field |
239
+ | `utility.display` | Display | Label of the display field, `d-*`, in the style plugin's Display section. Its other choices are the values themselves |
239
240
  | `utility.visibility_hidden` | Hidden | Its choice for `d-*-none` |
240
- | `utility.visibility_shown` | Shown | Its choice for `d-*-block`, or `d-*-flex` on a row |
241
- | `tool.hide_in_view` | Hide in this view | The visibility plugin's eye, on a node shown in the view being edited |
241
+ | `tool.hide_in_view` | Hide in this view | The style plugin's eye, on a node shown in the view being edited |
242
242
  | `tool.show_in_view` | Show in this view | The same eye, on a node hidden there |
243
243
  | `utility.order` | Order | Label of the order plugin's field |
244
244
  | `utility.order_first` | First | Its choice for `order-*-first` |
245
245
  | `utility.order_last` | Last | Its choice for `order-*-last` |
246
246
  | `tool.order_earlier` | Earlier in this view | The order plugin's left arrow in a column drawer |
247
247
  | `tool.order_later` | Later in this view | Its right arrow |
248
- | `utility.justify_content` | Justify columns | The alignment plugin's `justify-content-*` field, on a row |
249
- | `utility.align_items` | Align columns | Its `align-items-*` field, on a row |
250
- | `utility.align_self` | Align self | Its `align-self-*` field, on a column |
248
+ | `utility.align_self` | Align self | The alignment plugin's `align-self-*` field, on a column |
251
249
  | `utility.gutters` | Gutters | The gutters plugin's `g-*` field, on a row |
252
250
  | `utility.gutters_x` | Horizontal gutters | Its `gx-*` field |
253
251
  | `utility.gutters_y` | Vertical gutters | Its `gy-*` field |
254
- | `utility.padding` | Padding | The spacing plugin's padding group |
252
+ | `utility.padding` | Padding | The padding group, in the style plugin's Spacing section |
255
253
  | `utility.margin` | Margin | Its margin group |
256
254
  | `utility.side_all` | All sides | The side of `p-*` and `m-*` in a group's side choice |
257
255
  | `utility.side_x` | Left and right | The side of `px-*` and `mx-*` |
@@ -260,17 +258,106 @@ The labels of each utility and its values are the plugins' own keys.
260
258
  | `utility.side_b` | Bottom | The side of `pb-*` and `mb-*` |
261
259
  | `utility.side_s` | Start | The side of `ps-*` and `ms-*` |
262
260
  | `utility.side_e` | End | The side of `pe-*` and `me-*` |
263
- | `utility.text_align` | Text alignment | Label of the textalign plugin's field |
261
+ | `utility.text_align` | Text alignment | Label of the text alignment field, in the style plugin's Text section |
264
262
  | `utility.text_start` | Start | Its choice for `text-*-start` |
265
263
  | `utility.text_center` | Center | Its choice for `text-*-center` |
266
264
  | `utility.text_end` | End | Its choice for `text-*-end` |
267
- | `utility.float` | Float | Label of the float plugin's field, on an element |
265
+ | `utility.flex_direction` | Direction | The `flex-*-row` / `-column` field, in the style plugin's Flex section |
266
+ | `utility.flex_wrap` | Wrap | Its `flex-*-wrap` / `-nowrap` field |
267
+ | `utility.justify_content` | Justify columns | Its `justify-content-*` field |
268
+ | `utility.align_items` | Align columns | Its `align-items-*` field |
269
+ | `utility.align_content` | Align lines | Its `align-content-*` field |
270
+ | `utility.gap` | Gap | Its `gap-*` field, on anything but a row |
271
+ | `utility.row_gap` | Row gap | Its `row-gap-*` field |
272
+ | `utility.column_gap` | Column gap | Its `column-gap-*` field |
273
+ | `utility.flex_fill` | Fill | Its `flex-*-fill` field, on anything but a row |
274
+ | `utility.flex_grow` | Grow | Its `flex-*-grow-*` field |
275
+ | `utility.flex_shrink` | Shrink | Its `flex-*-shrink-*` field |
276
+ | `utility.sticky` | Sticky | The `sticky-*-top` / `-bottom` field, in the style plugin's Position section |
277
+ | `utility.float` | Float | Label of the float field, in the style plugin's Position section, on an element |
268
278
  | `utility.float_start` | Start | Its choice for `float-*-start` |
269
279
  | `utility.float_end` | End | Its choice for `float-*-end` |
270
280
  | `utility.float_none` | None | Its choice for `float-*-none` |
271
281
  | `utility.spacing_gutter` | A column's side padding is its gutter: changing it changes the gutter | Note in a column's spacing group while it carries side padding |
272
282
 
273
283
 
284
+ style.*
285
+ -------
286
+
287
+ The style plugin's accordion, in a node's settings panel or in the dialog.
288
+
289
+ | Key | English | Where |
290
+ | --- | --- | --- |
291
+ | `style.section_title` | Style | The style plugin's accordion, and the button that opens it in the dialog when `settings_panel` is `popover` or `inline` |
292
+ | `style.dialog_title` | Style: {kind} | Title of that dialog. `{kind}` is what the panel's title calls the node |
293
+ | `style.section_size` | Size | The accordion's section header |
294
+ | `style.section_spacing` | Spacing | The accordion's section header |
295
+ | `style.section_border` | Border | The accordion's section header |
296
+ | `style.section_background` | Background | The accordion's section header |
297
+ | `style.section_text` | Text | The accordion's section header |
298
+ | `style.section_typography` | Typography | The accordion's section header |
299
+ | `style.section_display` | Display | The accordion's section header |
300
+ | `style.section_flex` | Flex | The accordion's section header |
301
+ | `style.section_position` | Position | The accordion's section header |
302
+ | `style.section_custom` | Custom css | The accordion's section header |
303
+ | `style.all_sizes` | Applies to every size | Note over a section's inline fields in a breakpoint view: the style attribute is not responsive |
304
+ | `style.overridden` | The class {class} takes priority over this value | Note under an inline field whose property a Bootstrap utility on the node also sets. `{class}` is that class |
305
+ | `style.invalid` | Not a value this property takes | Tooltip of an inline field holding a value the browser refused |
306
+ | `style.catalog` | Bootstrap classes | Heading of a section's Bootstrap class chips |
307
+ | `style.shadow_x` | X | A part of the shadow builder |
308
+ | `style.shadow_y` | Y | A part of the shadow builder |
309
+ | `style.shadow_blur` | Blur | A part of the shadow builder |
310
+ | `style.shadow_spread` | Spread | A part of the shadow builder |
311
+ | `style.shadow_color` | Color | A part of the shadow builder |
312
+ | `style.shadow_inset` | Inset | The shadow builder's inset checkbox |
313
+ | `style.shadow_text_mode` | Edit as text | Link under the shadow builder that edits the value as text |
314
+ | `style.prop_width` | Width | Label of the `width` field |
315
+ | `style.prop_height` | Height | Label of the `height` field |
316
+ | `style.prop_min_width` | Min width | Label of the `min-width` field |
317
+ | `style.prop_min_height` | Min height | Label of the `min-height` field |
318
+ | `style.prop_max_width` | Max width | Label of the `max-width` field |
319
+ | `style.prop_max_height` | Max height | Label of the `max-height` field |
320
+ | `style.prop_margin_top` | Margin top | Label of the `margin-top` field |
321
+ | `style.prop_margin_right` | Margin right | Label of the `margin-right` field |
322
+ | `style.prop_margin_bottom` | Margin bottom | Label of the `margin-bottom` field |
323
+ | `style.prop_margin_left` | Margin left | Label of the `margin-left` field |
324
+ | `style.prop_padding_top` | Padding top | Label of the `padding-top` field |
325
+ | `style.prop_padding_right` | Padding right | Label of the `padding-right` field |
326
+ | `style.prop_padding_bottom` | Padding bottom | Label of the `padding-bottom` field |
327
+ | `style.prop_padding_left` | Padding left | Label of the `padding-left` field |
328
+ | `style.prop_border_width` | Border width | Label of the `border-width` field |
329
+ | `style.prop_border_style` | Border style | Label of the `border-style` field |
330
+ | `style.prop_border_color` | Border color | Label of the `border-color` field |
331
+ | `style.prop_border_radius` | Border radius | Label of the `border-radius` field |
332
+ | `style.prop_box_shadow` | Shadow | Label of the `box-shadow` field |
333
+ | `style.prop_background_color` | Background color | Label of the `background-color` field |
334
+ | `style.prop_background_image` | Background image | Label of the `background-image` field |
335
+ | `style.prop_background_size` | Background size | Label of the `background-size` field |
336
+ | `style.prop_background_position` | Background position | Label of the `background-position` field |
337
+ | `style.prop_background_repeat` | Background repeat | Label of the `background-repeat` field |
338
+ | `style.prop_color` | Color | Label of the `color` field |
339
+ | `style.prop_font_size` | Font size | Label of the `font-size` field |
340
+ | `style.prop_text_align` | Text align | Label of the `text-align` field |
341
+ | `style.prop_text_shadow` | Text shadow | Label of the `text-shadow` field |
342
+ | `style.prop_font_family` | Font family | Label of the `font-family` field |
343
+ | `style.prop_font_weight` | Font weight | Label of the `font-weight` field |
344
+ | `style.prop_font_style` | Font style | Label of the `font-style` field |
345
+ | `style.prop_line_height` | Line height | Label of the `line-height` field |
346
+ | `style.prop_letter_spacing` | Letter spacing | Label of the `letter-spacing` field |
347
+ | `style.prop_text_transform` | Text transform | Label of the `text-transform` field |
348
+ | `style.prop_text_decoration` | Text decoration | Label of the `text-decoration` field |
349
+ | `style.prop_display` | Display | Label of the `display` field |
350
+ | `style.prop_opacity` | Opacity | Label of the `opacity` field |
351
+ | `style.prop_overflow` | Overflow | Label of the `overflow` field |
352
+ | `style.prop_visibility` | Visibility | Label of the `visibility` field |
353
+ | `style.prop_position` | Position | Label of the `position` field |
354
+ | `style.prop_top` | Top | Label of the `top` field |
355
+ | `style.prop_right` | Right | Label of the `right` field |
356
+ | `style.prop_bottom` | Bottom | Label of the `bottom` field |
357
+ | `style.prop_left` | Left | Label of the `left` field |
358
+ | `style.prop_z_index` | Z-index | Label of the `z-index` field |
359
+
360
+
274
361
  badge.*
275
362
  -------
276
363
 
@@ -294,13 +381,10 @@ all the same: the developer reading them is the one who chose the locale.
294
381
  | Key | English | Where |
295
382
  | --- | --- | --- |
296
383
  | `error.sortable_missing` | SortableJS not available! … | Logged once when the drag library is not on the page |
297
- | `warning.setting_removed` | The {setting} setting was removed in 4.0. Use {replacement} instead. | Logged once per removed setting a host still passes |
298
384
  | `warning.already_editing` | This element already has an editor: … | An editor asked for on an element that has one; the one it has is handed back |
299
385
  | `warning.destroyed` | {method}() was called on an editor that has been destroyed, … | Logged once per method called on a destroyed editor |
300
386
  | `warning.duplicate_build` | grideditor.js was loaded twice: … | A second copy of the classic script, which keeps the first `GridEditor` |
301
- | `warning.plugin_6x` | The "{name}" plugin is written for grid-editor 6 … | `grideditor.jquery.js`: a plugin registered on `$.fn.gridEditor.*`, which is left out |
302
387
  | `warning.adapter_no_jquery` | grideditor.jquery.js needs jQuery 4, … | `grideditor.jquery.js` loaded on a page with no jQuery |
303
- | `warning.oninit_removed` | tinyMCE's oninit option was removed in 7.0 … | A `tinymce.config` that still has `oninit`; `init_instance_callback` is called |
304
388
  | `error.tinymce_missing` | tinyMCE not available! … | `content_types: ['tinymce']` with no tinyMCE loaded |
305
389
  | `error.ckeditor_missing` | CKEditor 5 not available! … | `content_types: ['ckeditor']` with no CKEditor 5 loaded, CKEditor 4 included |
306
390
  | `error.ckeditor_start` | CKEditor could not start: {message} | `InlineEditor.create` failed: most likely no `licenseKey` in `ckeditor.config` |
package/docs/plugins.md CHANGED
@@ -92,10 +92,10 @@ A page or an app imports it for that side effect, after the editor:
92
92
  editors made after a plugin registered have it.
93
93
 
94
94
  Everything the editor hands a plugin, and everything a plugin hands back, is
95
- DOM: elements, and arrays of them where there may be several. Up to 6.x it was
96
- jQuery objects; a plugin written for 6.x is ported by taking that out, and
97
- [UPGRADING.md](../UPGRADING.md) says how. The shipped plugins are written in
98
- plain DOM, and a plugin of your own is free to use whatever it likes.
95
+ DOM: elements, and arrays of them where there may be several. The shipped
96
+ plugins are written in plain DOM, and a plugin of your own is free to use
97
+ whatever it likes. [UPGRADING.md](../UPGRADING.md) says how to port a plugin
98
+ written for 6.x.
99
99
 
100
100
  - **`iconClass`**, when given, is the toolbar button's face: the icon alone,
101
101
  with the label as its title. Without one the button shows a plus and the
@@ -118,9 +118,8 @@ The handle
118
118
 
119
119
  Everything a plugin needs from the editor comes through the handle its factory
120
120
  is called with. It is the plugin contract: these names, and what they do, do
121
- not change without a major version. 7.0 was one: every node it takes or gives
122
- is an element, and where 6.x gave a jQuery set that may hold several, an
123
- array.
121
+ not change without a major version. Every node it takes or gives is an
122
+ element, and where there may be several, an array.
124
123
 
125
124
  | | |
126
125
  | --- | --- |
@@ -160,6 +159,9 @@ array.
160
159
  | `ge.nodeHtml(node)` | One node's markup as `getHtml` would give it. The canvas leaves editing to read it and comes back, as it does for `getHtml` |
161
160
  | `ge.toolbarItems(name)` | An array of the toolbar buttons the feature plugin `name` declared, for showing and hiding them |
162
161
  | `ge.bareStyle(node, family, property)` | A css property's value on the node with none of the family's classes: what a preview shows when no class applies and that is not a constant |
162
+ | `ge.hostStyle(node, property?)` | `{ value, priority }` of one property of the node's own style, as the host wrote it: never a breakpoint preview's. With no property, the whole of it as css text |
163
+ | `ge.setHostStyle(node, property, value, priority?)` | Write one property of the node's own style, or take it off with `''`. Under a breakpoint preview it is the host's value that changes, and the preview goes back on top. False, and nothing written, for a value the browser refuses. A priority left out keeps the one the property had; no `style=""` is left behind |
164
+ | `ge.openDialog(title, body, opener?)` / `ge.closeDialog()` | A modal of the editor's own, over whatever settings panel is open, which stays open under it. `body` is moved in, and back where it was when the dialog closes; `opener` has the focus back. Bootstrap's modal when Bootstrap's javascript is there, one of the editor's own when it is not. Escape closes the dialog and nothing else; `deinit`, `getHtml`, `setLocale`, `destroy` and closing the panel close it |
163
165
 
164
166
  The add, delete and move events for a container and its panes are fired by the
165
167
  editor, not by the plugin: `createPaneControls` handles a pane's delete, and
@@ -192,6 +194,7 @@ GridEditor.features.elements = function(ge) {
192
194
  accepts: function(region, node) { … }, // false turns a block away from a region
193
195
  toolbar: [{ labelKey: …, kind: …, create: function() { … } }], // buttons beside the containers'
194
196
  drawerTools: function(drawer, node, kind) { … }, // tools beside the gear, in every drawer
197
+ panelSection: function(node, kind) { … }, // a section of the node's settings panel, see below
195
198
  };
196
199
  };
197
200
  ```
@@ -224,6 +227,29 @@ needs to put a new kind of block on the canvas:
224
227
  child: it sits beside it, in a wrapper that only exists while editing, so
225
228
  `ge.drawerOf(node)` is how to find it.
226
229
 
230
+ ### A section of the settings panel
231
+
232
+ **`panelSection(node, kind)`**, which any kind of plugin can have, returns a
233
+ section for the node's settings panel - `{ labelKey, titleKey, body }` - or
234
+ null where it has none. The editor puts the sections between the panel's
235
+ general fields and *Responsive*, in the order the plugins were registered.
236
+ Where the panel has room for it, in the offcanvas and the modal, `body` is in
237
+ the panel. A popover, or a panel inline in the drawer, gets a button with the
238
+ label instead, and `body` opens in the dialog, titled `titleKey` - with the
239
+ node's kind as `{kind}` - or the label. `body` stays the panel's either way,
240
+ so `ge.detailsOf(node)` finds what is in it.
241
+
242
+ A field made with `ge.utilityField` in a section follows the view and the
243
+ classes field as the Responsive section's do, wherever the section is at the
244
+ time. The style plugin's accordion is a section, and what the spacing,
245
+ textalign, display, flex, sticky and float fields are in: its families are
246
+ `panel: false`, and it makes their fields itself.
247
+
248
+ A section that writes css should write it with `ge.setHostStyle` and read it
249
+ with `ge.hostStyle`: in a breakpoint view the node's `style` holds the
250
+ preview's `!important` values too, and they come off on `deinit` with
251
+ whatever was written under them.
252
+
227
253
  ### Settings of your own, saved on the node
228
254
 
229
255
  A tool that opens a dialog and saves what the user chose on the node is a
@@ -237,11 +263,9 @@ animation for rows, columns, containers and elements, kept in a
237
263
  - **The dialog lives outside the canvas**, appended to `body`, so it is never
238
264
  part of the markup.
239
265
  - **Nothing else.** A plain `attr()` on any node. An element is never inside a
240
- text editor since 6.0, and a text's own attributes, given while its editor
241
- is open, are kept by grid-editor when the editor closes - tinyMCE would put
242
- back the ones it found when it opened. Up to 5.x an element sat inside the
243
- text, and an attribute written behind the editor's back was lost to its
244
- undo.
266
+ text editor, and a text's own attributes, given while its editor is open,
267
+ are kept by grid-editor when the editor closes - tinyMCE would put back the
268
+ ones it found when it opened.
245
269
 
246
270
  A node's drawer is built again on every `init`, so a tool reads the node
247
271
  rather than remembering anything about it.
@@ -399,11 +423,7 @@ editor, and `onBeforeDeinit` to close it.
399
423
  on the browser's `contenteditable`, on a page that loads none of the shipped
400
424
  editors.
401
425
 
402
- Up to 5.x an editor of a host's own registered under
403
- `$.fn.gridEditor.RTEs`, and in 5.x and the 6.0 betas under
404
- `$.fn.gridEditor.texts`. 6.0 ignored the first, with a warning, and 7.0 has
405
- neither: `GridEditor.texts` is the shipped editors' own registry, not a
406
- contract.
426
+ `GridEditor.texts` is the shipped editors' own registry, not a contract.
407
427
 
408
428
 
409
429
  Utility plugins
@@ -477,19 +497,21 @@ tool does not belong. A tool writes with `ge.setUtility(node, family, value,
477
497
  `onRefresh(scope)` runs whenever the preview is redrawn — on `init`, on a view
478
498
  change, after a write, after the user types in a classes field — with the node
479
499
  whose utilities changed, or the canvas. It is for what a plugin marks the canvas
480
- with beyond inline styles: the visibility plugin keeps hidden nodes on the
481
- canvas and fades them there. Whatever it adds, `onDeinit` takes away.
500
+ with beyond inline styles: the style plugin's display keeps hidden nodes on the
501
+ canvas and fades them there, and takes the drawer of a flex node out of the
502
+ flow. Whatever it adds, `onDeinit` takes away.
482
503
 
483
504
  ### A panel of your own
484
505
 
485
506
  A field per family is the right panel for most plugins and the wrong one for
486
- some: spacing has fourteen families, and fourteen fields. Such a plugin marks
507
+ some: spacing, part of the style plugin, has fourteen families, and fourteen
508
+ fields. Such a plugin marks
487
509
  its families `panel: false` and returns its own element from
488
510
  `panel(node, kind)` — or null where it does not apply — and the editor puts it
489
511
  in the Responsive section. Inside it, `ge.utilityField(node, family)` makes the
490
512
  same field the editor would, and the editor keeps every such field up to date
491
513
  with the view and the classes; swapping one field for another is the plugin's
492
- business. The spacing plugin's panel is a side and one field, and choosing a
514
+ business. The spacing panel is a side and one field, and choosing a
493
515
  side swaps the field for that side's family.
494
516
 
495
517
  The same plugins tend to need the node as a whole for the preview, because
@@ -509,6 +531,8 @@ Two plugins cannot declare the same family name: the second one is ignored,
509
531
  with a warning.
510
532
 
511
533
  Plugin options live in the `utilities` setting, under the plugin's name:
512
- `utilities: { spacing: { values: ['0', '2', '4'] } }`. The editor passes the
513
- setting through as it is; each plugin fills in its own defaults.
534
+ `utilities: { gutters: { scale: [...] } }`. The editor passes the
535
+ setting through as it is; each plugin fills in its own defaults. The style
536
+ plugin's are the `style` setting, since most of them are about its inline
537
+ css.
514
538
 
@@ -35,11 +35,6 @@
35
35
  // CKEditor 5 is GPL-2.0-or-later: 'GPL' accepts that
36
36
  // licence. A commercial licence passes its own key.
37
37
  licenseKey: 'GPL',
38
- on: {
39
- instanceReady: function(evt) {
40
- console.log('instance ready', evt.editor);
41
- }
42
- }
43
38
  }
44
39
  }
45
40
  });