@themarioga/grid-editor 3.2.1 → 4.1.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.
- package/BUILDING.md +12 -3
- package/CHANGELOG.md +87 -0
- package/README.md +79 -7
- package/UPGRADING.md +79 -0
- package/dist/grideditor.css +188 -20
- package/dist/grideditor.min.css +1 -1
- package/dist/grideditor.min.css.map +1 -1
- package/dist/jquery.grideditor.bundle.min.js +10 -0
- package/dist/jquery.grideditor.js +924 -174
- package/dist/jquery.grideditor.min.js +1 -1
- package/dist/jquery.grideditor.min.js.map +1 -1
- package/dist/locales/grideditor.es.js +34 -0
- package/dist/locales/grideditor.es.min.js +1 -1
- package/dist/locales/grideditor.es.min.js.map +1 -1
- package/dist/plugins/grideditor.accordion.js +8 -0
- package/dist/plugins/grideditor.accordion.min.js +1 -1
- package/dist/plugins/grideditor.accordion.min.js.map +1 -1
- package/dist/plugins/grideditor.alignment.js +81 -0
- package/dist/plugins/grideditor.alignment.min.js +2 -0
- package/dist/plugins/grideditor.alignment.min.js.map +1 -0
- package/dist/plugins/grideditor.elements.js +5 -5
- package/dist/plugins/grideditor.elements.min.js +1 -1
- package/dist/plugins/grideditor.elements.min.js.map +1 -1
- package/dist/plugins/grideditor.gutters.js +145 -0
- package/dist/plugins/grideditor.gutters.min.js +2 -0
- package/dist/plugins/grideditor.gutters.min.js.map +1 -0
- package/dist/plugins/grideditor.order.js +206 -0
- package/dist/plugins/grideditor.order.min.js +2 -0
- package/dist/plugins/grideditor.order.min.js.map +1 -0
- package/dist/plugins/grideditor.spacing.js +299 -0
- package/dist/plugins/grideditor.spacing.min.js +2 -0
- package/dist/plugins/grideditor.spacing.min.js.map +1 -0
- package/dist/plugins/grideditor.tabs.js +8 -0
- package/dist/plugins/grideditor.tabs.min.js +1 -1
- package/dist/plugins/grideditor.tabs.min.js.map +1 -1
- package/dist/plugins/grideditor.visibility.js +172 -0
- package/dist/plugins/grideditor.visibility.min.js +2 -0
- package/dist/plugins/grideditor.visibility.min.js.map +1 -0
- package/docs/events.md +26 -8
- package/docs/locale-keys.md +54 -0
- package/docs/plugins.md +129 -10
- package/example/autosave.html +6 -1
- package/example/basic.html +8 -2
- package/example/breakpoints.html +6 -1
- package/example/ckeditor.html +6 -1
- package/example/containers.html +5 -1
- package/example/elements.html +6 -1
- package/example/index.html +24 -1
- package/example/locale.html +6 -1
- package/example/plugins.html +6 -1
- package/example/summernote.html +6 -1
- package/example/utilities.html +145 -0
- package/example/wrap_content.html +6 -1
- package/package.json +3 -2
- package/src/js/jquery.grideditor.js +924 -174
- package/src/js/locales/grideditor.es.js +34 -0
- package/src/js/plugins/grideditor.accordion.js +8 -0
- package/src/js/plugins/grideditor.alignment.js +81 -0
- package/src/js/plugins/grideditor.elements.js +5 -5
- package/src/js/plugins/grideditor.gutters.js +145 -0
- package/src/js/plugins/grideditor.order.js +206 -0
- package/src/js/plugins/grideditor.spacing.js +299 -0
- package/src/js/plugins/grideditor.tabs.js +8 -0
- package/src/js/plugins/grideditor.visibility.js +172 -0
- package/src/less/grideditor.less +210 -18
|
@@ -69,6 +69,40 @@
|
|
|
69
69
|
'view.lg': 'Escritorio',
|
|
70
70
|
'view.xl': 'Escritorio grande',
|
|
71
71
|
'view.xxl': 'Pantalla panorámica',
|
|
72
|
+
'utility.section': 'Responsive: {view}',
|
|
73
|
+
'utility.default': 'Por defecto',
|
|
74
|
+
'utility.inherit': 'Hereda: {value} (de {breakpoint})',
|
|
75
|
+
'utility.varies': 'Cambia en {breakpoints}; elegir aquí lo sustituye',
|
|
76
|
+
'utility.visibility': 'Visibilidad',
|
|
77
|
+
'utility.visibility_hidden': 'Oculto',
|
|
78
|
+
'utility.visibility_shown': 'Visible',
|
|
79
|
+
'tool.hide_in_view': 'Ocultar en esta vista',
|
|
80
|
+
'tool.show_in_view': 'Mostrar en esta vista',
|
|
81
|
+
'badge.hidden_in': 'Oculto en {breakpoints}',
|
|
82
|
+
'utility.order': 'Orden',
|
|
83
|
+
'utility.order_first': 'Primero',
|
|
84
|
+
'utility.order_last': 'Último',
|
|
85
|
+
'tool.order_earlier': 'Antes en esta vista',
|
|
86
|
+
'tool.order_later': 'Después en esta vista',
|
|
87
|
+
'badge.order': 'Orden: {value}',
|
|
88
|
+
'utility.justify_content': 'Justificar columnas',
|
|
89
|
+
'utility.align_items': 'Alinear columnas',
|
|
90
|
+
'utility.align_self': 'Alinearse',
|
|
91
|
+
'utility.gutters': 'Espaciado entre columnas',
|
|
92
|
+
'utility.gutters_x': 'Espaciado horizontal',
|
|
93
|
+
'utility.gutters_y': 'Espaciado vertical',
|
|
94
|
+
'utility.padding': 'Relleno',
|
|
95
|
+
'utility.margin': 'Margen',
|
|
96
|
+
'utility.side_all': 'Todos los lados',
|
|
97
|
+
'utility.side_x': 'Izquierda y derecha',
|
|
98
|
+
'utility.side_y': 'Arriba y abajo',
|
|
99
|
+
'utility.side_t': 'Arriba',
|
|
100
|
+
'utility.side_b': 'Abajo',
|
|
101
|
+
'utility.side_s': 'Inicio',
|
|
102
|
+
'utility.side_e': 'Fin',
|
|
103
|
+
'utility.spacing_gutter': 'El relleno lateral de una columna es su espaciado: cambiarlo cambia el espacio entre columnas',
|
|
104
|
+
'error.sortable_missing': '¡SortableJS no está disponible! Asegúrate de haber cargado el archivo js de Sortable; sin él no se puede arrastrar.',
|
|
105
|
+
'warning.setting_removed': 'El ajuste {setting} se eliminó en la 4.0. Usa {replacement} en su lugar.',
|
|
72
106
|
'error.tinymce_missing': '¡tinyMCE no está disponible! Asegúrate de haber cargado el archivo js de tinyMCE.',
|
|
73
107
|
'error.ckeditor_missing': '¡CKEditor no está disponible! Asegúrate de haber cargado los archivos js de ckeditor y del adaptador de jQuery.',
|
|
74
108
|
'error.summernote_missing': '¡Summernote no está disponible! Asegúrate de haber cargado el archivo js de Summernote.',
|
|
@@ -99,6 +99,14 @@ $.fn.gridEditor.containers.accordion = function(ge) {
|
|
|
99
99
|
|
|
100
100
|
return {
|
|
101
101
|
labelKey: 'container.add_accordion',
|
|
102
|
+
|
|
103
|
+
// Items sort within their accordion and into any other one
|
|
104
|
+
onSortable: function(sortable) {
|
|
105
|
+
sortable(ge.canvas.find('.ge-container-accordion > .accordion'), {
|
|
106
|
+
draggable: '.ge-accordion-item',
|
|
107
|
+
group: 'accordion',
|
|
108
|
+
});
|
|
109
|
+
},
|
|
102
110
|
addPaneKey: 'container.add_accordion_item',
|
|
103
111
|
paneKind: 'accordion-item',
|
|
104
112
|
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alignment for grid-editor.
|
|
3
|
+
*
|
|
4
|
+
* A utility plugin: load this file after the editor and a row's columns can be
|
|
5
|
+
* justified and aligned per breakpoint, and a column can align itself, with
|
|
6
|
+
* Bootstrap's justify-content-{breakpoint}-*, align-items-{breakpoint}-* and
|
|
7
|
+
* align-self-{breakpoint}-* classes. What it can ask the editor for is the
|
|
8
|
+
* handle its factory is called with, described in docs/plugins.md.
|
|
9
|
+
*
|
|
10
|
+
* <script src="dist/jquery.grideditor.min.js"></script>
|
|
11
|
+
* <script src="dist/plugins/grideditor.alignment.min.js"></script>
|
|
12
|
+
*
|
|
13
|
+
* Fields only, in the settings panels: alignment is set now and then, not
|
|
14
|
+
* clicked through, and a drawer is short of room.
|
|
15
|
+
*/
|
|
16
|
+
(function($) {
|
|
17
|
+
|
|
18
|
+
$.extend($.fn.gridEditor.locales.en, {
|
|
19
|
+
'utility.justify_content': 'Justify columns',
|
|
20
|
+
'utility.align_items': 'Align columns',
|
|
21
|
+
'utility.align_self': 'Align self',
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
/** What Bootstrap's value names come to in css. */
|
|
25
|
+
var FLEX = {
|
|
26
|
+
start: 'flex-start',
|
|
27
|
+
end: 'flex-end',
|
|
28
|
+
center: 'center',
|
|
29
|
+
between: 'space-between',
|
|
30
|
+
around: 'space-around',
|
|
31
|
+
evenly: 'space-evenly',
|
|
32
|
+
baseline: 'baseline',
|
|
33
|
+
stretch: 'stretch',
|
|
34
|
+
auto: 'auto',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A family whose preview is its one css property. `none` is what the
|
|
39
|
+
* property is when no class says anything, which a view has to show over a
|
|
40
|
+
* wider breakpoint's class that is live in a wide window.
|
|
41
|
+
*/
|
|
42
|
+
function family(definition) {
|
|
43
|
+
return $.extend({
|
|
44
|
+
prefix: definition.name,
|
|
45
|
+
preview: function(value) {
|
|
46
|
+
var styles = {};
|
|
47
|
+
styles[definition.name] = value === null ? definition.none : FLEX[value];
|
|
48
|
+
return styles;
|
|
49
|
+
},
|
|
50
|
+
}, definition);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
$.fn.gridEditor.utilities.alignment = function() {
|
|
54
|
+
return {
|
|
55
|
+
families: [
|
|
56
|
+
family({
|
|
57
|
+
name: 'justify-content',
|
|
58
|
+
labelKey: 'utility.justify_content',
|
|
59
|
+
values: ['start', 'center', 'end', 'between', 'around', 'evenly'],
|
|
60
|
+
appliesTo: ['row'],
|
|
61
|
+
none: 'normal',
|
|
62
|
+
}),
|
|
63
|
+
family({
|
|
64
|
+
name: 'align-items',
|
|
65
|
+
labelKey: 'utility.align_items',
|
|
66
|
+
values: ['start', 'center', 'end', 'baseline', 'stretch'],
|
|
67
|
+
appliesTo: ['row'],
|
|
68
|
+
none: 'normal',
|
|
69
|
+
}),
|
|
70
|
+
family({
|
|
71
|
+
name: 'align-self',
|
|
72
|
+
labelKey: 'utility.align_self',
|
|
73
|
+
values: ['auto', 'start', 'center', 'end', 'baseline', 'stretch'],
|
|
74
|
+
appliesTo: ['column'],
|
|
75
|
+
none: 'auto',
|
|
76
|
+
}),
|
|
77
|
+
],
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
})(jQuery);
|
|
@@ -127,13 +127,13 @@ $.fn.gridEditor.features.elements = function(ge) {
|
|
|
127
127
|
onContentReady: markElements,
|
|
128
128
|
|
|
129
129
|
/** Elements move within a content area and between them. */
|
|
130
|
-
onSortable: function(
|
|
130
|
+
onSortable: function(sortable) {
|
|
131
131
|
if (!elementsEnabled()) { return; }
|
|
132
132
|
|
|
133
|
-
ge.canvas.find('.ge-content')
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
133
|
+
sortable(ge.canvas.find('.ge-content'), {
|
|
134
|
+
draggable: '.ge-element',
|
|
135
|
+
group: 'element',
|
|
136
|
+
});
|
|
137
137
|
},
|
|
138
138
|
};
|
|
139
139
|
};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gutters for grid-editor.
|
|
3
|
+
*
|
|
4
|
+
* A utility plugin: load this file after the editor and a row's gutters can
|
|
5
|
+
* differ per breakpoint, with Bootstrap's g-{breakpoint}-*, gx-{breakpoint}-*
|
|
6
|
+
* and gy-{breakpoint}-* classes. What it can ask the editor for is the handle
|
|
7
|
+
* its factory is called with, described in docs/plugins.md.
|
|
8
|
+
*
|
|
9
|
+
* <script src="dist/jquery.grideditor.min.js"></script>
|
|
10
|
+
* <script src="dist/plugins/grideditor.gutters.min.js"></script>
|
|
11
|
+
*
|
|
12
|
+
* The editor draws its own frame round every column, narrower than any
|
|
13
|
+
* gutter, so a row with gutter classes is drawn with its real gutters instead.
|
|
14
|
+
*
|
|
15
|
+
* utilities.gutters.scale is what 0 to 5 come to, for a page that changed
|
|
16
|
+
* Bootstrap's $spacers.
|
|
17
|
+
*/
|
|
18
|
+
(function($) {
|
|
19
|
+
|
|
20
|
+
$.extend($.fn.gridEditor.locales.en, {
|
|
21
|
+
'utility.gutters': 'Gutters',
|
|
22
|
+
'utility.gutters_x': 'Horizontal gutters',
|
|
23
|
+
'utility.gutters_y': 'Vertical gutters',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
var VALUES = ['0', '1', '2', '3', '4', '5'];
|
|
27
|
+
|
|
28
|
+
/** Bootstrap's own: $spacers, and what a row's gutters are with no class. */
|
|
29
|
+
var SCALE = ['0', '.25rem', '.5rem', '1rem', '1.5rem', '3rem'];
|
|
30
|
+
var DEFAULT_X = '1.5rem';
|
|
31
|
+
var DEFAULT_Y = '0';
|
|
32
|
+
|
|
33
|
+
var INFIXES = ['', 'sm', 'md', 'lg', 'xl', 'xxl'];
|
|
34
|
+
var CLASS_PATTERN = /(?:^|\s)g[xy]?-(?:(?:sm|md|lg|xl|xxl)-)?[0-5](?:\s|$)/;
|
|
35
|
+
|
|
36
|
+
$.fn.gridEditor.utilities.gutters = function(ge) {
|
|
37
|
+
|
|
38
|
+
var options = $.extend({ scale: SCALE }, ge.settings.utilities.gutters);
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The class of a family that decides a row's gutters at a breakpoint:
|
|
42
|
+
* the widest breakpoint up to it that has one, as { tier, value }.
|
|
43
|
+
*/
|
|
44
|
+
function source(row, prefix, tier) {
|
|
45
|
+
var classes = (row.attr('class') || '').split(/\s+/);
|
|
46
|
+
|
|
47
|
+
for (var i = tier; i >= 0; i--) {
|
|
48
|
+
for (var value = VALUES.length - 1; value >= 0; value--) {
|
|
49
|
+
var name = prefix + (INFIXES[i] ? '-' + INFIXES[i] : '') + '-' + value;
|
|
50
|
+
if (classes.indexOf(name) !== -1) { return { tier: i, value: value }; }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* One axis the way Bootstrap's css settles it. g and gx (or gy) set the
|
|
59
|
+
* same variable, every breakpoint's rules come after the smaller ones',
|
|
60
|
+
* and within a breakpoint the bigger values come later. So the class
|
|
61
|
+
* that wins is the one from the wider breakpoint, then the bigger one -
|
|
62
|
+
* not the more specific family, whatever that would suggest.
|
|
63
|
+
*/
|
|
64
|
+
function axis(row, prefix, fallback) {
|
|
65
|
+
var tier = ge.breakpoints.indexOf(ge.view());
|
|
66
|
+
var winner = [source(row, 'g', tier), source(row, prefix, tier)]
|
|
67
|
+
.filter(Boolean)
|
|
68
|
+
.sort(function(a, b) { return b.tier - a.tier || b.value - a.value; })[0];
|
|
69
|
+
|
|
70
|
+
return winner ? options.scale[winner.value] : fallback;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function preview(axes) {
|
|
74
|
+
return function(value, row) {
|
|
75
|
+
var styles = {};
|
|
76
|
+
|
|
77
|
+
if (axes.indexOf('x') !== -1) { styles['--bs-gutter-x'] = axis(row, 'gx', DEFAULT_X); }
|
|
78
|
+
if (axes.indexOf('y') !== -1) { styles['--bs-gutter-y'] = axis(row, 'gy', DEFAULT_Y); }
|
|
79
|
+
|
|
80
|
+
return styles;
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Choosing g sets both axes, so a gx or gy the same breakpoint had is
|
|
86
|
+
* taken off: left on, the bigger of the two would win, and the field the
|
|
87
|
+
* user just chose would not be what the row shows.
|
|
88
|
+
*/
|
|
89
|
+
function afterUtility(e, payload) {
|
|
90
|
+
if (payload.family !== 'g') { return; }
|
|
91
|
+
|
|
92
|
+
['gx', 'gy'].forEach(function(family) {
|
|
93
|
+
ge.setUtility(payload.node, family, null, { view: payload.breakpoint, source: payload.source });
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
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
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
families: [
|
|
106
|
+
{
|
|
107
|
+
name: 'g',
|
|
108
|
+
prefix: 'g',
|
|
109
|
+
values: VALUES,
|
|
110
|
+
appliesTo: ['row'],
|
|
111
|
+
labelKey: 'utility.gutters',
|
|
112
|
+
preview: preview(['x', 'y']),
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: 'gx',
|
|
116
|
+
prefix: 'gx',
|
|
117
|
+
values: VALUES,
|
|
118
|
+
appliesTo: ['row'],
|
|
119
|
+
labelKey: 'utility.gutters_x',
|
|
120
|
+
preview: preview(['x']),
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: 'gy',
|
|
124
|
+
prefix: 'gy',
|
|
125
|
+
values: VALUES,
|
|
126
|
+
appliesTo: ['row'],
|
|
127
|
+
labelKey: 'utility.gutters_y',
|
|
128
|
+
preview: preview(['y']),
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
|
|
132
|
+
onInit: function() {
|
|
133
|
+
ge.canvas.off('grideditor:after-utility.ge-gutters').on('grideditor:after-utility.ge-gutters', afterUtility);
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
onRefresh: mark,
|
|
137
|
+
|
|
138
|
+
onDeinit: function() {
|
|
139
|
+
ge.canvas.off('grideditor:after-utility.ge-gutters');
|
|
140
|
+
ge.canvas.find('.ge-gutters').removeClass('ge-gutters');
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
})(jQuery);
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Column order for grid-editor.
|
|
3
|
+
*
|
|
4
|
+
* A utility plugin: load this file after the editor and a column's place in
|
|
5
|
+
* its row can differ per breakpoint, with Bootstrap's order-{breakpoint}-*
|
|
6
|
+
* classes. What it can ask the editor for is the handle its factory is called
|
|
7
|
+
* with, described in docs/plugins.md.
|
|
8
|
+
*
|
|
9
|
+
* <script src="dist/jquery.grideditor.min.js"></script>
|
|
10
|
+
* <script src="dist/plugins/grideditor.order.min.js"></script>
|
|
11
|
+
*
|
|
12
|
+
* Two arrows in each column's drawer move it one place earlier or later in
|
|
13
|
+
* the view being edited, by numbering the row's columns; the markup does not
|
|
14
|
+
* move. Dragging still moves the markup, as it always has.
|
|
15
|
+
*
|
|
16
|
+
* utilities.order.drawer: false leaves the arrows out, and the panel field is
|
|
17
|
+
* the only control.
|
|
18
|
+
*/
|
|
19
|
+
(function($) {
|
|
20
|
+
|
|
21
|
+
$.extend($.fn.gridEditor.locales.en, {
|
|
22
|
+
'utility.order': 'Order',
|
|
23
|
+
'utility.order_first': 'First',
|
|
24
|
+
'utility.order_last': 'Last',
|
|
25
|
+
'tool.order_earlier': 'Earlier in this view',
|
|
26
|
+
'tool.order_later': 'Later in this view',
|
|
27
|
+
'badge.order': 'Order: {value}',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
var VALUES = ['first', '0', '1', '2', '3', '4', '5', 'last'];
|
|
31
|
+
|
|
32
|
+
/** Where each value puts a column, as Bootstrap's css has it. */
|
|
33
|
+
var RANK = { first: -1, last: 6 };
|
|
34
|
+
|
|
35
|
+
/** A column that carries any class of the family, at any breakpoint. */
|
|
36
|
+
var CLASS_PATTERN = /(?:^|\s)order-(?:(?:sm|md|lg|xl|xxl)-)?(?:first|last|[0-5])(?:\s|$)/;
|
|
37
|
+
|
|
38
|
+
$.fn.gridEditor.utilities.order = function(ge) {
|
|
39
|
+
|
|
40
|
+
var options = $.extend({ drawer: true }, ge.settings.utilities.order);
|
|
41
|
+
var warnedAboutDrag = false;
|
|
42
|
+
|
|
43
|
+
function rank(value) {
|
|
44
|
+
if (value === null) { return 0; }
|
|
45
|
+
|
|
46
|
+
return RANK[value] !== undefined ? RANK[value] : parseInt(value, 10);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function label(value) {
|
|
50
|
+
if (value === 'first') { return ge.t('utility.order_first'); }
|
|
51
|
+
if (value === 'last') { return ge.t('utility.order_last'); }
|
|
52
|
+
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The columns of a row in the order a view shows them, given what each one's order is. */
|
|
57
|
+
function visualOrder(columns, read) {
|
|
58
|
+
return columns.get()
|
|
59
|
+
.map(function(element, index) {
|
|
60
|
+
return { element: element, index: index, rank: rank(read($(element))) };
|
|
61
|
+
})
|
|
62
|
+
.sort(function(a, b) { return a.rank - b.rank || a.index - b.index; })
|
|
63
|
+
.map(function(entry) { return entry.element; });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function sameOrder(a, b) {
|
|
67
|
+
return a.every(function(element, index) { return element === b[index]; });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The values that put n columns in n places, or null past eight: that
|
|
72
|
+
* is how many places Bootstrap's order classes have.
|
|
73
|
+
*/
|
|
74
|
+
function slots(count) {
|
|
75
|
+
if (count <= 6) { return VALUES.slice(1, 1 + count); }
|
|
76
|
+
if (count === 7) { return VALUES.slice(1); }
|
|
77
|
+
if (count === 8) { return VALUES.slice(); }
|
|
78
|
+
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Move a column one place earlier or later in the view being edited.
|
|
84
|
+
*
|
|
85
|
+
* The row's columns are numbered in their new order. When that order is
|
|
86
|
+
* the markup's own, the numbers are taken off instead - unless what is
|
|
87
|
+
* left underneath, the breakpoint below, would then order them some other
|
|
88
|
+
* way, and the numbers are what keep them in the markup's order.
|
|
89
|
+
*/
|
|
90
|
+
function move(col, direction) {
|
|
91
|
+
var view = ge.view();
|
|
92
|
+
var columns = col.parent().children('.column');
|
|
93
|
+
var shown = visualOrder(columns, function(column) { return ge.getUtility(column, 'order', view); });
|
|
94
|
+
var from = shown.indexOf(col[0]);
|
|
95
|
+
var to = from + direction;
|
|
96
|
+
|
|
97
|
+
if (to < 0 || to >= shown.length) { return; }
|
|
98
|
+
|
|
99
|
+
shown.splice(to, 0, shown.splice(from, 1)[0]);
|
|
100
|
+
|
|
101
|
+
var values = null;
|
|
102
|
+
if (!sameOrder(shown, columns.get()) || !inheritsMarkupOrder(columns, view)) {
|
|
103
|
+
values = slots(shown.length);
|
|
104
|
+
|
|
105
|
+
if (!values) {
|
|
106
|
+
ge.warn('a row of ' + shown.length + ' columns cannot be reordered with Bootstrap\'s ' +
|
|
107
|
+
'order classes, which have eight places');
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
ge.operate(function() {
|
|
113
|
+
shown.forEach(function(element, index) {
|
|
114
|
+
ge.setUtility($(element), 'order', values ? values[index] : null, { source: 'tool' });
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Whether taking this view's classes off leaves the columns in the markup's order. */
|
|
120
|
+
function inheritsMarkupOrder(columns, view) {
|
|
121
|
+
var index = ge.breakpoints.indexOf(view);
|
|
122
|
+
if (index <= 0) { return true; }
|
|
123
|
+
|
|
124
|
+
var below = ge.breakpoints[index - 1];
|
|
125
|
+
|
|
126
|
+
return sameOrder(visualOrder(columns, function(column) {
|
|
127
|
+
return ge.getUtility(column, 'order', below);
|
|
128
|
+
}), columns.get());
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Whether a row's columns are ordered by class, rather than by the markup, in this view. */
|
|
132
|
+
function ordered(row) {
|
|
133
|
+
return row.children('.column').get().some(function(element) {
|
|
134
|
+
return ge.getUtility($(element), 'order', ge.view()) !== null;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** The badge: a column ordered by class in this view says where. */
|
|
139
|
+
function mark(scope) {
|
|
140
|
+
scope.find('.column').addBack('.column').each(function() {
|
|
141
|
+
var col = $(this);
|
|
142
|
+
var value = CLASS_PATTERN.test(col.attr('class') || '')
|
|
143
|
+
? ge.getUtility(col, 'order', ge.view())
|
|
144
|
+
: null;
|
|
145
|
+
|
|
146
|
+
if (value === null) {
|
|
147
|
+
col.removeAttr('data-ge-order');
|
|
148
|
+
} else {
|
|
149
|
+
col.attr('data-ge-order', ge.t('badge.order', { value: label(value) }));
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* A column dropped in a row ordered by class lands where the markup puts
|
|
156
|
+
* it, and shows up where its order does, which is worth saying once.
|
|
157
|
+
*/
|
|
158
|
+
function afterMove(e, payload) {
|
|
159
|
+
if (warnedAboutDrag || payload.kind !== 'column' || !payload.to) { return; }
|
|
160
|
+
if (!ordered(payload.to.parent)) { return; }
|
|
161
|
+
|
|
162
|
+
warnedAboutDrag = true;
|
|
163
|
+
ge.warn('a column was dropped in a row whose columns carry order classes in this view: ' +
|
|
164
|
+
'where it shows is set by those classes, not by where it sits in the markup');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
families: [{
|
|
169
|
+
name: 'order',
|
|
170
|
+
prefix: 'order',
|
|
171
|
+
values: VALUES,
|
|
172
|
+
appliesTo: ['column'],
|
|
173
|
+
labelKey: 'utility.order',
|
|
174
|
+
label: label,
|
|
175
|
+
preview: function(value) {
|
|
176
|
+
return { order: rank(value) };
|
|
177
|
+
},
|
|
178
|
+
}],
|
|
179
|
+
|
|
180
|
+
drawerTools: function(drawer, node, kind) {
|
|
181
|
+
if (!options.drawer || kind !== 'column') { return; }
|
|
182
|
+
|
|
183
|
+
ge.createTool(drawer, ge.t('tool.order_earlier'), 'ge-order-earlier', 'bi bi-chevron-left', function() {
|
|
184
|
+
move(node, -1);
|
|
185
|
+
});
|
|
186
|
+
ge.createTool(drawer, ge.t('tool.order_later'), 'ge-order-later', 'bi bi-chevron-right', function() {
|
|
187
|
+
move(node, 1);
|
|
188
|
+
});
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
// init runs again whenever a node is added, without a deinit
|
|
192
|
+
// between, so the listener is replaced rather than stacked
|
|
193
|
+
onInit: function() {
|
|
194
|
+
ge.canvas.off('grideditor:after-move.ge-order').on('grideditor:after-move.ge-order', afterMove);
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
onRefresh: mark,
|
|
198
|
+
|
|
199
|
+
onDeinit: function() {
|
|
200
|
+
ge.canvas.off('grideditor:after-move.ge-order');
|
|
201
|
+
ge.canvas.find('[data-ge-order]').removeAttr('data-ge-order');
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
})(jQuery);
|