@themarioga/grid-editor 3.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.
Files changed (52) hide show
  1. package/AUTO_SAVE.md +30 -0
  2. package/BUILDING.md +68 -0
  3. package/CHANGELOG.md +362 -0
  4. package/LICENSE +23 -0
  5. package/README.md +521 -0
  6. package/UPGRADING.md +88 -0
  7. package/dist/grideditor.css +3875 -0
  8. package/dist/grideditor.min.css +2 -0
  9. package/dist/grideditor.min.css.map +1 -0
  10. package/dist/jquery.grideditor.js +2996 -0
  11. package/dist/jquery.grideditor.min.js +2 -0
  12. package/dist/jquery.grideditor.min.js.map +1 -0
  13. package/dist/locales/grideditor.es.js +74 -0
  14. package/dist/locales/grideditor.es.min.js +2 -0
  15. package/dist/locales/grideditor.es.min.js.map +1 -0
  16. package/dist/plugins/grideditor.accordion.js +185 -0
  17. package/dist/plugins/grideditor.accordion.min.js +2 -0
  18. package/dist/plugins/grideditor.accordion.min.js.map +1 -0
  19. package/dist/plugins/grideditor.elements.js +141 -0
  20. package/dist/plugins/grideditor.elements.min.js +2 -0
  21. package/dist/plugins/grideditor.elements.min.js.map +1 -0
  22. package/dist/plugins/grideditor.popup.js +143 -0
  23. package/dist/plugins/grideditor.popup.min.js +2 -0
  24. package/dist/plugins/grideditor.popup.min.js.map +1 -0
  25. package/dist/plugins/grideditor.tabs.js +140 -0
  26. package/dist/plugins/grideditor.tabs.min.js +2 -0
  27. package/dist/plugins/grideditor.tabs.min.js.map +1 -0
  28. package/docs/events.md +158 -0
  29. package/docs/locale-keys.md +140 -0
  30. package/docs/plugins.md +163 -0
  31. package/example/autosave.html +89 -0
  32. package/example/basic.html +93 -0
  33. package/example/breakpoints.html +94 -0
  34. package/example/ckeditor.html +104 -0
  35. package/example/containers.html +214 -0
  36. package/example/elements.html +147 -0
  37. package/example/index.html +119 -0
  38. package/example/locale.html +84 -0
  39. package/example/plugins.html +217 -0
  40. package/example/summernote.html +106 -0
  41. package/example/wrap_content.html +44 -0
  42. package/package.json +66 -0
  43. package/src/js/jquery.grideditor.ckeditor.js +77 -0
  44. package/src/js/jquery.grideditor.js +2711 -0
  45. package/src/js/jquery.grideditor.summernote.js +72 -0
  46. package/src/js/jquery.grideditor.tinymce.js +135 -0
  47. package/src/js/locales/grideditor.es.js +74 -0
  48. package/src/js/plugins/grideditor.accordion.js +185 -0
  49. package/src/js/plugins/grideditor.elements.js +141 -0
  50. package/src/js/plugins/grideditor.popup.js +143 -0
  51. package/src/js/plugins/grideditor.tabs.js +140 -0
  52. package/src/less/grideditor.less +594 -0
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Popups for grid-editor.
3
+ *
4
+ * A container plugin: load this file after the editor and the toolbar offers
5
+ * a popup: a bootstrap modal and its trigger. What it can ask the editor for is the handle its factory is
6
+ * called with, described in docs/plugins.md.
7
+ *
8
+ * <script src="dist/jquery.grideditor.min.js"></script>
9
+ * <script src="dist/plugins/grideditor.popup.min.js"></script>
10
+ */
11
+ (function($) {
12
+
13
+ $.extend($.fn.gridEditor.locales.en, {
14
+ 'container.add_popup': 'Popup',
15
+ 'container.popup_title': 'Title',
16
+ 'container.popup_trigger': 'Open',
17
+ 'tool.toggle_popup': 'Fold this popup away while editing',
18
+ });
19
+
20
+ $.fn.gridEditor.containers.popup = function(ge) {
21
+
22
+ function popupIdOf(container) {
23
+ return container.attr('data-ge-popup-id');
24
+ }
25
+
26
+ 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');
30
+
31
+ // Bootstrap's own attributes are written at getHtml time, not
32
+ // while editing, so a click here cannot open a real modal
33
+ trigger.removeAttr('data-bs-toggle').removeAttr('data-bs-target');
34
+
35
+ if (ge.canvas.find('[data-ge-popup-id="' + wanted + '"]').length) {
36
+ trigger.removeClass('ge-popup-orphan');
37
+ return;
38
+ }
39
+
40
+ var nearby = trigger.closest('.column').find('[data-ge-popup-id]');
41
+
42
+ if (nearby.length === 1) {
43
+ trigger.attr('data-ge-popup-target', popupIdOf(nearby)).removeClass('ge-popup-orphan');
44
+ return;
45
+ }
46
+
47
+ trigger.addClass('ge-popup-orphan');
48
+
49
+ ge.operate(function() {
50
+ ge.emit('popup-orphan', ge.payloadFor('popup', trigger, {
51
+ parent: trigger.parent(),
52
+ source: 'api',
53
+ missing: wanted,
54
+ }));
55
+ });
56
+ });
57
+ }
58
+
59
+ 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');
63
+
64
+ // The warning marking is editing furniture, whether or not
65
+ // the trigger can be wired up
66
+ trigger.removeClass('ge-popup-orphan');
67
+ if (!trigger.attr('class')) { trigger.removeAttr('class'); }
68
+
69
+ if (!ge.canvas.find('[data-ge-popup-id="' + wanted + '"]').length) { return; }
70
+
71
+ trigger.attr('data-bs-toggle', 'modal').attr('data-bs-target', '#' + wanted);
72
+ });
73
+ }
74
+
75
+ return {
76
+ labelKey: 'container.add_popup',
77
+ paneKind: 'popup',
78
+
79
+ // Triggers are markup the host owns, anywhere in the canvas, so they
80
+ // are looked at whenever the canvas is initialized rather than only
81
+ // when a popup is touched
82
+ onInit: wirePopupTriggers,
83
+ onDeinit: writePopupTriggerAttributes,
84
+
85
+ create: function(options) {
86
+ var id = ge.containerId('popup');
87
+ var container = $('<div />')
88
+ .attr('data-ge-container', 'popup')
89
+ .attr('data-ge-popup-id', id)
90
+ ;
91
+
92
+ 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
+ ;
98
+ }
99
+
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
+ ;
114
+
115
+ return container;
116
+ },
117
+
118
+ mark: function(container) {
119
+ // Nothing in a popup may reach Bootstrap while editing:
120
+ // the modal is rendered unfolded and static, and a real
121
+ // modal opening over it would be the editor fighting
122
+ // itself
123
+ ge.suspendToggles(container.find('[data-bs-dismiss]'));
124
+ ge.makeLabelEditable(ge.labelIn(container.find('.modal-title')));
125
+ },
126
+
127
+ unmark: function(container) {
128
+ ge.resumeToggles(container);
129
+ container.removeClass('ge-popup-collapsed');
130
+ ge.unwrapLabels(container);
131
+ },
132
+
133
+ /** A page of unfolded modals stays workable if they can be folded away. */
134
+ tools: function(drawer, container) {
135
+ ge.createTool(drawer, ge.t('tool.toggle_popup'), 'ge-toggle-popup', 'bi bi-chevron-bar-contract',
136
+ function() {
137
+ container.toggleClass('ge-popup-collapsed');
138
+ });
139
+ },
140
+ };
141
+ };
142
+
143
+ })(jQuery);
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Tabs for grid-editor.
3
+ *
4
+ * A container plugin: load this file after the editor and the toolbar offers
5
+ * a tabs container. What it can ask the editor for is the handle its factory is
6
+ * called with, described in docs/plugins.md.
7
+ *
8
+ * <script src="dist/jquery.grideditor.min.js"></script>
9
+ * <script src="dist/plugins/grideditor.tabs.min.js"></script>
10
+ */
11
+ (function($) {
12
+
13
+ $.extend($.fn.gridEditor.locales.en, {
14
+ 'container.add_tabs': 'Tabs',
15
+ 'container.add_tab': 'Add tab',
16
+ 'container.tab_label': 'Tab {number}',
17
+ 'confirm.delete_tab': 'Delete this tab and everything in it?',
18
+ });
19
+
20
+ $.fn.gridEditor.containers.tabs = function(ge) {
21
+
22
+ function addTabTo(container, options) {
23
+ options = options || {};
24
+
25
+ var strip = container.find('> .nav-tabs');
26
+ var content = container.find('> .tab-content');
27
+ var id = ge.containerId('tab');
28
+ var number = strip.children('.nav-item').length + 1;
29
+
30
+ $('<li class="nav-item ge-tab" role="presentation" />')
31
+ .append($('<button class="nav-link" type="button" role="tab" data-bs-toggle="tab" />')
32
+ .attr('data-bs-target', '#' + id)
33
+ .attr('aria-controls', id)
34
+ .append($('<span class="ge-pane-label" />')
35
+ .text(options.label || ge.t('container.tab_label', { number: number })))
36
+ )
37
+ .appendTo(strip)
38
+ ;
39
+
40
+ var pane = $('<div class="tab-pane fade" role="tabpanel" tabindex="0" />')
41
+ .attr('id', id)
42
+ .append(ge.defaultRegion())
43
+ .appendTo(content)
44
+ ;
45
+
46
+ if (options.activate || number === 1) { activatePane(container, pane); }
47
+
48
+ return pane;
49
+ }
50
+
51
+ function activatePane(container, pane) {
52
+ var id = pane.attr('id');
53
+
54
+ container.find('> .tab-content > .tab-pane').removeClass('show active');
55
+ pane.addClass('show active');
56
+
57
+ container.find('> .nav-tabs .nav-link').each(function() {
58
+ var button = $(this);
59
+ var active = button.attr('data-bs-target') === '#' + id;
60
+
61
+ button.toggleClass('active', active).attr('aria-selected', active ? 'true' : 'false');
62
+ });
63
+ }
64
+
65
+ function tabOf(container, pane) {
66
+ return container.find('> .nav-tabs .nav-link[data-bs-target="#' + pane.attr('id') + '"]')
67
+ .closest('.nav-item');
68
+ }
69
+
70
+ function paneOf(container, tab) {
71
+ return container.find(tab.find('.nav-link').attr('data-bs-target'));
72
+ }
73
+
74
+ return {
75
+ labelKey: 'container.add_tabs',
76
+ addPaneKey: 'container.add_tab',
77
+ paneKind: 'tab',
78
+
79
+ create: function(options) {
80
+ var container = $('<div />').attr('data-ge-container', 'tabs');
81
+ var labels = options.labels || [];
82
+ var count = options.tabs || labels.length || 2;
83
+
84
+ $('<ul class="nav nav-tabs" role="tablist" />').appendTo(container);
85
+ $('<div class="tab-content" />').appendTo(container);
86
+
87
+ for (var i = 0; i < count; i++) {
88
+ addTabTo(container, { label: labels[i] });
89
+ }
90
+
91
+ return container;
92
+ },
93
+
94
+ addPane: addTabTo,
95
+
96
+ mark: function(container) {
97
+ container.find('> .tab-content > .tab-pane').addClass('ge-tab-pane');
98
+
99
+ container.find('> .nav-tabs > .nav-item').each(function() {
100
+ var tab = $(this).addClass('ge-tab');
101
+
102
+
103
+ ge.makeLabelEditable(ge.labelIn(tab.find('.nav-link')));
104
+
105
+ if (tab.find('> .ge-tools-drawer').length) { return; }
106
+
107
+ ge.createPaneControls(tab, 'tab', ge.settings.tab_tools, ge.t('confirm.delete_tab'),
108
+ function(removed) {
109
+ var pane = paneOf(container, tab);
110
+ var wasActive = pane.hasClass('active');
111
+
112
+ tab.fadeOut(200, function() {
113
+ pane.remove();
114
+ removed();
115
+
116
+ var first = container.find('> .tab-content > .tab-pane').first();
117
+ if (wasActive && first.length) { activatePane(container, first); }
118
+ });
119
+ });
120
+ });
121
+ },
122
+
123
+ unmark: function(container) {
124
+ ge.resumeToggles(container);
125
+ container.find('.ge-tab-pane').removeClass('ge-tab-pane');
126
+ ge.unwrapLabels(container);
127
+ },
128
+
129
+ /** Panes read in tab order, whatever order they were dropped in. */
130
+ afterPaneMove: function(container) {
131
+ var content = container.find('> .tab-content');
132
+
133
+ container.find('> .nav-tabs > .nav-item').each(function() {
134
+ content.append(paneOf(container, $(this)));
135
+ });
136
+ },
137
+ };
138
+ };
139
+
140
+ })(jQuery);