mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-21 06:52:46 +01:00
437b2bfc64
The `.toolbar ul li a` that holds the `span.button` has a padding of `4px 5px`. This means if the mouse is on the edge of the button the `:hover` state is active but the relevant tooltip does not show up. Moving the `title` attribute to the `<a>` itself solves this problem. Also removed some extra whitespace.
239 lines
5.8 KiB
JavaScript
239 lines
5.8 KiB
JavaScript
/**
|
|
* 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 {
|
|
command: name,
|
|
localizationId: "pad.toolbar." + name + ".title",
|
|
class: "buttonicon 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.command,
|
|
};
|
|
return tag("li", liAttributes,
|
|
tag("a", { "class": this.grouping, "data-l10n-id": this.attributes.localizationId },
|
|
tag("span", { "class": " "+ this.attributes.class })
|
|
)
|
|
);
|
|
}
|
|
});
|
|
|
|
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: {
|
|
command: "insertorderedlist",
|
|
localizationId: "pad.toolbar.ol.title",
|
|
class: "buttonicon buttonicon-insertorderedlist"
|
|
},
|
|
|
|
unorderedlist: {
|
|
command: "insertunorderedlist",
|
|
localizationId: "pad.toolbar.ul.title",
|
|
class: "buttonicon buttonicon-insertunorderedlist"
|
|
},
|
|
|
|
indent: defaultButtonAttributes("indent"),
|
|
outdent: {
|
|
command: "outdent",
|
|
localizationId: "pad.toolbar.unindent.title",
|
|
class: "buttonicon buttonicon-outdent"
|
|
},
|
|
|
|
undo: defaultButtonAttributes("undo"),
|
|
redo: defaultButtonAttributes("redo"),
|
|
|
|
clearauthorship: {
|
|
command: "clearauthorship",
|
|
localizationId: "pad.toolbar.clearAuthorship.title",
|
|
class: "buttonicon buttonicon-clearauthorship"
|
|
},
|
|
|
|
importexport: {
|
|
command: "import_export",
|
|
localizationId: "pad.toolbar.import_export.title",
|
|
class: "buttonicon buttonicon-import_export"
|
|
},
|
|
|
|
timeslider: {
|
|
command: "showTimeSlider",
|
|
localizationId: "pad.toolbar.timeslider.title",
|
|
class: "buttonicon buttonicon-history"
|
|
},
|
|
|
|
savedrevision: defaultButtonAttributes("savedRevision"),
|
|
settings: defaultButtonAttributes("settings"),
|
|
embed: defaultButtonAttributes("embed"),
|
|
showusers: defaultButtonAttributes("showusers"),
|
|
|
|
timeslider_export: {
|
|
command: "import_export",
|
|
localizationId: "timeslider.toolbar.exportlink.title",
|
|
class: "buttonicon buttonicon-import_export"
|
|
},
|
|
|
|
timeslider_returnToPad: {
|
|
command: "timeslider_returnToPad",
|
|
localizationId: "timeslider.toolbar.returnbutton",
|
|
class: "buttontext"
|
|
}
|
|
},
|
|
|
|
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());
|
|
}
|
|
};
|