diff options
5 files changed, 77 insertions, 18 deletions
diff --git a/addons/web_editor/static/lib/summernote/src/js/module/Editor.js b/addons/web_editor/static/lib/summernote/src/js/module/Editor.js index 40b7c95e98d..b5e3190ce2e 100644 --- a/addons/web_editor/static/lib/summernote/src/js/module/Editor.js +++ b/addons/web_editor/static/lib/summernote/src/js/module/Editor.js @@ -618,6 +618,9 @@ define([ var isNewWindow = linkInfo.isNewWindow; var rng = linkInfo.range || this.createRange($editable); var isTextChanged = rng.toString() !== linkText; + // Hack : This method was updated to create buttons as well (using the same logic as anchor nodes). + const nodeName = linkInfo.isButton ? 'BUTTON' : 'A'; + const pred = dom.makePredByNodeName(nodeName); options = options || dom.makeLayoutInfo($editable).editor().data('options'); @@ -629,23 +632,25 @@ define([ var anchors = []; // ODOO: adding this branch to modify existing anchor if it fully contains the range - var ancestor_anchor = dom.ancestor(rng.sc, dom.isAnchor); - if(ancestor_anchor && ancestor_anchor === dom.ancestor(rng.ec, dom.isAnchor)) { + var ancestor_anchor = dom.ancestor(rng.sc, pred); + if (ancestor_anchor && ancestor_anchor === dom.ancestor(rng.ec, pred)) { anchors.push($(ancestor_anchor).html(linkText).get(0)); } else if (isTextChanged) { - // Create a new link when text changed. - var anchor = rng.insertNode($('<A>' + linkText + '</A>')[0]); + // Create a new element when text changed. + var anchor = rng.insertNode($(`<${nodeName}>${linkText}</${nodeName}>`)[0]); anchors.push(anchor); } else { anchors = style.styleNodes(rng, { - nodeName: 'A', + nodeName: nodeName, expandClosestSibling: true, onlyPartialContains: true }); } $.each(anchors, function (idx, anchor) { - $(anchor).attr('href', linkUrl); + if (!linkInfo.isButton) { + $(anchor).attr('href', linkUrl); + } $(anchor).attr('class', linkInfo.className || null); // ODOO: addition $(anchor).css(linkInfo.style || {}); // ODOO: addition if (isNewWindow) { @@ -672,6 +677,8 @@ define([ /** * returns link info + * Hack : This method was updated to return a boolean attribute 'isButton' to allow + * handling buttons in linkDialog. * * @return {Object} * @return {WrappedRange} return.range @@ -706,11 +713,24 @@ define([ // Get the first anchor on range(for edit). var $anchor = $(list.head(rng.nodes(dom.isAnchor))); + // Check if the target is a button element. + let isButton = false; + if (!$anchor.length) { + const pred = dom.makePredByNodeName('BUTTON'); + const rngNew = range.create().expand(pred); + const target = list.head(rngNew.nodes(pred)); + if (target && target.nodeName === 'BUTTON') { + isButton = true; + rng = rngNew; + } + } + return { range: rng, text: rng.toString(), isNewWindow: $anchor.length ? $anchor.attr('target') === '_blank' : false, - url: $anchor.length ? $anchor.attr('href') : '' + url: $anchor.length ? $anchor.attr('href') : '', + isButton: isButton, }; }; diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js b/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js index ed17127c55a..cf2fa9dd04a 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/link_dialog.js @@ -26,6 +26,7 @@ var LinkDialog = Dialog.extend({ /** * @constructor + * @param {Boolean} linkInfo.isButton - whether if the target is a button element. */ init: function (parent, options, editable, linkInfo) { this.options = options || {}; @@ -40,8 +41,11 @@ var LinkDialog = Dialog.extend({ }, }); + this.data = linkInfo || {}; + this.isButton = this.data.isButton; + // Using explicit type 'link' to preserve style when the target is <button class="...btn-link"/>. this.colorsData = [ - {type: '', label: _t("Link"), btnPreview: 'link'}, + {type: this.isButton ? 'link' : '', label: _t("Link"), btnPreview: 'link'}, {type: 'primary', label: _t("Primary"), btnPreview: 'primary'}, {type: 'secondary', label: _t("Secondary"), btnPreview: 'secondary'}, // Note: by compatibility the dialog should be able to remove old @@ -51,8 +55,6 @@ var LinkDialog = Dialog.extend({ ]; this.editable = editable; - this.data = linkInfo || {}; - this.data.className = ""; this.data.iniClassName = ""; @@ -60,10 +62,10 @@ var LinkDialog = Dialog.extend({ this.needLabel = !r || (r.sc === r.ec && r.so === r.eo); if (this.data.range) { - const $link = $(this.data.range.sc).filter("a"); - this.data.iniClassName = $link.attr("class") || ""; + const $el = $(this.data.range.sc).filter(this.isButton ? "button" : "a"); + this.data.iniClassName = $el.attr("class") || ""; this.colorCombinationClass = false; - let $node = $link; + let $node = $el; while ($node.length && !$node.is('body')) { const className = $node.attr('class') || ''; const m = className.match(/\b(o_cc\d+)\b/g); @@ -156,6 +158,10 @@ var LinkDialog = Dialog.extend({ this.data.className = this.data.iniClassName .replace(allBtnClassSuffixes, ' ') .replace(allBtnShapes, ' '); + // 'o_submit' class will force anchor to be handled as a button in linkdialog. + if (/(?:s_website_form_send|o_submit)/.test(this.data.className)) { + this.isButton = true; + } }, /** * @override @@ -263,7 +269,7 @@ var LinkDialog = Dialog.extend({ } } - if ($url.prop('required') && (!url || !$url[0].checkValidity())) { + if (!this.isButton && $url.prop('required') && (!url || !$url[0].checkValidity())) { return null; } diff --git a/addons/web_editor/static/src/xml/wysiwyg.xml b/addons/web_editor/static/src/xml/wysiwyg.xml index cef24aec75e..5c9164dca0d 100644 --- a/addons/web_editor/static/src/xml/wysiwyg.xml +++ b/addons/web_editor/static/src/xml/wysiwyg.xml @@ -466,7 +466,7 @@ <input type="text" name="label" class="form-control" id="o_link_dialog_label_input" required="required" t-att-value="widget.data.text"/> </div> </div> - <div class="form-group row o_url_input"> + <div t-attf-class="form-group row o_url_input#{widget.isButton ? ' d-none' : ''}"> <label class="col-form-label col-md-3" for="o_link_dialog_url_input">URL or Email</label> <div class="col-md-9"> <input type="text" name="url" class="form-control" id="o_link_dialog_url_input" required="required"/> @@ -518,7 +518,7 @@ </div> </div> </div> - <div class="form-group row"> + <div t-if="!widget.isButton" class="form-group row"> <div class="offset-md-3 col-md-9"> <label class="o_switch"> <input type="checkbox" name="is_new_window" t-att-checked="widget.data.isNewWindow ? 'checked' : undefined"/> diff --git a/addons/website_form/static/tests/tours/website_form_editor.js b/addons/website_form/static/tests/tours/website_form_editor.js index a50afdf1e7b..97708dccc52 100644 --- a/addons/website_form/static/tests/tours/website_form_editor.js +++ b/addons/website_form/static/tests/tours/website_form_editor.js @@ -226,6 +226,39 @@ odoo.define('website_form_editor.tour', function (require) { ...addExistingField('attachment_ids', 'file', 'Invoice Scan'), + // Edit the submit button using linkDialog. + { + content: "Double click submit button to edit it", + trigger: '.s_website_form_send', + run: 'dblclick', + }, { + content: "Check that no URL field is suggested", + trigger: 'form:has(#o_link_dialog_label_input:hidden)', + run: () => null, + }, { + content: "Check that preview element has the same style", + trigger: '.o_link_dialog_preview:has(.s_website_form_send.btn.btn-lg.btn-primary)', + run: () => null, + }, { + content: "Change button's style", + trigger: 'label:has(input[name="link_style_color"][value="secondary"])', + run: () => { + $('input[name="link_style_color"][value="secondary"]').click(); + $('select[name="link_style_shape"]').val('rounded-circle').change(); + $('select[name="link_style_size"]').val('sm').change(); + }, + }, { + content: "Check that preview is updated too", + trigger: '.o_link_dialog_preview:has(.s_website_form_send.btn.btn-sm.btn-secondary.rounded-circle)', + run: () => null, + }, { + content: "Save changes from linkDialog", + trigger: '.modal-footer .btn-primary', + }, { + content: "Check the resulting button", + trigger: '.s_website_form_send.btn.btn-sm.btn-secondary.rounded-circle', + run: () => null, + }, // Save the page { trigger: 'body', diff --git a/addons/website_mass_mailing/views/snippets_templates.xml b/addons/website_mass_mailing/views/snippets_templates.xml index bbfefbb93de..1c7c58e86dd 100644 --- a/addons/website_mass_mailing/views/snippets_templates.xml +++ b/addons/website_mass_mailing/views/snippets_templates.xml @@ -29,8 +29,8 @@ <div class="input-group"> <input type="email" name="email" class="js_subscribe_email form-control" placeholder="your email..."/> <span class="input-group-append"> - <a role="button" href="#" class="btn btn-primary js_subscribe_btn">Subscribe</a> - <a role="button" href="#" class="btn btn-success js_subscribed_btn d-none" disabled="disabled">Thanks</a> + <a role="button" href="#" class="btn btn-primary js_subscribe_btn o_submit">Subscribe</a> + <a role="button" href="#" class="btn btn-success js_subscribed_btn d-none o_submit" disabled="disabled">Thanks</a> </span> </div> </div> |
