mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-20 23:46:14 -04:00
Merge branch 'pr/1579' into toolbar-test
Conflicts: settings.json.template src/static/js/pad_editbar.js
This commit is contained in:
commit
a369347d86
6 changed files with 438 additions and 181 deletions
|
@ -103,6 +103,22 @@
|
||||||
// restrict socket.io transport methods
|
// restrict socket.io transport methods
|
||||||
"socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"],
|
"socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"],
|
||||||
|
|
||||||
|
/* The toolbar buttons configuration.
|
||||||
|
"toolbar": {
|
||||||
|
"left": [
|
||||||
|
["bold", "italic", "underline", "strikethrough"],
|
||||||
|
["orderedlist", "unorderedlist", "indent", "outdent"],
|
||||||
|
["undo", "redo"],
|
||||||
|
["clearauthorship"]
|
||||||
|
],
|
||||||
|
"right": [
|
||||||
|
["importexport", "timeslider", "savedrevision"],
|
||||||
|
["settings", "embed"],
|
||||||
|
["showusers"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
/* The log level we are using, can be: DEBUG, INFO, WARN, ERROR */
|
/* The log level we are using, can be: DEBUG, INFO, WARN, ERROR */
|
||||||
"loglevel": "INFO",
|
"loglevel": "INFO",
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var eejs = require('ep_etherpad-lite/node/eejs');
|
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) {
|
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
// expose current stats
|
// expose current stats
|
||||||
|
@ -31,7 +33,14 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
//serve pad.html under /p
|
//serve pad.html under /p
|
||||||
args.app.get('/p/:pad', function(req, res, next)
|
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
|
//serve timeslider.html under /p/$padname/timeslider
|
||||||
|
|
|
@ -79,6 +79,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";
|
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
|
* A flag that requires any user to have a valid session (via the api) before accessing a pad
|
||||||
*/
|
*/
|
||||||
|
|
227
src/node/utils/toolbar.js
Normal file
227
src/node/utils/toolbar.js
Normal file
|
@ -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());
|
||||||
|
}
|
||||||
|
};
|
|
@ -20,18 +20,60 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var hooks = require('./pluginfw/hooks');
|
||||||
var padutils = require('./pad_utils').padutils;
|
var padutils = require('./pad_utils').padutils;
|
||||||
var padeditor = require('./pad_editor').padeditor;
|
var padeditor = require('./pad_editor').padeditor;
|
||||||
var padsavedrevs = require('./pad_savedrevs');
|
var padsavedrevs = require('./pad_savedrevs');
|
||||||
|
|
||||||
function indexOf(array, value) {
|
var ToolbarItem = function (element) {
|
||||||
for (var i = 0, ii = array.length; i < ii; i++) {
|
this.$el = element;
|
||||||
if (array[i] == value) {
|
};
|
||||||
return i;
|
|
||||||
|
ToolbarItem.prototype.getCommand = function () {
|
||||||
|
return this.$el.attr("data-key");
|
||||||
|
};
|
||||||
|
|
||||||
|
ToolbarItem.prototype.getValue = function () {
|
||||||
|
if (this.isSelect()) {
|
||||||
|
return this.$el.find("select").val();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ToolbarItem.prototype.setValue = function (val) {
|
||||||
|
if (this.isSelect()) {
|
||||||
|
return this.$el.find("select").val(val);
|
||||||
}
|
}
|
||||||
return -1;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
ToolbarItem.prototype.getType = function () {
|
||||||
|
return this.$el.attr("data-type");
|
||||||
|
};
|
||||||
|
|
||||||
|
ToolbarItem.prototype.isSelect = function () {
|
||||||
|
return this.getType() == "select";
|
||||||
|
};
|
||||||
|
|
||||||
|
ToolbarItem.prototype.isButton = function () {
|
||||||
|
return this.getType() == "button";
|
||||||
|
};
|
||||||
|
|
||||||
|
ToolbarItem.prototype.bind = function (callback) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
if (self.isButton()) {
|
||||||
|
self.$el.click(function (event) {
|
||||||
|
callback(self.getCommand(), self);
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (self.isSelect()) {
|
||||||
|
self.$el.find("select").change(function () {
|
||||||
|
callback(self.getCommand(), self);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
var padeditbar = (function()
|
var padeditbar = (function()
|
||||||
{
|
{
|
||||||
|
@ -95,17 +137,22 @@ var padeditbar = (function()
|
||||||
}());
|
}());
|
||||||
|
|
||||||
var self = {
|
var self = {
|
||||||
init: function()
|
init: function() {
|
||||||
{
|
|
||||||
var self = this;
|
var self = this;
|
||||||
$("#editbar .editbarbutton").attr("unselectable", "on"); // for IE
|
$("#editbar .editbarbutton").attr("unselectable", "on"); // for IE
|
||||||
$("#editbar").removeClass("disabledtoolbar").addClass("enabledtoolbar");
|
$("#editbar").removeClass("disabledtoolbar").addClass("enabledtoolbar");
|
||||||
$("#editbar [data-key]").each(function (i, e) {
|
$("#editbar [data-key]").each(function () {
|
||||||
$(e).click(function (event) {
|
(new ToolbarItem($(this))).bind(function (command, item) {
|
||||||
self.toolbarClick($(e).attr('data-key'));
|
self.triggerCommand(command, item);
|
||||||
event.preventDefault();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
registerDefaultCommands(self);
|
||||||
|
|
||||||
|
hooks.callAll("postToolbarInit", {
|
||||||
|
toolbar: self,
|
||||||
|
ace: padeditor.ace
|
||||||
|
});
|
||||||
},
|
},
|
||||||
isEnabled: function()
|
isEnabled: function()
|
||||||
{
|
{
|
||||||
|
@ -116,70 +163,27 @@ var padeditbar = (function()
|
||||||
{
|
{
|
||||||
$("#editbar").addClass('disabledtoolbar').removeClass("enabledtoolbar");
|
$("#editbar").addClass('disabledtoolbar').removeClass("enabledtoolbar");
|
||||||
},
|
},
|
||||||
toolbarClick: function(cmd)
|
commands: {},
|
||||||
{
|
registerCommand: function (cmd, callback) {
|
||||||
if (self.isEnabled())
|
this.commands[cmd] = callback;
|
||||||
{
|
return this;
|
||||||
if(cmd == "showusers")
|
},
|
||||||
{
|
registerDropdownCommand: function (cmd, dropdown) {
|
||||||
self.toggleDropDown("users");
|
dropdown = dropdown || cmd;
|
||||||
}
|
this.registerCommand(cmd, function () {
|
||||||
else if (cmd == 'settings')
|
self.toggleDropDown(dropdown);
|
||||||
{
|
});
|
||||||
self.toggleDropDown("settings");
|
},
|
||||||
}
|
registerAceCommand: function (cmd, callback) {
|
||||||
else if (cmd == 'connectivity')
|
this.registerCommand(cmd, function (cmd, ace) {
|
||||||
{
|
ace.callWithAce(function (ace) {
|
||||||
self.toggleDropDown("connectivity");
|
callback(cmd, ace);
|
||||||
}
|
|
||||||
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')
|
|
||||||
{
|
|
||||||
ace.ace_doIndentOutdent(false);
|
|
||||||
}
|
|
||||||
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);
|
}, cmd, true);
|
||||||
}
|
});
|
||||||
|
},
|
||||||
|
triggerCommand: function (cmd, item) {
|
||||||
|
if (self.isEnabled() && this.commands[cmd]) {
|
||||||
|
this.commands[cmd](cmd, padeditor.ace, item);
|
||||||
}
|
}
|
||||||
if(padeditor.ace) padeditor.ace.focus();
|
if(padeditor.ace) padeditor.ace.focus();
|
||||||
},
|
},
|
||||||
|
@ -257,6 +261,76 @@ var padeditbar = (function()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function aceAttributeCommand(cmd, ace) {
|
||||||
|
ace.ace_toggleAttributeOnSelection(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerDefaultCommands(toolbar) {
|
||||||
|
toolbar.registerDropdownCommand("showusers", "users");
|
||||||
|
toolbar.registerDropdownCommand("settings");
|
||||||
|
toolbar.registerDropdownCommand("connectivity");
|
||||||
|
toolbar.registerDropdownCommand("import_export", "importexport");
|
||||||
|
|
||||||
|
toolbar.registerCommand("embed", function () {
|
||||||
|
toolbar.setEmbedLinks();
|
||||||
|
$('#linkinput').focus().select();
|
||||||
|
toolbar.toggleDropDown("embed");
|
||||||
|
});
|
||||||
|
|
||||||
|
toolbar.registerCommand("savedRevision", function () {
|
||||||
|
padsavedrevs.saveNow();
|
||||||
|
});
|
||||||
|
|
||||||
|
toolbar.registerCommand("showTimeSlider", function () {
|
||||||
|
document.location = document.location + "/timeslider";
|
||||||
|
});
|
||||||
|
|
||||||
|
toolbar.registerAceCommand("bold", aceAttributeCommand);
|
||||||
|
toolbar.registerAceCommand("italic", aceAttributeCommand);
|
||||||
|
toolbar.registerAceCommand("underline", aceAttributeCommand);
|
||||||
|
toolbar.registerAceCommand("strikethrough", aceAttributeCommand);
|
||||||
|
|
||||||
|
toolbar.registerAceCommand("undo", function (cmd, ace) {
|
||||||
|
ace.ace_doUndoRedo(cmd);
|
||||||
|
});
|
||||||
|
|
||||||
|
toolbar.registerAceCommand("redo", function (cmd) {
|
||||||
|
ace.ace_doUndoRedo(cmd);
|
||||||
|
});
|
||||||
|
|
||||||
|
toolbar.registerAceCommand("insertunorderedlist", function (cmd, ace) {
|
||||||
|
ace.ace_doInsertUnorderedList();
|
||||||
|
});
|
||||||
|
|
||||||
|
toolbar.registerAceCommand("insertorderedlist", function (cmd, ace) {
|
||||||
|
ace.ace_doInsertOrderedList();
|
||||||
|
});
|
||||||
|
|
||||||
|
toolbar.registerAceCommand("indent", function (cmd, ace) {
|
||||||
|
if (!ace.ace_doIndentOutdent(false)) {
|
||||||
|
ace.ace_doInsertUnorderedList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
toolbar.registerAceCommand("outdent", function (cmd, ace) {
|
||||||
|
ace.ace_doIndentOutdent(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
toolbar.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;
|
return self;
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<%
|
<%
|
||||||
var settings = require("ep_etherpad-lite/node/utils/Settings")
|
var settings = require("ep_etherpad-lite/node/utils/Settings")
|
||||||
|
, hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks')
|
||||||
, langs = require("ep_etherpad-lite/node/hooks/i18n").availableLangs
|
, langs = require("ep_etherpad-lite/node/hooks/i18n").availableLangs
|
||||||
|
;
|
||||||
%>
|
%>
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<% e.begin_block("htmlHead"); %>
|
<% e.begin_block("htmlHead"); %>
|
||||||
|
@ -54,103 +56,15 @@
|
||||||
<div id="overlay">
|
<div id="overlay">
|
||||||
<div id="overlay-inner"></div>
|
<div id="overlay-inner"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="menu_left">
|
<ul class="menu_left">
|
||||||
<% e.begin_block("editbarMenuLeft"); %>
|
<% e.begin_block("editbarMenuLeft"); %>
|
||||||
<li class="acl-write" id="bold" data-key="bold">
|
<%- toolbar.menu(settings.toolbar.left) %>
|
||||||
<a class="grouped-left" data-l10n-id="pad.toolbar.bold.title">
|
|
||||||
<span class="buttonicon buttonicon-bold"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="acl-write" id="italic" data-key="italic">
|
|
||||||
<a class="grouped-middle" data-l10n-id="pad.toolbar.italic.title">
|
|
||||||
<span class="buttonicon buttonicon-italic"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="acl-write" id="underline" data-key="underline">
|
|
||||||
<a class="grouped-middle" data-l10n-id="pad.toolbar.underline.title">
|
|
||||||
<span class="buttonicon buttonicon-underline"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="acl-write" id="strikethrough" data-key="strikethrough">
|
|
||||||
<a class="grouped-right" data-l10n-id="pad.toolbar.strikethrough.title">
|
|
||||||
<span class="buttonicon buttonicon-strikethrough"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="acl-write separator"></li>
|
|
||||||
<li class="acl-write" id="oderedlist" data-key="insertorderedlist">
|
|
||||||
<a class="grouped-left" data-l10n-id="pad.toolbar.ol.title">
|
|
||||||
<span class="buttonicon buttonicon-insertorderedlist"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="acl-write" id="unoderedlist" data-key="insertunorderedlist">
|
|
||||||
<a class="grouped-middle" data-l10n-id="pad.toolbar.ul.title">
|
|
||||||
<span class="buttonicon buttonicon-insertunorderedlist"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="acl-write" id="indent" data-key="indent">
|
|
||||||
<a class="grouped-middle" data-l10n-id="pad.toolbar.indent.title">
|
|
||||||
<span class="buttonicon buttonicon-indent"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="acl-write" id="outdent" data-key="outdent">
|
|
||||||
<a class="grouped-right" data-l10n-id="pad.toolbar.unindent.title">
|
|
||||||
<span class="buttonicon buttonicon-outdent"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="acl-write separator"></li>
|
|
||||||
<li class="acl-write" id="undo" data-key="undo">
|
|
||||||
<a class="grouped-left" data-l10n-id="pad.toolbar.undo.title">
|
|
||||||
<span class="buttonicon buttonicon-undo"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="acl-write" id="redo" data-key="redo">
|
|
||||||
<a class="grouped-right" data-l10n-id="pad.toolbar.redo.title">
|
|
||||||
<span class="buttonicon buttonicon-redo"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="acl-write separator"></li>
|
|
||||||
<li class="acl-write" id="clearAuthorship" data-key="clearauthorship">
|
|
||||||
<a data-l10n-id="pad.toolbar.clearAuthorship.title">
|
|
||||||
<span class="buttonicon buttonicon-clearauthorship"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<% e.end_block(); %>
|
<% e.end_block(); %>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="menu_right">
|
<ul class="menu_right">
|
||||||
<% e.begin_block("editbarMenuRight"); %>
|
<% e.begin_block("editbarMenuRight"); %>
|
||||||
<li data-key="import_export">
|
<%- toolbar.menu(settings.toolbar.right) %>
|
||||||
<a class="grouped-left" id="importexportlink" data-l10n-id="pad.toolbar.import_export.title">
|
|
||||||
<span class="buttonicon buttonicon-import_export"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li onClick="document.location = document.location.pathname+ '/timeslider'">
|
|
||||||
<a id="timesliderlink" class="grouped-middle" data-l10n-id="pad.toolbar.timeslider.title">
|
|
||||||
<span class="buttonicon buttonicon-history"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="acl-write" data-key="savedRevision">
|
|
||||||
<a class="grouped-right" id="revisionlink" data-l10n-id="pad.toolbar.savedRevision.title">
|
|
||||||
<span class="buttonicon buttonicon-savedRevision"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="acl-write separator"></li>
|
|
||||||
<li class="acl-write" data-key="settings">
|
|
||||||
<a class="grouped-left" id="settingslink" data-l10n-id="pad.toolbar.settings.title">
|
|
||||||
<span class="buttonicon buttonicon-settings"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li data-key="embed">
|
|
||||||
<a class="grouped-right" id="embedlink" data-l10n-id="pad.toolbar.embed.title">
|
|
||||||
<span class="grouped-right buttonicon buttonicon-embed"></span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="separator"></li>
|
|
||||||
<li id="usericon" data-key="showusers">
|
|
||||||
<a data-l10n-id="pad.toolbar.showusers.title">
|
|
||||||
<span class="buttonicon buttonicon-showusers"></span>
|
|
||||||
<span id="online_count">1</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<% e.end_block(); %>
|
<% e.end_block(); %>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue