[IMP] website editor: remove button style from cke and insert into the link dialog box. Fix the dialog box label value when the user create a link.

This commit is contained in:
Christophe Matthieu 2014-07-10 13:34:02 +02:00
parent caa534e503
commit c2c0fdc916
2 changed files with 117 additions and 201 deletions

View File

@ -209,155 +209,6 @@
}
});
CKEDITOR.plugins.add('linkstyle', {
requires: 'panelbutton,floatpanel',
init: function (editor) {
var label = "Link Style";
editor.ui.add('LinkStyle', CKEDITOR.UI_PANELBUTTON, {
label: label,
title: label,
icon: '/website/static/src/img/bglink.png',
modes: { wysiwyg: true },
editorFocus: true,
context: 'a',
panel: {
css: '/web/static/lib/bootstrap/css/bootstrap.css',
attributes: { 'role': 'listbox', 'aria-label': label },
},
types: {
'btn-default': _t("Basic"),
'btn-primary': _t("Primary"),
'btn-success': _t("Success"),
'btn-info': _t("Info"),
'btn-warning': _t("Warning"),
'btn-danger': _t("Danger"),
},
sizes: {
'btn-xs': _t("Extra Small"),
'btn-sm': _t("Small"),
'': _t("Default"),
'btn-lg': _t("Large")
},
onRender: function () {
var self = this;
editor.on('selectionChange', function (e) {
var path = e.data.path, el;
if (!(e = path.contains('a')) || e.isReadOnly()) {
self.disable();
return;
}
self.enable();
});
// no hook where button is available, so wait
// "some time" after render.
setTimeout(function () {
self.disable();
}, 0)
},
enable: function () {
this.setState(CKEDITOR.TRISTATE_OFF);
},
disable: function () {
this.setState(CKEDITOR.TRISTATE_DISABLED);
},
onOpen: function () {
var link = get_selected_link(editor);
var id = this._.id;
var block = this._.panel._.panel._.blocks[id];
var $root = $(block.element.$);
$root.find('button').removeClass('active').removeProp('disabled');
// enable buttons matching link state
for (var type in this.types) {
if (!this.types.hasOwnProperty(type)) { continue; }
if (!link.hasClass(type)) { continue; }
$root.find('button[data-type=types].' + type)
.addClass('active');
}
var found;
for (var size in this.sizes) {
if (!this.sizes.hasOwnProperty(size)) { continue; }
if (!size || !link.hasClass(size)) { continue; }
found = true;
$root.find('button[data-type=sizes].' + size)
.addClass('active');
}
if (!found && link.hasClass('btn')) {
$root.find('button[data-type="sizes"][data-set-class=""]')
.addClass('active');
}
},
onBlock: function (panel, block) {
var self = this;
block.autoSize = true;
var html = ['<div style="padding: 5px">'];
html.push('<div style="white-space: nowrap">');
_(this.types).each(function (label, key) {
html.push(_.str.sprintf(
'<button type="button" class="btn %s" ' +
'data-type="types" data-set-class="%s">%s</button>',
key, key, label));
});
html.push('</div>');
html.push('<div style="white-space: nowrap; margin: 5px 0; text-align: center">');
_(this.sizes).each(function (label, key) {
html.push(_.str.sprintf(
'<button type="button" class="btn btn-default %s" ' +
'data-type="sizes" data-set-class="%s">%s</button>',
key, key, label));
});
html.push('</div>');
html.push('<button type="button" class="btn btn-link btn-block" ' +
'data-type="reset">Reset</button>');
html.push('</div>');
block.element.setHtml(html.join(' '));
var $panel = $(block.element.$);
$panel.on('click', 'button', function () {
self.clicked(this);
});
},
clicked: function (button) {
editor.focus();
editor.fire('saveSnapshot');
var $button = $(button),
$link = $(get_selected_link(editor).$);
if (!$link.hasClass('btn')) {
$link.addClass('btn btn-default');
}
switch($button.data('type')) {
case 'reset':
$link.removeClass('btn')
.removeClass(_.keys(this.types).join(' '))
.removeClass(_.keys(this.sizes).join(' '));
break;
case 'types':
$link.removeClass(_.keys(this.types).join(' '))
.addClass($button.data('set-class'));
break;
case 'sizes':
$link.removeClass(_.keys(this.sizes).join(' '))
.addClass($button.data('set-class'));
}
this._.panel.hide();
editor.fire('saveSnapshot');
},
});
}
});
CKEDITOR.plugins.add('oeref', {
requires: 'widget',
@ -1011,7 +862,7 @@
fillEmptyBlocks: false,
filebrowserImageUploadUrl: "/website/attach",
// Support for sharedSpaces in 4.x
extraPlugins: 'sharedspace,customdialogs,tablebutton,oeref,linkstyle',
extraPlugins: 'sharedspace,customdialogs,tablebutton,oeref',
// Place toolbar in controlled location
sharedSpaces: { top: 'oe_rte_toolbar' },
toolbar: [{
@ -1020,7 +871,7 @@
"Superscript", "TextColor", "BGColor", "RemoveFormat"
]},{
name: 'span', items: [
"Link", "LinkStyle", "Blockquote", "BulletedList",
"Link", "Blockquote", "BulletedList",
"NumberedList", "Indent", "Outdent"
]},{
name: 'justify', items: [
@ -1081,19 +932,25 @@
website.editor.LinkDialog = website.editor.Dialog.extend({
template: 'website.editor.dialog.link',
events: _.extend({}, website.editor.Dialog.prototype.events, {
'change :input.url-source': function (e) { this.changed($(e.target)); },
'change :input.url-source': 'changed',
'keyup :input.url': 'onkeyup',
'keyup :input': 'preview',
'mousedown': function (e) {
var $target = $(e.target).closest('.list-group-item');
var $target = $(e.target).closest('.list-group-item:has(.url-source)');
if (!$target.length || $target.hasClass('active')) {
// clicked outside groups, or clicked in active groups
return;
}
this.changed($target.find('.url-source').filter(':input'));
$target.find("input.url-source").change();
},
'click button.remove': 'remove_link',
'change input#link-text': function (e) {
this.text = $(e.target).val()
this.text = $(e.target).val();
},
'change select.link-style': function (e) {
if (this.$("input.url-source[value!='']").val()) {
this.preview();
}
},
}),
init: function (editor) {
@ -1137,67 +994,90 @@
});
return this._super().then(this.proxy('bind_data'));
},
save: function () {
var self = this, _super = this._super.bind(this);
var $e = this.$('.list-group-item.active .url-source').filter(':input');
var val = $e.val();
get_data: function () {
var self = this,
def = new $.Deferred(),
$e = this.$('.active input.url-source').filter(':input'),
val = $e.val(),
label = this.$('#link-text').val() || val;
if (!val || !$e[0].checkValidity()) {
// FIXME: error message
$e.closest('.form-group').addClass('has-error');
$e.focus();
return;
def.reject();
}
var done = $.when();
if ($e.hasClass('email-address')) {
this.make_link('mailto:' + val, false, val);
var style = this.$("#link-style-type").val();
var size = this.$("#link-style-size").val();
var classes = (style && style.length ? "btn " : "") + style + " " + size;
if ($e.hasClass('email-address') && $e.val().indexOf("@") !== -1) {
def.resolve('mailto:' + val, false, label);
} else if ($e.hasClass('page')) {
var data = $e.select2('data');
if (!data.create) {
self.make_link(data.id, false, data.text);
def.resolve(data.id, false, data.text);
} else {
// Create the page, get the URL back
done = $.get(_.str.sprintf(
$.get(_.str.sprintf(
'/website/add/%s?noredirect=1', encodeURI(data.id)))
.then(function (response) {
self.make_link(response, false, data.id);
def.resolve(response, false, data.id);
});
}
} else {
this.make_link(val, this.$('input.window-new').prop('checked'));
def.resolve(val, this.$('input.window-new').prop('checked'), label, classes);
}
done.then(_super);
return def;
},
make_link: function (url, new_window, label) {
save: function () {
var self = this;
var _super = this._super.bind(this);
return this.get_data()
.then(function (url, new_window, label, classes) {
self.make_link(url, new_window, label, classes);
}).then(_super);
},
bind_data: function (text, href, new_window) {
href = href || this.element && (this.element.data( 'cke-saved-href')
make_link: function (url, new_window, label, classes) {
},
bind_data: function () {
var href = this.element && (this.element.data( 'cke-saved-href')
|| this.element.getAttribute('href'));
if (new_window === undefined) {
new_window = this.element
var new_window = this.element
? this.element.getAttribute('target') === '_blank'
: false;
}
if (text === undefined) {
text = this.element ? this.element.getText() : '';
var text = this.element ? this.element.getText() : '';
if (!text.length) {
var selection = this.editor.getSelection();
text = selection.getSelectedText();
}
this.$('input#link-text').val(text);
this.$('input.window-new').prop('checked', new_window);
var classes = this.element && this.element.$.className;
if (classes) {
this.$('option[value!=""]').each(function () {
var $option = $(this);
if (classes.indexOf($option.val()) !== -1) {
$option.attr("selected", "selected");
}
});
}
if (!href) { return; }
var match, $control;
if ((match = /mailto:(.+)/.exec(href))) {
$control = this.$('input.email-address').val(match[1]);
this.$('input.email-address').val(match[1]).change();
}
if (!$control) {
$control = this.$('input.url').val(href);
this.$('input.url').val(href).change();
this.$('input.window-new').closest("div").show();
}
this.changed($control);
},
changed: function ($e) {
changed: function (e) {
var $e = $(e.target);
this.$('.url-source').filter(':input').not($e).val('')
.filter(function () { return !!$(this).data('select2'); })
.select2('data', null);
@ -1205,6 +1085,9 @@
.addClass('active')
.siblings().removeClass('active')
.addBack().removeClass('has-error');
if ($e.val() && $e.val().length) {
this.preview();
}
},
call: function (method, args, kwargs) {
var self = this;
@ -1232,6 +1115,21 @@
context: website.get_context(),
});
},
onkeyup: function (e) {
var $e = $(e.target);
var is_link = ($e.val()||'').length && $e.val().indexOf("@") === -1;
this.$('input.window-new').closest("div").toggle(is_link);
this.preview();
},
preview: function () {
var $preview = this.$("#link-preview");
this.get_data().then(function (url, new_window, label, classes) {
$preview.attr("href", url)
.attr("target", new_window ? '_blank' : "")
.text(label && label.length ? label : url)
.attr("class", classes);
});
}
});
website.editor.RTELinkDialog = website.editor.LinkDialog.extend({
start: function () {
@ -1271,7 +1169,7 @@
* @param {Boolean} [new_window=false]
* @param {String} [label=null]
*/
make_link: function (url, new_window, label) {
make_link: function (url, new_window, label, classes) {
var attributes = {href: url, 'data-cke-saved-href': url};
var to_remove = [];
if (new_window) {
@ -1279,6 +1177,9 @@
} else {
to_remove.push('target');
}
if (classes && classes.length) {
attributes['class'] = classes;
}
if (this.element) {
this.element.setAttributes(attributes);

View File

@ -51,7 +51,7 @@
id="link-page" type="hidden"/>
</li>
<li class="list-group-item form-group clearfix">
<div class="pull-right">
<div class="pull-right" style="display: none;">
<label>
<input type="checkbox" class="window-new"/>
Open in new window
@ -59,32 +59,47 @@
</div>
<h4 class="list-group-item-heading">
<label for="link-external" class="control-label">
URL
URL or Email Address
</label>
</h4>
<input type="text" class="form-control url url-source"
<input type="text" class="form-control url email-address url-source"
id="link-external" placeholder="http://openerp.com"/>
</li>
<li class="list-group-item form-group">
<h4 class="list-group-item-heading">
<label for="link-email" class="control-label">
Email Address
<label for="link-text" class="control-label">
Link text
</label>
</h4>
<input type="email" class="form-control email-address url-source"
id="link-email" placeholder="you@yourwebsite.com"/>
</li>
</ul>
<div class="form-horizontal">
<div class="form-group">
<label for="link-text" class="col-sm-2 control-label">
Link text
</label>
<div class="col-sm-10">
<input type="text" class="form-control"
id="link-text"/>
</div>
</div>
</li>
<li class="list-group-item form-group">
<h4 class="list-group-item-heading">
<label for="link-type" class="control-label">
Style
</label>
</h4>
<select id="link-style-type" class="form-control link-style pull-left" style="display: inline-block; width: 49%;">
<option value="" selected="selected">Link</option>
<option value="btn-default">Basic</option>
<option value="btn-primary">Primary</option>
<option value="btn-success">Success</option>
<option value="btn-info">Info</option>
<option value="btn-warning">Warning</option>
<option value="btn-danger">Danger</option>
</select>
<select id="link-style-size" class="form-control link-style pull-right" style="display: inline-block; width: 49%;">
<option value="btn-xs">Extra Small</option>
<option value="btn-sm">Small</option>
<option value="" selected="selected">Default</option>
<option value="btn-lg">Large</option>
</select>
<div class="clearfix"/>
</li>
</ul>
<div class="text-center">
<a id="link-preview" href="#" class="hidden">Preview</a>
</div>
</form>
</t>