diff --git a/src/node/utils/toolbar.js b/src/node/utils/toolbar.js index 5bff6bb8b..3a073ff36 100644 --- a/src/node/utils/toolbar.js +++ b/src/node/utils/toolbar.js @@ -22,17 +22,16 @@ defaultButtonAttributes = function (name, overrides) { tag = function (name, attributes, contents) { var aStr = tagAttributes(attributes); - if (contents) { + if (_.isString(contents) && contents.length > 0) { return '<' + name + aStr + '>' + contents + ''; } else { - return '<' + name + aStr + '/>'; + return '<' + name + aStr + '>'; } }; tagAttributes = function (attributes) { - attributes = attributes || {}; - attributes = _.reduce(attributes, function (o, val, name) { + attributes = _.reduce(attributes || {}, function (o, val, name) { if (!_.isUndefined(val)) { o[name] = val; } @@ -41,7 +40,7 @@ tagAttributes = function (attributes) { return " " + _.map(attributes, function (val, name) { return "" + name + '="' + _.escape(val) + '"'; - }, " "); + }).join(" "); }; defaultButtons = { @@ -85,7 +84,7 @@ defaultButtons = { }, timeslider: { - onclick: "document.location = document.location.pathname + '/timeslider'", + key: "showTimeSlider", localizationId: "pad.toolbar.timeslider.title", icon: "buttonicon-history" }, @@ -101,10 +100,9 @@ ButtonsGroup = function () { }; ButtonsGroup.fromArray = function (array) { - var btnGroup = new ButtonsGroup(); + var btnGroup = new this; _.each(array, function (btnName) { - var b = new Button(defaultButtons[btnName]); - btnGroup.addButton(b); + btnGroup.addButton(Button.load(btnName)); }); return btnGroup; }; @@ -133,19 +131,24 @@ ButtonsGroup.prototype.render = function () { Button = function (attributes) { this.attributes = attributes; +}; - +Button.load = function (btnName) { + return new Button(defaultButtons[btnName]); }; _.extend(Button.prototype, { grouping: "", - render: function () { - var liAttributes = { + li: function (attributes, contents) { + attributes = _.extend({ "data-key": this.attributes.key, - "onclick": this.attributes.onclick - }; - return tag("li", liAttributes, + }, attributes); + return tag("li", attributes, contents); + }, + + render: function () { + return this.li({}, tag("a", { "class": this.grouping, "data-l10n-id": this.attributes.localizationId }, tag("span", { "class": "buttonicon " + this.attributes.icon }) ) @@ -153,15 +156,54 @@ _.extend(Button.prototype, { } }); +SelectButton = function (attributes) { + this.attributes = attributes; + this.options = []; +}; + +_.extend(SelectButton.prototype, Button.prototype, { + addOption: function (value, text, attributes) { + this.options.push({ + value: value, + text: text, + attributes: attributes + }); + return this; + }, + + select: function (attributes) { + var self = this + , options = []; + + _.each(this.options, function (opt) { + var a = _.extend({ + value: opt.value + }, opt.attributes); + + options.push( tag("option", a, opt.text) ); + }); + return tag("select", attributes, options.join("")); + }, + render: function () { + return this.li({ id: this.attributes.id }, + this.select({ id: this.attributes.selectId }) + ); + } +}); + Separator = function () {}; Separator.prototype.render = function () { - return tag("li", { "class": "separator"}); + return tag("li", { "class": "separator" }); }; module.exports = { + availableButtons: {}, separator: function () { return (new Separator).render(); }, + selectButton: function (attributes) { + return new SelectButton(attributes); + }, menu: function (buttons) { var groups = _.map(buttons, function (group) { return ButtonsGroup.fromArray(group).render(); diff --git a/src/static/js/pad_editbar.js b/src/static/js/pad_editbar.js index 7346ce78f..31273d71b 100644 --- a/src/static/js/pad_editbar.js +++ b/src/static/js/pad_editbar.js @@ -24,15 +24,6 @@ var padutils = require('./pad_utils').padutils; var padeditor = require('./pad_editor').padeditor; var padsavedrevs = require('./pad_savedrevs'); -function indexOf(array, value) { - for (var i = 0, ii = array.length; i < ii; i++) { - if (array[i] == value) { - return i; - } - } - return -1; -} - var padeditbar = (function() { @@ -95,8 +86,7 @@ var padeditbar = (function() }()); var self = { - init: function() - { + init: function() { var self = this; $("#editbar .editbarbutton").attr("unselectable", "on"); // for IE $("#editbar").removeClass("disabledtoolbar").addClass("enabledtoolbar"); @@ -116,72 +106,30 @@ var padeditbar = (function() { $("#editbar").addClass('disabledtoolbar').removeClass("enabledtoolbar"); }, + commands: {}, + registerCommand: function (cmd, callback) { + this.commands[cmd] = callback; + return this; + }, + registerDropdownCommand: function (cmd, dropdown) { + dropdown = dropdown || cmd; + this.registerCommand(cmd, function () { + self.toggleDropDown(dropdown); + }); + }, + registerAceCommand: function (cmd, callback) { + this.registerCommand(cmd, function (cmd, ace) { + ace.callWithAce(function (ace) { + callback(cmd, ace); + }, cmd, true); + }); + }, toolbarClick: function(cmd) { if (self.isEnabled()) { - if(cmd == "showusers") - { - self.toggleDropDown("users"); - } - else if (cmd == 'settings') - { - self.toggleDropDown("settings"); - } - else if (cmd == 'connectivity') - { - self.toggleDropDown("connectivity"); - } - else if (cmd == 'embed') - { - self.setEmbedLinks(); - $('#linkinput').focus().select(); - self.toggleDropDown("embed"); - } - else if (cmd == 'import_export') - { - self.toggleDropDown("importexport"); - } - else if (cmd == 'savedRevision') - { - padsavedrevs.saveNow(); - } - else - { - padeditor.ace.callWithAce(function(ace) - { - if (cmd == 'bold' || cmd == 'italic' || cmd == 'underline' || cmd == 'strikethrough') ace.ace_toggleAttributeOnSelection(cmd); - else if (cmd == 'undo' || cmd == 'redo') ace.ace_doUndoRedo(cmd); - else if (cmd == 'insertunorderedlist') ace.ace_doInsertUnorderedList(); - else if (cmd == 'insertorderedlist') ace.ace_doInsertOrderedList(); - else if (cmd == 'indent') - { - if (!ace.ace_doIndentOutdent(false)) - { - ace.ace_doInsertUnorderedList(); - } - } - else if (cmd == 'outdent') - { - ace.ace_doIndentOutdent(true); - } - else if (cmd == 'clearauthorship') - { - if ((!(ace.ace_getRep().selStart && ace.ace_getRep().selEnd)) || ace.ace_isCaret()) - { - if (window.confirm(html10n.get("pad.editbar.clearcolors"))) - { - ace.ace_performDocumentApplyAttributesToCharRange(0, ace.ace_getRep().alltext.length, [ - ['author', ''] - ]); - } - } - else - { - ace.ace_setAttributeOnSelection('author', ''); - } - } - }, cmd, true); + if (this.commands[cmd]) { + this.commands[cmd](cmd, padeditor.ace); } } if(padeditor.ace) padeditor.ace.focus(); @@ -260,6 +208,74 @@ var padeditbar = (function() } } }; + + self.registerDropdownCommand("showusers", "users"); + self.registerDropdownCommand("settings"); + self.registerDropdownCommand("connectivity"); + self.registerDropdownCommand("import_export", "importexport"); + + self.registerCommand("embed", function () { + self.setEmbedLinks(); + $('#linkinput').focus().select(); + self.toggleDropDown("embed"); + }); + + self.registerCommand("savedRevision", function () { + padsavedrevs.saveNow(); + }); + + self.registerCommand("showTimeSlider", function () { + document.location = document.location + "/timeslider"; + }); + + function aceAttributeCommand (cmd, ace) { + ace.ace_toggleAttributeOnSelection(cmd); + } + + self.registerAceCommand("bold", aceAttributeCommand); + self.registerAceCommand("italic", aceAttributeCommand); + self.registerAceCommand("underline", aceAttributeCommand); + self.registerAceCommand("strikethrough", aceAttributeCommand); + + self.registerAceCommand("undo", function (cmd, ace) { + ace.ace_doUndoRedo(cmd); + }); + + self.registerAceCommand("redo", function (cmd) { + ace.ace_doUndoRedo(cmd); + }); + + self.registerAceCommand("insertunorderedlist", function (cmd, ace) { + ace.ace_doInsertUnorderedList(); + }); + + self.registerAceCommand("insertorderedlist", function (cmd, ace) { + ace.ace_doInsertOrderedList(); + }); + + self.registerAceCommand("indent", function (cmd, ace) { + if (!ace.ace_doIndentOutdent(false)) { + ace.ace_doInsertUnorderedList(); + } + }); + + self.registerAceCommand("outdent", function (cmd, ace) { + ace.ace_doIndentOutdent(true); + }); + + self.registerAceCommand("clearauthorship", function (cmd, ace) { + if ((!(ace.ace_getRep().selStart && ace.ace_getRep().selEnd)) || ace.ace_isCaret()) { + if (window.confirm(html10n.get("pad.editbar.clearcolors"))) { + ace.ace_performDocumentApplyAttributesToCharRange(0, ace.ace_getRep().alltext.length, [ + ['author', ''] + ]); + } + } + else { + ace.ace_setAttributeOnSelection('author', ''); + } + }); + return self; }());