@themarioga/grid-editor 7.3.0 → 8.0.0-beta.3

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 (103) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +34 -30
  3. package/UPGRADING.md +55 -0
  4. package/dist/grideditor.bundle.min.js +3 -3
  5. package/dist/grideditor.css +72 -6
  6. package/dist/grideditor.d.ts +24 -3
  7. package/dist/grideditor.esm.js +7 -58
  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 +7 -58
  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 +30 -6
  17. package/dist/locales/grideditor.es.js +30 -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 +393 -60
  39. package/dist/plugins/grideditor.style.js +387 -56
  40. package/dist/plugins/grideditor.style.min.js +4 -2
  41. package/dist/plugins/grideditor.style.min.js.map +4 -4
  42. package/dist/plugins/grideditor.summernote.min.js.map +2 -2
  43. package/dist/plugins/grideditor.tabs.esm.js +274 -6
  44. package/dist/plugins/grideditor.tabs.js +274 -6
  45. package/dist/plugins/grideditor.tabs.min.js +1 -1
  46. package/dist/plugins/grideditor.tabs.min.js.map +3 -3
  47. package/dist/plugins/grideditor.tinymce.esm.js +1 -8
  48. package/dist/plugins/grideditor.tinymce.js +1 -8
  49. package/dist/plugins/grideditor.tinymce.min.js +1 -1
  50. package/dist/plugins/grideditor.tinymce.min.js.map +3 -3
  51. package/docs/events.md +4 -6
  52. package/docs/locale-keys.md +35 -13
  53. package/docs/plugins.md +15 -35
  54. package/example/ckeditor.html +0 -5
  55. package/example/containers.html +64 -2
  56. package/example/index.html +5 -4
  57. package/example/style.html +16 -4
  58. package/example/utilities.html +12 -11
  59. package/package.json +1 -1
  60. package/src/js/dom.js +1 -2
  61. package/src/js/grideditor.jquery.js +7 -28
  62. package/src/js/grideditor.js +12 -81
  63. package/src/js/locales/grideditor.es.js +30 -6
  64. package/src/js/plugins/grideditor.alignment.js +21 -50
  65. package/src/js/plugins/grideditor.ckeditor.js +10 -23
  66. package/src/js/plugins/grideditor.style.js +18 -12
  67. package/src/js/plugins/grideditor.summernote.js +4 -5
  68. package/src/js/plugins/grideditor.tabs.js +311 -5
  69. package/src/js/plugins/grideditor.tinymce.js +4 -17
  70. package/src/js/style/accordion.js +14 -3
  71. package/src/js/style/display.js +229 -0
  72. package/src/js/style/drawerflow.js +118 -0
  73. package/src/js/style/flex.js +156 -0
  74. package/src/js/style/float.js +2 -4
  75. package/src/js/style/options.js +5 -20
  76. package/src/js/style/sections.js +42 -15
  77. package/src/js/style/spacing.js +2 -4
  78. package/src/js/style/sticky.js +39 -0
  79. package/src/js/style/textalign.js +2 -4
  80. package/src/js/text/grideditor.text.js +1 -1
  81. package/src/less/grideditor.less +68 -10
  82. package/types/grideditor.d.ts +24 -3
  83. package/dist/plugins/grideditor.float.esm.js +0 -43
  84. package/dist/plugins/grideditor.float.js +0 -47
  85. package/dist/plugins/grideditor.float.min.js +0 -1
  86. package/dist/plugins/grideditor.float.min.js.map +0 -7
  87. package/dist/plugins/grideditor.spacing.esm.js +0 -327
  88. package/dist/plugins/grideditor.spacing.js +0 -329
  89. package/dist/plugins/grideditor.spacing.min.js +0 -1
  90. package/dist/plugins/grideditor.spacing.min.js.map +0 -7
  91. package/dist/plugins/grideditor.textalign.esm.js +0 -49
  92. package/dist/plugins/grideditor.textalign.js +0 -53
  93. package/dist/plugins/grideditor.textalign.min.js +0 -1
  94. package/dist/plugins/grideditor.textalign.min.js.map +0 -7
  95. package/dist/plugins/grideditor.visibility.esm.js +0 -167
  96. package/dist/plugins/grideditor.visibility.js +0 -169
  97. package/dist/plugins/grideditor.visibility.min.js +0 -1
  98. package/dist/plugins/grideditor.visibility.min.js.map +0 -7
  99. package/src/js/plugins/grideditor.float.js +0 -29
  100. package/src/js/plugins/grideditor.spacing.js +0 -31
  101. package/src/js/plugins/grideditor.textalign.js +0 -27
  102. package/src/js/plugins/grideditor.visibility.js +0 -32
  103. package/src/js/style/visibility.js +0 -160
@@ -10,11 +10,10 @@
10
10
  * <script src="dist/grideditor.min.js"></script>
11
11
  * <script src="dist/plugins/grideditor.tinymce.min.js"></script>
12
12
  *
13
- * Up to 5.x the main bundle carried a copy of this file; since 6.0 it is
14
- * loaded on its own, like every plugin. It imports what every text editor
15
- * shares - text blocks, the Text button, createText, making the host's plain
16
- * content a text - from src/js/text/grideditor.text.js, which the build puts
17
- * in its classic script, installed once however many editors a page loads.
13
+ * It imports what every text editor shares - text blocks, the Text button,
14
+ * createText, making the host's plain content a text - from
15
+ * src/js/text/grideditor.text.js, which the build puts in its classic
16
+ * script, installed once however many editors a page loads.
18
17
  */
19
18
  import { GridEditor } from '../grideditor.js';
20
19
  import * as dom from '../dom.js';
@@ -22,7 +21,6 @@ import '../text/grideditor.text.js';
22
21
 
23
22
  Object.assign(GridEditor.locales.en, {
24
23
  'text.tinymce': 'tinyMCE',
25
- 'warning.oninit_removed': 'tinyMCE\'s oninit option was removed in 7.0 and is ignored: use init_instance_callback.',
26
24
  });
27
25
 
28
26
  // tinyMCE snapshots the target element's attributes when an inline editor is
@@ -42,9 +40,6 @@ var INITIAL_CONTENT = '<p>Lorem ipsum dolores</p>';
42
40
  var editors = new WeakMap();
43
41
  var pendingRemove = new WeakSet();
44
42
 
45
- // Said once per page, however many editors are on it
46
- var warnedOninit = false;
47
-
48
43
  GridEditor.texts.tinymce = function(ge) {
49
44
  return {
50
45
  labelKey: 'text.tinymce',
@@ -57,13 +52,6 @@ GridEditor.texts.tinymce = function(ge) {
57
52
  var settings = ge.settings;
58
53
  var userConfig = (settings.tinymce && settings.tinymce.config) ? settings.tinymce.config : {};
59
54
 
60
- // 'oninit' was the pre-6 name for init_instance_callback, honoured
61
- // through 6.x and gone in 7.0
62
- if (userConfig.oninit && !warnedOninit) {
63
- warnedOninit = true;
64
- ge.warn(ge.t('warning.oninit_removed'));
65
- }
66
-
67
55
  contentAreas.forEach(function(contentArea) {
68
56
  if (dom.hasClass(contentArea, 'active')) { return; }
69
57
 
@@ -147,7 +135,6 @@ GridEditor.texts.tinymce = function(ge) {
147
135
  // We always edit the element we were handed, so a selector in the
148
136
  // user config would only fight with target
149
137
  delete configuration.selector;
150
- delete configuration.oninit;
151
138
 
152
139
  window.tinymce.init(configuration);
153
140
  });
@@ -32,13 +32,24 @@ function familyApplies(family, node, kind) {
32
32
 
33
33
  /**
34
34
  * What a merged part shows in its section for a node: the spacing part
35
- * its own panel, the others the field of their one family.
35
+ * its own panel, the others a field per family that applies to it - one,
36
+ * or flex's eleven, together.
36
37
  */
37
38
  function partContent(ge, part, node, kind) {
38
39
  if (part.panel) { return part.panel(node, kind); }
39
40
 
40
- var family = part.families[0];
41
- return familyApplies(family, node, kind) ? ge.utilityField(node, family.name) : null;
41
+ var fields = part.families.filter(function(family) {
42
+ return familyApplies(family, node, kind);
43
+ }).map(function(family) {
44
+ return ge.utilityField(node, family.name);
45
+ });
46
+
47
+ if (fields.length < 2) { return fields[0] || null; }
48
+
49
+ var box = dom.element('div', { 'class': 'ge-style-part-fields' });
50
+ fields.forEach(function(field) { box.appendChild(field); });
51
+
52
+ return box;
42
53
  }
43
54
 
44
55
  /**
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Display, a part of the style plugin: how a node is displayed per
3
+ * breakpoint, hidden included, with Bootstrap's d-{breakpoint}-* classes,
4
+ * and the eye in the drawers that hides and shows it.
5
+ *
6
+ * Its families, and whatever it does on the canvas, as a function of the
7
+ * handle and its options: grideditor.style.js puts them in its sections.
8
+ */
9
+ import { GridEditor } from '../grideditor.js';
10
+ import * as dom from '../dom.js';
11
+
12
+ Object.assign(GridEditor.locales.en, {
13
+ 'utility.display': 'Display',
14
+ 'utility.visibility_hidden': 'Hidden',
15
+ 'tool.hide_in_view': 'Hide in this view',
16
+ 'tool.show_in_view': 'Show in this view',
17
+ 'badge.hidden_in': 'Hidden at {breakpoints}',
18
+ });
19
+
20
+ /** Bootstrap's display values, less its table ones. */
21
+ var VALUES = ['none', 'inline', 'inline-block', 'block', 'grid', 'inline-grid', 'flex', 'inline-flex'];
22
+
23
+ /** A node that carries any class of the family, at any breakpoint. */
24
+ var CLASS_PATTERN = new RegExp('(?:^|\\s)d-(?:(?:sm|md|lg|xl|xxl)-)?(?:' + VALUES.join('|') + ')(?:\\s|$)');
25
+ var NONE_PATTERN = /^d-(?:(?:sm|md|lg|xl|xxl)-)?none$/;
26
+
27
+ var NODES = '.row, .column, .ge-content, .ge-element, [data-ge-container]';
28
+
29
+ /** What the canvas shows a hidden node as, in a view where Bootstrap hides it. */
30
+ var SHOWN_ATTR = 'data-ge-display';
31
+
32
+ export function displayPart(ge, given) {
33
+
34
+ var options = Object.assign({ drawer: true }, given);
35
+
36
+ /**
37
+ * What a kind of node is offered: a row is a flex container or it is no
38
+ * grid, and a text is a block of text.
39
+ */
40
+ function choices(kind) {
41
+ if (kind === 'row') { return ['none', 'flex']; }
42
+ if (kind === 'text' || kind === 'plain') { return ['none', 'block']; }
43
+
44
+ return VALUES;
45
+ }
46
+
47
+ /** What "shown" is written as on this kind of node, when nothing below says. */
48
+ function shownByDefault(kind) {
49
+ return kind === 'row' ? 'flex' : 'block';
50
+ }
51
+
52
+ function applies(node, kind) {
53
+ return kind === 'row' || kind === 'column' || kind === 'element' || kind === 'text' || kind === 'plain' ||
54
+ dom.is(node, '[data-ge-container]');
55
+ }
56
+
57
+ function hiddenAt(node, view) {
58
+ return ge.getUtility(node, 'display', view) === 'none';
59
+ }
60
+
61
+ /** The breakpoints at which the node is hidden, smallest first. */
62
+ function hiddenTiers(node) {
63
+ return ge.breakpoints.filter(function(key) { return hiddenAt(node, key); });
64
+ }
65
+
66
+ /**
67
+ * Whether the node is hidden in the view being edited. In the all view
68
+ * that means hidden at every breakpoint, since "hidden at some" is what
69
+ * the badge is for.
70
+ */
71
+ function hiddenHere(node) {
72
+ return ge.view() === 'all'
73
+ ? hiddenTiers(node).length === ge.breakpoints.length
74
+ : hiddenAt(node, ge.view());
75
+ }
76
+
77
+ /** What the breakpoint below the view shows, which an inherit falls back to. */
78
+ function hiddenBelow(node) {
79
+ var index = ge.breakpoints.indexOf(ge.view());
80
+
81
+ return index > 0 && hiddenAt(node, ge.breakpoints[index - 1]);
82
+ }
83
+
84
+ /**
85
+ * How the nearest breakpoint below this one that shows the node shows
86
+ * it, or null when none below does.
87
+ */
88
+ function shownBelow(node, view) {
89
+ for (var i = ge.breakpoints.indexOf(view) - 1; i >= 0; i--) {
90
+ var value = ge.getUtility(node, 'display', ge.breakpoints[i]);
91
+
92
+ if (value === null) { return null; }
93
+ if (value !== 'none') { return value; }
94
+ }
95
+
96
+ return null;
97
+ }
98
+
99
+ /**
100
+ * Hide or show the node in the view being edited, with as few classes as
101
+ * that takes. In a breakpoint view that is often none at all: showing a
102
+ * node the breakpoint below shows removes this breakpoint's d-*-none
103
+ * rather than writing another class on top of it. Showing one that the
104
+ * breakpoint below hides writes the display it had further down, so a
105
+ * flex column comes back flex. In the all view a node is hidden
106
+ * everywhere or shown everywhere, and shown is no class.
107
+ */
108
+ function toggle(node, kind) {
109
+ var hide = !hiddenHere(node);
110
+ var value;
111
+
112
+ if (ge.view() === 'all') {
113
+ value = hide ? 'none' : null;
114
+ } else if (hide) {
115
+ value = hiddenBelow(node) ? null : 'none';
116
+ } else {
117
+ value = hiddenBelow(node) ? (shownBelow(node, ge.view()) || shownByDefault(kind)) : null;
118
+ }
119
+
120
+ ge.setUtility(node, 'display', value, { source: 'tool' });
121
+ }
122
+
123
+ /**
124
+ * A node Bootstrap hides in this view stays on the canvas, shown as it
125
+ * would be if it were not hidden: with its classes' none taken off for
126
+ * the moment it takes to ask the browser.
127
+ */
128
+ function shownAs(node) {
129
+ var original = node.getAttribute('class');
130
+
131
+ node.setAttribute('class', original.split(/\s+/).filter(function(name) {
132
+ return !NONE_PATTERN.test(name);
133
+ }).join(' '));
134
+
135
+ var display = getComputedStyle(node).display;
136
+ node.setAttribute('class', original);
137
+
138
+ // The canvas has a rule for each of Bootstrap's values, and a block for anything else
139
+ return display !== 'none' && VALUES.indexOf(display) !== -1 ? display : 'block';
140
+ }
141
+
142
+ /**
143
+ * The canvas shows each node as the view sees it. A node Bootstrap would
144
+ * hide is kept on the canvas with the display it would have, and
145
+ * ge-hidden-in-view fades it; data-ge-hidden-in carries the badge text
146
+ * for the all view.
147
+ */
148
+ function mark(scope) {
149
+ dom.selfAndAll(scope, NODES).forEach(function(node) {
150
+ var kind = ge.kindOf(node);
151
+ var carries = applies(node, kind) && CLASS_PATTERN.test(node.getAttribute('class') || '');
152
+ var tiers = carries ? hiddenTiers(node) : [];
153
+ var here = carries && hiddenHere(node);
154
+ var partly = carries && ge.view() === 'all' && tiers.length > 0 && !here;
155
+
156
+ node.removeAttribute(SHOWN_ATTR);
157
+ if (carries && getComputedStyle(node).display === 'none') {
158
+ node.setAttribute(SHOWN_ATTR, shownAs(node));
159
+ }
160
+
161
+ dom.toggleClass(node, 'ge-hidden-in-view', here);
162
+
163
+ if (partly) {
164
+ node.setAttribute('data-ge-hidden-in', ge.t('badge.hidden_in', { breakpoints: tiers.join(', ') }));
165
+ } else {
166
+ node.removeAttribute('data-ge-hidden-in');
167
+ }
168
+
169
+ dom.children(node, '.ge-tools-drawer').forEach(function(drawer) {
170
+ dom.children(drawer, '.ge-visibility-tool').forEach(function(tool) {
171
+ tool.setAttribute('title', here ? ge.t('tool.show_in_view') : ge.t('tool.hide_in_view'));
172
+ dom.all(tool, 'i').forEach(function(icon) {
173
+ icon.setAttribute('class', here ? 'bi bi-eye-slash' : 'bi bi-eye');
174
+ });
175
+ });
176
+ });
177
+ });
178
+ }
179
+
180
+ function unmark() {
181
+ dom.all(ge.canvas, '.ge-hidden-in-view, [data-ge-hidden-in], [' + SHOWN_ATTR + ']').forEach(function(node) {
182
+ dom.removeClass(node, 'ge-hidden-in-view');
183
+ node.removeAttribute('data-ge-hidden-in');
184
+ node.removeAttribute(SHOWN_ATTR);
185
+ dom.dropEmptyClass(node);
186
+ });
187
+ }
188
+
189
+ return {
190
+ families: [{
191
+ name: 'display',
192
+ prefix: 'd',
193
+ values: VALUES,
194
+ appliesTo: ['row', 'column', 'text', 'element', 'container'],
195
+ labelKey: 'utility.display',
196
+
197
+ choices: function(node, kind) {
198
+ return choices(kind);
199
+ },
200
+
201
+ label: function(value) {
202
+ return value === 'none' ? ge.t('utility.visibility_hidden') : value;
203
+ },
204
+
205
+ /**
206
+ * What the view being edited displays the node as. Hidden is
207
+ * shown the way the breakpoints below show it, since the canvas
208
+ * keeps a hidden node, faded; with no class applying, it is what
209
+ * the node is without any.
210
+ */
211
+ preview: function(value, node) {
212
+ if (value === 'none') { value = shownBelow(node, ge.view()); }
213
+
214
+ return { display: value === null ? ge.bareStyle(node, 'display', 'display') : value };
215
+ },
216
+ }],
217
+
218
+ drawerTools: function(drawer, node, kind) {
219
+ if (!options.drawer || !applies(node, kind)) { return; }
220
+
221
+ ge.createTool(drawer, ge.t('tool.hide_in_view'), 'ge-visibility-tool', 'bi bi-eye', function() {
222
+ toggle(node, kind);
223
+ });
224
+ },
225
+
226
+ onRefresh: mark,
227
+ onDeinit: unmark,
228
+ };
229
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * The drawer of a flex or grid node, a part of the style plugin.
3
+ *
4
+ * A drawer is its node's first child, in the flow: in a row, which wraps,
5
+ * it is a line of its own above the columns, but in anything else that
6
+ * lays its children out - a column made flex, a row that does not wrap, a
7
+ * grid - it would be one of the items, beside the content or in a cell of
8
+ * its own. So on such a node the drawer leaves the flow: it sits on top, as
9
+ * wide as the node, over a transparent top border as tall as it is, and
10
+ * the content is laid out below as the page would lay it out.
11
+ *
12
+ * The node's own style is the host's, so what is written on it is an
13
+ * attribute, and the border comes from a rule per height, here.
14
+ */
15
+ import * as dom from '../dom.js';
16
+
17
+ var NODES = '.row, .column, .ge-element, [data-ge-container]';
18
+ var OUT_CLASS = 'ge-drawer-out';
19
+ var OUT_ATTR = 'data-ge-drawer-out';
20
+
21
+ /** The space left between the drawer and the content, as the editor's frame leaves it. */
22
+ var GAP = 5;
23
+
24
+ var LAYS_OUT = /^(?:inline-)?(?:flex|grid)$/;
25
+
26
+ export function drawerflowPart(ge) {
27
+
28
+ var sheet = null;
29
+ var heights = {};
30
+ var observer = null;
31
+
32
+ /** The rule for a node whose drawer takes this much room. */
33
+ function rule(room) {
34
+ if (heights[room]) { return; }
35
+ heights[room] = true;
36
+
37
+ if (!sheet) {
38
+ sheet = document.head.appendChild(dom.element('style', { 'data-ge-drawer-flow': '' }));
39
+ }
40
+
41
+ var node = '.ge-canvas.ge-editing [' + OUT_ATTR + '="' + room + '"]';
42
+ sheet.appendChild(document.createTextNode(
43
+ node + ' { border-top-width: ' + room + 'px !important; }\n' +
44
+ node + ' > .ge-tools-drawer { top: -' + room + 'px; }\n'
45
+ ));
46
+ }
47
+
48
+ /** Whether the node lays its drawer out as an item of its own. */
49
+ function laysOut(node) {
50
+ var style = getComputedStyle(node);
51
+
52
+ if (!LAYS_OUT.test(style.display)) { return false; }
53
+
54
+ // A row as the grid has it: its drawer is a line of its own already
55
+ return !(dom.hasClass(node, 'row') && style.flexDirection === 'row' && style.flexWrap === 'wrap');
56
+ }
57
+
58
+ function measure(node, drawer) {
59
+ var room = Math.ceil(drawer.offsetHeight) + GAP;
60
+
61
+ rule(room);
62
+ node.setAttribute(OUT_ATTR, String(room));
63
+ }
64
+
65
+ /** A drawer that grows - its tools wrap, its settings unfold - takes more room. */
66
+ function watch(drawer) {
67
+ if (typeof ResizeObserver === 'undefined') { return; }
68
+
69
+ if (!observer) {
70
+ observer = new ResizeObserver(function(entries) {
71
+ entries.forEach(function(entry) {
72
+ var node = entry.target.parentNode;
73
+ if (node && dom.hasClass(node, OUT_CLASS)) { measure(node, entry.target); }
74
+ });
75
+ });
76
+ }
77
+ observer.observe(drawer);
78
+ }
79
+
80
+ function mark(scope) {
81
+ dom.selfAndAll(scope, NODES).forEach(function(node) {
82
+ var drawer = dom.child(node, '.ge-tools-drawer');
83
+ if (!drawer) { return; }
84
+
85
+ if (laysOut(node)) {
86
+ dom.addClass(node, OUT_CLASS);
87
+ measure(node, drawer);
88
+ watch(drawer);
89
+ } else if (dom.hasClass(node, OUT_CLASS)) {
90
+ dom.removeClass(node, OUT_CLASS);
91
+ node.removeAttribute(OUT_ATTR);
92
+ dom.dropEmptyClass(node);
93
+ if (observer) { observer.unobserve(drawer); }
94
+ }
95
+ });
96
+ }
97
+
98
+ function unmark() {
99
+ if (observer) { observer.disconnect(); }
100
+ observer = null;
101
+
102
+ dom.all(ge.canvas, '.' + OUT_CLASS).forEach(function(node) {
103
+ dom.removeClass(node, OUT_CLASS);
104
+ node.removeAttribute(OUT_ATTR);
105
+ dom.dropEmptyClass(node);
106
+ });
107
+
108
+ if (sheet) { sheet.remove(); }
109
+ sheet = null;
110
+ heights = {};
111
+ }
112
+
113
+ return {
114
+ families: [],
115
+ onRefresh: mark,
116
+ onDeinit: unmark,
117
+ };
118
+ }
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Flex, a part of the style plugin: a flex container's direction, wrap,
3
+ * alignment and gaps, and how its children grow, shrink and fill, per
4
+ * breakpoint, with Bootstrap's flex-{breakpoint}-*, justify-content-*,
5
+ * align-items-*, align-content-*, gap-* and row-/column-gap-* classes.
6
+ *
7
+ * Its families, and whatever it does on the canvas, as a function of the
8
+ * handle and the spacing options, whose scale the gaps share:
9
+ * grideditor.style.js puts them in its Flex section.
10
+ */
11
+ import { GridEditor } from '../grideditor.js';
12
+
13
+ Object.assign(GridEditor.locales.en, {
14
+ 'utility.flex_direction': 'Direction',
15
+ 'utility.flex_wrap': 'Wrap',
16
+ 'utility.justify_content': 'Justify columns',
17
+ 'utility.align_items': 'Align columns',
18
+ 'utility.align_content': 'Align lines',
19
+ 'utility.gap': 'Gap',
20
+ 'utility.row_gap': 'Row gap',
21
+ 'utility.column_gap': 'Column gap',
22
+ 'utility.flex_fill': 'Fill',
23
+ 'utility.flex_grow': 'Grow',
24
+ 'utility.flex_shrink': 'Shrink',
25
+ });
26
+
27
+ /** What Bootstrap's value names come to in css. */
28
+ var FLEX = {
29
+ start: 'flex-start',
30
+ end: 'flex-end',
31
+ center: 'center',
32
+ between: 'space-between',
33
+ around: 'space-around',
34
+ evenly: 'space-evenly',
35
+ baseline: 'baseline',
36
+ stretch: 'stretch',
37
+ };
38
+
39
+ var GAPS = ['0', '1', '2', '3', '4', '5'];
40
+
41
+ /** Bootstrap's $spacers. */
42
+ var SCALE = ['0', '.25rem', '.5rem', '1rem', '1.5rem', '3rem'];
43
+
44
+ /** A flex container: a row is one already, and has its gutters for gaps. */
45
+ var CONTAINERS = ['row', 'column', 'element', 'container'];
46
+
47
+ /** What sits in a flex container and can grow, shrink or fill it. */
48
+ var ITEMS = ['column', 'element', 'container'];
49
+
50
+ export function flexPart(ge, spacing) {
51
+
52
+ var scale = (spacing && spacing.scale) || SCALE;
53
+
54
+ /** A family whose preview is its one css property, the node's own without a class. */
55
+ function family(definition) {
56
+ var property = definition.property || definition.name;
57
+
58
+ return Object.assign({
59
+ prefix: definition.name,
60
+ panel: false,
61
+ preview: function(value, node) {
62
+ var styles = {};
63
+ styles[property] = value === null ? ge.bareStyle(node, definition.name, property) : definition.css(value);
64
+ return styles;
65
+ },
66
+ }, definition);
67
+ }
68
+
69
+ /** An alignment family: its values are Bootstrap's names, and without a class it is normal. */
70
+ function alignment(definition) {
71
+ return family(Object.assign({
72
+ appliesTo: CONTAINERS,
73
+ preview: function(value) {
74
+ var styles = {};
75
+ styles[definition.name] = value === null ? 'normal' : FLEX[value];
76
+ return styles;
77
+ },
78
+ }, definition));
79
+ }
80
+
81
+ function gap(definition) {
82
+ return family(Object.assign({
83
+ values: GAPS,
84
+ appliesTo: ITEMS,
85
+ css: function(value) { return scale[value]; },
86
+ }, definition));
87
+ }
88
+
89
+ function same(value) {
90
+ return value;
91
+ }
92
+
93
+ return {
94
+ families: [
95
+ family({
96
+ name: 'flex-direction',
97
+ prefix: 'flex',
98
+ labelKey: 'utility.flex_direction',
99
+ values: ['row', 'row-reverse', 'column', 'column-reverse'],
100
+ appliesTo: CONTAINERS,
101
+ css: same,
102
+ }),
103
+ family({
104
+ name: 'flex-wrap',
105
+ prefix: 'flex',
106
+ labelKey: 'utility.flex_wrap',
107
+ values: ['wrap', 'nowrap', 'wrap-reverse'],
108
+ appliesTo: CONTAINERS,
109
+ css: same,
110
+ }),
111
+ alignment({
112
+ name: 'justify-content',
113
+ labelKey: 'utility.justify_content',
114
+ values: ['start', 'center', 'end', 'between', 'around', 'evenly'],
115
+ }),
116
+ alignment({
117
+ name: 'align-items',
118
+ labelKey: 'utility.align_items',
119
+ values: ['start', 'center', 'end', 'baseline', 'stretch'],
120
+ }),
121
+ alignment({
122
+ name: 'align-content',
123
+ labelKey: 'utility.align_content',
124
+ values: ['start', 'center', 'end', 'between', 'around', 'stretch'],
125
+ }),
126
+ gap({ name: 'gap', labelKey: 'utility.gap' }),
127
+ gap({ name: 'row-gap', labelKey: 'utility.row_gap' }),
128
+ gap({ name: 'column-gap', labelKey: 'utility.column_gap' }),
129
+ family({
130
+ name: 'flex-fill',
131
+ prefix: 'flex',
132
+ property: 'flex',
133
+ labelKey: 'utility.flex_fill',
134
+ values: ['fill'],
135
+ appliesTo: ITEMS,
136
+ css: function() { return '1 1 auto'; },
137
+ }),
138
+ family({
139
+ name: 'flex-grow',
140
+ prefix: 'flex',
141
+ labelKey: 'utility.flex_grow',
142
+ values: ['grow-0', 'grow-1'],
143
+ appliesTo: ITEMS,
144
+ css: function(value) { return value.slice(-1); },
145
+ }),
146
+ family({
147
+ name: 'flex-shrink',
148
+ prefix: 'flex',
149
+ labelKey: 'utility.flex_shrink',
150
+ values: ['shrink-0', 'shrink-1'],
151
+ appliesTo: ITEMS,
152
+ css: function(value) { return value.slice(-1); },
153
+ }),
154
+ ],
155
+ };
156
+ }
@@ -2,10 +2,8 @@
2
2
  * Float, a part of the style plugin: floating an element per breakpoint, with Bootstrap's
3
3
  * float-{breakpoint}-start, -end and -none classes.
4
4
  *
5
- * The part is what the float plugin was up to 7.2 - its families, and
6
- * whatever it did on the canvas - as a function of the handle.
7
- * grideditor.style.js puts it in its sections; the deprecated
8
- * grideditor.float.js still registers it on its own, as it always did.
5
+ * Its families, and whatever it does on the canvas, as a function of the
6
+ * handle: grideditor.style.js puts them in its sections.
9
7
  */
10
8
  import { GridEditor } from '../grideditor.js';
11
9
 
@@ -3,13 +3,11 @@
3
3
  *
4
4
  * style: {
5
5
  * sections: { border: { properties: [...], catalog: false }, position: false, … },
6
- * spacing: { values, scale }, // what utilities.spacing was
7
- * visibility: { drawer }, // what utilities.visibility was
6
+ * spacing: { values, scale }, // the values offered, and what 0 to 5 come to
7
+ * visibility: { drawer }, // false leaves the eye out of the drawers
8
8
  * }
9
9
  *
10
- * Every section is on unless it is turned off. utilities.spacing and
11
- * utilities.visibility are still read, for 7.x, when the new key is not
12
- * there, and said to be deprecated.
10
+ * Every section is on unless it is turned off.
13
11
  */
14
12
  import { SECTIONS, section } from './sections.js';
15
13
 
@@ -51,25 +49,12 @@ function resolveSections(ge, given) {
51
49
  return resolved;
52
50
  }
53
51
 
54
- /** An option of a merged part: the new key, or the old one, deprecated. */
55
- function partOption(ge, style, name) {
56
- if (style[name] !== undefined) { return style[name]; }
57
-
58
- var old = (ge.settings.utilities || {})[name];
59
- if (old !== undefined) {
60
- ge.warn('utilities.' + name + ' is deprecated and will be removed in 8.0: use style.' + name);
61
- return old;
62
- }
63
-
64
- return undefined;
65
- }
66
-
67
52
  export function resolveOptions(ge) {
68
53
  var style = ge.settings.style || {};
69
54
 
70
55
  return {
71
56
  sections: resolveSections(ge, style.sections),
72
- spacing: partOption(ge, style, 'spacing'),
73
- visibility: partOption(ge, style, 'visibility'),
57
+ spacing: style.spacing,
58
+ visibility: style.visibility,
74
59
  };
75
60
  }