@themarioga/grid-editor 6.0.0-beta.5 → 7.0.0

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 (147) hide show
  1. package/AUTO_SAVE.md +2 -2
  2. package/BUILDING.md +45 -29
  3. package/CHANGELOG.md +54 -0
  4. package/README.md +140 -89
  5. package/UPGRADING.md +146 -2
  6. package/dist/grideditor.bundle.min.js +14 -0
  7. package/dist/grideditor.d.ts +335 -0
  8. package/dist/grideditor.esm.js +3977 -0
  9. package/dist/grideditor.jquery.js +253 -0
  10. package/dist/grideditor.jquery.min.js +1 -0
  11. package/dist/grideditor.jquery.min.js.map +7 -0
  12. package/dist/grideditor.js +3983 -0
  13. package/dist/grideditor.min.js +6 -0
  14. package/dist/grideditor.min.js.map +7 -0
  15. package/dist/locales/grideditor.es.esm.js +158 -0
  16. package/dist/locales/grideditor.es.js +164 -170
  17. package/dist/locales/grideditor.es.min.js +6 -2
  18. package/dist/locales/grideditor.es.min.js.map +7 -1
  19. package/dist/plugins/grideditor.accordion.esm.js +294 -0
  20. package/dist/plugins/grideditor.accordion.js +286 -180
  21. package/dist/plugins/grideditor.accordion.min.js +1 -2
  22. package/dist/plugins/grideditor.accordion.min.js.map +7 -1
  23. package/dist/plugins/grideditor.alignment.esm.js +55 -0
  24. package/dist/plugins/grideditor.alignment.js +58 -77
  25. package/dist/plugins/grideditor.alignment.min.js +1 -2
  26. package/dist/plugins/grideditor.alignment.min.js.map +7 -1
  27. package/dist/plugins/grideditor.card.esm.js +73 -0
  28. package/dist/plugins/grideditor.card.js +74 -64
  29. package/dist/plugins/grideditor.card.min.js +1 -2
  30. package/dist/plugins/grideditor.card.min.js.map +7 -1
  31. package/dist/plugins/grideditor.ckeditor.esm.js +500 -0
  32. package/dist/plugins/grideditor.ckeditor.js +482 -493
  33. package/dist/plugins/grideditor.ckeditor.min.js +1 -2
  34. package/dist/plugins/grideditor.ckeditor.min.js.map +7 -1
  35. package/dist/plugins/grideditor.clipboard.esm.js +326 -0
  36. package/dist/plugins/grideditor.clipboard.js +298 -235
  37. package/dist/plugins/grideditor.clipboard.min.js +1 -2
  38. package/dist/plugins/grideditor.clipboard.min.js.map +7 -1
  39. package/dist/plugins/grideditor.codemirror-inline.esm.js +205 -0
  40. package/dist/plugins/grideditor.codemirror-inline.js +188 -168
  41. package/dist/plugins/grideditor.codemirror-inline.min.js +1 -2
  42. package/dist/plugins/grideditor.codemirror-inline.min.js.map +7 -1
  43. package/dist/plugins/grideditor.codemirror.esm.js +63 -0
  44. package/dist/plugins/grideditor.codemirror.js +60 -71
  45. package/dist/plugins/grideditor.codemirror.min.js +1 -2
  46. package/dist/plugins/grideditor.codemirror.min.js.map +7 -1
  47. package/dist/plugins/grideditor.elements.esm.js +271 -0
  48. package/dist/plugins/grideditor.elements.js +256 -149
  49. package/dist/plugins/grideditor.elements.min.js +1 -2
  50. package/dist/plugins/grideditor.elements.min.js.map +7 -1
  51. package/dist/plugins/grideditor.float.esm.js +34 -0
  52. package/dist/plugins/grideditor.float.js +37 -52
  53. package/dist/plugins/grideditor.float.min.js +1 -2
  54. package/dist/plugins/grideditor.float.min.js.map +7 -1
  55. package/dist/plugins/grideditor.gutters.esm.js +143 -0
  56. package/dist/plugins/grideditor.gutters.js +134 -131
  57. package/dist/plugins/grideditor.gutters.min.js +1 -2
  58. package/dist/plugins/grideditor.gutters.min.js.map +7 -1
  59. package/dist/plugins/grideditor.order.esm.js +189 -0
  60. package/dist/plugins/grideditor.order.js +170 -182
  61. package/dist/plugins/grideditor.order.min.js +1 -2
  62. package/dist/plugins/grideditor.order.min.js.map +7 -1
  63. package/dist/plugins/grideditor.popup.esm.js +187 -0
  64. package/dist/plugins/grideditor.popup.js +183 -134
  65. package/dist/plugins/grideditor.popup.min.js +1 -2
  66. package/dist/plugins/grideditor.popup.min.js.map +7 -1
  67. package/dist/plugins/grideditor.sections.esm.js +271 -0
  68. package/dist/plugins/grideditor.sections.js +250 -173
  69. package/dist/plugins/grideditor.sections.min.js +1 -2
  70. package/dist/plugins/grideditor.sections.min.js.map +7 -1
  71. package/dist/plugins/grideditor.spacing.esm.js +318 -0
  72. package/dist/plugins/grideditor.spacing.js +296 -272
  73. package/dist/plugins/grideditor.spacing.min.js +1 -2
  74. package/dist/plugins/grideditor.spacing.min.js.map +7 -1
  75. package/dist/plugins/grideditor.summernote.esm.js +509 -0
  76. package/dist/plugins/grideditor.summernote.js +491 -471
  77. package/dist/plugins/grideditor.summernote.min.js +1 -2
  78. package/dist/plugins/grideditor.summernote.min.js.map +7 -1
  79. package/dist/plugins/grideditor.tabs.esm.js +237 -0
  80. package/dist/plugins/grideditor.tabs.js +233 -139
  81. package/dist/plugins/grideditor.tabs.min.js +1 -2
  82. package/dist/plugins/grideditor.tabs.min.js.map +7 -1
  83. package/dist/plugins/grideditor.textalign.esm.js +40 -0
  84. package/dist/plugins/grideditor.textalign.js +43 -56
  85. package/dist/plugins/grideditor.textalign.min.js +1 -2
  86. package/dist/plugins/grideditor.textalign.min.js.map +7 -1
  87. package/dist/plugins/grideditor.tinymce.esm.js +519 -0
  88. package/dist/plugins/grideditor.tinymce.js +500 -534
  89. package/dist/plugins/grideditor.tinymce.min.js +1 -2
  90. package/dist/plugins/grideditor.tinymce.min.js.map +7 -1
  91. package/dist/plugins/grideditor.visibility.esm.js +158 -0
  92. package/dist/plugins/grideditor.visibility.js +140 -149
  93. package/dist/plugins/grideditor.visibility.min.js +1 -2
  94. package/dist/plugins/grideditor.visibility.min.js.map +7 -1
  95. package/docs/events.md +47 -21
  96. package/docs/locale-keys.md +7 -4
  97. package/docs/plugins.md +49 -27
  98. package/example/adapter.html +112 -0
  99. package/example/attributes.html +85 -61
  100. package/example/autocols.html +9 -9
  101. package/example/autosave.html +13 -14
  102. package/example/basic.html +4 -5
  103. package/example/breakpoints.html +5 -6
  104. package/example/ckeditor.html +4 -5
  105. package/example/clipboard.html +11 -10
  106. package/example/codemirror.html +9 -7
  107. package/example/containers.html +7 -8
  108. package/example/custom_editor.html +53 -34
  109. package/example/elements.html +10 -11
  110. package/example/index.html +16 -2
  111. package/example/locale.html +6 -7
  112. package/example/plugins.html +44 -29
  113. package/example/summernote.html +6 -5
  114. package/example/utilities.html +17 -13
  115. package/example/wrap_content.html +9 -9
  116. package/package.json +43 -12
  117. package/src/js/dom.js +401 -0
  118. package/src/js/grideditor.classic.js +16 -0
  119. package/src/js/grideditor.jquery.js +325 -0
  120. package/src/js/{jquery.grideditor.js → grideditor.js} +1284 -1124
  121. package/src/js/locales/grideditor.es.js +163 -158
  122. package/src/js/plugins/grideditor.accordion.js +97 -77
  123. package/src/js/plugins/grideditor.alignment.js +5 -7
  124. package/src/js/plugins/grideditor.card.js +23 -23
  125. package/src/js/plugins/grideditor.ckeditor.js +107 -106
  126. package/src/js/plugins/grideditor.clipboard.js +49 -37
  127. package/src/js/plugins/grideditor.codemirror-inline.js +50 -37
  128. package/src/js/plugins/grideditor.codemirror.js +9 -10
  129. package/src/js/plugins/grideditor.elements.js +57 -33
  130. package/src/js/plugins/grideditor.float.js +4 -6
  131. package/src/js/plugins/grideditor.gutters.js +20 -15
  132. package/src/js/plugins/grideditor.order.js +28 -25
  133. package/src/js/plugins/grideditor.popup.js +63 -51
  134. package/src/js/plugins/grideditor.sections.js +39 -32
  135. package/src/js/plugins/grideditor.spacing.js +42 -45
  136. package/src/js/plugins/grideditor.summernote.js +112 -76
  137. package/src/js/plugins/grideditor.tabs.js +65 -57
  138. package/src/js/plugins/grideditor.textalign.js +4 -6
  139. package/src/js/plugins/grideditor.tinymce.js +147 -139
  140. package/src/js/plugins/grideditor.visibility.js +24 -25
  141. package/src/js/register.js +18 -0
  142. package/src/js/text/grideditor.text.js +81 -106
  143. package/types/grideditor.d.ts +335 -0
  144. package/dist/jquery.grideditor.bundle.min.js +0 -10
  145. package/dist/jquery.grideditor.js +0 -4927
  146. package/dist/jquery.grideditor.min.js +0 -2
  147. package/dist/jquery.grideditor.min.js.map +0 -1
@@ -8,16 +8,16 @@
8
8
  * editor for is the handle its factory is called with, described in
9
9
  * docs/plugins.md.
10
10
  *
11
- * <script src="dist/jquery.grideditor.min.js"></script>
11
+ * <script src="dist/grideditor.min.js"></script>
12
12
  * <script src="dist/plugins/grideditor.elements.min.js"></script>
13
13
  * <script src="dist/plugins/grideditor.float.min.js"></script>
14
14
  *
15
15
  * Elements only. A floated row or column stops being part of the grid, and a
16
16
  * container sits beside the content areas rather than in their text.
17
17
  */
18
- (function($) {
18
+ import { GridEditor } from '../grideditor.js';
19
19
 
20
- $.extend($.fn.gridEditor.locales.en, {
20
+ Object.assign(GridEditor.locales.en, {
21
21
  'utility.float': 'Float',
22
22
  'utility.float_start': 'Start',
23
23
  'utility.float_end': 'End',
@@ -27,7 +27,7 @@ $.extend($.fn.gridEditor.locales.en, {
27
27
  /** Start and end are left and right: Bootstrap's css is left to right. */
28
28
  var CSS = { start: 'left', end: 'right', none: 'none' };
29
29
 
30
- $.fn.gridEditor.utilities.float = function(ge) {
30
+ GridEditor.utilities.float = function(ge) {
31
31
 
32
32
  function label(value) {
33
33
  if (value === 'start') { return ge.t('utility.float_start'); }
@@ -52,5 +52,3 @@ $.fn.gridEditor.utilities.float = function(ge) {
52
52
  }],
53
53
  };
54
54
  };
55
-
56
- })(jQuery);
@@ -6,7 +6,7 @@
6
6
  * and gy-{breakpoint}-* classes. What it can ask the editor for is the handle
7
7
  * its factory is called with, described in docs/plugins.md.
8
8
  *
9
- * <script src="dist/jquery.grideditor.min.js"></script>
9
+ * <script src="dist/grideditor.min.js"></script>
10
10
  * <script src="dist/plugins/grideditor.gutters.min.js"></script>
11
11
  *
12
12
  * The editor draws its own frame round every column, narrower than any
@@ -15,9 +15,10 @@
15
15
  * utilities.gutters.scale is what 0 to 5 come to, for a page that changed
16
16
  * Bootstrap's $spacers.
17
17
  */
18
- (function($) {
18
+ import { GridEditor } from '../grideditor.js';
19
+ import * as dom from '../dom.js';
19
20
 
20
- $.extend($.fn.gridEditor.locales.en, {
21
+ Object.assign(GridEditor.locales.en, {
21
22
  'utility.gutters': 'Gutters',
22
23
  'utility.gutters_x': 'Horizontal gutters',
23
24
  'utility.gutters_y': 'Vertical gutters',
@@ -33,16 +34,17 @@ var DEFAULT_Y = '0';
33
34
  var INFIXES = ['', 'sm', 'md', 'lg', 'xl', 'xxl'];
34
35
  var CLASS_PATTERN = /(?:^|\s)g[xy]?-(?:(?:sm|md|lg|xl|xxl)-)?[0-5](?:\s|$)/;
35
36
 
36
- $.fn.gridEditor.utilities.gutters = function(ge) {
37
+ GridEditor.utilities.gutters = function(ge) {
37
38
 
38
- var options = $.extend({ scale: SCALE }, ge.settings.utilities.gutters);
39
+ var options = Object.assign({ scale: SCALE }, ge.settings.utilities.gutters);
40
+ var listening = null; // The after-utility listener, while editing
39
41
 
40
42
  /**
41
43
  * The class of a family that decides a row's gutters at a breakpoint:
42
44
  * the widest breakpoint up to it that has one, as { tier, value }.
43
45
  */
44
46
  function source(row, prefix, tier) {
45
- var classes = (row.attr('class') || '').split(/\s+/);
47
+ var classes = (row.getAttribute('class') || '').split(/\s+/);
46
48
 
47
49
  for (var i = tier; i >= 0; i--) {
48
50
  for (var value = VALUES.length - 1; value >= 0; value--) {
@@ -86,7 +88,8 @@ $.fn.gridEditor.utilities.gutters = function(ge) {
86
88
  * taken off: left on, the bigger of the two would win, and the field the
87
89
  * user just chose would not be what the row shows.
88
90
  */
89
- function afterUtility(e, payload) {
91
+ function afterUtility(e) {
92
+ var payload = e.detail;
90
93
  if (payload.family !== 'g') { return; }
91
94
 
92
95
  ['gx', 'gy'].forEach(function(family) {
@@ -95,9 +98,8 @@ $.fn.gridEditor.utilities.gutters = function(ge) {
95
98
  }
96
99
 
97
100
  function mark(scope) {
98
- scope.find('.row').addBack('.row').each(function() {
99
- var row = $(this);
100
- row.toggleClass('ge-gutters', CLASS_PATTERN.test(row.attr('class') || ''));
101
+ dom.selfAndAll(scope, '.row').forEach(function(row) {
102
+ dom.toggleClass(row, 'ge-gutters', CLASS_PATTERN.test(row.getAttribute('class') || ''));
101
103
  });
102
104
  }
103
105
 
@@ -130,16 +132,19 @@ $.fn.gridEditor.utilities.gutters = function(ge) {
130
132
  ],
131
133
 
132
134
  onInit: function() {
133
- ge.canvas.off('grideditor:after-utility.ge-gutters').on('grideditor:after-utility.ge-gutters', afterUtility);
135
+ // init runs again whenever a node is added, without a deinit
136
+ // between, so the listener is replaced rather than stacked
137
+ if (listening) { ge.canvas.removeEventListener('grideditor:after-utility', listening); }
138
+ listening = afterUtility;
139
+ ge.canvas.addEventListener('grideditor:after-utility', listening);
134
140
  },
135
141
 
136
142
  onRefresh: mark,
137
143
 
138
144
  onDeinit: function() {
139
- ge.canvas.off('grideditor:after-utility.ge-gutters');
140
- ge.canvas.find('.ge-gutters').removeClass('ge-gutters');
145
+ if (listening) { ge.canvas.removeEventListener('grideditor:after-utility', listening); }
146
+ listening = null;
147
+ dom.all(ge.canvas, '.ge-gutters').forEach(function(row) { dom.removeClass(row, 'ge-gutters'); });
141
148
  },
142
149
  };
143
150
  };
144
-
145
- })(jQuery);
@@ -6,7 +6,7 @@
6
6
  * classes. What it can ask the editor for is the handle its factory is called
7
7
  * with, described in docs/plugins.md.
8
8
  *
9
- * <script src="dist/jquery.grideditor.min.js"></script>
9
+ * <script src="dist/grideditor.min.js"></script>
10
10
  * <script src="dist/plugins/grideditor.order.min.js"></script>
11
11
  *
12
12
  * Two arrows in each column's drawer move it one place earlier or later in
@@ -16,9 +16,10 @@
16
16
  * utilities.order.drawer: false leaves the arrows out, and the panel field is
17
17
  * the only control.
18
18
  */
19
- (function($) {
19
+ import { GridEditor } from '../grideditor.js';
20
+ import * as dom from '../dom.js';
20
21
 
21
- $.extend($.fn.gridEditor.locales.en, {
22
+ Object.assign(GridEditor.locales.en, {
22
23
  'utility.order': 'Order',
23
24
  'utility.order_first': 'First',
24
25
  'utility.order_last': 'Last',
@@ -35,10 +36,11 @@ var RANK = { first: -1, last: 6 };
35
36
  /** A column that carries any class of the family, at any breakpoint. */
36
37
  var CLASS_PATTERN = /(?:^|\s)order-(?:(?:sm|md|lg|xl|xxl)-)?(?:first|last|[0-5])(?:\s|$)/;
37
38
 
38
- $.fn.gridEditor.utilities.order = function(ge) {
39
+ GridEditor.utilities.order = function(ge) {
39
40
 
40
- var options = $.extend({ drawer: true }, ge.settings.utilities.order);
41
+ var options = Object.assign({ drawer: true }, ge.settings.utilities.order);
41
42
  var warnedAboutDrag = false;
43
+ var listening = null; // The after-move listener, while editing
42
44
 
43
45
  function rank(value) {
44
46
  if (value === null) { return 0; }
@@ -55,9 +57,9 @@ $.fn.gridEditor.utilities.order = function(ge) {
55
57
 
56
58
  /** The columns of a row in the order a view shows them, given what each one's order is. */
57
59
  function visualOrder(columns, read) {
58
- return columns.get()
60
+ return columns
59
61
  .map(function(element, index) {
60
- return { element: element, index: index, rank: rank(read($(element))) };
62
+ return { element: element, index: index, rank: rank(read(element)) };
61
63
  })
62
64
  .sort(function(a, b) { return a.rank - b.rank || a.index - b.index; })
63
65
  .map(function(entry) { return entry.element; });
@@ -89,9 +91,9 @@ $.fn.gridEditor.utilities.order = function(ge) {
89
91
  */
90
92
  function move(col, direction) {
91
93
  var view = ge.view();
92
- var columns = col.parent().children('.column');
94
+ var columns = dom.children(col.parentElement, '.column');
93
95
  var shown = visualOrder(columns, function(column) { return ge.getUtility(column, 'order', view); });
94
- var from = shown.indexOf(col[0]);
96
+ var from = shown.indexOf(col);
95
97
  var to = from + direction;
96
98
 
97
99
  if (to < 0 || to >= shown.length) { return; }
@@ -99,7 +101,7 @@ $.fn.gridEditor.utilities.order = function(ge) {
99
101
  shown.splice(to, 0, shown.splice(from, 1)[0]);
100
102
 
101
103
  var values = null;
102
- if (!sameOrder(shown, columns.get()) || !inheritsMarkupOrder(columns, view)) {
104
+ if (!sameOrder(shown, columns) || !inheritsMarkupOrder(columns, view)) {
103
105
  values = slots(shown.length);
104
106
 
105
107
  if (!values) {
@@ -111,7 +113,7 @@ $.fn.gridEditor.utilities.order = function(ge) {
111
113
 
112
114
  ge.operate(function() {
113
115
  shown.forEach(function(element, index) {
114
- ge.setUtility($(element), 'order', values ? values[index] : null, { source: 'tool' });
116
+ ge.setUtility(element, 'order', values ? values[index] : null, { source: 'tool' });
115
117
  });
116
118
  });
117
119
  }
@@ -125,28 +127,27 @@ $.fn.gridEditor.utilities.order = function(ge) {
125
127
 
126
128
  return sameOrder(visualOrder(columns, function(column) {
127
129
  return ge.getUtility(column, 'order', below);
128
- }), columns.get());
130
+ }), columns);
129
131
  }
130
132
 
131
133
  /** Whether a row's columns are ordered by class, rather than by the markup, in this view. */
132
134
  function ordered(row) {
133
- return row.children('.column').get().some(function(element) {
134
- return ge.getUtility($(element), 'order', ge.view()) !== null;
135
+ return dom.children(row, '.column').some(function(element) {
136
+ return ge.getUtility(element, 'order', ge.view()) !== null;
135
137
  });
136
138
  }
137
139
 
138
140
  /** The badge: a column ordered by class in this view says where. */
139
141
  function mark(scope) {
140
- scope.find('.column').addBack('.column').each(function() {
141
- var col = $(this);
142
- var value = CLASS_PATTERN.test(col.attr('class') || '')
142
+ dom.selfAndAll(scope, '.column').forEach(function(col) {
143
+ var value = CLASS_PATTERN.test(col.getAttribute('class') || '')
143
144
  ? ge.getUtility(col, 'order', ge.view())
144
145
  : null;
145
146
 
146
147
  if (value === null) {
147
- col.removeAttr('data-ge-order');
148
+ col.removeAttribute('data-ge-order');
148
149
  } else {
149
- col.attr('data-ge-order', ge.t('badge.order', { value: label(value) }));
150
+ col.setAttribute('data-ge-order', ge.t('badge.order', { value: label(value) }));
150
151
  }
151
152
  });
152
153
  }
@@ -155,7 +156,8 @@ $.fn.gridEditor.utilities.order = function(ge) {
155
156
  * A column dropped in a row ordered by class lands where the markup puts
156
157
  * it, and shows up where its order does, which is worth saying once.
157
158
  */
158
- function afterMove(e, payload) {
159
+ function afterMove(e) {
160
+ var payload = e.detail;
159
161
  if (warnedAboutDrag || payload.kind !== 'column' || !payload.to) { return; }
160
162
  if (!ordered(payload.to.parent)) { return; }
161
163
 
@@ -191,16 +193,17 @@ $.fn.gridEditor.utilities.order = function(ge) {
191
193
  // init runs again whenever a node is added, without a deinit
192
194
  // between, so the listener is replaced rather than stacked
193
195
  onInit: function() {
194
- ge.canvas.off('grideditor:after-move.ge-order').on('grideditor:after-move.ge-order', afterMove);
196
+ if (listening) { ge.canvas.removeEventListener('grideditor:after-move', listening); }
197
+ listening = afterMove;
198
+ ge.canvas.addEventListener('grideditor:after-move', listening);
195
199
  },
196
200
 
197
201
  onRefresh: mark,
198
202
 
199
203
  onDeinit: function() {
200
- ge.canvas.off('grideditor:after-move.ge-order');
201
- ge.canvas.find('[data-ge-order]').removeAttr('data-ge-order');
204
+ if (listening) { ge.canvas.removeEventListener('grideditor:after-move', listening); }
205
+ listening = null;
206
+ dom.all(ge.canvas, '[data-ge-order]').forEach(function(col) { col.removeAttribute('data-ge-order'); });
202
207
  },
203
208
  };
204
209
  };
205
-
206
- })(jQuery);
@@ -5,50 +5,61 @@
5
5
  * a popup: a bootstrap modal and its trigger. What it can ask the editor for is the handle its factory is
6
6
  * called with, described in docs/plugins.md.
7
7
  *
8
- * <script src="dist/jquery.grideditor.min.js"></script>
8
+ * <script src="dist/grideditor.min.js"></script>
9
9
  * <script src="dist/plugins/grideditor.popup.min.js"></script>
10
10
  */
11
- (function($) {
11
+ import { GridEditor } from '../grideditor.js';
12
+ import * as dom from '../dom.js';
12
13
 
13
- $.extend($.fn.gridEditor.locales.en, {
14
+ Object.assign(GridEditor.locales.en, {
14
15
  'container.add_popup': 'Popup',
15
16
  'container.popup_title': 'Title',
16
17
  'container.popup_trigger': 'Open',
17
18
  'tool.toggle_popup': 'Fold this popup away while editing',
18
19
  });
19
20
 
20
- $.fn.gridEditor.containers.popup = function(ge) {
21
+ GridEditor.containers.popup = function(ge) {
21
22
 
22
23
  function popupIdOf(container) {
23
- return container.attr('data-ge-popup-id');
24
+ return container.getAttribute('data-ge-popup-id');
25
+ }
26
+
27
+ /** Whether a popup with this id is on the canvas. */
28
+ function popupExists(id) {
29
+ return dom.all(ge.canvas, '[data-ge-popup-id]').some(function(popup) {
30
+ return popupIdOf(popup) === id;
31
+ });
24
32
  }
25
33
 
26
34
  function wirePopupTriggers() {
27
- ge.canvas.find('[data-ge-popup-target]').each(function() {
28
- var trigger = $(this).addClass('ge-popup-trigger');
29
- var wanted = trigger.attr('data-ge-popup-target');
35
+ dom.all(ge.canvas, '[data-ge-popup-target]').forEach(function(trigger) {
36
+ dom.addClass(trigger, 'ge-popup-trigger');
37
+ var wanted = trigger.getAttribute('data-ge-popup-target');
30
38
 
31
39
  // Bootstrap's own attributes are written at getHtml time, not
32
40
  // while editing, so a click here cannot open a real modal
33
- trigger.removeAttr('data-bs-toggle').removeAttr('data-bs-target');
41
+ trigger.removeAttribute('data-bs-toggle');
42
+ trigger.removeAttribute('data-bs-target');
34
43
 
35
- if (ge.canvas.find('[data-ge-popup-id="' + wanted + '"]').length) {
36
- trigger.removeClass('ge-popup-orphan');
44
+ if (popupExists(wanted)) {
45
+ dom.removeClass(trigger, 'ge-popup-orphan');
37
46
  return;
38
47
  }
39
48
 
40
- var nearby = trigger.closest('.column').find('[data-ge-popup-id]');
49
+ var column = trigger.closest('.column');
50
+ var nearby = column ? dom.all(column, '[data-ge-popup-id]') : [];
41
51
 
42
52
  if (nearby.length === 1) {
43
- trigger.attr('data-ge-popup-target', popupIdOf(nearby)).removeClass('ge-popup-orphan');
53
+ trigger.setAttribute('data-ge-popup-target', popupIdOf(nearby[0]));
54
+ dom.removeClass(trigger, 'ge-popup-orphan');
44
55
  return;
45
56
  }
46
57
 
47
- trigger.addClass('ge-popup-orphan');
58
+ dom.addClass(trigger, 'ge-popup-orphan');
48
59
 
49
60
  ge.operate(function() {
50
61
  ge.emit('popup-orphan', ge.payloadFor('popup', trigger, {
51
- parent: trigger.parent(),
62
+ parent: trigger.parentElement,
52
63
  source: 'api',
53
64
  missing: wanted,
54
65
  }));
@@ -57,18 +68,18 @@ $.fn.gridEditor.containers.popup = function(ge) {
57
68
  }
58
69
 
59
70
  function writePopupTriggerAttributes() {
60
- ge.canvas.find('[data-ge-popup-target]').each(function() {
61
- var trigger = $(this);
62
- var wanted = trigger.attr('data-ge-popup-target');
71
+ dom.all(ge.canvas, '[data-ge-popup-target]').forEach(function(trigger) {
72
+ var wanted = trigger.getAttribute('data-ge-popup-target');
63
73
 
64
74
  // The warning marking is editing furniture, whether or not
65
75
  // the trigger can be wired up
66
- trigger.removeClass('ge-popup-orphan');
67
- if (!trigger.attr('class')) { trigger.removeAttr('class'); }
76
+ dom.removeClass(trigger, 'ge-popup-orphan');
77
+ dom.dropEmptyClass(trigger);
68
78
 
69
- if (!ge.canvas.find('[data-ge-popup-id="' + wanted + '"]').length) { return; }
79
+ if (!popupExists(wanted)) { return; }
70
80
 
71
- trigger.attr('data-bs-toggle', 'modal').attr('data-bs-target', '#' + wanted);
81
+ trigger.setAttribute('data-bs-toggle', 'modal');
82
+ trigger.setAttribute('data-bs-target', '#' + wanted);
72
83
  });
73
84
  }
74
85
 
@@ -84,33 +95,32 @@ $.fn.gridEditor.containers.popup = function(ge) {
84
95
 
85
96
  create: function(options) {
86
97
  var id = ge.containerId('popup');
87
- var container = $('<div />')
88
- .attr('data-ge-container', 'popup')
89
- .attr('data-ge-popup-id', id)
90
- ;
98
+ var container = dom.element('div', { 'data-ge-container': 'popup', 'data-ge-popup-id': id });
91
99
 
92
100
  if (options.trigger !== false) {
93
- $('<button type="button" class="btn btn-primary ge-popup-trigger" />')
94
- .attr('data-ge-popup-target', id)
95
- .text(options.trigger_label || ge.t('container.popup_trigger'))
96
- .appendTo(container)
97
- ;
101
+ container.appendChild(dom.element('button', {
102
+ type: 'button',
103
+ 'class': 'btn btn-primary ge-popup-trigger',
104
+ 'data-ge-popup-target': id,
105
+ }, options.trigger_label || ge.t('container.popup_trigger')));
98
106
  }
99
107
 
100
- var dialog = $('<div class="modal-dialog" />');
101
- if (options.size) { dialog.addClass('modal-' + options.size); }
102
-
103
- $('<div class="modal fade" tabindex="-1" aria-hidden="true" />')
104
- .attr('id', id)
105
- .append(dialog.append($('<div class="modal-content" />')
106
- .append($('<div class="modal-header" />')
107
- .append($('<h5 class="modal-title" />')
108
- .append($('<span class="ge-pane-label" />')
109
- .text(options.title || ge.t('container.popup_title'))))
110
- .append('<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>'))
111
- .append($('<div class="modal-body" />').append(ge.defaultRegion()))))
112
- .appendTo(container)
113
- ;
108
+ var modal = container.appendChild(dom.element('div', {
109
+ 'class': 'modal fade',
110
+ tabindex: '-1',
111
+ 'aria-hidden': 'true',
112
+ id: id,
113
+ }));
114
+ var dialog = modal.appendChild(dom.element('div', { 'class': 'modal-dialog' }));
115
+ if (options.size) { dom.addClass(dialog, 'modal-' + options.size); }
116
+
117
+ var content = dialog.appendChild(dom.element('div', { 'class': 'modal-content' }));
118
+ var header = content.appendChild(dom.element('div', { 'class': 'modal-header' }));
119
+ header.appendChild(dom.element('h5', { 'class': 'modal-title' }))
120
+ .appendChild(dom.element('span', { 'class': 'ge-pane-label' },
121
+ options.title || ge.t('container.popup_title')));
122
+ header.appendChild(dom.create('<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>'));
123
+ content.appendChild(dom.element('div', { 'class': 'modal-body' })).appendChild(ge.defaultRegion());
114
124
 
115
125
  return container;
116
126
  },
@@ -120,13 +130,17 @@ $.fn.gridEditor.containers.popup = function(ge) {
120
130
  // the modal is rendered unfolded and static, and a real
121
131
  // modal opening over it would be the editor fighting
122
132
  // itself
123
- ge.suspendToggles(container.find('[data-bs-dismiss]'));
124
- ge.makeLabelEditable(ge.labelIn(container.find('.modal-title')));
133
+ dom.all(container, '[data-bs-dismiss]').forEach(function(dismiss) {
134
+ ge.suspendToggles(dismiss);
135
+ });
136
+ dom.all(container, '.modal-title').forEach(function(title) {
137
+ ge.makeLabelEditable(ge.labelIn(title));
138
+ });
125
139
  },
126
140
 
127
141
  unmark: function(container) {
128
142
  ge.resumeToggles(container);
129
- container.removeClass('ge-popup-collapsed');
143
+ dom.removeClass(container, 'ge-popup-collapsed');
130
144
  ge.unwrapLabels(container);
131
145
  },
132
146
 
@@ -134,10 +148,8 @@ $.fn.gridEditor.containers.popup = function(ge) {
134
148
  tools: function(drawer, container) {
135
149
  ge.createTool(drawer, ge.t('tool.toggle_popup'), 'ge-toggle-popup', 'bi bi-chevron-bar-contract',
136
150
  function() {
137
- container.toggleClass('ge-popup-collapsed');
151
+ dom.toggleClass(container, 'ge-popup-collapsed');
138
152
  });
139
153
  },
140
154
  };
141
155
  };
142
-
143
- })(jQuery);
@@ -6,7 +6,7 @@
6
6
  * each grouping rows at a width of its own. What it can ask the editor for is
7
7
  * the handle its factory is called with, described in docs/plugins.md.
8
8
  *
9
- * <script src="dist/jquery.grideditor.min.js"></script>
9
+ * <script src="dist/grideditor.min.js"></script>
10
10
  * <script src="dist/plugins/grideditor.sections.min.js"></script>
11
11
  *
12
12
  * Called sections, not containers, because a container is what the tabs,
@@ -16,9 +16,10 @@
16
16
  *
17
17
  * sections.widths narrows the widths the field offers.
18
18
  */
19
- (function($) {
19
+ import { GridEditor } from '../grideditor.js';
20
+ import * as dom from '../dom.js';
20
21
 
21
- $.extend($.fn.gridEditor.locales.en, {
22
+ Object.assign(GridEditor.locales.en, {
22
23
  'section.add': 'Section',
23
24
  'section.width': 'Width',
24
25
  'section.fixed': 'Fixed',
@@ -42,26 +43,26 @@ var WIDTHS = {
42
43
 
43
44
  var ORDER = ['fixed', 'sm', 'md', 'lg', 'xl', 'xxl', 'fluid'];
44
45
 
45
- $.fn.gridEditor.features.sections = function(ge) {
46
+ GridEditor.features.sections = function(ge) {
46
47
 
47
- var options = $.extend({ widths: ORDER }, ge.settings.sections);
48
+ var options = Object.assign({ widths: ORDER }, ge.settings.sections);
48
49
 
49
50
  function widthOf(section) {
50
51
  var found = null;
51
52
 
52
- $.each(WIDTHS, function(width, className) {
53
- if (!found && section.hasClass(className)) { found = width; }
53
+ Object.keys(WIDTHS).forEach(function(width) {
54
+ if (!found && dom.hasClass(section, WIDTHS[width])) { found = width; }
54
55
  });
55
56
 
56
57
  return found;
57
58
  }
58
59
 
59
60
  function isSection(node) {
60
- return node.parent()[0] === ge.canvas[0] && widthOf(node) !== null;
61
+ return node.parentElement === ge.canvas && widthOf(node) !== null;
61
62
  }
62
63
 
63
64
  function sections() {
64
- return ge.canvas.children().filter(function() { return isSection($(this)); });
65
+ return dom.children(ge.canvas).filter(isSection);
65
66
  }
66
67
 
67
68
  function label(width) {
@@ -90,11 +91,13 @@ $.fn.gridEditor.features.sections = function(ge) {
90
91
  });
91
92
 
92
93
  if (!ge.emit('before-utility', payload)) {
93
- ge.detailsOf(section).find('.ge-section-width select').val(from);
94
+ var select = dom.one(ge.detailsOf(section), '.ge-section-width select');
95
+ if (select) { select.value = from; }
94
96
  return false;
95
97
  }
96
98
 
97
- section.removeClass(WIDTHS[from]).addClass(WIDTHS[width]);
99
+ dom.removeClass(section, WIDTHS[from]);
100
+ dom.addClass(section, WIDTHS[width]);
98
101
  ge.emit('after-utility', payload);
99
102
 
100
103
  return true;
@@ -102,31 +105,35 @@ $.fn.gridEditor.features.sections = function(ge) {
102
105
  }
103
106
 
104
107
  function widthField(section) {
105
- var select = $('<select class="form-select form-select-sm" />');
108
+ var select = dom.element('select', { 'class': 'form-select form-select-sm' });
106
109
  var current = widthOf(section);
107
110
  var offered = options.widths.indexOf(current) === -1 ? options.widths.concat([current]) : options.widths;
108
111
 
109
112
  ORDER.forEach(function(width) {
110
113
  if (offered.indexOf(width) === -1) { return; }
111
- $('<option />').attr('value', width).text(label(width)).appendTo(select);
114
+ select.appendChild(dom.element('option', { value: width }, label(width)));
112
115
  });
113
116
 
114
- select.val(current).on('change', function() { setWidth(section, this.value, 'panel'); });
117
+ select.value = current;
118
+ select.addEventListener('change', function() { setWidth(section, this.value, 'panel'); });
115
119
 
116
- return $('<label class="ge-utility ge-section-width" />')
117
- .append($('<span class="ge-utility-label" />').text(ge.t('section.width')))
118
- .append(select);
120
+ var field = dom.element('label', { 'class': 'ge-utility ge-section-width' });
121
+ field.appendChild(dom.element('span', { 'class': 'ge-utility-label' }, ge.t('section.width')));
122
+ field.appendChild(select);
123
+
124
+ return field;
119
125
  }
120
126
 
121
127
  function createControls(section) {
122
- var drawer = $('<div class="ge-tools-drawer ge-section-drawer" />').prependTo(section);
128
+ var drawer = dom.element('div', { 'class': 'ge-tools-drawer ge-section-drawer' });
129
+ section.insertBefore(drawer, section.firstChild);
123
130
 
124
131
  ge.createMoveTool(drawer);
125
- ge.addSettingsTool(drawer, section, ge.settings.section_classes || []).append(widthField(section));
132
+ ge.addSettingsTool(drawer, section, ge.settings.section_classes || []).appendChild(widthField(section));
126
133
 
127
134
  ge.createTool(drawer, ge.t('tool.delete_section'), 'ge-delete-section', 'bi bi-trash', function() {
128
135
  ge.deleteNode('section', section, ge.t('confirm.delete_section'), function(removed) {
129
- section.slideUp(removed);
136
+ dom.slideUp(section, removed);
130
137
  });
131
138
  });
132
139
 
@@ -136,24 +143,26 @@ $.fn.gridEditor.features.sections = function(ge) {
136
143
  }
137
144
 
138
145
  function mark() {
139
- sections().each(function() {
140
- var section = $(this).addClass('ge-section');
141
- if (!section.children('.ge-tools-drawer').length) { createControls(section); }
146
+ sections().forEach(function(section) {
147
+ dom.addClass(section, 'ge-section');
148
+ if (!dom.child(section, '.ge-tools-drawer')) { createControls(section); }
142
149
  });
143
150
  }
144
151
 
145
152
  function unmark() {
146
- ge.canvas.children('.ge-section').removeClass('ge-section');
153
+ dom.children(ge.canvas, '.ge-section').forEach(function(section) {
154
+ dom.removeClass(section, 'ge-section');
155
+ });
147
156
  }
148
157
 
149
158
  /** createSection(options): a section, detached unless a placement is given. */
150
159
  function createSection(settings) {
151
160
  settings = settings || {};
152
161
 
153
- var section = $('<div />').addClass(WIDTHS[settings.width] || WIDTHS.fixed);
162
+ var section = dom.element('div', { 'class': WIDTHS[settings.width] || WIDTHS.fixed });
154
163
 
155
164
  (settings.rows || [[12]]).forEach(function(layout) {
156
- ge.rowFromLayout(layout).appendTo(section);
165
+ section.appendChild(ge.rowFromLayout(layout));
157
166
  });
158
167
 
159
168
  return ge.place(section, 'section', settings);
@@ -165,7 +174,7 @@ $.fn.gridEditor.features.sections = function(ge) {
165
174
  },
166
175
 
167
176
  kindOf: function(node) {
168
- return node.hasClass('ge-section') ? 'section' : null;
177
+ return dom.hasClass(node, 'ge-section') ? 'section' : null;
169
178
  },
170
179
 
171
180
  // A section is a block the canvas moves, and a region rows move in
@@ -174,8 +183,8 @@ $.fn.gridEditor.features.sections = function(ge) {
174
183
 
175
184
  /** A section goes on the canvas and nowhere else, and holds rows and nothing else. */
176
185
  accepts: function(region, node) {
177
- if (node.hasClass('ge-section') || isSectionMade(node)) { return region[0] === ge.canvas[0]; }
178
- if (region.hasClass('ge-section')) { return node.hasClass('row'); }
186
+ if (dom.hasClass(node, 'ge-section') || isSectionMade(node)) { return region === ge.canvas; }
187
+ if (dom.hasClass(region, 'ge-section')) { return dom.hasClass(node, 'row'); }
179
188
 
180
189
  return true;
181
190
  },
@@ -192,8 +201,6 @@ $.fn.gridEditor.features.sections = function(ge) {
192
201
 
193
202
  /** A section the toolbar just made, before init has marked it. */
194
203
  function isSectionMade(node) {
195
- return !node.parent().length && widthOf(node) !== null;
204
+ return !node.parentElement && widthOf(node) !== null;
196
205
  }
197
206
  };
198
-
199
- })(jQuery);