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.
- checksums.yaml +4 -4
- data/README.md +38 -8
- data/app/assets/config/decidim_admin_decidim_awesome_manifest.css +2 -2
- data/app/assets/config/decidim_admin_decidim_awesome_manifest.js +1 -1
- data/app/assets/config/decidim_decidim_awesome_manifest.css +2 -2
- data/app/assets/config/decidim_decidim_awesome_manifest.js +3 -2
- data/app/assets/config/legacy_decidim_admin_decidim_awesome_manifest.js +2 -0
- data/app/assets/config/legacy_decidim_decidim_awesome_manifest.js +4 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin/auto_edit.js.es6 +77 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin/codemirror.js.es6 +14 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin/form_builder.js.es6 +80 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin/legacy_form_builder.js.es6 +80 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin/user_picker.js.es6 +24 -0
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_admin.js +7 -0
- data/app/assets/javascripts/decidim/decidim_awesome/{application.js → awesome_application.js} +1 -2
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/hashtags.js.es6 +48 -0
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/layers.js.es6 +107 -0
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/load_map.js.es6 +15 -0
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/map.js.es6 +170 -178
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/markers.js.es6 +56 -0
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/meetings.js.es6 +7 -6
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/proposals.js.es6 +18 -5
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/utilities.js.es6 +57 -0
- data/app/assets/javascripts/decidim/decidim_awesome/editors/legacy_quill_editor.js.es6 +172 -0
- data/app/assets/javascripts/decidim/decidim_awesome/editors/quill_editor.js.es6 +34 -9
- data/app/assets/javascripts/decidim/decidim_awesome/editors/tabs_focus.js.es6 +24 -0
- data/app/assets/javascripts/decidim/decidim_awesome/forms/custom_fields_builder.js.es6 +211 -0
- data/app/assets/javascripts/decidim/decidim_awesome/forms/rich_text_plugin.js.es6 +106 -0
- data/app/assets/javascripts/decidim/decidim_awesome/legacy_admin.js +7 -0
- data/app/assets/javascripts/decidim/decidim_awesome/legacy_application.js +3 -0
- data/app/assets/javascripts/decidim/decidim_awesome/proposals/custom_fields.js.es6 +21 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/auto_edits.scss +15 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/codemirror.scss +27 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/constraints.scss +12 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/custom_fields.scss +66 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/admin/user_picker.scss +35 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/{admin.scss → awesome_admin.scss} +19 -4
- data/app/assets/stylesheets/decidim/decidim_awesome/awesome_application.scss +22 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/awesome_map/leaflet.scss.erb +9 -0
- data/app/assets/stylesheets/decidim/decidim_awesome/awesome_map/map.scss +95 -1
- data/app/assets/stylesheets/decidim/decidim_awesome/editors/markdown_editor.scss +1 -1
- data/app/assets/stylesheets/decidim/decidim_awesome/editors/quill_editor.scss +16 -1
- data/app/awesome_overrides/forms/decidim/proposals/proposal_wizard_create_step_form_override.rb +28 -0
- data/app/awesome_overrides/presenters/decidim/menu_presenter_override.rb +11 -3
- data/app/cells/decidim/decidim_awesome/content_blocks/map/show.erb +74 -0
- data/app/cells/decidim/decidim_awesome/content_blocks/map_cell.rb +54 -0
- data/app/cells/decidim/decidim_awesome/content_blocks/map_form/show.erb +61 -0
- data/app/cells/decidim/decidim_awesome/content_blocks/map_form_cell.rb +19 -0
- data/app/commands/concerns/decidim/decidim_awesome/admin/needs_constraint_helpers.rb +32 -0
- data/app/commands/decidim/decidim_awesome/admin/create_proposal_custom_field.rb +45 -0
- data/app/commands/decidim/decidim_awesome/admin/create_scoped_admin.rb +38 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_constraint.rb +4 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_proposal_custom_field.rb +40 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_admin.rb +40 -0
- data/app/commands/decidim/decidim_awesome/admin/destroy_scoped_style.rb +1 -1
- data/app/commands/decidim/decidim_awesome/admin/rename_scope_label.rb +58 -0
- data/app/commands/decidim/decidim_awesome/admin/update_config.rb +5 -1
- data/app/controllers/concerns/decidim/decidim_awesome/admin_not_found_redirect.rb +39 -0
- data/app/controllers/decidim/decidim_awesome/admin/checks_controller.rb +1 -1
- data/app/controllers/decidim/decidim_awesome/admin/config_controller.rb +33 -20
- data/app/controllers/decidim/decidim_awesome/admin/constraints_controller.rb +4 -0
- data/app/controllers/decidim/decidim_awesome/admin/menu_hacks_controller.rb +2 -2
- data/app/controllers/decidim/decidim_awesome/admin/proposal_custom_fields_controller.rb +38 -0
- data/app/controllers/decidim/decidim_awesome/admin/scoped_admins_controller.rb +38 -0
- data/app/controllers/decidim/decidim_awesome/admin/scoped_styles_controller.rb +38 -0
- data/app/controllers/decidim/decidim_awesome/map_component/map_controller.rb +1 -4
- data/app/forms/decidim/decidim_awesome/admin/config_form.rb +50 -0
- data/app/forms/decidim/decidim_awesome/admin/constraint_form.rb +3 -1
- data/app/helpers/decidim/decidim_awesome/admin/config_constraints_helpers.rb +11 -7
- data/app/helpers/decidim/decidim_awesome/amendments_helper_override.rb +48 -0
- data/app/helpers/decidim/decidim_awesome/map_helper.rb +66 -53
- data/app/helpers/decidim/decidim_awesome/proposals/application_helper_override.rb +78 -0
- data/app/middleware/decidim/decidim_awesome/current_config.rb +182 -0
- data/app/models/decidim/decidim_awesome/awesome_config.rb +15 -0
- data/app/models/decidim/decidim_awesome/user_override.rb +25 -0
- data/app/permissions/decidim/decidim_awesome/admin/permissions.rb +2 -0
- data/app/uploaders/decidim/decidim_awesome/image_uploader.rb +0 -5
- data/app/views/decidim/decidim_awesome/admin/checks/index.html.erb +2 -2
- data/app/views/decidim/decidim_awesome/admin/config/_autoedit_box_label.html.erb +7 -0
- data/app/views/decidim/decidim_awesome/admin/config/_constraints.html.erb +2 -2
- data/app/views/decidim/decidim_awesome/admin/config/_form_admins.html.erb +21 -0
- data/app/views/decidim/decidim_awesome/admin/config/_form_editors.html.erb +0 -3
- data/app/views/decidim/decidim_awesome/admin/config/_form_proposal_custom_fields.html.erb +25 -0
- data/app/views/decidim/decidim_awesome/admin/config/_form_proposals.html.erb +0 -2
- data/app/views/decidim/decidim_awesome/admin/config/_form_styles.html.erb +4 -6
- data/app/views/decidim/decidim_awesome/admin/config/show.html.erb +1 -2
- data/app/views/decidim/decidim_awesome/admin/proposals/_editor.html.erb +4 -0
- data/app/views/decidim/decidim_awesome/custom_fields/_form_render.html.erb +6 -0
- data/app/views/decidim/decidim_awesome/map_component/map/show.html.erb +3 -32
- data/app/views/decidim/proposals/admin/proposals/_form.html.erb +101 -0
- data/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +83 -0
- data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +1 -0
- data/app/views/layouts/decidim/admin/decidim_awesome.html.erb +25 -11
- data/app/views/layouts/decidim/decidim_awesome/_awesome_config.html.erb +8 -1
- data/app/views/layouts/decidim/decidim_awesome/_custom_styles.html.erb +1 -1
- data/app/views/v0.23/decidim/proposals/collaborative_drafts/_show.html.erb +134 -0
- data/app/views/v0.23/layouts/decidim/_head.html.erb +2 -2
- data/app/views/v0.23/layouts/decidim/admin/_header.html.erb +2 -2
- data/app/views/v0.24/decidim/proposals/collaborative_drafts/_show.html.erb +128 -0
- data/app/views/{v0.22 → v0.24}/layouts/decidim/_head.html.erb +4 -2
- data/app/views/{v0.22 → v0.24}/layouts/decidim/admin/_header.html.erb +3 -2
- data/config/locales/ca.yml +75 -3
- data/config/locales/cs.yml +75 -3
- data/config/locales/en.yml +104 -11
- data/config/locales/es.yml +74 -2
- data/config/locales/eu.yml +76 -4
- data/config/locales/fr.yml +214 -142
- data/config/locales/it.yml +284 -0
- data/config/locales/ja.yml +284 -0
- data/config/locales/nl.yml +208 -136
- data/config/locales/sv.yml +109 -37
- data/db/migrate/20210628150825_change_awesome_config_var_type.rb +12 -0
- data/lib/decidim/decidim_awesome/admin_engine.rb +16 -4
- data/lib/decidim/decidim_awesome/awesome_helpers.rb +17 -10
- data/lib/decidim/decidim_awesome/checksums.yml +19 -9
- data/lib/decidim/decidim_awesome/config.rb +54 -9
- data/lib/decidim/decidim_awesome/context_analyzers/request_analyzer.rb +27 -21
- data/lib/decidim/decidim_awesome/custom_fields.rb +94 -0
- data/lib/decidim/decidim_awesome/engine.rb +64 -8
- data/lib/decidim/decidim_awesome/iframe_component/component.rb +1 -1
- data/lib/decidim/decidim_awesome/map_component/component.rb +8 -2
- data/lib/decidim/decidim_awesome/menu_hacker.rb +17 -15
- data/lib/decidim/decidim_awesome/system_checker.rb +1 -1
- data/lib/decidim/decidim_awesome/test/shared_examples/box_label_editor.rb +116 -0
- data/lib/decidim/decidim_awesome/test/shared_examples/current_config_examples.rb +143 -0
- data/lib/decidim/decidim_awesome/test/shared_examples/editor_examples.rb +4 -0
- data/lib/decidim/decidim_awesome/test/shared_examples/scoped_admins_examples.rb +428 -0
- data/lib/decidim/decidim_awesome/version.rb +2 -2
- data/lib/decidim/decidim_awesome.rb +41 -8
- data/vendor/assets/javascripts/codemirror.js +9801 -0
- data/vendor/assets/javascripts/delta.min.js +405 -0
- data/vendor/assets/javascripts/delta.min.js.map +1 -0
- data/vendor/assets/javascripts/europa.min.js +4 -0
- data/vendor/assets/javascripts/form-builder.min.js +19 -0
- data/vendor/assets/javascripts/form-render.min.js +19 -0
- data/vendor/assets/javascripts/inscrybmde.min.js +1 -1
- data/vendor/assets/javascripts/jquery-ui.min.js +13 -0
- data/vendor/assets/javascripts/jquery.truncate.js +105 -0
- data/vendor/assets/javascripts/keymap/sublime.js +720 -0
- data/vendor/assets/javascripts/mode/css/css.js +864 -0
- data/vendor/assets/javascripts/select2.js +6147 -0
- data/vendor/assets/langs/en-US.lang +110 -0
- data/vendor/assets/stylesheets/codemirror.css +350 -0
- data/vendor/assets/stylesheets/inscrybmde.min.scss +194 -0
- data/vendor/assets/stylesheets/jquery-ui.min.css +7 -0
- data/vendor/assets/stylesheets/select2-foundation-theme.css +249 -0
- data/vendor/assets/stylesheets/select2.css +515 -0
- metadata +101 -34
- data/app/assets/images/decidim/decidim_awesome/loading.gif +0 -0
- data/app/assets/javascripts/decidim/decidim_awesome/admin.js +0 -2
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/legacy_map.js.es6 +0 -225
- data/app/assets/javascripts/decidim/decidim_awesome/awesome_map/legacy_proposals.js.es6 +0 -82
- data/app/assets/javascripts/decidim/decidim_awesome/editors/markdown_view.js.es6 +0 -12
- data/app/assets/stylesheets/decidim/decidim_awesome/application.scss +0 -8
- data/app/assets/stylesheets/decidim/decidim_awesome/editors/markdown_view.scss +0 -27
- data/app/awesome_overrides/presenters/decidim/proposals/proposal_presenter_override.rb +0 -64
- data/lib/decidim/decidim_awesome/content_renderers/markdown_renderer.rb +0 -18
- data/lib/decidim/decidim_awesome/content_renderers.rb +0 -9
- 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
|
-
|
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"
|
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: $
|
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,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
|
+
}
|