summaryrefslogtreecommitdiff
path: root/src/node
diff options
context:
space:
mode:
authorMarcel Klehr <mklehr@gmx.net>2014-03-16 13:30:22 +0100
committerMarcel Klehr <mklehr@gmx.net>2014-03-16 13:30:22 +0100
commita369347d86df01db04014fb519813ca5d18c3683 (patch)
tree6a6948e5cfa6fc1fb9150706f14a36daca9b0590 /src/node
parentcd0f5742f606e7310f735cb879aa0f19595ac023 (diff)
parent602380abb7e99febfaf9f574da32ae3cc5064458 (diff)
downloadetherpad-lite-a369347d86df01db04014fb519813ca5d18c3683.zip
Merge branch 'pr/1579' into toolbar-test
Conflicts: settings.json.template src/static/js/pad_editbar.js
Diffstat (limited to 'src/node')
-rw-r--r--src/node/hooks/express/specialpages.js13
-rw-r--r--src/node/utils/Settings.js17
-rw-r--r--src/node/utils/toolbar.js227
3 files changed, 255 insertions, 2 deletions
diff --git a/src/node/hooks/express/specialpages.js b/src/node/hooks/express/specialpages.js
index 7d051965..8609d657 100644
--- a/src/node/hooks/express/specialpages.js
+++ b/src/node/hooks/express/specialpages.js
@@ -1,5 +1,7 @@
var path = require('path');
var eejs = require('ep_etherpad-lite/node/eejs');
+var toolbar = require("ep_etherpad-lite/node/utils/toolbar");
+var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
exports.expressCreateServer = function (hook_name, args, cb) {
// expose current stats
@@ -30,8 +32,15 @@ exports.expressCreateServer = function (hook_name, args, cb) {
//serve pad.html under /p
args.app.get('/p/:pad', function(req, res, next)
- {
- res.send(eejs.require("ep_etherpad-lite/templates/pad.html", {req: req}));
+ {
+ hooks.callAll("padInitToolbar", {
+ toolbar: toolbar
+ });
+
+ res.send(eejs.require("ep_etherpad-lite/templates/pad.html", {
+ req: req,
+ toolbar: toolbar
+ }));
});
//serve timeslider.html under /p/$padname/timeslider
diff --git a/src/node/utils/Settings.js b/src/node/utils/Settings.js
index bc13a211..9bfcae4b 100644
--- a/src/node/utils/Settings.js
+++ b/src/node/utils/Settings.js
@@ -80,6 +80,23 @@ exports.dbSettings = { "filename" : path.join(exports.root, "dirty.db") };
exports.defaultPadText = "Welcome to Etherpad!\n\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\n\nEtherpad on Github: http:\/\/j.mp/ep-lite\n";
/**
+ * The toolbar buttons and order.
+ */
+exports.toolbar = {
+ left: [
+ ["bold", "italic", "underline", "strikethrough"],
+ ["orderedlist", "unorderedlist", "indent", "outdent"],
+ ["undo", "redo"],
+ ["clearauthorship"]
+ ],
+ right: [
+ ["importexport", "timeslider", "savedrevision"],
+ ["settings", "embed"],
+ ["showusers"]
+ ]
+}
+
+/**
* A flag that requires any user to have a valid session (via the api) before accessing a pad
*/
exports.requireSession = false;
diff --git a/src/node/utils/toolbar.js b/src/node/utils/toolbar.js
new file mode 100644
index 00000000..a0a4fe01
--- /dev/null
+++ b/src/node/utils/toolbar.js
@@ -0,0 +1,227 @@
+/**
+ * The Toolbar Module creates and renders the toolbars and buttons
+ */
+var _ = require("underscore")
+ , tagAttributes
+ , tag
+ , defaultButtons
+ , Button
+ , ButtonsGroup
+ , Separator
+ , defaultButtonAttributes;
+
+defaultButtonAttributes = function (name, overrides) {
+ return {
+ key: name,
+ localizationId: "pad.toolbar." + name + ".title",
+ icon: "buttonicon-" + name
+ };
+};
+
+tag = function (name, attributes, contents) {
+ var aStr = tagAttributes(attributes);
+
+ if (_.isString(contents) && contents.length > 0) {
+ return '<' + name + aStr + '>' + contents + '</' + name + '>';
+ }
+ else {
+ return '<' + name + aStr + '></' + name + '>';
+ }
+};
+
+tagAttributes = function (attributes) {
+ attributes = _.reduce(attributes || {}, function (o, val, name) {
+ if (!_.isUndefined(val)) {
+ o[name] = val;
+ }
+ return o;
+ }, {});
+
+ return " " + _.map(attributes, function (val, name) {
+ return "" + name + '="' + _.escape(val) + '"';
+ }).join(" ");
+};
+
+ButtonsGroup = function () {
+ this.buttons = [];
+};
+
+ButtonsGroup.fromArray = function (array) {
+ var btnGroup = new this;
+ _.each(array, function (btnName) {
+ btnGroup.addButton(Button.load(btnName));
+ });
+ return btnGroup;
+};
+
+ButtonsGroup.prototype.addButton = function (button) {
+ this.buttons.push(button);
+ return this;
+};
+
+ButtonsGroup.prototype.render = function () {
+ if (this.buttons.length == 1) {
+ this.buttons[0].grouping = "";
+ }
+ else {
+ _.first(this.buttons).grouping = "grouped-left";
+ _.last(this.buttons).grouping = "grouped-right";
+ _.each(this.buttons.slice(1, -1), function (btn) {
+ btn.grouping = "grouped-middle"
+ });
+ }
+
+ return _.map(this.buttons, function (btn) {
+ return btn.render();
+ }).join("\n");
+};
+
+Button = function (attributes) {
+ this.attributes = attributes;
+};
+
+Button.load = function (btnName) {
+ var button = module.exports.availableButtons[btnName];
+ if (button.constructor === Button || button.constructor === SelectButton) {
+ return button;
+ }
+ else {
+ return new Button(button);
+ }
+};
+
+_.extend(Button.prototype, {
+ grouping: "",
+
+ render: function () {
+ var liAttributes = {
+ "data-type": "button",
+ "data-key": this.attributes.key,
+ };
+ return tag("li", liAttributes,
+ tag("a", { "class": this.grouping, "data-l10n-id": this.attributes.localizationId },
+ tag("span", { "class": "buttonicon " + this.attributes.icon })
+ )
+ );
+ }
+});
+
+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 () {
+ var attributes = {
+ id: this.attributes.id,
+ "data-key": this.attributes.command,
+ "data-type": "select"
+ };
+ return tag("li", attributes,
+ this.select({ id: this.attributes.selectId })
+ );
+ }
+});
+
+Separator = function () {};
+Separator.prototype.render = function () {
+ return tag("li", { "class": "separator" });
+};
+
+module.exports = {
+ availableButtons: {
+ bold: defaultButtonAttributes("bold"),
+ italic: defaultButtonAttributes("italic"),
+ underline: defaultButtonAttributes("underline"),
+ strikethrough: defaultButtonAttributes("strikethrough"),
+
+ orderedlist: {
+ key: "insertorderedlist",
+ localizationId: "pad.toolbar.ol.title",
+ icon: "buttonicon-insertorderedlist"
+ },
+
+ unorderedlist: {
+ key: "insertunorderedlist",
+ localizationId: "pad.toolbar.ul.title",
+ icon: "buttonicon-insertunorderedlist"
+ },
+
+ indent: defaultButtonAttributes("indent"),
+ outdent: {
+ key: "outdent",
+ localizationId: "pad.toolbar.unindent.title",
+ icon: "buttonicon-outdent"
+ },
+
+ undo: defaultButtonAttributes("undo"),
+ redo: defaultButtonAttributes("redo"),
+
+ clearauthorship: {
+ key: "clearauthorship",
+ localizationId: "pad.toolbar.clearAuthorship.title",
+ icon: "buttonicon-clearauthorship"
+ },
+
+ importexport: {
+ key: "import_export",
+ localizationId: "pad.toolbar.import_export.title",
+ icon: "buttonicon-import_export"
+ },
+
+ timeslider: {
+ key: "showTimeSlider",
+ localizationId: "pad.toolbar.timeslider.title",
+ icon: "buttonicon-history"
+ },
+
+ savedrevision: defaultButtonAttributes("savedRevision"),
+ settings: defaultButtonAttributes("settings"),
+ embed: defaultButtonAttributes("embed"),
+ showusers: defaultButtonAttributes("showusers")
+ },
+
+ registerButton: function (buttonName, buttonInfo) {
+ this.availableButtons[buttonName] = buttonInfo;
+ },
+
+ button: function (attributes) {
+ return new Button(attributes);
+ },
+ 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();
+ });
+ return groups.join(this.separator());
+ }
+};