[IMP] website editor: remove button style from cke and insert into the link dialog...
authorChristophe Matthieu <chm@odoo.com>
Thu, 10 Jul 2014 11:34:02 +0000 (13:34 +0200)
committerChristophe Matthieu <chm@odoo.com>
Thu, 10 Jul 2014 11:34:02 +0000 (13:34 +0200)
addons/website/static/src/js/website.editor.js
addons/website/static/src/xml/website.editor.xml

index 2ff6fca..ff50619 100644 (file)
             }
         });
 
-        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',
 
                 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: [{
                         "Superscript", "TextColor", "BGColor", "RemoveFormat"
                     ]},{
                     name: 'span', items: [
-                        "Link", "LinkStyle", "Blockquote", "BulletedList",
+                        "Link", "Blockquote", "BulletedList",
                         "NumberedList", "Indent", "Outdent"
                     ]},{
                     name: 'justify', items: [
     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) {
             });
             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;
+        },
+        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);
         },
-        make_link: function (url, new_window, label) {
+        make_link: function (url, new_window, label, classes) {
         },
-        bind_data: function (text, href, new_window) {
-            href = href || this.element && (this.element.data( 'cke-saved-href')
+        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);
                 .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;
                 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 () {
          * @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) {
             } else {
                 to_remove.push('target');
             }
+            if (classes && classes.length) {
+                attributes['class'] = classes;
+            }
 
             if (this.element) {
                 this.element.setAttributes(attributes);
index d61b6ed..e895c08 100644 (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
                         </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>