[IMP] clarity of links edition
According to user tests, users have a hard time finding out how to edit links. Thus, add same system as image edition (a small button appearing when hovering the element). Extract and unify these two to avoid redundancies between handlings as they are broadly similar (only details such as label, positioning and size of button relative to the element being hovered really change, the lifecycle itself is the same). The main setup still isn't very clean, there might be a better way to do it. bzr revid: xmo@openerp.com-20131204105212-u0a49nbvwilgtfst
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
@charset "utf-8";
|
||||
/* ---- CKEditor Minimal Reset ---- */
|
||||
.navbar.navbar-inverse .cke_chrome {
|
||||
border: none;
|
||||
@@ -221,6 +220,13 @@ ul.oe_menu_editor .disclose {
|
||||
background-color: #ffd9dd !important;
|
||||
}
|
||||
|
||||
.hover-edition-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 42;
|
||||
}
|
||||
|
||||
/* ---- SNIPPET EDITOR ---- */
|
||||
#oe_snippets {
|
||||
position: fixed;
|
||||
|
||||
@@ -181,6 +181,12 @@ ul.oe_menu_editor
|
||||
outline: 1px solid red !important
|
||||
background-color: #ffd9dd !important
|
||||
|
||||
.hover-edition-button
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
z-index: 42
|
||||
|
||||
/* ---- SNIPPET EDITOR ---- */
|
||||
|
||||
#oe_snippets
|
||||
|
||||
@@ -73,57 +73,6 @@
|
||||
link_dialog(editor);
|
||||
}, null, null, 500);
|
||||
|
||||
var previousSelection;
|
||||
$(editor.element.$).on('mouseenter', 'img', function () {
|
||||
if (previousSelection) { return; }
|
||||
var selected = new CKEDITOR.dom.element(this);
|
||||
if (!selected.is('img')
|
||||
|| selected.data('cke-realelement')
|
||||
|| selected.isReadOnly()
|
||||
|| selected.data('oe-model') === 'ir.ui.view') {
|
||||
return;
|
||||
}
|
||||
|
||||
// display button
|
||||
var $el = $((previousSelection = selected).$);
|
||||
var $btn = $('<button type="button" class="btn btn-primary image-edit-button" contenteditable="false">Edit</button>')
|
||||
.insertAfter($el)
|
||||
.click(function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
image_dialog(editor, selected);
|
||||
});
|
||||
|
||||
var position = $el.position();
|
||||
// http://bugs.jquery.com/ticket/5445#comment:6
|
||||
// if the image has margin: x auto for centering, FF & IE
|
||||
// will report top/left as the "correct" value and
|
||||
// marginTop/marginLeft at "0px", webkit browsers will
|
||||
// report top/left as 0-ish and set marginTop and
|
||||
// marginLeft
|
||||
var image_top = position.top + parseInt($el.css('marginTop'), 10);
|
||||
var image_left = position.left + parseInt($el.css('marginLeft'), 10);
|
||||
$btn.css({
|
||||
position: 'absolute',
|
||||
top: $el.height() / 2 + image_top - $btn.outerHeight() / 2,
|
||||
left: $el.width() / 2 + image_left - $btn.outerWidth() / 2,
|
||||
});
|
||||
}).on('mouseleave', 'img', function (e) {
|
||||
if (!previousSelection) { return; }
|
||||
var $previous = $(previousSelection.$);
|
||||
var $button = $previous.next('button');
|
||||
$button.css('visibility', 'hidden');
|
||||
var el = document.elementFromPoint(e.clientX, e.clientY);
|
||||
$button.css('visibility', '');
|
||||
if (el === this) { return; }
|
||||
$button.remove();
|
||||
previousSelection = null;
|
||||
});
|
||||
editor.on('destroy', function () {
|
||||
if (!previousSelection) { return; }
|
||||
$('.image-edit-button').remove();
|
||||
});
|
||||
|
||||
//noinspection JSValidateTypes
|
||||
editor.addCommand('link', {
|
||||
exec: function (editor) {
|
||||
@@ -463,6 +412,7 @@
|
||||
this.rte = new website.RTE(this);
|
||||
this.rte.on('change', this, this.proxy('rte_changed'));
|
||||
this.rte.on('rte:ready', this, function () {
|
||||
self.setup_hover_buttons();
|
||||
self.trigger('rte:ready');
|
||||
});
|
||||
|
||||
@@ -586,6 +536,97 @@
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a "hover" button for image and link edition
|
||||
*
|
||||
* @param {String} label the button's label
|
||||
* @param {Function} editfn edition function, called when clicking the button
|
||||
* @param {String} [classes] additional classes to set on the button
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
make_hover_button: function (label, editfn, classes) {
|
||||
return $(openerp.qweb.render('website.editor.hoverbutton', {
|
||||
label: label,
|
||||
classes: classes,
|
||||
})).hide().appendTo(document.body).click(function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
editfn.call(this, e);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* For UI clarity, during RTE edition when the user hovers links and
|
||||
* images a small button should appear to make the capability clear,
|
||||
* as not all users think of double-clicking the image or link.
|
||||
*/
|
||||
setup_hover_buttons: function () {
|
||||
var editor = this.rte.editor;
|
||||
var $link_button = this.make_hover_button(_t("Edit Link"), function () {
|
||||
var sel = new CKEDITOR.dom.element(previous);
|
||||
editor.getSelection().selectElement(sel);
|
||||
link_dialog(editor);
|
||||
$link_button.hide();
|
||||
previous = null;
|
||||
}, 'btn-xs');
|
||||
var $image_button = this.make_hover_button(_t("Edit Image"), function () {
|
||||
image_dialog(editor, new CKEDITOR.dom.element(previous));
|
||||
$image_button.hide();
|
||||
previous = null;
|
||||
});
|
||||
|
||||
// previous is the state of the button-trigger: it's the
|
||||
// currently-ish hovered element which can trigger a button showing.
|
||||
// -ish, because when moving to the button itself ``previous`` is
|
||||
// still set to the element having triggered showing the button.
|
||||
var previous;
|
||||
$(editor.element.$).on('mouseover', 'a, img', function (e) {
|
||||
// Back from edit button -> ignore
|
||||
if (previous && previous === this) { return; }
|
||||
|
||||
var selected = new CKEDITOR.dom.element(this);
|
||||
if (selected.data('oe-model') === 'ir.ui.view'
|
||||
|| selected.data('cke-realelement')
|
||||
|| selected.isReadOnly()) {
|
||||
return;
|
||||
}
|
||||
|
||||
previous = this;
|
||||
var $selected = $(this);
|
||||
var position = $selected.offset();
|
||||
if ($selected.is('img')) {
|
||||
var image_top = position.top + parseInt($selected.css('marginTop'), 10);
|
||||
var image_left = position.left + parseInt($selected.css('marginLeft'), 10);
|
||||
$link_button.hide();
|
||||
// center button on image
|
||||
$image_button.show().offset({
|
||||
top: $selected.outerHeight() / 2
|
||||
+ image_top
|
||||
- $image_button.outerHeight() / 2,
|
||||
left: $selected.outerWidth() / 2
|
||||
+ image_left
|
||||
- $image_button.outerWidth() / 2,
|
||||
});
|
||||
} else {
|
||||
$image_button.hide();
|
||||
// put button below link, horizontally centered
|
||||
$link_button.show().offset({
|
||||
top: $selected.outerHeight()
|
||||
+ position.top,
|
||||
left: $selected.outerWidth() / 2
|
||||
+ position.left
|
||||
- $link_button.outerWidth() / 2
|
||||
})
|
||||
}
|
||||
}).on('mouseleave', 'a, img', function (e) {
|
||||
var current = document.elementFromPoint(e.clientX, e.clientY);
|
||||
if (current === $link_button[0] || current === $image_button[0]) {
|
||||
return;
|
||||
}
|
||||
$image_button.add($link_button).hide();
|
||||
previous = null;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var blocks_selector = _.keys(CKEDITOR.dtd.$block).join(',');
|
||||
@@ -1438,11 +1479,6 @@
|
||||
// <br type="_moz"> appears when focusing RTE in FF, ignore
|
||||
continue;
|
||||
}
|
||||
if (node.className.indexOf('image-edit-button') !== -1) {
|
||||
// [Edit] button added and removed on image hover, don't count
|
||||
// as making parent node dirty
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
output.push(node);
|
||||
|
||||
@@ -194,4 +194,11 @@
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="website.editor.hoverbutton">
|
||||
<button type="button" contenteditable="false"
|
||||
t-attf-class="btn btn-primary hover-edition-button #{classes or ''}">
|
||||
<t t-esc="label"/>
|
||||
</button>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
||||
Reference in New Issue
Block a user