summaryrefslogtreecommitdiff
path: root/addons/website/static/src
diff options
context:
space:
mode:
Diffstat (limited to 'addons/website/static/src')
-rw-r--r--addons/website/static/src/js/editor/snippets.options.js73
-rw-r--r--addons/website/static/src/xml/website.editor.xml1
2 files changed, 56 insertions, 18 deletions
diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js
index c3ea729d28d..cb94093c731 100644
--- a/addons/website/static/src/js/editor/snippets.options.js
+++ b/addons/website/static/src/js/editor/snippets.options.js
@@ -1547,7 +1547,7 @@ options.registry.topMenuColor = options.registry.colorpicker.extend({
/**
* Handles the edition of snippet's anchor name.
*/
-options.registry.anchorName = options.Class.extend({
+options.registry.anchor = options.Class.extend({
xmlDependencies: ['/website/static/src/xml/website.editor.xml'],
//--------------------------------------------------------------------------
@@ -1557,6 +1557,24 @@ options.registry.anchorName = options.Class.extend({
/**
* @override
*/
+ start: function () {
+ // Generate anchor and copy it to clipboard on click, show the tooltip on success
+ this.$button = this.$el.find('we-button');
+ const clipboard = new ClipboardJS(this.$button[0], {text: () => this._getAnchorLink()});
+ clipboard.on('success', () => {
+ const anchor = decodeURIComponent(this._getAnchorLink());
+ this.displayNotification({
+ title: _t("Copied !"),
+ message: _.str.sprintf(_t("The anchor has been copied to your clipboard.<br>Link: %s"), anchor),
+ buttons: [{text: _t("edit"), click: () => this.openAnchorDialog()}],
+ });
+ });
+
+ return this._super.apply(this, arguments);
+ },
+ /**
+ * @override
+ */
isTopOption: function () {
return true;
},
@@ -1568,20 +1586,19 @@ options.registry.anchorName = options.Class.extend({
},
//--------------------------------------------------------------------------
- // Options
+ // Private
//--------------------------------------------------------------------------
-
/**
* @see this.selectClass for parameters
*/
openAnchorDialog: function (previewMode, value, $opt) {
var self = this;
var buttons = [{
- text: _t("Save"),
+ text: _t("Save & copy"),
classes: 'btn-primary',
click: function () {
var $input = this.$('.o_input_anchor_name');
- var anchorName = $input.val().trim().replace(/\s/g, '_');
+ var anchorName = self._text2Anchor($input.val());
if (self.$target[0].id === anchorName) {
// If the chosen anchor name is already the one used by the
// element, close the dialog and do nothing else
@@ -1589,15 +1606,13 @@ options.registry.anchorName = options.Class.extend({
return;
}
- var isValid = /^[\w-]+$/.test(anchorName);
- var alreadyExists = isValid && $('#' + anchorName).length > 0;
- var anchorOK = isValid && !alreadyExists;
- this.$('.o_anchor_not_valid').toggleClass('d-none', isValid);
+ const alreadyExists = !!document.getElementById(anchorName);
this.$('.o_anchor_already_exists').toggleClass('d-none', !alreadyExists);
- $input.toggleClass('is-invalid', !anchorOK);
- if (anchorOK) {
+ $input.toggleClass('is-invalid', alreadyExists);
+ if (!alreadyExists) {
self._setAnchorName(anchorName);
this.close();
+ self.$button[0].click();
}
},
}, {
@@ -1618,16 +1633,11 @@ options.registry.anchorName = options.Class.extend({
new Dialog(this, {
title: _t("Link Anchor"),
$content: $(qweb.render('website.dialog.anchorName', {
- currentAnchor: this.$target.attr('id'),
+ currentAnchor: decodeURIComponent(this.$target.attr('id')),
})),
buttons: buttons,
}).open();
},
-
- //--------------------------------------------------------------------------
- // Private
- //--------------------------------------------------------------------------
-
/**
* @private
* @param {String} value
@@ -1643,6 +1653,35 @@ options.registry.anchorName = options.Class.extend({
}
this.$target.trigger('content_changed');
},
+ /**
+ * Returns anchor text.
+ *
+ * @private
+ * @returns {string}
+ */
+ _getAnchorLink: function () {
+ if (!this.$target[0].id) {
+ const $titles = this.$target.find('h1, h2, h3, h4, h5, h6');
+ const title = $titles.length > 0 ? $titles[0].innerText : this.data.snippetName;
+ const anchorName = this._text2Anchor(title);
+ let n = '';
+ while (document.getElementById(anchorName + n)) {
+ n = (n || 1) + 1;
+ }
+ this._setAnchorName(anchorName + n);
+ }
+ return `#${this.$target[0].id}`;
+ },
+ /**
+ * Creates a safe id/anchor from text.
+ *
+ * @private
+ * @param {string} text
+ * @returns {string}
+ */
+ _text2Anchor: function (text) {
+ return encodeURIComponent(text.trim().replace(/\s+/g, '-'));
+ },
});
/**
diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml
index 9f8a2e302fc..31ffb28704d 100644
--- a/addons/website/static/src/xml/website.editor.xml
+++ b/addons/website/static/src/xml/website.editor.xml
@@ -115,7 +115,6 @@
<div class="col-md-9">
<input type="text" class="form-control o_input_anchor_name" id="anchorName" t-attf-value="#{currentAnchor}" placeholder="Anchor name"/>
<div class="invalid-feedback">
- <p class="d-none o_anchor_not_valid">The chosen name is not valid (use only a-Z A-Z 0-9 - _)</p>
<p class="d-none o_anchor_already_exists">The chosen name already exists</p>
</div>
</div>