decidim-decidim_awesome 0.6.5 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +38 -8
  3. data/app/assets/config/decidim_admin_decidim_awesome_manifest.css +2 -2
  4. data/app/assets/config/decidim_admin_decidim_awesome_manifest.js +1 -1
  5. data/app/assets/config/decidim_decidim_awesome_manifest.css +2 -2
  6. data/app/assets/config/decidim_decidim_awesome_manifest.js +3 -2
  7. data/app/assets/config/legacy_decidim_admin_decidim_awesome_manifest.js +2 -0
  8. data/app/assets/config/legacy_decidim_decidim_awesome_manifest.js +4 -0
  9. data/app/assets/javascripts/decidim/decidim_awesome/admin/auto_edit.js.es6 +77 -0
  10. data/app/assets/javascripts/decidim/decidim_awesome/admin/codemirror.js.es6 +14 -0
  11. data/app/assets/javascripts/decidim/decidim_awesome/admin/form_builder.js.es6 +80 -0
  12. data/app/assets/javascripts/decidim/decidim_awesome/admin/legacy_form_builder.js.es6 +80 -0
  13. data/app/assets/javascripts/decidim/decidim_awesome/admin/user_picker.js.es6 +24 -0
  14. data/app/assets/javascripts/decidim/decidim_awesome/awesome_admin.js +7 -0
  15. data/app/assets/javascripts/decidim/decidim_awesome/{application.js → awesome_application.js} +1 -2
  16. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/hashtags.js.es6 +48 -0
  17. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/layers.js.es6 +107 -0
  18. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/load_map.js.es6 +15 -0
  19. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/map.js.es6 +170 -178
  20. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/markers.js.es6 +56 -0
  21. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/meetings.js.es6 +7 -6
  22. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/proposals.js.es6 +18 -5
  23. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/utilities.js.es6 +57 -0
  24. data/app/assets/javascripts/decidim/decidim_awesome/editors/legacy_quill_editor.js.es6 +172 -0
  25. data/app/assets/javascripts/decidim/decidim_awesome/editors/quill_editor.js.es6 +34 -9
  26. data/app/assets/javascripts/decidim/decidim_awesome/editors/tabs_focus.js.es6 +24 -0
  27. data/app/assets/javascripts/decidim/decidim_awesome/forms/custom_fields_builder.js.es6 +211 -0
  28. data/app/assets/javascripts/decidim/decidim_awesome/forms/rich_text_plugin.js.es6 +106 -0
  29. data/app/assets/javascripts/decidim/decidim_awesome/legacy_admin.js +7 -0
  30. data/app/assets/javascripts/decidim/decidim_awesome/legacy_application.js +3 -0
  31. data/app/assets/javascripts/decidim/decidim_awesome/proposals/custom_fields.js.es6 +21 -0
  32. data/app/assets/stylesheets/decidim/decidim_awesome/admin/auto_edits.scss +15 -0
  33. data/app/assets/stylesheets/decidim/decidim_awesome/admin/codemirror.scss +27 -0
  34. data/app/assets/stylesheets/decidim/decidim_awesome/admin/constraints.scss +12 -0
  35. data/app/assets/stylesheets/decidim/decidim_awesome/admin/custom_fields.scss +66 -0
  36. data/app/assets/stylesheets/decidim/decidim_awesome/admin/user_picker.scss +35 -0
  37. data/app/assets/stylesheets/decidim/decidim_awesome/{admin.scss → awesome_admin.scss} +19 -4
  38. data/app/assets/stylesheets/decidim/decidim_awesome/awesome_application.scss +22 -0
  39. data/app/assets/stylesheets/decidim/decidim_awesome/awesome_map/leaflet.scss.erb +9 -0
  40. data/app/assets/stylesheets/decidim/decidim_awesome/awesome_map/map.scss +95 -1
  41. data/app/assets/stylesheets/decidim/decidim_awesome/editors/markdown_editor.scss +1 -1
  42. data/app/assets/stylesheets/decidim/decidim_awesome/editors/quill_editor.scss +16 -1
  43. data/app/awesome_overrides/forms/decidim/proposals/proposal_wizard_create_step_form_override.rb +28 -0
  44. data/app/awesome_overrides/presenters/decidim/menu_presenter_override.rb +11 -3
  45. data/app/cells/decidim/decidim_awesome/content_blocks/map/show.erb +74 -0
  46. data/app/cells/decidim/decidim_awesome/content_blocks/map_cell.rb +54 -0
  47. data/app/cells/decidim/decidim_awesome/content_blocks/map_form/show.erb +61 -0
  48. data/app/cells/decidim/decidim_awesome/content_blocks/map_form_cell.rb +19 -0
  49. data/app/commands/concerns/decidim/decidim_awesome/admin/needs_constraint_helpers.rb +32 -0
  50. data/app/commands/decidim/decidim_awesome/admin/create_proposal_custom_field.rb +45 -0
  51. data/app/commands/decidim/decidim_awesome/admin/create_scoped_admin.rb +38 -0
  52. data/app/commands/decidim/decidim_awesome/admin/destroy_constraint.rb +4 -0
  53. data/app/commands/decidim/decidim_awesome/admin/destroy_proposal_custom_field.rb +40 -0
  54. data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_admin.rb +40 -0
  55. data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_style.rb +1 -1
  56. data/app/commands/decidim/decidim_awesome/admin/rename_scope_label.rb +58 -0
  57. data/app/commands/decidim/decidim_awesome/admin/update_config.rb +5 -1
  58. data/app/controllers/concerns/decidim/decidim_awesome/admin_not_found_redirect.rb +39 -0
  59. data/app/controllers/decidim/decidim_awesome/admin/checks_controller.rb +1 -1
  60. data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +33 -20
  61. data/app/controllers/decidim/decidim_awesome/admin/constraints_controller.rb +4 -0
  62. data/app/controllers/decidim/decidim_awesome/admin/menu_hacks_controller.rb +2 -2
  63. data/app/controllers/decidim/decidim_awesome/admin/proposal_custom_fields_controller.rb +38 -0
  64. data/app/controllers/decidim/decidim_awesome/admin/scoped_admins_controller.rb +38 -0
  65. data/app/controllers/decidim/decidim_awesome/admin/scoped_styles_controller.rb +38 -0
  66. data/app/controllers/decidim/decidim_awesome/map_component/map_controller.rb +1 -4
  67. data/app/forms/decidim/decidim_awesome/admin/config_form.rb +50 -0
  68. data/app/forms/decidim/decidim_awesome/admin/constraint_form.rb +3 -1
  69. data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +11 -7
  70. data/app/helpers/decidim/decidim_awesome/amendments_helper_override.rb +48 -0
  71. data/app/helpers/decidim/decidim_awesome/map_helper.rb +66 -53
  72. data/app/helpers/decidim/decidim_awesome/proposals/application_helper_override.rb +78 -0
  73. data/app/middleware/decidim/decidim_awesome/current_config.rb +182 -0
  74. data/app/models/decidim/decidim_awesome/awesome_config.rb +15 -0
  75. data/app/models/decidim/decidim_awesome/user_override.rb +25 -0
  76. data/app/permissions/decidim/decidim_awesome/admin/permissions.rb +2 -0
  77. data/app/uploaders/decidim/decidim_awesome/image_uploader.rb +0 -5
  78. data/app/views/decidim/decidim_awesome/admin/checks/index.html.erb +2 -2
  79. data/app/views/decidim/decidim_awesome/admin/config/_autoedit_box_label.html.erb +7 -0
  80. data/app/views/decidim/decidim_awesome/admin/config/_constraints.html.erb +2 -2
  81. data/app/views/decidim/decidim_awesome/admin/config/_form_admins.html.erb +21 -0
  82. data/app/views/decidim/decidim_awesome/admin/config/_form_editors.html.erb +0 -3
  83. data/app/views/decidim/decidim_awesome/admin/config/_form_proposal_custom_fields.html.erb +25 -0
  84. data/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb +0 -2
  85. data/app/views/decidim/decidim_awesome/admin/config/_form_styles.html.erb +4 -6
  86. data/app/views/decidim/decidim_awesome/admin/config/show.html.erb +1 -2
  87. data/app/views/decidim/decidim_awesome/admin/proposals/_editor.html.erb +4 -0
  88. data/app/views/decidim/decidim_awesome/custom_fields/_form_render.html.erb +6 -0
  89. data/app/views/decidim/decidim_awesome/map_component/map/show.html.erb +3 -32
  90. data/app/views/decidim/proposals/admin/proposals/_form.html.erb +101 -0
  91. data/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +83 -0
  92. data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +1 -0
  93. data/app/views/layouts/decidim/admin/decidim_awesome.html.erb +25 -11
  94. data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +8 -1
  95. data/app/views/layouts/decidim/decidim_awesome/_custom_styles.html.erb +1 -1
  96. data/app/views/v0.23/decidim/proposals/collaborative_drafts/_show.html.erb +134 -0
  97. data/app/views/v0.23/layouts/decidim/_head.html.erb +2 -2
  98. data/app/views/v0.23/layouts/decidim/admin/_header.html.erb +2 -2
  99. data/app/views/v0.24/decidim/proposals/collaborative_drafts/_show.html.erb +128 -0
  100. data/app/views/{v0.22 → v0.24}/layouts/decidim/_head.html.erb +4 -2
  101. data/app/views/{v0.22 → v0.24}/layouts/decidim/admin/_header.html.erb +3 -2
  102. data/config/locales/ca.yml +75 -3
  103. data/config/locales/cs.yml +75 -3
  104. data/config/locales/en.yml +104 -11
  105. data/config/locales/es.yml +74 -2
  106. data/config/locales/eu.yml +76 -4
  107. data/config/locales/fr.yml +214 -142
  108. data/config/locales/it.yml +284 -0
  109. data/config/locales/ja.yml +284 -0
  110. data/config/locales/nl.yml +208 -136
  111. data/config/locales/sv.yml +109 -37
  112. data/db/migrate/20210628150825_change_awesome_config_var_type.rb +12 -0
  113. data/lib/decidim/decidim_awesome/admin_engine.rb +16 -4
  114. data/lib/decidim/decidim_awesome/awesome_helpers.rb +17 -10
  115. data/lib/decidim/decidim_awesome/checksums.yml +19 -9
  116. data/lib/decidim/decidim_awesome/config.rb +54 -9
  117. data/lib/decidim/decidim_awesome/context_analyzers/request_analyzer.rb +27 -21
  118. data/lib/decidim/decidim_awesome/custom_fields.rb +94 -0
  119. data/lib/decidim/decidim_awesome/engine.rb +64 -8
  120. data/lib/decidim/decidim_awesome/iframe_component/component.rb +1 -1
  121. data/lib/decidim/decidim_awesome/map_component/component.rb +8 -2
  122. data/lib/decidim/decidim_awesome/menu_hacker.rb +17 -15
  123. data/lib/decidim/decidim_awesome/system_checker.rb +1 -1
  124. data/lib/decidim/decidim_awesome/test/shared_examples/box_label_editor.rb +116 -0
  125. data/lib/decidim/decidim_awesome/test/shared_examples/current_config_examples.rb +143 -0
  126. data/lib/decidim/decidim_awesome/test/shared_examples/editor_examples.rb +4 -0
  127. data/lib/decidim/decidim_awesome/test/shared_examples/scoped_admins_examples.rb +428 -0
  128. data/lib/decidim/decidim_awesome/version.rb +2 -2
  129. data/lib/decidim/decidim_awesome.rb +41 -8
  130. data/vendor/assets/javascripts/codemirror.js +9801 -0
  131. data/vendor/assets/javascripts/delta.min.js +405 -0
  132. data/vendor/assets/javascripts/delta.min.js.map +1 -0
  133. data/vendor/assets/javascripts/europa.min.js +4 -0
  134. data/vendor/assets/javascripts/form-builder.min.js +19 -0
  135. data/vendor/assets/javascripts/form-render.min.js +19 -0
  136. data/vendor/assets/javascripts/inscrybmde.min.js +1 -1
  137. data/vendor/assets/javascripts/jquery-ui.min.js +13 -0
  138. data/vendor/assets/javascripts/jquery.truncate.js +105 -0
  139. data/vendor/assets/javascripts/keymap/sublime.js +720 -0
  140. data/vendor/assets/javascripts/mode/css/css.js +864 -0
  141. data/vendor/assets/javascripts/select2.js +6147 -0
  142. data/vendor/assets/langs/en-US.lang +110 -0
  143. data/vendor/assets/stylesheets/codemirror.css +350 -0
  144. data/vendor/assets/stylesheets/inscrybmde.min.scss +194 -0
  145. data/vendor/assets/stylesheets/jquery-ui.min.css +7 -0
  146. data/vendor/assets/stylesheets/select2-foundation-theme.css +249 -0
  147. data/vendor/assets/stylesheets/select2.css +515 -0
  148. metadata +101 -34
  149. data/app/assets/images/decidim/decidim_awesome/loading.gif +0 -0
  150. data/app/assets/javascripts/decidim/decidim_awesome/admin.js +0 -2
  151. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/legacy_map.js.es6 +0 -225
  152. data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/legacy_proposals.js.es6 +0 -82
  153. data/app/assets/javascripts/decidim/decidim_awesome/editors/markdown_view.js.es6 +0 -12
  154. data/app/assets/stylesheets/decidim/decidim_awesome/application.scss +0 -8
  155. data/app/assets/stylesheets/decidim/decidim_awesome/editors/markdown_view.scss +0 -27
  156. data/app/awesome_overrides/presenters/decidim/proposals/proposal_presenter_override.rb +0 -64
  157. data/lib/decidim/decidim_awesome/content_renderers/markdown_renderer.rb +0 -18
  158. data/lib/decidim/decidim_awesome/content_renderers.rb +0 -9
  159. data/vendor/assets/stylesheets/inscrybmde.min.css +0 -8
@@ -0,0 +1,172 @@
1
+ // = require image-upload.min
2
+ // = require image-resize.min
3
+ // = require inscrybmde.min.js
4
+ // = require inline-attachment.js
5
+ // = require codemirror-4.inline-attachment.js
6
+ // = require jquery.inline-attachment.js
7
+ // = require europa.min.js
8
+ // = require_self
9
+
10
+ ((exports) => {
11
+ exports.DecidimAwesome = exports.DecidimAwesome || {};
12
+
13
+ // Redefines Quill editor with images
14
+ if(exports.DecidimAwesome.allow_images_in_full_editor || exports.DecidimAwesome.allow_images_in_small_editor || exports.DecidimAwesome.use_markdown_editor) {
15
+
16
+ const quillFormats = ["bold", "italic", "link", "underline", "header", "list", "video", "image", "alt"];
17
+
18
+ const createQuillEditor = (container) => {
19
+ const toolbar = $(container).data("toolbar");
20
+ const disabled = $(container).data("disabled");
21
+
22
+ let quillToolbar = [
23
+ ["bold", "italic", "underline"],
24
+ [{ list: "ordered" }, { list: "bullet" }],
25
+ ["link", "clean"]
26
+ ];
27
+
28
+ let addImage = false;
29
+
30
+ if (toolbar === "full") {
31
+ quillToolbar = [
32
+ [{ header: [1, 2, 3, 4, 5, 6, false] }],
33
+ ...quillToolbar
34
+ ];
35
+ if(exports.DecidimAwesome.allow_images_in_full_editor) {
36
+ quillToolbar.push(["video", "image"]);
37
+ addImage = true;
38
+ } else {
39
+ quillToolbar.push(["video"]);
40
+ }
41
+ } else if (toolbar === "basic") {
42
+ if(exports.DecidimAwesome.allow_images_in_small_editor) {
43
+ quillToolbar.push(["video", "image"]);
44
+ addImage = true;
45
+ } else {
46
+ quillToolbar.push(["video"]);
47
+ }
48
+ } else if(exports.DecidimAwesome.allow_images_in_small_editor) {
49
+ quillToolbar.push(["image"]);
50
+ addImage = true;
51
+ }
52
+
53
+ let modules = {
54
+ toolbar: quillToolbar
55
+ };
56
+ const $input = $(container).siblings('input[type="hidden"]');
57
+ container.innerHTML = $input.val() || "";
58
+ const token = $( 'meta[name="csrf-token"]' ).attr( 'content' );
59
+
60
+ if(addImage) {
61
+ modules.imageResize = {
62
+ modules: ["Resize", "DisplaySize"]
63
+ }
64
+ modules.imageUpload = {
65
+ url: exports.DecidimAwesome.editor_uploader_path, // server url. If the url is empty then the base64 returns
66
+ method: 'POST', // change query method, default 'POST'
67
+ name: 'image', // custom form name
68
+ withCredentials: false, // withCredentials
69
+ headers: { 'X-CSRF-Token': token }, // add custom headers, example { token: 'your-token'}
70
+ // personalize successful callback and call next function to insert new url to the editor
71
+ callbackOK: (serverResponse, next) => {
72
+ $(quill.getModule("toolbar").container).last().removeClass('editor-loading')
73
+ next(serverResponse.url);
74
+ },
75
+ // personalize failed callback
76
+ callbackKO: serverError => {
77
+ $(quill.getModule("toolbar").container).last().removeClass('editor-loading')
78
+ alert(serverError.message);
79
+ },
80
+ checkBeforeSend: (file, next) => {
81
+ $(quill.getModule("toolbar").container).last().addClass('editor-loading')
82
+ next(file); // go back to component and send to the server
83
+ }
84
+ }
85
+ }
86
+
87
+ const quill = new Quill(container, {
88
+ modules: modules,
89
+ formats: quillFormats,
90
+ theme: "snow"
91
+ });
92
+
93
+ if (disabled) {
94
+ quill.disable();
95
+ }
96
+
97
+ quill.on("text-change", () => {
98
+ const text = quill.getText();
99
+
100
+ // Triggers CustomEvent with the cursor position
101
+ // It is required in input_mentions.js
102
+ let event = new CustomEvent("quill-position", {
103
+ detail: quill.getSelection()
104
+ });
105
+ container.dispatchEvent(event);
106
+
107
+ if (text === "\n") {
108
+ $input.val("");
109
+ } else {
110
+ $input.val(quill.root.innerHTML);
111
+ }
112
+ });
113
+
114
+ if(addImage) {
115
+ const t = window.DecidimAwesome.texts["drag_and_drop_image"];
116
+ $(container).after(`<p class="help-text" style="margin-top:-1.5rem;">${t}</p>`);
117
+ }
118
+ };
119
+
120
+ const createMarkdownEditor = (container) => {
121
+ const t = window.DecidimAwesome.texts["drag_and_drop_image"];
122
+ const token = $( 'meta[name="csrf-token"]' ).attr( 'content' );
123
+ const $input = $(container).siblings('input[type="hidden"]');
124
+ const $faker = $('<input type="hidden" name="faker-inscrybmde">');
125
+ const $form = $(container).closest('form');
126
+ const europa = new Europa();
127
+ $faker.val(europa.convert($input.val()));
128
+ $faker.insertBefore($(container));
129
+ $(container).hide();
130
+ const inscrybmde = new InscrybMDE({
131
+ element: $faker[0],
132
+ spellChecker: false,
133
+ renderingConfig: {
134
+ codeSyntaxHighlighting: true
135
+ }
136
+ });
137
+ $faker[0].InscrybMDE = inscrybmde;
138
+
139
+ // Allow image upload
140
+ if(window.DecidimAwesome.allow_images_in_markdown_editor) {
141
+ $(inscrybmde.gui.statusbar).prepend(`<span class="help-text" style="float:left;margin:0;text-align:left;">${t}</span>`);
142
+ inlineAttachment.editors.codemirror4.attach(inscrybmde.codemirror, {
143
+ uploadUrl: window.DecidimAwesome.editor_uploader_path,
144
+ uploadFieldName: "image",
145
+ jsonFieldName: "url",
146
+ extraHeaders: { "X-CSRF-Token": token }
147
+ });
148
+ }
149
+
150
+ // convert to html on submit
151
+ $form.on("submit", () => {
152
+ $input.val(inscrybmde.markdown(inscrybmde.value()));
153
+ });
154
+ };
155
+
156
+ const quillEditor = () => {
157
+ $(".editor-container").each((idx, container) => {
158
+ if(exports.DecidimAwesome.use_markdown_editor) {
159
+ createMarkdownEditor(container);
160
+ } else {
161
+ createQuillEditor(container);
162
+ }
163
+ });
164
+ };
165
+
166
+ exports.Decidim = exports.Decidim || {};
167
+ exports.Decidim.quillEditor = quillEditor;
168
+ exports.Decidim.createQuillEditor = createQuillEditor;
169
+ exports.Decidim.createMarkdownEditor = createMarkdownEditor;
170
+
171
+ }
172
+ })(window);
@@ -4,6 +4,8 @@
4
4
  // = require inline-attachment.js
5
5
  // = require codemirror-4.inline-attachment.js
6
6
  // = require jquery.inline-attachment.js
7
+ // = require europa.min.js
8
+ // = require decidim/editor/linebreak_module.js
7
9
  // = require_self
8
10
 
9
11
  ((exports) => {
@@ -12,14 +14,14 @@
12
14
  // Redefines Quill editor with images
13
15
  if(exports.DecidimAwesome.allow_images_in_full_editor || exports.DecidimAwesome.allow_images_in_small_editor || exports.DecidimAwesome.use_markdown_editor) {
14
16
 
15
- const quillFormats = ["bold", "italic", "link", "underline", "header", "list", "video", "image", "alt"];
17
+ const quillFormats = ["bold", "italic", "link", "underline", "header", "list", "video", "image", "alt", "break"];
16
18
 
17
19
  const createQuillEditor = (container) => {
18
20
  const toolbar = $(container).data("toolbar");
19
21
  const disabled = $(container).data("disabled");
20
22
 
21
23
  let quillToolbar = [
22
- ["bold", "italic", "underline"],
24
+ ["bold", "italic", "underline", "linebreak"],
23
25
  [{ list: "ordered" }, { list: "bullet" }],
24
26
  ["link", "clean"]
25
27
  ];
@@ -50,7 +52,13 @@
50
52
  }
51
53
 
52
54
  let modules = {
53
- toolbar: quillToolbar
55
+ linebreak: {},
56
+ toolbar: {
57
+ container: quillToolbar,
58
+ handlers: {
59
+ "linebreak": exports.Decidim.Editor.lineBreakButtonHandler
60
+ }
61
+ }
54
62
  };
55
63
  const $input = $(container).siblings('input[type="hidden"]');
56
64
  container.innerHTML = $input.val() || "";
@@ -103,31 +111,42 @@
103
111
  });
104
112
  container.dispatchEvent(event);
105
113
 
106
- if (text === "\n") {
114
+ if (text === "\n" || text === "\n\n") {
107
115
  $input.val("");
108
116
  } else {
109
117
  $input.val(quill.root.innerHTML);
110
118
  }
111
119
  });
112
-
120
+
113
121
  if(addImage) {
114
122
  const t = window.DecidimAwesome.texts["drag_and_drop_image"];
115
- $(container).after(`<p class="help-text" style="margin-top:-1.5rem;">${t}</p>`);
123
+ $(container).after(`<p class="help-text">${t}</p>`);
116
124
  }
125
+
126
+ // After editor is ready, linebreak_module deletes two extraneous new lines
127
+ quill.emitter.emit("editor-ready");
128
+
129
+ return quill;
117
130
  };
118
131
 
119
132
  const createMarkdownEditor = (container) => {
120
- $(container).hide();
121
133
  const t = window.DecidimAwesome.texts["drag_and_drop_image"];
122
134
  const token = $( 'meta[name="csrf-token"]' ).attr( 'content' );
123
135
  const $input = $(container).siblings('input[type="hidden"]');
136
+ const $faker = $('<input type="hidden" name="faker-inscrybmde">');
137
+ const $form = $(container).closest('form');
138
+ const europa = new Europa();
139
+ $faker.val(europa.convert($input.val()));
140
+ $faker.insertBefore($(container));
141
+ $(container).hide();
124
142
  const inscrybmde = new InscrybMDE({
125
- element: $input[0],
143
+ element: $faker[0],
126
144
  spellChecker: false,
127
145
  renderingConfig: {
128
146
  codeSyntaxHighlighting: true
129
147
  }
130
148
  });
149
+ $faker[0].InscrybMDE = inscrybmde;
131
150
 
132
151
  // Allow image upload
133
152
  if(window.DecidimAwesome.allow_images_in_markdown_editor) {
@@ -139,6 +158,12 @@
139
158
  extraHeaders: { "X-CSRF-Token": token }
140
159
  });
141
160
  }
161
+
162
+ // convert to html on submit
163
+ $form.on("submit", () => {
164
+ // e.preventDefault();
165
+ $input.val(inscrybmde.markdown(inscrybmde.value()));
166
+ });
142
167
  };
143
168
 
144
169
  const quillEditor = () => {
@@ -157,4 +182,4 @@
157
182
  exports.Decidim.createMarkdownEditor = createMarkdownEditor;
158
183
 
159
184
  }
160
- })(window);
185
+ })(window);
@@ -0,0 +1,24 @@
1
+ // = require_self
2
+
3
+ /**
4
+ * When switching tabs in i18n fields, autofocus on the markdown if exists
5
+ */
6
+ $(() => {
7
+ // Event launched by foundation
8
+ $("[data-tabs]").on("change.zf.tabs", (event) => {
9
+ const $container = $(event.target).closest(".label--tabs").next(".tabs-content").find(".tabs-panel.is-active");
10
+ // fix inscrybemde if present
11
+ let $input = $container.find('[name="faker-inscrybmde"]');
12
+ if ($input.length > 0) {
13
+ $input[0].InscrybMDE.codemirror.refresh();
14
+ }
15
+ // fix custom fields if present
16
+ $input = $container.find(".proposal_custom_field:first");
17
+ if($input.length > 0) {
18
+ // saves current data to the hidden field for the lang
19
+ DecidimAwesome.FormRenderBuilder.storeData();
20
+ // init the current language
21
+ DecidimAwesome.FormRenderBuilder.init($input);
22
+ }
23
+ });
24
+ });
@@ -0,0 +1,211 @@
1
+ // = require form-render.min
2
+ // = require decidim/decidim_awesome/forms/rich_text_plugin
3
+
4
+ class CustomFieldsBuilder { // eslint-disable-line no-unused-vars
5
+ constructor(container_selector) {
6
+ this.container_selector = container_selector || ".proposal_custom_field:last";
7
+ this.lang = this.getLang($("html").attr("lang"));
8
+ }
9
+
10
+ getLang(lang) {
11
+ const langs = {
12
+ // ar: 'ar-SA', // Not in decidim yet
13
+ 'ar': 'ar-TN',
14
+ 'ca': 'ca-ES',
15
+ 'cs': 'cs-CZ',
16
+ 'da': 'da-DK',
17
+ 'de': 'de-DE',
18
+ 'el': 'el-GR',
19
+ 'en': 'en-US',
20
+ 'es': 'es-ES',
21
+ 'fa': 'fa-IR',
22
+ 'fi': 'fi-FI',
23
+ 'fr': 'fr-FR',
24
+ 'he': 'he-IL',
25
+ 'hu': 'hu-HU',
26
+ 'it': 'it-IT',
27
+ 'ja': 'ja-JP',
28
+ 'my': 'my-MM',
29
+ 'nb': 'nb-NO',
30
+ 'nl': 'nl-NL',
31
+ 'pl': 'pl-PL',
32
+ 'pt': 'pt-BR',
33
+ 'qz': 'qz-MM',
34
+ 'ro': 'ro-RO',
35
+ 'ru': 'ru-RU',
36
+ 'sl': 'sl-SI',
37
+ 'th': 'th-TH',
38
+ 'tr': 'tr-TR',
39
+ 'uk': 'uk-UA',
40
+ 'vi': 'vi-VN',
41
+ 'zh-TW': 'zh-TW',
42
+ 'zh': 'zh-CN'
43
+ };
44
+ if(langs[lang]) {
45
+ return langs[lang];
46
+ }
47
+ if(langs[lang.substr(0, 2)]) {
48
+ return langs[lang.substr(0, 2)];
49
+ }
50
+ return 'en-US';
51
+ }
52
+
53
+ /*
54
+ * Creates an XML document with a subset of html-compatible dl/dd/dt elements
55
+ * to store the custom fields answers
56
+ */
57
+ dataToXML(data) {
58
+ const doc = $.parseXML("<xml/>");
59
+ const xml = doc.getElementsByTagName("xml")[0];
60
+ const dl = doc.createElement("dl");
61
+ let key, dt, dd, div, val, text, label, l;
62
+ xml.appendChild(dl);
63
+ $(dl).attr("class", "decidim_awesome-custom_fields");
64
+ $(dl).attr("data-generator", "decidim_awesome");
65
+ $(dl).attr("data-version", window.DecidimAwesome.version);
66
+ for (key in data) {
67
+ // console.log("get the data!", key, data[key]);
68
+ // Richtext plugin does not saves userdata, so we get it from the hidden input
69
+ if(data[key].type == "textarea" && data[key].subtype == "richtext") {
70
+ data[key].userData = [$(`#${data[key].name}-input`).val()];
71
+ }
72
+ if (data[key].userData && data[key].userData.length) {
73
+ dt = doc.createElement("dt");
74
+ $(dt).text(data[key].label);
75
+ $(dt).attr("name", data[key].name);
76
+ dd = doc.createElement("dd");
77
+ // console.log("data for", key, data[key].name, data[key])
78
+ for(val in data[key].userData) {
79
+ div = doc.createElement("div");
80
+ label = data[key].userData[val];
81
+ text = null;
82
+ if(data[key].values) {
83
+ l = data[key].values.find((v) => v["value"] == data[key].userData[val]);
84
+ if(l) {
85
+ text = label;
86
+ label = l.label;
87
+ }
88
+ } else if(data[key].type == "date" && label) {
89
+ l = new Date(label).toLocaleDateString();
90
+ if(l) {
91
+ text = label;
92
+ label = l;
93
+ }
94
+ }
95
+ // console.log("userData", text, "label", label, 'key', key, 'data', data)
96
+ if(data[key].type == "textarea" && data[key].subtype == "richtext") {
97
+ $(div).html(label);
98
+ } else {
99
+ $(div).text(label);
100
+ }
101
+ if(text) {
102
+ $(div).attr("alt", text);
103
+ }
104
+ dd.appendChild(div);
105
+ }
106
+ $(dd).attr("id", data[key].name);
107
+ $(dd).attr("name", data[key].type);
108
+ dl.appendChild(dt);
109
+ dl.appendChild(dd);
110
+ }
111
+ }
112
+ return xml.outerHTML;
113
+ }
114
+
115
+ fixBuggyFields() {
116
+ if(!this.$container) {
117
+ return false;
118
+ }
119
+ /**
120
+ * Hack to fix required checkboxes being reset
121
+ * Issue: https://github.com/Platoniq/decidim-module-decidim_awesome/issues/82
122
+ */
123
+ this.$container.find('.formbuilder-checkbox-group').each((_key, group) => {
124
+ const inputs = $('.formbuilder-checkbox input', group);
125
+ const data = this.spec.find((a) => a.type=="checkbox-group");
126
+ let values = data.userData;
127
+ if(!inputs.length || !data || !values) {
128
+ return;
129
+ }
130
+
131
+ inputs.each((_key, input) => {
132
+ let index = values.indexOf(input.value);
133
+ if(index >= 0) {
134
+ values.splice(index, 1)
135
+ // setting checked=true do not makes the browser aware that the form is valid if the field is required
136
+ if(!input.checked)
137
+ $(input).click();
138
+ } else {
139
+ if(input.checked)
140
+ $(input).click();
141
+ }
142
+ });
143
+
144
+ // Fill "other" option
145
+ const other_option = $('.other-option', inputs.parent())[0];
146
+ const other_val = $('.other-val', inputs.parent())[0];
147
+ const other_text = values.join(" ");
148
+
149
+ if (other_option) {
150
+ if (other_text) {
151
+ other_option.checked = true;
152
+ other_option.value = other_text;
153
+ other_val.value = other_text;
154
+ } else {
155
+ other_option.checked = false;
156
+ other_option.value = '';
157
+ other_val.value = '';
158
+ }
159
+ }
160
+ });
161
+ /**
162
+ * Hack to fix required radio buttons "other" value
163
+ * Issue: https://github.com/Platoniq/decidim-module-decidim_awesome/issues/133
164
+ */
165
+ this.$container.find('.formbuilder-radio input.other-val').on('input', (input) => {
166
+ const $input = $(input.currentTarget);
167
+ const $group = $input.closest('.formbuilder-radio-group');
168
+ $group.find("input").each((_key, radio) => {
169
+ const name = $(radio).attr('name');
170
+ if(name && name.endsWith('[]')) {
171
+ $(radio).attr('name', name.slice(0, -2));
172
+ }
173
+ });
174
+ });
175
+ }
176
+
177
+ // Saves xml to the hidden input
178
+ storeData() {
179
+ if(!this.$container) {
180
+ return false;
181
+ }
182
+ const $form = this.$container.closest("form");
183
+ const $body = $form.find('input[name="' + this.$element.data("name") +'"]');
184
+ if($body.length && this.instance) {
185
+ this.spec = this.instance.userData;
186
+ $body.val(this.dataToXML(this.spec));
187
+ this.$element.data("spec", this.spec);
188
+ }
189
+ // console.log("storeData", this.spec, "xml", $body.val());
190
+ }
191
+
192
+ init($element) {
193
+ this.$element = $element;
194
+ this.spec = $element.data("spec");
195
+ if(!this.$container) {
196
+ this.$container = $(this.container_selector);
197
+ }
198
+ // console.log("init", $element, "data", data)
199
+ // TODO: save current data to the hidden field
200
+ // always use the last field (in case of multilang tabs we only render one form due a limitation of the library to handle several instances)
201
+ this.instance = this.$container.formRender({
202
+ i18n: {
203
+ locale: this.lang,
204
+ location: 'https://cdn.jsdelivr.net/npm/formbuilder-languages@1.1.0/'
205
+ },
206
+ formData: this.spec,
207
+ render: true
208
+ });
209
+ this.fixBuggyFields();
210
+ }
211
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ *
3
+ * NOTE: For some reason, this seems to throw an error while transpiling
4
+ * For this reason a rich_text_plugin.js is provided using the online transpiler https://babeljs.io/repl
5
+ * Hopefully, this situation will change when webpacker is updated in the v0.25 of Decidim
6
+ *
7
+ * Decidim rich text editor control plugin
8
+ * Renders standard Decidim WYSIWYG editor
9
+ *
10
+ * Registers Decidim Richtext as a subtype for the textarea control
11
+ */
12
+
13
+ // configure the class for runtime loading
14
+ if (!window.fbControls) window.fbControls = []
15
+ window.fbControls.push(function(controlClass, allControlClasses) {
16
+ const controlTextarea = allControlClasses.textarea
17
+ /**
18
+ * DecidimRichtext control class
19
+ *
20
+ * NOTE: I haven't found a way to set the userData value using this plugin
21
+ * For this reason the value of the field must be collected manually
22
+ * from the hidden input name same as the field with the suffix '-input'
23
+ */
24
+ class controlRichtext extends controlTextarea {
25
+ /**
26
+ * Class configuration - return the icons & label related to this control
27
+ * @returndefinition object
28
+ */
29
+ static get definition() {
30
+ return {
31
+ icon: '📝',
32
+ i18n: {
33
+ default: 'Rich Text Editor'
34
+ },
35
+ }
36
+ }
37
+
38
+ /**
39
+ * configure the richtext editor requirements
40
+ */
41
+ configure() {
42
+ window.fbEditors.richtext = {};
43
+ }
44
+
45
+ /**
46
+ * build a div DOM element & convert to a richtext editor
47
+ * @return {DOMElement} DOM Element to be injected into the form.
48
+ */
49
+ build() {
50
+ const { value, userData, ...attrs } = this.config;
51
+
52
+ // hidden input for storing the current HTML value of the div
53
+ this.inputId = this.id + '-input'
54
+ this.input = this.markup('input', null, {
55
+ name: name,
56
+ id: this.inputId,
57
+ type: 'hidden',
58
+ value: (userData && userData[0]) || value
59
+ });
60
+
61
+ const css = this.markup(
62
+ 'style',
63
+ `
64
+ #${attrs.id} { height: auto; padding-left: 0; padding-right: 0; }
65
+ #${attrs.id} div.ql-container { height: ${attrs.rows || 1}rem; }
66
+ #${attrs.id} p.help-text { margin-top: .5rem; }
67
+ `,
68
+ { type: 'text/css' }
69
+ );
70
+ // console.log("build value", value, "userData", userData, "attrs", attrs, attrs.id);
71
+ this.wrapper = this.markup('div', null, attrs);
72
+ return this.markup('div', [css, this.input, this.wrapper], attrs);
73
+ }
74
+
75
+ /**
76
+ * When the element is rendered into the DOM, execute the following code to initialise it
77
+ * @param {Object} evt - event
78
+ */
79
+ onRender(evt) {
80
+ // const value = this.config.value || '';
81
+ if (window.fbEditors.richtext[this.id]) {
82
+ // console.log("todo destroy", window.fbEditors.richtext[this.id]);
83
+ // window.fbEditors.richtext[this.id].richtext('destroy')
84
+ }
85
+
86
+ window.fbEditors.quill[this.id] = {};
87
+ const editor = window.fbEditors.quill[this.id];
88
+ // createQuillEditor does all the job to update the hidden input wrapper
89
+ editor.instance = window.Decidim.createQuillEditor(this.wrapper);
90
+ // editor.data = new Delta();
91
+ // if (value) {
92
+ // editor.instance.setContents(window.JSON.parse(this.parsedHtml(value)));
93
+ // }
94
+ // editor.instance.on('text-change', function(delta) {
95
+ // console.log("text-change", "delta", delta, "editor", editor);
96
+ // // // editor.data = editor.data.compose(delta);
97
+ // });
98
+
99
+ // console.log("render! editor", editor, "this", this, "value", value);
100
+ return evt;
101
+ }
102
+ }
103
+
104
+ // register Decidim richtext as a richtext control
105
+ controlTextarea.register('richtext', controlRichtext, 'textarea');
106
+ })
@@ -0,0 +1,7 @@
1
+ // = require decidim/decidim_awesome/admin/constraints
2
+ // = require decidim/decidim_awesome/editors/legacy_quill_editor
3
+ // = require decidim/decidim_awesome/admin/legacy_form_builder
4
+ // = require decidim/decidim_awesome/editors/tabs_focus
5
+ // = require decidim/decidim_awesome/admin/codemirror
6
+ // = require decidim/decidim_awesome/admin/user_picker.js
7
+ // = require decidim/decidim_awesome/admin/auto_edit.js
@@ -0,0 +1,3 @@
1
+ // = require decidim/decidim_awesome/proposals/images
2
+ // = require decidim/decidim_awesome/editors/legacy_quill_editor
3
+ // = require decidim/decidim_awesome/forms/autosave
@@ -0,0 +1,21 @@
1
+ // = require decidim/decidim_awesome/forms/custom_fields_builder
2
+ // = require_self
3
+
4
+ window.DecidimAwesome.FormRenderBuilder = window.DecidimAwesome.FormRenderBuilder || new CustomFieldsBuilder();
5
+
6
+ $(() => {
7
+ // use admin multilang specs if exists
8
+ let $el = $("proposal_custom_field:first", ".tabs-title.is-active");
9
+ $el = $el.length ? $el : $(".proposal_custom_field:first");
10
+ DecidimAwesome.FormRenderBuilder.init($el);
11
+
12
+ DecidimAwesome.FormRenderBuilder.$container.closest("form").on("submit", (e) => {
13
+ if(e.target.checkValidity()) {
14
+ // save current editor
15
+ DecidimAwesome.FormRenderBuilder.storeData();
16
+ } else {
17
+ e.preventDefault();
18
+ e.target.reportValidity();
19
+ }
20
+ });
21
+ });
@@ -0,0 +1,15 @@
1
+ input.awesome-auto-edit {
2
+ display: inline-block;
3
+ width: auto;
4
+ margin: 0 2px;
5
+ padding: 1px;
6
+ line-height: 0;
7
+ height: auto;
8
+ }
9
+ span.awesome-auto-edit {
10
+ padding: 0 4px;
11
+ background-color: #f0f0f0;
12
+ border-radius: 5px;
13
+ margin: 0;
14
+ font-weight: 600;
15
+ }