merge develop

This commit is contained in:
John McLear 2013-02-25 10:13:50 +00:00
commit f915285f15
23 changed files with 689 additions and 192 deletions

View File

@ -3,7 +3,15 @@
* NEW: Plugins can now provide their own frontend tests * NEW: Plugins can now provide their own frontend tests
* NEW: Improved server-side logging * NEW: Improved server-side logging
* NEW: Admin dashboard mobile device support and new hooks for Admin dashboard * NEW: Admin dashboard mobile device support and new hooks for Admin dashboard
* NEW: Get current API version from API
* Fix: Text Export indentation now supports multiple indentations
* Fix: Bugfix getChatHistory API method * Fix: Bugfix getChatHistory API method
* Fix: Stop Chrome losing caret after paste is texted
* Fix: Make colons on end of line create 4 spaces on indent
* Fix: Make indent when on middle of the line stop creating list
* Fix: Stop long strings breaking the UX by moving focus away from beginning of line
* Fix: padUsersCount no longer hangs server
* Fix: Issue with two part locale specs not working
* Fix: Make plugin search case insensitive * Fix: Make plugin search case insensitive
* Fix: Indentation and bullets on text export * Fix: Indentation and bullets on text export
* Fix: Resolve various warnings on dependencies during install * Fix: Resolve various warnings on dependencies during install

View File

@ -28,7 +28,7 @@ documented codebase makes it easier for developers to improve the code and contr
Etherpad Lite is designed to be easily embeddable and provides a [HTTP API](https://github.com/ether/etherpad-lite/wiki/HTTP-API) Etherpad Lite is designed to be easily embeddable and provides a [HTTP API](https://github.com/ether/etherpad-lite/wiki/HTTP-API)
that allows your web application to manage pads, users and groups. It is recommended to use the [available client implementations](https://github.com/ether/etherpad-lite/wiki/HTTP-API-client-libraries) in order to interact with this API. There is also a [jQuery plugin](https://github.com/johnyma22/etherpad-lite-jquery-plugin) that helps you to embed Pads into your website. that allows your web application to manage pads, users and groups. It is recommended to use the [available client implementations](https://github.com/ether/etherpad-lite/wiki/HTTP-API-client-libraries) in order to interact with this API. There is also a [jQuery plugin](https://github.com/ether/etherpad-lite-jquery-plugin) that helps you to embed Pads into your website.
There's also a full-featured plugin framework, allowing you to easily add your own features. There's also a full-featured plugin framework, allowing you to easily add your own features.
Finally, Etherpad Lite comes with translations into tons of different languages! Finally, Etherpad Lite comes with translations into tons of different languages!
@ -108,7 +108,7 @@ You know all this and just want to know how you can help?
Look at the [TODO list](https://github.com/ether/etherpad-lite/wiki/TODO) and our [Issue tracker](https://github.com/ether/etherpad-lite/issues). (Please consider using [jshint](http://www.jshint.com/about/), if you plan to contribute code.) Look at the [TODO list](https://github.com/ether/etherpad-lite/wiki/TODO) and our [Issue tracker](https://github.com/ether/etherpad-lite/issues). (Please consider using [jshint](http://www.jshint.com/about/), if you plan to contribute code.)
Also, and most importantly, read our [**Developer Guidelines**](https://github.com/ether/etherpad-lite/wiki/Developer-Guidelines), really! Also, and most importantly, read our [**Developer Guidelines**](https://github.com/ether/etherpad-lite/blob/master/CONTRIBUTING.md), really!
# Get in touch # Get in touch
Join the [mailinglist](http://groups.google.com/group/etherpad-lite-dev) and make some noise on our freenode irc channel [#etherpad-lite-dev](http://webchat.freenode.net?channels=#etherpad-lite-dev)! Join the [mailinglist](http://groups.google.com/group/etherpad-lite-dev) and make some noise on our freenode irc channel [#etherpad-lite-dev](http://webchat.freenode.net?channels=#etherpad-lite-dev)!

View File

@ -35,7 +35,8 @@ async.series([
function(callback) { function(callback) {
settings = require('../src/node/utils/Settings'); settings = require('../src/node/utils/Settings');
db = require('../src/node/db/DB'); db = require('../src/node/db/DB');
dirty = require("../src/node_modules/ueberDB/node_modules/dirty")(padId + ".db"); dirty = require("../node_modules/ep_etherpad-lite/node_modules/ueberDB/node_modules/dirty")(padId + ".db");
callback();
}, },
//intallize the database //intallize the database
function (callback) function (callback)
@ -45,7 +46,7 @@ async.series([
//get the pad //get the pad
function (callback) function (callback)
{ {
padManager = require('../node/db/PadManager'); padManager = require('../src/node/db/PadManager');
padManager.getPad(padId, function(err, _pad) padManager.getPad(padId, function(err, _pad)
{ {
@ -82,7 +83,10 @@ async.series([
db.db.db.wrappedDB.get(dbkey, function(err, dbvalue) db.db.db.wrappedDB.get(dbkey, function(err, dbvalue)
{ {
if(err) { callback(err); return} if(err) { callback(err); return}
dbvalue=JSON.parse(dbvalue);
if(typeof dbvalue != 'object'){
dbvalue=JSON.parse(dbvalue); // if its not json then parse it as json
}
dirty.set(dbkey, dbvalue, callback); dirty.set(dbkey, dbvalue, callback);
}); });

View File

@ -2,26 +2,60 @@
"@metadata": { "@metadata": {
"authors": [ "authors": [
"Bellayet", "Bellayet",
"Nasir8891" "Nasir8891",
"Sankarshan"
] ]
}, },
"index.newPad": "\u09a8\u09a4\u09c1\u09a8 \u09aa\u09cd\u09af\u09be\u09a1", "index.newPad": "\u09a8\u09a4\u09c1\u09a8 \u09aa\u09cd\u09af\u09be\u09a1",
"index.createOpenPad": "\u0985\u09a5\u09ac\u09be \u09a8\u09be\u09ae \u09b2\u09bf\u0996\u09c7 \u09aa\u09cd\u09af\u09be\u09a1 \u0996\u09c1\u09b2\u09c1\u09a8\/\u09a4\u09c8\u09b0\u09c0 \u0995\u09b0\u09c1\u09a8:", "index.createOpenPad": "\u0985\u09a5\u09ac\u09be \u09a8\u09be\u09ae \u09b2\u09bf\u0996\u09c7 \u09aa\u09cd\u09af\u09be\u09a1 \u0996\u09c1\u09b2\u09c1\u09a8\/\u09a4\u09c8\u09b0\u09c0 \u0995\u09b0\u09c1\u09a8:",
"pad.toolbar.bold.title": "\u0997\u09be\u09a1\u09bc \u0995\u09b0\u09be (Ctrl-B)", "pad.toolbar.bold.title": "\u0997\u09be\u09a1\u09bc \u0995\u09b0\u09be (Ctrl-B)",
"pad.toolbar.italic.title": "\u09ac\u09be\u0981\u0995\u09be \u0995\u09b0\u09be (Ctrl-I)", "pad.toolbar.italic.title": "\u09ac\u09be\u0981\u0995\u09be \u0995\u09b0\u09be (Ctrl-I)",
"pad.toolbar.underline.title": "\u0986\u09a8\u09cd\u09a1\u09be\u09b0\u09b2\u09be\u0987\u09a8 (Ctrl-U)",
"pad.toolbar.ol.title": "\u09b8\u09be\u09b0\u09bf\u09ac\u09a6\u09cd\u09a7 \u09a4\u09be\u09b2\u09bf\u0995\u09be",
"pad.toolbar.indent.title": "\u09aa\u09cd\u09b0\u09be\u09a8\u09cd\u09a4\u09bf\u0995\u0995\u09b0\u09a3", "pad.toolbar.indent.title": "\u09aa\u09cd\u09b0\u09be\u09a8\u09cd\u09a4\u09bf\u0995\u0995\u09b0\u09a3",
"pad.toolbar.unindent.title": "\u0986\u0989\u099f\u09a1\u09c7\u09a8\u09cd\u099f",
"pad.toolbar.undo.title": "\u09ac\u09be\u09a4\u09bf\u09b2 \u0995\u09b0\u09c1\u09a8 (Ctrl-Z)",
"pad.toolbar.redo.title": "\u09aa\u09c1\u09a8\u09b0\u09be\u09af\u09bc \u0995\u09b0\u09c1\u09a8 (Ctrl-Y)",
"pad.toolbar.clearAuthorship.title": "\u0995\u09c3\u09a4\u09bf \u09b0\u0982 \u09aa\u09b0\u09bf\u09b7\u09cd\u0995\u09be\u09b0 \u0995\u09b0\u09c1\u09a8",
"pad.toolbar.timeslider.title": "\u099f\u09be\u0987\u09ae\u09b8\u09cd\u09b2\u09be\u0987\u09a1\u09be\u09b0",
"pad.toolbar.savedRevision.title": "\u09b8\u0982\u09b8\u09cd\u0995\u09b0\u09a3 \u09b8\u0982\u09b0\u0995\u09cd\u09b7\u09a3 \u0995\u09b0\u09c1\u09a8",
"pad.toolbar.settings.title": "\u09b8\u09c7\u099f\u09bf\u0982", "pad.toolbar.settings.title": "\u09b8\u09c7\u099f\u09bf\u0982",
"pad.toolbar.embed.title": "\u098f\u0987 \u09aa\u09cd\u09af\u09be\u09a1-\u099f\u09bf \u098f\u09ae\u09cd\u09ac\u09c7\u09a1 \u0995\u09b0\u09c1\u09a8",
"pad.toolbar.showusers.title": "\u098f\u0987 \u09aa\u09cd\u09af\u09be\u09a1\u09c7\u09b0 \u09ac\u09cd\u09af\u09ac\u09b9\u09be\u09b0\u0995\u09be\u09b0\u09c0\u09a6\u09c7\u09b0 \u09a6\u09c7\u0996\u09be\u09a8",
"pad.colorpicker.save": "\u09b8\u0982\u09b0\u0995\u09cd\u09b7\u09a3", "pad.colorpicker.save": "\u09b8\u0982\u09b0\u0995\u09cd\u09b7\u09a3",
"pad.colorpicker.cancel": "\u09ac\u09be\u09a4\u09bf\u09b2", "pad.colorpicker.cancel": "\u09ac\u09be\u09a4\u09bf\u09b2",
"pad.loading": "\u09b2\u09cb\u09a1\u09bf\u0982...", "pad.loading": "\u09b2\u09cb\u09a1\u09bf\u0982...",
"pad.passwordRequired": "\u098f\u0987 \u09aa\u09cd\u09af\u09be\u09a1-\u099f\u09bf \u09a6\u09c7\u0996\u09be\u09b0 \u099c\u09a8\u09cd\u09af \u0986\u09aa\u09a8\u09be\u0995\u09c7 \u09aa\u09be\u09b8\u0993\u09af\u09bc\u09be\u09b0\u09cd\u09a1 \u09ac\u09cd\u09af\u09ac\u09b9\u09be\u09b0 \u0995\u09b0\u09a4\u09c7 \u09b9\u09ac\u09c7",
"pad.permissionDenied": "\u09a6\u09c1\u0983\u0996\u09bf\u09a4, \u098f \u09aa\u09cd\u09af\u09be\u09a1-\u099f\u09bf \u09a6\u09c7\u0996\u09be\u09b0 \u0985\u09a7\u09bf\u0995\u09be\u09b0 \u0986\u09aa\u09a8\u09be\u09b0 \u09a8\u09c7\u0987",
"pad.wrongPassword": "\u0986\u09aa\u09a8\u09be\u09b0 \u09aa\u09be\u09b8\u0993\u09af\u09bc\u09be\u09b0\u09cd\u09a1 \u09b8\u09a0\u09bf\u0995 \u09a8\u09af\u09bc",
"pad.settings.padSettings": "\u09aa\u09cd\u09af\u09be\u09a1\u09c7\u09b0 \u09b8\u09cd\u09a5\u09be\u09aa\u09a8",
"pad.settings.myView": "\u0986\u09ae\u09be\u09b0 \u09a6\u09c3\u09b6\u09cd\u09af",
"pad.settings.stickychat": "\u099a\u09cd\u09af\u09be\u099f \u09b8\u0995\u09cd\u09b0\u09c0\u09a8\u09c7 \u09aa\u09cd\u09b0\u09a6\u09b0\u09cd\u09b6\u09a8 \u0995\u09b0\u09be \u09b9\u09ac\u09c7",
"pad.settings.colorcheck": "\u09b2\u09c7\u0996\u0995\u09a6\u09c7\u09b0 \u09a8\u09bf\u099c\u09b8\u09cd\u09ac \u09a8\u09bf\u09b0\u09cd\u09ac\u09be\u099a\u09bf\u09a4 \u09b0\u0982",
"pad.settings.linenocheck": "\u09b2\u09be\u0987\u09a8 \u09a8\u09ae\u09cd\u09ac\u09b0",
"pad.settings.fontType": "\u09ab\u09a8\u09cd\u099f-\u098f\u09b0 \u09aa\u09cd\u09b0\u0995\u09be\u09b0:",
"pad.settings.fontType.normal": "\u09b8\u09be\u09a7\u09be\u09b0\u09a3", "pad.settings.fontType.normal": "\u09b8\u09be\u09a7\u09be\u09b0\u09a3",
"pad.settings.fontType.monospaced": "Monospace",
"pad.settings.globalView": "\u09b8\u09b0\u09cd\u09ac\u09ac\u09cd\u09af\u09be\u09aa\u09c0 \u09a6\u09c3\u09b6\u09cd\u09af",
"pad.settings.language": "\u09ad\u09be\u09b7\u09be:", "pad.settings.language": "\u09ad\u09be\u09b7\u09be:",
"pad.importExport.import_export": "\u0987\u09ae\u09cd\u09aa\u09cb\u09b0\u099f\/\u098f\u0995\u09cd\u09b8\u09aa\u09cb\u09b0\u09cd\u099f",
"pad.importExport.import": "\u0995\u09cb\u09a8 \u099f\u09c7\u0995\u09cd\u09b8\u099f \u09ab\u09be\u0987\u09b2 \u09ac\u09be \u09a1\u0995\u09c1\u09ae\u09c7\u09a8\u09cd\u099f \u0986\u09aa\u09b2\u09cb\u09a1 \u0995\u09b0\u09c1\u09a8",
"pad.importExport.importSuccessful": "\u09b8\u09ab\u09b2!",
"pad.importExport.export": "\u098f\u0987 \u09aa\u09cd\u09af\u09be\u09a1\u099f\u09bf \u098f\u0995\u09cd\u09b8\u09aa\u09cb\u09b0\u09cd\u099f \u0995\u09b0\u09c1\u09a8", "pad.importExport.export": "\u098f\u0987 \u09aa\u09cd\u09af\u09be\u09a1\u099f\u09bf \u098f\u0995\u09cd\u09b8\u09aa\u09cb\u09b0\u09cd\u099f \u0995\u09b0\u09c1\u09a8",
"pad.importExport.exporthtml": "\u098f\u0987\u099a\u099f\u09bf\u098f\u09ae\u098f\u09b2", "pad.importExport.exporthtml": "\u098f\u0987\u099a\u099f\u09bf\u098f\u09ae\u098f\u09b2",
"pad.importExport.exportplain": "\u09b8\u09be\u09a7\u09be\u09b0\u09a3 \u09b2\u09c7\u0996\u09be", "pad.importExport.exportplain": "\u09b8\u09be\u09a7\u09be\u09b0\u09a3 \u09b2\u09c7\u0996\u09be",
"pad.importExport.exportword": "\u09ae\u09be\u0987\u0995\u09cd\u09b0\u09cb\u09b8\u09ab\u099f \u0993\u09af\u09bc\u09be\u09b0\u09cd\u09a1", "pad.importExport.exportword": "\u09ae\u09be\u0987\u0995\u09cd\u09b0\u09cb\u09b8\u09ab\u099f \u0993\u09af\u09bc\u09be\u09b0\u09cd\u09a1",
"pad.importExport.exportpdf": "\u09aa\u09bf\u09a1\u09bf\u098f\u09ab", "pad.importExport.exportpdf": "\u09aa\u09bf\u09a1\u09bf\u098f\u09ab",
"pad.importExport.exportopen": "\u0993\u09a1\u09bf\u098f\u09ab (\u0993\u09aa\u09c7\u09a8 \u09a1\u0995\u09c1\u09ae\u09c7\u09a8\u09cd\u099f \u09ab\u09b0\u09ae\u09cd\u09af\u09be\u099f)", "pad.importExport.exportopen": "\u0993\u09a1\u09bf\u098f\u09ab (\u0993\u09aa\u09c7\u09a8 \u09a1\u0995\u09c1\u09ae\u09c7\u09a8\u09cd\u099f \u09ab\u09b0\u09ae\u09cd\u09af\u09be\u099f)",
"pad.importExport.exportdokuwiki": "DokuWiki",
"pad.modals.connected": "\u09af\u09cb\u0997\u09be\u09af\u09cb\u0997 \u09b8\u09ab\u09b2",
"pad.modals.reconnecting": "\u0986\u09aa\u09a8\u09be\u09b0 \u09aa\u09cd\u09af\u09be\u09a1\u09c7\u09b0 \u09b8\u09be\u09a5\u09c7 \u09b8\u0982\u09af\u09cb\u0997\u09b8\u09cd\u09a5\u09be\u09aa\u09a8 \u0995\u09b0\u09be \u09b9\u099a\u09cd\u099b\u09c7..",
"pad.modals.forcereconnect": "\u09aa\u09c1\u09a8\u09b0\u09be\u09af\u09bc \u09b8\u0982\u09af\u09cb\u0997\u09b8\u09cd\u09a5\u09be\u09aa\u09a8\u09c7\u09b0 \u099a\u09c7\u09b7\u09cd\u099f\u09be",
"pad.modals.userdup": "\u0985\u09a8\u09cd\u09af \u0989\u0987\u09a8\u09cd\u09a1\u09cb-\u09a4\u09c7 \u0996\u09cb\u09b2\u09be \u09b9\u09af\u09bc\u09c7\u099b\u09c7",
"pad.modals.unauth": "\u0986\u09aa\u09a8\u09be\u09b0 \u0985\u09a7\u09bf\u0995\u09be\u09b0 \u09a8\u09c7\u0987",
"pad.modals.looping": "\u09af\u09cb\u0997\u09be\u09af\u09cb\u0997 \u09ac\u09bf\u099a\u09cd\u099b\u09bf\u09a8\u09cd\u09a8",
"pad.modals.initsocketfail": "\u09b8\u09be\u09b0\u09cd\u09ad\u09be\u09b0-\u098f\u09b0 \u09b8\u09be\u09a5\u09c7 \u09af\u09cb\u0997\u09be\u09af\u09cb\u0997 \u0995\u09b0\u09a4\u09c7 \u0985\u09b8\u0995\u09cd\u09b7\u09ae\u0964",
"pad.modals.slowcommit": "\u09af\u09cb\u0997\u09be\u09af\u09cb\u0997 \u09ac\u09bf\u099a\u09cd\u099b\u09bf\u09a8\u09cd\u09a8",
"pad.modals.deleted": "\u0985\u09aa\u09b8\u09be\u09b0\u09bf\u09a4\u0964", "pad.modals.deleted": "\u0985\u09aa\u09b8\u09be\u09b0\u09bf\u09a4\u0964",
"pad.modals.deleted.explanation": "\u098f\u0987 \u09aa\u09cd\u09af\u09be\u09a1\u099f\u09bf \u0985\u09aa\u09b8\u09be\u09b0\u09a3 \u0995\u09b0\u09be \u09b9\u09af\u09bc\u09c7\u099b\u09c7\u0964", "pad.modals.deleted.explanation": "\u098f\u0987 \u09aa\u09cd\u09af\u09be\u09a1\u099f\u09bf \u0985\u09aa\u09b8\u09be\u09b0\u09a3 \u0995\u09b0\u09be \u09b9\u09af\u09bc\u09c7\u099b\u09c7\u0964",
"pad.modals.disconnected.explanation": "\u09b8\u09be\u09b0\u09cd\u09ad\u09be\u09b0\u09c7\u09b0 \u09b8\u09be\u09a5\u09c7 \u09af\u09cb\u0997\u09be\u09af\u09cb\u0997 \u0995\u09b0\u09be \u09af\u09be\u099a\u09cd\u099b\u09c7 \u09a8\u09be", "pad.modals.disconnected.explanation": "\u09b8\u09be\u09b0\u09cd\u09ad\u09be\u09b0\u09c7\u09b0 \u09b8\u09be\u09a5\u09c7 \u09af\u09cb\u0997\u09be\u09af\u09cb\u0997 \u0995\u09b0\u09be \u09af\u09be\u099a\u09cd\u099b\u09c7 \u09a8\u09be",
@ -34,6 +68,7 @@
"timeslider.toolbar.authors": "\u09b2\u09c7\u0996\u0995\u0997\u09a3:", "timeslider.toolbar.authors": "\u09b2\u09c7\u0996\u0995\u0997\u09a3:",
"timeslider.toolbar.authorsList": "\u0995\u09cb\u09a8\u09cb \u09b2\u09c7\u0996\u0995 \u09a8\u09c7\u0987", "timeslider.toolbar.authorsList": "\u0995\u09cb\u09a8\u09cb \u09b2\u09c7\u0996\u0995 \u09a8\u09c7\u0987",
"timeslider.exportCurrent": "\u09ac\u09b0\u09cd\u09a4\u09ae\u09be\u09a8 \u09b8\u0982\u09b8\u09cd\u0995\u09b0\u09a3\u099f\u09bf \u098f\u0995\u09cd\u09b8\u09aa\u09cb\u09b0\u09cd\u099f \u0995\u09b0\u09c1\u09a8:", "timeslider.exportCurrent": "\u09ac\u09b0\u09cd\u09a4\u09ae\u09be\u09a8 \u09b8\u0982\u09b8\u09cd\u0995\u09b0\u09a3\u099f\u09bf \u098f\u0995\u09cd\u09b8\u09aa\u09cb\u09b0\u09cd\u099f \u0995\u09b0\u09c1\u09a8:",
"timeslider.dateformat": "{{month}}\/{{day}}\/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "\u099c\u09be\u09a8\u09c1\u09af\u09bc\u09be\u09b0\u09bf", "timeslider.month.january": "\u099c\u09be\u09a8\u09c1\u09af\u09bc\u09be\u09b0\u09bf",
"timeslider.month.february": "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09af\u09bc\u09be\u09b0\u09bf", "timeslider.month.february": "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09af\u09bc\u09be\u09b0\u09bf",
"timeslider.month.march": "\u09ae\u09be\u09b0\u09cd\u099a", "timeslider.month.march": "\u09ae\u09be\u09b0\u09cd\u099a",
@ -45,5 +80,12 @@
"timeslider.month.september": "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0", "timeslider.month.september": "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0",
"timeslider.month.october": "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0", "timeslider.month.october": "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0",
"timeslider.month.november": "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0", "timeslider.month.november": "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0",
"timeslider.month.december": "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0" "timeslider.month.december": "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0",
"pad.userlist.entername": "\u0986\u09aa\u09a8\u09be\u09b0 \u09a8\u09be\u09ae",
"pad.userlist.unnamed": "\u0995\u09cb\u09a8 \u09a8\u09be\u09ae \u09a8\u09bf\u09b0\u09cd\u09ac\u09be\u099a\u09a8 \u0995\u09b0\u09be \u09b9\u09af\u09bc\u09a8\u09bf",
"pad.userlist.guest": "\u0985\u09a4\u09bf\u09a5\u09bf",
"pad.userlist.approve": "\u0985\u09a8\u09c1\u09ae\u09cb\u09a6\u09bf\u09a4",
"pad.impexp.importbutton": "\u098f\u0996\u09a8 \u0987\u09ae\u09cd\u09aa\u09cb\u09b0\u09cd\u099f \u0995\u09b0\u09c1\u09a8",
"pad.impexp.importing": "\u0987\u09ae\u09cd\u09aa\u09cb\u09b0\u09cd\u099f \u099a\u09b2\u099b\u09c7...",
"pad.impexp.importfailed": "\u0987\u09ae\u09cd\u09aa\u09cb\u09b0\u09cd\u099f \u0985\u09b8\u0995\u09cd\u09b7\u09ae"
} }

View File

@ -1,34 +1,96 @@
{ {
"@metadata": {
"authors": [
"Fohanno",
"Fulup",
"Gwenn-Ael",
"Y-M D"
]
},
"index.newPad": "Pad nevez", "index.newPad": "Pad nevez",
"index.createOpenPad": "pe kroui\u00f1\/digeri\u00f1 ur pad gant an anv :", "index.createOpenPad": "pe kroui\u00f1\/digeri\u00f1 ur pad gant an anv :",
"pad.toolbar.bold.title": "Tev (Ctrl-B)", "pad.toolbar.bold.title": "Tev (Ctrl-B)",
"pad.toolbar.italic.title": "Italek (Ctrl-I)", "pad.toolbar.italic.title": "Italek (Ctrl-I)",
"pad.toolbar.underline.title": "Islinenna\u00f1 (Ctrl-U)", "pad.toolbar.underline.title": "Islinenna\u00f1 (Ctrl-U)",
"pad.toolbar.strikethrough.title": "Barrennet",
"pad.toolbar.ol.title": "Roll urzhiet",
"pad.toolbar.ul.title": "Roll en dizurzh",
"pad.toolbar.indent.title": "Endanta\u00f1", "pad.toolbar.indent.title": "Endanta\u00f1",
"pad.toolbar.unindent.title": "Diendanta\u00f1", "pad.toolbar.unindent.title": "Diendanta\u00f1",
"pad.toolbar.undo.title": "Dizober (Ktrl-Z)",
"pad.toolbar.redo.title": "Adober (Ktrl-Y)",
"pad.toolbar.clearAuthorship.title": "Diverka\u00f1 al livio\u00f9 oc'h anaout an aozerien",
"pad.toolbar.import_export.title": "Enporzhia\u00f1\/Ezporzhia\u00f1 eus\/war-zu ur furmad restr dishe\u00f1vel",
"pad.toolbar.timeslider.title": "Istor dinamek",
"pad.toolbar.savedRevision.title": "Doareo\u00f9 enrollet",
"pad.toolbar.settings.title": "Arventenno\u00f9", "pad.toolbar.settings.title": "Arventenno\u00f9",
"pad.toolbar.embed.title": "Enframma\u00f1 ar pad-ma\u00f1",
"pad.toolbar.showusers.title": "Diskwelet implijerien ar Pad",
"pad.colorpicker.save": "Enrolla\u00f1", "pad.colorpicker.save": "Enrolla\u00f1",
"pad.colorpicker.cancel": "Nulla\u00f1", "pad.colorpicker.cancel": "Nulla\u00f1",
"pad.loading": "O karga\u00f1...", "pad.loading": "O karga\u00f1...",
"pad.passwordRequired": "Ezhomm ho peus ur ger-tremen evit mont d'ar Pad-se",
"pad.permissionDenied": "\nN'oc'h ket aotreet da vont d'ar pad-ma\u00f1",
"pad.wrongPassword": "Fazius e oa ho ker-tremen",
"pad.settings.padSettings": "Arventenno\u00f9 Pad",
"pad.settings.myView": "Ma diskwel", "pad.settings.myView": "Ma diskwel",
"pad.settings.stickychat": "Diskwel ar flap bepred",
"pad.settings.colorcheck": "Livio\u00f9 anaout",
"pad.settings.linenocheck": "Niverenno\u00f9 linenno\u00f9",
"pad.settings.fontType": "Seurt font :",
"pad.settings.fontType.normal": "Reizh", "pad.settings.fontType.normal": "Reizh",
"pad.settings.fontType.monospaced": "Monospas",
"pad.settings.globalView": "Gwel dre vras",
"pad.settings.language": "Yezh :", "pad.settings.language": "Yezh :",
"pad.importExport.import_export": "Enporzhia\u00f1\/Ezporzhia\u00f1", "pad.importExport.import_export": "Enporzhia\u00f1\/Ezporzhia\u00f1",
"pad.importExport.import": "Enkarga\u00f1 un destenn pe ur restr", "pad.importExport.import": "Enkarga\u00f1 un destenn pe ur restr",
"pad.importExport.importSuccessful": "Deuet eo ganeoc'h !",
"pad.importExport.export": "Ezporzhia\u00f1 ar pad brema\u00f1 evel :",
"pad.importExport.exporthtml": "HTML", "pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Testenn blaen", "pad.importExport.exportplain": "Testenn blaen",
"pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF", "pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)", "pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.exportdokuwiki": "DokuWiki", "pad.importExport.exportdokuwiki": "DokuWiki",
"pad.importExport.abiword.innerHTML": "Ne c'hallit ket emporzjia\u00f1 furmado\u00f9 testenno\u00f9 kriz pe html. Evit arc'hwelio\u00f9 enporzhia\u00f1 emdroetoc'h, staliit <a href=\"https:\/\/github.com\/ether\/etherpad-lite\/wiki\/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">abiword<\/a> mar plij.",
"pad.modals.connected": "Kevreet.", "pad.modals.connected": "Kevreet.",
"pad.modals.reconnecting": "Adkevrea\u00f1 war-zu ho pad...",
"pad.modals.forcereconnect": "Adkevrea\u00f1 dre heg",
"pad.modals.userdup": "Digor en ur prenestr all",
"pad.modals.userdup.explanation": "Digor eo ho pad, war a seblant, e meur a brenestr eus ho merdeer en urzhiataer-ma\u00f1.",
"pad.modals.userdup.advice": "Kevrea\u00f1 en ur implijout ar prenestr-ma\u00f1.",
"pad.modals.unauth": "N'eo ket aotreet",
"pad.modals.unauth.explanation": "Kemmet e vo hoc'h aotreo\u00f9 pa vo diskwelet ar bajenn.-ma\u00f1 Klaskit kevrea\u00f1 en-dro.",
"pad.modals.looping": "Digevreet.",
"pad.modals.looping.explanation": "Kudenno\u00f9 kehenti\u00f1 zo gant ar servijer sinkronelekaat.",
"pad.modals.looping.cause": "Posupl eo e vefe gwarezet ho kevreadur gant ur maltouter diembreget pe ur servijer proksi",
"pad.modals.initsocketfail": "Ne c'haller ket tizhout ar servijer.",
"pad.modals.initsocketfail.explanation": "Ne c'haller ket kevrea\u00f1 ouzh ar servijer sinkronelaat.",
"pad.modals.initsocketfail.cause": "Gallout a ra ar gudenn dont eus ho merdeer Web pe eus ho kevreadur Internet.",
"pad.modals.slowcommit": "Digevreet.", "pad.modals.slowcommit": "Digevreet.",
"pad.modals.slowcommit.explanation": "Ne respont ket ar serveur.",
"pad.modals.slowcommit.cause": "Gallout a ra dont diwar kudenno\u00f9 kevrea\u00f1 gant ar rouedad.",
"pad.modals.deleted": "Dilamet.",
"pad.modals.deleted.explanation": "Lamet eo bet ar pad-ma\u00f1.",
"pad.modals.disconnected": "Digevreet oc'h bet.",
"pad.modals.disconnected.explanation": "Kollet eo bet ar c'hevreadur gant ar servijer",
"pad.modals.disconnected.cause": "Dizimplijadus eo ar servijer marteze. Kelaouit ac'hanomp ma pad ar gudenn.",
"pad.share": "Ranna\u00f1 ar pad-ma\u00f1.",
"pad.share.readonly": "Lenn hepken", "pad.share.readonly": "Lenn hepken",
"pad.share.link": "Liamm", "pad.share.link": "Liamm",
"pad.share.emebdcode": "Enframma\u00f1 an URL",
"pad.chat": "Flap", "pad.chat": "Flap",
"pad.chat.title": "Digeri\u00f1 ar flap kevelet gant ar pad-ma\u00f1.",
"pad.chat.loadmessages": "Karga\u00f1 muioc'h a gemennadenno\u00f9",
"timeslider.pageTitle": "Istor dinamek eus {{appTitle}}",
"timeslider.toolbar.returnbutton": "Distrei\u00f1 d'ar pad-ma\u00f1.",
"timeslider.toolbar.authors": "Aozerien :", "timeslider.toolbar.authors": "Aozerien :",
"timeslider.toolbar.authorsList": "Aozer ebet", "timeslider.toolbar.authorsList": "Aozer ebet",
"timeslider.toolbar.exportlink.title": "Ezporzhia\u00f1", "timeslider.toolbar.exportlink.title": "Ezporzhia\u00f1",
"timeslider.exportCurrent": "Ezporzhia\u00f1 an doare brema\u00f1 evel :",
"timeslider.version": "Stumm {{version}}",
"timeslider.saved": "Enrolla\u00f1 {{day}} {{month}} {{year}}",
"timeslider.dateformat": "{{month}}\/{{day}}\/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Genver", "timeslider.month.january": "Genver",
"timeslider.month.february": "C'hwevrer", "timeslider.month.february": "C'hwevrer",
"timeslider.month.march": "Meurzh", "timeslider.month.march": "Meurzh",
@ -41,16 +103,21 @@
"timeslider.month.october": "Here", "timeslider.month.october": "Here",
"timeslider.month.november": "Du", "timeslider.month.november": "Du",
"timeslider.month.december": "Kerzu", "timeslider.month.december": "Kerzu",
"timeslider.unnamedauthor": "{{niver}} aozer dianav",
"timeslider.unnamedauthors": "Aozerien dianav",
"pad.savedrevs.marked": "Merket eo an adweladenn-ma\u00f1 evel adweladenn gwiriet",
"pad.userlist.entername": "Ebarzhit hoc'h anv",
"pad.userlist.unnamed": "dizanv",
"pad.userlist.guest": "Den pedet", "pad.userlist.guest": "Den pedet",
"pad.userlist.deny": "Nac'h", "pad.userlist.deny": "Nac'h",
"pad.userlist.approve": "Aproui\u00f1", "pad.userlist.approve": "Aproui\u00f1",
"pad.editbar.clearcolors": "Diverka\u00f1 al livio\u00f9 stag ouzh an aozerien en teul a-bezh ?",
"pad.impexp.importbutton": "Enporzhia\u00f1 brema\u00f1", "pad.impexp.importbutton": "Enporzhia\u00f1 brema\u00f1",
"pad.impexp.importing": "Oc'h enporzhia\u00f1...", "pad.impexp.importing": "Oc'h enporzhia\u00f1...",
"pad.impexp.confirmimport": "Ma vez enporzhiet ur restr e vo diverket ar pezh zo en teul a-vrema\u00f1. Ha sur oc'h e fell deoc'h mont betek penn ?",
"pad.impexp.convertFailed": "N'eus ket bet gallet enporzhia\u00f1 ar restr. Ober gant ur furmad teul all pe eila\u00f1\/pega\u00f1 gant an dorn.",
"pad.impexp.uploadFailed": "C'hwitet eo bet an enporzhia\u00f1. Klaskit en-dro.",
"pad.impexp.importfailed": "C'hwitet eo an enporzhiadenn", "pad.impexp.importfailed": "C'hwitet eo an enporzhiadenn",
"@metadata": { "pad.impexp.copypaste": "Eilit\/pegit, mar plij",
"authors": [ "pad.impexp.exportdisabled": "Diweredekaet eo ezporzhia\u00f1 d'ar furmad {{type}}. Kit e darempred gant merour ar reizhiad evit gouzout hiroc'h."
"Fulup",
"Y-M D"
]
}
} }

View File

@ -22,7 +22,7 @@
"pad.toolbar.clearAuthorship.title": "Autorenfarben zur\u00fccksetzen", "pad.toolbar.clearAuthorship.title": "Autorenfarben zur\u00fccksetzen",
"pad.toolbar.import_export.title": "Import\/Export in verschiedenen Dateiformaten", "pad.toolbar.import_export.title": "Import\/Export in verschiedenen Dateiformaten",
"pad.toolbar.timeslider.title": "Pad-Versionsgeschichte anzeigen", "pad.toolbar.timeslider.title": "Pad-Versionsgeschichte anzeigen",
"pad.toolbar.savedRevision.title": "Diese Revision markieren", "pad.toolbar.savedRevision.title": "Version speichern",
"pad.toolbar.settings.title": "Einstellungen", "pad.toolbar.settings.title": "Einstellungen",
"pad.toolbar.embed.title": "Dieses Pad teilen oder einbetten", "pad.toolbar.embed.title": "Dieses Pad teilen oder einbetten",
"pad.toolbar.showusers.title": "Aktuell verbundene Benutzer anzeigen", "pad.toolbar.showusers.title": "Aktuell verbundene Benutzer anzeigen",

View File

@ -24,7 +24,7 @@
"pad.toolbar.clearAuthorship.title": "Poista kirjoittajav\u00e4rit", "pad.toolbar.clearAuthorship.title": "Poista kirjoittajav\u00e4rit",
"pad.toolbar.import_export.title": "Tuo tai vie eri tiedostomuodoista tai -muotoihin", "pad.toolbar.import_export.title": "Tuo tai vie eri tiedostomuodoista tai -muotoihin",
"pad.toolbar.timeslider.title": "Aikajana", "pad.toolbar.timeslider.title": "Aikajana",
"pad.toolbar.savedRevision.title": "Tallennetut versiot", "pad.toolbar.savedRevision.title": "Tallenna muutos",
"pad.toolbar.settings.title": "Asetukset", "pad.toolbar.settings.title": "Asetukset",
"pad.toolbar.embed.title": "Upota muistio", "pad.toolbar.embed.title": "Upota muistio",
"pad.toolbar.showusers.title": "N\u00e4yt\u00e4 muistion k\u00e4ytt\u00e4j\u00e4t", "pad.toolbar.showusers.title": "N\u00e4yt\u00e4 muistion k\u00e4ytt\u00e4j\u00e4t",

View File

@ -19,7 +19,7 @@
"pad.toolbar.clearAuthorship.title": "Kleuren auteurs wissen", "pad.toolbar.clearAuthorship.title": "Kleuren auteurs wissen",
"pad.toolbar.import_export.title": "Naar\/van andere opmaak exporteren\/importeren", "pad.toolbar.import_export.title": "Naar\/van andere opmaak exporteren\/importeren",
"pad.toolbar.timeslider.title": "Tijdlijn", "pad.toolbar.timeslider.title": "Tijdlijn",
"pad.toolbar.savedRevision.title": "Opgeslagen versies", "pad.toolbar.savedRevision.title": "Versie opslaan",
"pad.toolbar.settings.title": "Instellingen", "pad.toolbar.settings.title": "Instellingen",
"pad.toolbar.embed.title": "Pad insluiten", "pad.toolbar.embed.title": "Pad insluiten",
"pad.toolbar.showusers.title": "Gebruikers van dit pad weergeven", "pad.toolbar.showusers.title": "Gebruikers van dit pad weergeven",

View File

@ -21,7 +21,7 @@
"pad.toolbar.clearAuthorship.title": "Usu\u0144 kolory autor\u00f3w", "pad.toolbar.clearAuthorship.title": "Usu\u0144 kolory autor\u00f3w",
"pad.toolbar.import_export.title": "Import\/eksport z\/do r\u00f3\u017cnych format\u00f3w plik\u00f3w", "pad.toolbar.import_export.title": "Import\/eksport z\/do r\u00f3\u017cnych format\u00f3w plik\u00f3w",
"pad.toolbar.timeslider.title": "O\u015b czasu", "pad.toolbar.timeslider.title": "O\u015b czasu",
"pad.toolbar.savedRevision.title": "Zapisane wersje", "pad.toolbar.savedRevision.title": "Zapisz wersj\u0119",
"pad.toolbar.settings.title": "Ustawienia", "pad.toolbar.settings.title": "Ustawienia",
"pad.toolbar.embed.title": "Umie\u015b\u0107 ten Notatnik", "pad.toolbar.embed.title": "Umie\u015b\u0107 ten Notatnik",
"pad.toolbar.showusers.title": "Poka\u017c u\u017cytkownik\u00f3w", "pad.toolbar.showusers.title": "Poka\u017c u\u017cytkownik\u00f3w",
@ -102,6 +102,8 @@
"timeslider.month.october": "Pa\u017adziernik", "timeslider.month.october": "Pa\u017adziernik",
"timeslider.month.november": "Listopad", "timeslider.month.november": "Listopad",
"timeslider.month.december": "Grudzie\u0144", "timeslider.month.december": "Grudzie\u0144",
"timeslider.unnamedauthor": "{{num}} nienazwany autor",
"timeslider.unnamedauthors": "{{num}} autor\u00f3w bez nazw",
"pad.savedrevs.marked": "Ta wersja zosta\u0142a w\u0142a\u015bnie oznaczona jako zapisana.", "pad.savedrevs.marked": "Ta wersja zosta\u0142a w\u0142a\u015bnie oznaczona jako zapisana.",
"pad.userlist.entername": "Wprowad\u017a swoj\u0105 nazw\u0119", "pad.userlist.entername": "Wprowad\u017a swoj\u0105 nazw\u0119",
"pad.userlist.unnamed": "bez nazwy", "pad.userlist.unnamed": "bez nazwy",

View File

@ -3,6 +3,7 @@
"authors": [ "authors": [
"Dimension", "Dimension",
"Hydra", "Hydra",
"Yfdyh000",
"\u4e4c\u62c9\u8de8\u6c2a", "\u4e4c\u62c9\u8de8\u6c2a",
"\u71c3\u7389" "\u71c3\u7389"
] ]
@ -19,6 +20,7 @@
"pad.toolbar.undo.title": "\u64a4\u6d88 (Ctrl-Z)", "pad.toolbar.undo.title": "\u64a4\u6d88 (Ctrl-Z)",
"pad.toolbar.redo.title": "\u91cd\u505a (Ctrl-Y)", "pad.toolbar.redo.title": "\u91cd\u505a (Ctrl-Y)",
"pad.toolbar.clearAuthorship.title": "\u6e05\u9664\u4f5c\u540d\u989c\u8272", "pad.toolbar.clearAuthorship.title": "\u6e05\u9664\u4f5c\u540d\u989c\u8272",
"pad.toolbar.import_export.title": "\u4ee5\u5176\u4ed6\u6587\u4ef6\u683c\u5f0f\u5bfc\u5165\/\u5bfc\u51fa",
"pad.toolbar.timeslider.title": "\u65f6\u95f4\u8f74", "pad.toolbar.timeslider.title": "\u65f6\u95f4\u8f74",
"pad.toolbar.savedRevision.title": "\u4fdd\u5b58\u4fee\u8ba2", "pad.toolbar.savedRevision.title": "\u4fdd\u5b58\u4fee\u8ba2",
"pad.toolbar.settings.title": "\u8bbe\u7f6e", "pad.toolbar.settings.title": "\u8bbe\u7f6e",

View File

@ -20,7 +20,7 @@
"pad.toolbar.clearAuthorship.title": "\u6e05\u9664\u4f5c\u540d\u984f\u8272", "pad.toolbar.clearAuthorship.title": "\u6e05\u9664\u4f5c\u540d\u984f\u8272",
"pad.toolbar.import_export.title": "\u4ee5\u5176\u4ed6\u6a94\u6848\u683c\u5f0f\u5c0e\u5165\uff0f\u532f\u51fa", "pad.toolbar.import_export.title": "\u4ee5\u5176\u4ed6\u6a94\u6848\u683c\u5f0f\u5c0e\u5165\uff0f\u532f\u51fa",
"pad.toolbar.timeslider.title": "\u6642\u9593\u8ef8", "pad.toolbar.timeslider.title": "\u6642\u9593\u8ef8",
"pad.toolbar.savedRevision.title": "\u5df2\u5132\u5b58\u7684\u4fee\u8a02", "pad.toolbar.savedRevision.title": "\u5132\u5b58\u4fee\u8a02",
"pad.toolbar.settings.title": "\u8a2d\u5b9a", "pad.toolbar.settings.title": "\u8a2d\u5b9a",
"pad.toolbar.embed.title": "\u5d4c\u5165\u6b64pad", "pad.toolbar.embed.title": "\u5d4c\u5165\u6b64pad",
"pad.toolbar.showusers.title": "\u986f\u793a\u6b64pad\u7684\u7528\u6236", "pad.toolbar.showusers.title": "\u986f\u793a\u6b64pad\u7684\u7528\u6236",

View File

@ -146,12 +146,11 @@ exports.getPad = function(id, text, callback)
else else
{ {
pad = new Pad(id); pad = new Pad(id);
//initalize the pad //initalize the pad
pad.init(text, function(err) pad.init(text, function(err)
{ {
if(ERR(err, callback)) return; if(ERR(err, callback)) return;
globalPads.set(id, pad); globalPads.set(id, pad);
callback(null, pad); callback(null, pad);
}); });

View File

@ -20,6 +20,7 @@
var ERR = require("async-stacktrace"); var ERR = require("async-stacktrace");
var exporthtml = require("../utils/ExportHtml"); var exporthtml = require("../utils/ExportHtml");
var exporttxt = require("../utils/ExportTxt");
var exportdokuwiki = require("../utils/ExportDokuWiki"); var exportdokuwiki = require("../utils/ExportDokuWiki");
var padManager = require("../db/PadManager"); var padManager = require("../db/PadManager");
var async = require("async"); var async = require("async");
@ -48,22 +49,75 @@ exports.doExport = function(req, res, padId, type)
res.attachment(padId + "." + type); res.attachment(padId + "." + type);
//if this is a plain text export, we can do this directly //if this is a plain text export, we can do this directly
// We have to over engineer this because tabs are stored as attributes and not plain text
if(type == "txt") if(type == "txt")
{ {
padManager.getPad(padId, function(err, pad) var txt;
{ var randNum;
ERR(err); var srcFile, destFile;
if(req.params.rev){
pad.getInternalRevisionAText(req.params.rev, function(junk, text) async.series([
{ //render the txt document
res.send(text.text ? text.text : null); function(callback)
});
}
else
{ {
res.send(pad.text()); exporttxt.getPadTXTDocument(padId, req.params.rev, false, function(err, _txt)
{
if(ERR(err, callback)) return;
txt = _txt;
callback();
});
},
//decide what to do with the txt export
function(callback)
{
//if this is a txt export, we can send this from here directly
res.send(txt);
callback("stop");
},
//send the convert job to abiword
function(callback)
{
//ensure html can be collected by the garbage collector
txt = null;
destFile = tempDirectory + "/eplite_export_" + randNum + "." + type;
abiword.convertFile(srcFile, destFile, type, callback);
},
//send the file
function(callback)
{
res.sendfile(destFile, null, callback);
},
//clean up temporary files
function(callback)
{
async.parallel([
function(callback)
{
fs.unlink(srcFile, callback);
},
function(callback)
{
//100ms delay to accomidate for slow windows fs
if(os.type().indexOf("Windows") > -1)
{
setTimeout(function()
{
fs.unlink(destFile, callback);
}, 100);
}
else
{
fs.unlink(destFile, callback);
}
}
], callback);
} }
}); ], function(err)
{
if(err && err != "stop") ERR(err);
})
} }
else if(type == 'dokuwiki') else if(type == 'dokuwiki')
{ {

View File

@ -1035,7 +1035,7 @@ function handleClientReady(client, message)
} }
// notify all existing users about new user // notify all existing users about new user
client.broadcast.to(padIds.padIds).json.send(messageToTheOtherUsers); client.broadcast.to(padIds.padId).json.send(messageToTheOtherUsers);
//Run trough all sessions of this pad //Run trough all sessions of this pad
async.forEach(socketio.sockets.clients(padIds.padId), function(roomClient, callback) async.forEach(socketio.sockets.clients(padIds.padId), function(roomClient, callback)

View File

@ -0,0 +1,87 @@
/**
* Helpers for export requests
*/
/*
* 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var async = require("async");
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
var padManager = require("../db/PadManager");
var ERR = require("async-stacktrace");
var Security = require('ep_etherpad-lite/static/js/security');
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
exports.getPadPlainText = function(pad, revNum){
var atext = ((revNum !== undefined) ? pad.getInternalRevisionAText(revNum) : pad.atext());
var textLines = atext.text.slice(0, -1).split('\n');
var attribLines = Changeset.splitAttributionLines(atext.attribs, atext.text);
var apool = pad.pool();
var pieces = [];
for (var i = 0; i < textLines.length; i++){
var line = _analyzeLine(textLines[i], attribLines[i], apool);
if (line.listLevel){
var numSpaces = line.listLevel * 2 - 1;
var bullet = '*';
pieces.push(new Array(numSpaces + 1).join(' '), bullet, ' ', line.text, '\n');
}
else{
pieces.push(line.text, '\n');
}
}
return pieces.join('');
}
exports._analyzeLine = function(text, aline, apool){
var line = {};
// identify list
var lineMarker = 0;
line.listLevel = 0;
if (aline){
var opIter = Changeset.opIterator(aline);
if (opIter.hasNext()){
var listType = Changeset.opAttributeValue(opIter.next(), 'list', apool);
if (listType){
lineMarker = 1;
listType = /([a-z]+)([12345678])/.exec(listType);
if (listType){
line.listTypeName = listType[1];
line.listLevel = Number(listType[2]);
}
}
}
}
if (lineMarker){
line.text = text.substring(1);
line.aline = Changeset.subattribution(aline, 1);
}
else{
line.text = text;
line.aline = aline;
}
return line;
}
exports._encodeWhitespace = function(s){
return s.replace(/[^\x21-\x7E\s\t\n\r]/g, function(c){
return "&#" +c.charCodeAt(0) + ";"
});
}

View File

@ -21,31 +21,9 @@ var padManager = require("../db/PadManager");
var ERR = require("async-stacktrace"); var ERR = require("async-stacktrace");
var Security = require('ep_etherpad-lite/static/js/security'); var Security = require('ep_etherpad-lite/static/js/security');
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks'); var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
function getPadPlainText(pad, revNum) var getPadPlainText = require('./ExportHelper').getPadPlainText
{ var _analyzeLine = require('./ExportHelper')._analyzeLine;
var atext = ((revNum !== undefined) ? pad.getInternalRevisionAText(revNum) : pad.atext()); var _encodeWhitespace = require('./ExportHelper')._encodeWhitespace;
var textLines = atext.text.slice(0, -1).split('\n');
var attribLines = Changeset.splitAttributionLines(atext.attribs, atext.text);
var apool = pad.pool();
var pieces = [];
for (var i = 0; i < textLines.length; i++)
{
var line = _analyzeLine(textLines[i], attribLines[i], apool);
if (line.listLevel)
{
var numSpaces = line.listLevel * 2 - 1;
var bullet = '*';
pieces.push(new Array(numSpaces + 1).join(' '), bullet, ' ', line.text, '\n');
}
else
{
pieces.push(line.text, '\n');
}
}
return pieces.join('');
}
function getPadHTML(pad, revNum, callback) function getPadHTML(pad, revNum, callback)
{ {
@ -503,45 +481,6 @@ function getHTMLFromAtext(pad, atext, authorColors)
return pieces.join(''); return pieces.join('');
} }
function _analyzeLine(text, aline, apool)
{
var line = {};
// identify list
var lineMarker = 0;
line.listLevel = 0;
if (aline)
{
var opIter = Changeset.opIterator(aline);
if (opIter.hasNext())
{
var listType = Changeset.opAttributeValue(opIter.next(), 'list', apool);
if (listType)
{
lineMarker = 1;
listType = /([a-z]+)([12345678])/.exec(listType);
if (listType)
{
line.listTypeName = listType[1];
line.listLevel = Number(listType[2]);
}
}
}
}
if (lineMarker)
{
line.text = text.substring(1);
line.aline = Changeset.subattribution(aline, 1);
}
else
{
line.text = text;
line.aline = aline;
}
return line;
}
exports.getPadHTMLDocument = function (padId, revNum, noDocType, callback) exports.getPadHTMLDocument = function (padId, revNum, noDocType, callback)
{ {
padManager.getPad(padId, function (err, pad) padManager.getPad(padId, function (err, pad)
@ -578,79 +517,6 @@ exports.getPadHTMLDocument = function (padId, revNum, noDocType, callback)
}); });
} }
function _encodeWhitespace(s) {
return s.replace(/[^\x21-\x7E\s\t\n\r]/g, function(c)
{
return "&#" +c.charCodeAt(0) + ";"
});
}
// copied from ACE
function _processSpaces(s)
{
var doesWrap = true;
if (s.indexOf("<") < 0 && !doesWrap)
{
// short-cut
return s.replace(/ /g, '&nbsp;');
}
var parts = [];
s.replace(/<[^>]*>?| |[^ <]+/g, function (m)
{
parts.push(m);
});
if (doesWrap)
{
var endOfLine = true;
var beforeSpace = false;
// last space in a run is normal, others are nbsp,
// end of line is nbsp
for (var i = parts.length - 1; i >= 0; i--)
{
var p = parts[i];
if (p == " ")
{
if (endOfLine || beforeSpace) parts[i] = '&nbsp;';
endOfLine = false;
beforeSpace = true;
}
else if (p.charAt(0) != "<")
{
endOfLine = false;
beforeSpace = false;
}
}
// beginning of line is nbsp
for (var i = 0; i < parts.length; i++)
{
var p = parts[i];
if (p == " ")
{
parts[i] = '&nbsp;';
break;
}
else if (p.charAt(0) != "<")
{
break;
}
}
}
else
{
for (var i = 0; i < parts.length; i++)
{
var p = parts[i];
if (p == " ")
{
parts[i] = '&nbsp;';
}
}
}
return parts.join('');
}
// copied from ACE // copied from ACE
var _REGEX_WORDCHAR = /[\u0030-\u0039\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u1FFF\u3040-\u9FFF\uF900-\uFDFF\uFE70-\uFEFE\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]/; var _REGEX_WORDCHAR = /[\u0030-\u0039\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u1FFF\u3040-\u9FFF\uF900-\uFDFF\uFE70-\uFEFE\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]/;
@ -676,3 +542,57 @@ function _findURLs(text)
return urls; return urls;
} }
// copied from ACE
function _processSpaces(s){
var doesWrap = true;
if (s.indexOf("<") < 0 && !doesWrap){
// short-cut
return s.replace(/ /g, '&nbsp;');
}
var parts = [];
s.replace(/<[^>]*>?| |[^ <]+/g, function (m){
parts.push(m);
});
if (doesWrap){
var endOfLine = true;
var beforeSpace = false;
// last space in a run is normal, others are nbsp,
// end of line is nbsp
for (var i = parts.length - 1; i >= 0; i--){
var p = parts[i];
if (p == " "){
if (endOfLine || beforeSpace) parts[i] = '&nbsp;';
endOfLine = false;
beforeSpace = true;
}
else if (p.charAt(0) != "<"){
endOfLine = false;
beforeSpace = false;
}
}
// beginning of line is nbsp
for (var i = 0; i < parts.length; i++){
var p = parts[i];
if (p == " "){
parts[i] = '&nbsp;';
break;
}
else if (p.charAt(0) != "<"){
break;
}
}
}
else
{
for (var i = 0; i < parts.length; i++){
var p = parts[i];
if (p == " "){
parts[i] = '&nbsp;';
}
}
}
return parts.join('');
}

293
src/node/utils/ExportTxt.js Normal file
View File

@ -0,0 +1,293 @@
/**
* TXT export
*/
/*
* 2013 John McLear
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var async = require("async");
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
var padManager = require("../db/PadManager");
var ERR = require("async-stacktrace");
var Security = require('ep_etherpad-lite/static/js/security');
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
var getPadPlainText = require('./ExportHelper').getPadPlainText;
var _analyzeLine = require('./ExportHelper')._analyzeLine;
// This is slightly different than the HTML method as it passes the output to getTXTFromAText
function getPadTXT(pad, revNum, callback)
{
var atext = pad.atext;
var html;
async.waterfall([
// fetch revision atext
function (callback)
{
if (revNum != undefined)
{
pad.getInternalRevisionAText(revNum, function (err, revisionAtext)
{
if(ERR(err, callback)) return;
atext = revisionAtext;
callback();
});
}
else
{
callback(null);
}
},
// convert atext to html
function (callback)
{
html = getTXTFromAtext(pad, atext); // only this line is different to the HTML function
callback(null);
}],
// run final callback
function (err)
{
if(ERR(err, callback)) return;
callback(null, html);
});
}
exports.getPadTXT = getPadTXT;
// This is different than the functionality provided in ExportHtml as it provides formatting
// functionality that is designed specifically for TXT exports
function getTXTFromAtext(pad, atext, authorColors)
{
var apool = pad.apool();
var textLines = atext.text.slice(0, -1).split('\n');
var attribLines = Changeset.splitAttributionLines(atext.attribs, atext.text);
var tags = ['h1', 'h2', 'strong', 'em', 'u', 's'];
var props = ['heading1', 'heading2', 'bold', 'italic', 'underline', 'strikethrough'];
var anumMap = {};
var css = "";
props.forEach(function (propName, i)
{
var propTrueNum = apool.putAttrib([propName, true], true);
if (propTrueNum >= 0)
{
anumMap[propTrueNum] = i;
}
});
function getLineTXT(text, attribs)
{
var propVals = [false, false, false];
var ENTER = 1;
var STAY = 2;
var LEAVE = 0;
// Use order of tags (b/i/u) as order of nesting, for simplicity
// and decent nesting. For example,
// <b>Just bold<b> <b><i>Bold and italics</i></b> <i>Just italics</i>
// becomes
// <b>Just bold <i>Bold and italics</i></b> <i>Just italics</i>
var taker = Changeset.stringIterator(text);
var assem = Changeset.stringAssembler();
var openTags = [];
var idx = 0;
function processNextChars(numChars)
{
if (numChars <= 0)
{
return;
}
var iter = Changeset.opIterator(Changeset.subattribution(attribs, idx, idx + numChars));
idx += numChars;
while (iter.hasNext())
{
var o = iter.next();
var propChanged = false;
Changeset.eachAttribNumber(o.attribs, function (a)
{
if (a in anumMap)
{
var i = anumMap[a]; // i = 0 => bold, etc.
if (!propVals[i])
{
propVals[i] = ENTER;
propChanged = true;
}
else
{
propVals[i] = STAY;
}
}
});
for (var i = 0; i < propVals.length; i++)
{
if (propVals[i] === true)
{
propVals[i] = LEAVE;
propChanged = true;
}
else if (propVals[i] === STAY)
{
propVals[i] = true; // set it back
}
}
// now each member of propVal is in {false,LEAVE,ENTER,true}
// according to what happens at start of span
if (propChanged)
{
// leaving bold (e.g.) also leaves italics, etc.
var left = false;
for (var i = 0; i < propVals.length; i++)
{
var v = propVals[i];
if (!left)
{
if (v === LEAVE)
{
left = true;
}
}
else
{
if (v === true)
{
propVals[i] = STAY; // tag will be closed and re-opened
}
}
}
var tags2close = [];
for (var i = propVals.length - 1; i >= 0; i--)
{
if (propVals[i] === LEAVE)
{
//emitCloseTag(i);
tags2close.push(i);
propVals[i] = false;
}
else if (propVals[i] === STAY)
{
//emitCloseTag(i);
tags2close.push(i);
}
}
for (var i = 0; i < propVals.length; i++)
{
if (propVals[i] === ENTER || propVals[i] === STAY)
{
propVals[i] = true;
}
}
// propVals is now all {true,false} again
} // end if (propChanged)
var chars = o.chars;
if (o.lines)
{
chars--; // exclude newline at end of line, if present
}
var s = taker.take(chars);
// removes the characters with the code 12. Don't know where they come
// from but they break the abiword parser and are completly useless
// s = s.replace(String.fromCharCode(12), "");
// remove * from s, it's just not needed on a blank line.. This stops
// plugins from being able to display * at the beginning of a line
// s = s.replace("*", ""); // Then remove it
assem.append(s);
} // end iteration over spans in line
var tags2close = [];
for (var i = propVals.length - 1; i >= 0; i--)
{
if (propVals[i])
{
tags2close.push(i);
propVals[i] = false;
}
}
} // end processNextChars
processNextChars(text.length - idx);
return(assem.toString());
} // end getLineHTML
var pieces = [css];
// Need to deal with constraints imposed on HTML lists; can
// only gain one level of nesting at once, can't change type
// mid-list, etc.
// People might use weird indenting, e.g. skip a level,
// so we want to do something reasonable there. We also
// want to deal gracefully with blank lines.
// => keeps track of the parents level of indentation
var lists = []; // e.g. [[1,'bullet'], [3,'bullet'], ...]
for (var i = 0; i < textLines.length; i++)
{
var line = _analyzeLine(textLines[i], attribLines[i], apool);
var lineContent = getLineTXT(line.text, line.aline);
if(line.listTypeName == "bullet"){
lineContent = "* " + lineContent; // add a bullet
}
if(line.listLevel > 0){
for (var j = line.listLevel - 1; j >= 0; j--){
pieces.push('\t');
}
if(line.listTypeName == "number"){
pieces.push(line.listLevel + ". ");
// This is bad because it doesn't truly reflect what the user
// sees because browsers do magic on nested <ol><li>s
}
pieces.push(lineContent, '\n');
}else{
pieces.push(lineContent, '\n');
}
}
return pieces.join('');
}
exports.getTXTFromAtext = getTXTFromAtext;
exports.getPadTXTDocument = function (padId, revNum, noDocType, callback)
{
padManager.getPad(padId, function (err, pad)
{
if(ERR(err, callback)) return;
getPadTXT(pad, revNum, function (err, html)
{
if(ERR(err, callback)) return;
callback(null, html);
});
});
}

View File

@ -1622,9 +1622,17 @@ function Ace2Inner(){
lines = ccData.lines; lines = ccData.lines;
var lineAttribs = ccData.lineAttribs; var lineAttribs = ccData.lineAttribs;
var linesWrapped = ccData.linesWrapped; var linesWrapped = ccData.linesWrapped;
var scrollToTheLeftNeeded = false;
if (linesWrapped > 0) if (linesWrapped > 0)
{ {
if(!browser.ie){
// chrome decides in it's infinite wisdom that its okay to put the browsers visisble window in the middle of the span
// an outcome of this is that the first chars of the string are no longer visible to the user.. Yay chrome..
// Move the browsers visible area to the left hand side of the span
// Firefox isn't quite so bad, but it's still pretty quirky.
var scrollToTheLeftNeeded = true;
}
// console.log("Editor warning: " + linesWrapped + " long line" + (linesWrapped == 1 ? " was" : "s were") + " hard-wrapped into " + ccData.numLinesAfter + " lines."); // console.log("Editor warning: " + linesWrapped + " long line" + (linesWrapped == 1 ? " was" : "s were") + " hard-wrapped into " + ccData.numLinesAfter + " lines.");
} }
@ -1692,6 +1700,10 @@ function Ace2Inner(){
//console.log("removed: "+id); //console.log("removed: "+id);
}); });
if(scrollToTheLeftNeeded){ // needed to stop chrome from breaking the ui when long strings without spaces are pasted
$("#innerdocbody").scrollLeft(0);
}
p.mark("findsel"); p.mark("findsel");
// if the nodes that define the selection weren't encountered during // if the nodes that define the selection weren't encountered during
// content collection, figure out where those nodes are now. // content collection, figure out where those nodes are now.
@ -1897,7 +1909,7 @@ function Ace2Inner(){
var prevLine = rep.lines.prev(thisLine); var prevLine = rep.lines.prev(thisLine);
var prevLineText = prevLine.text; var prevLineText = prevLine.text;
var theIndent = /^ *(?:)/.exec(prevLineText)[0]; var theIndent = /^ *(?:)/.exec(prevLineText)[0];
if (/[\[\(\{]\s*$/.exec(prevLineText)) theIndent += THE_TAB; if (/[\[\(\:\{]\s*$/.exec(prevLineText)) theIndent += THE_TAB;
var cs = Changeset.builder(rep.lines.totalWidth()).keep( var cs = Changeset.builder(rep.lines.totalWidth()).keep(
rep.lines.offsetOfIndex(lineNum), lineNum).insert( rep.lines.offsetOfIndex(lineNum), lineNum).insert(
theIndent, [ theIndent, [
@ -3287,7 +3299,7 @@ function Ace2Inner(){
listType = /([a-z]+)([12345678])/.exec(listType); listType = /([a-z]+)([12345678])/.exec(listType);
var type = listType[1]; var type = listType[1];
var level = Number(listType[2]); var level = Number(listType[2]);
//detect empty list item; exclude indentation //detect empty list item; exclude indentation
if(text === '*' && type !== "indent") if(text === '*' && type !== "indent")
{ {
@ -3317,8 +3329,10 @@ function Ace2Inner(){
function doIndentOutdent(isOut) function doIndentOutdent(isOut)
{ {
if (!(rep.selStart && rep.selEnd) || if (!((rep.selStart && rep.selEnd) ||
((rep.selStart[0] == rep.selEnd[0]) && (rep.selStart[1] == rep.selEnd[1]) && rep.selEnd[1] > 1)) ((rep.selStart[0] == rep.selEnd[0]) && (rep.selStart[1] == rep.selEnd[1]) && rep.selEnd[1] > 1)) &&
(isOut != true)
)
{ {
return false; return false;
} }
@ -3326,7 +3340,6 @@ function Ace2Inner(){
var firstLine, lastLine; var firstLine, lastLine;
firstLine = rep.selStart[0]; firstLine = rep.selStart[0];
lastLine = Math.max(firstLine, rep.selEnd[0] - ((rep.selEnd[1] === 0) ? 1 : 0)); lastLine = Math.max(firstLine, rep.selEnd[0] - ((rep.selEnd[1] === 0) ? 1 : 0));
var mods = []; var mods = [];
for (var n = firstLine; n <= lastLine; n++) for (var n = firstLine; n <= lastLine; n++)
{ {
@ -3539,7 +3552,6 @@ function Ace2Inner(){
{ {
// if (DEBUG && window.DONT_INCORP) return; // if (DEBUG && window.DONT_INCORP) return;
if (!isEditable) return; if (!isEditable) return;
var type = evt.type; var type = evt.type;
var charCode = evt.charCode; var charCode = evt.charCode;
var keyCode = evt.keyCode; var keyCode = evt.keyCode;
@ -3736,26 +3748,30 @@ function Ace2Inner(){
We have to do this the way we do because rep. doesn't hold the value for keyheld events IE if the user We have to do this the way we do because rep. doesn't hold the value for keyheld events IE if the user
presses and holds the arrow key */ presses and holds the arrow key */
if((evt.which == 37 || evt.which == 38 || evt.which == 39 || evt.which == 40) && $.browser.chrome){ if((evt.which == 37 || evt.which == 38 || evt.which == 39 || evt.which == 40) && $.browser.chrome){
var isLeftArrow = evt.which === 37;
var isUpArrow = evt.which === 38;
var isRightArrow = evt.which === 39;
var isDownArrow = evt.which === 40;
var newVisibleLineRange = getVisibleLineRange(); // get the current visible range -- This works great. var newVisibleLineRange = getVisibleLineRange(); // get the current visible range -- This works great.
var lineHeight = textLineHeight(); // what Is the height of each line? var lineHeight = textLineHeight(); // what Is the height of each line?
var myselection = document.getSelection(); // get the current caret selection, can't use rep. here because that only gives us the start position not the current var myselection = document.getSelection(); // get the current caret selection, can't use rep. here because that only gives us the start position not the current
var caretOffsetTop = myselection.focusNode.parentNode.offsetTop; // get the carets selection offset in px IE 214 var caretOffsetTop = myselection.focusNode.parentNode.offsetTop; // get the carets selection offset in px IE 214
if((isUpArrow || isLeftArrow || isRightArrow || isDownArrow) && caretOffsetTop){ // was it an up arrow or left arrow? if(caretOffsetTop){ // sometimes caretOffsetTop bugs out and returns 0, not sure why, possible Chrome bug? Either way if it does we don't wanna mess with it
var lineNum = Math.round(caretOffsetTop / lineHeight) ; // Get the current Line Number IE 84 var lineNum = Math.round(caretOffsetTop / lineHeight) ; // Get the current Line Number IE 84
newVisibleLineRange[1] = newVisibleLineRange[1]-1;
var caretIsVisible = (lineNum > newVisibleLineRange[0] && lineNum < newVisibleLineRange[1]); // Is the cursor in the visible Range IE ie 84 > 14 and 84 < 90? var caretIsVisible = (lineNum > newVisibleLineRange[0] && lineNum < newVisibleLineRange[1]); // Is the cursor in the visible Range IE ie 84 > 14 and 84 < 90?
if(!caretIsVisible){ // is the cursor no longer visible to the user? if(!caretIsVisible){ // is the cursor no longer visible to the user?
// Oh boy the caret is out of the visible area, I need to scroll the browser window to lineNum. // Oh boy the caret is out of the visible area, I need to scroll the browser window to lineNum.
// Get the new Y by getting the line number and multiplying by the height of each line. // Get the new Y by getting the line number and multiplying by the height of each line.
var newY = lineHeight * (lineNum -1); // -1 to go to the line above if(evt.which == 37 || evt.which == 38){ // If left or up
var newY = lineHeight * (lineNum -1); // -1 to go to the line above
}else if(evt.which == 39 || evt.which == 40){ // if down or right
var newY = getScrollY() + (lineHeight*3); // the offset and one additional line
}
setScrollY(newY); // set the scroll height of the browser setScrollY(newY); // set the scroll height of the browser
} }
} }
} }
} }

View File

@ -1,8 +1,8 @@
(function(document) { (function(document) {
// Set language for l10n // Set language for l10n
var language = document.cookie.match(/language=((\w{2,3})(-w+)?)/); var language = document.cookie.match(/language=((\w{2,3})(-\w+)?)/);
if(language) language = language[1]; if(language) language = language[1];
html10n.bind('indexed', function() { html10n.bind('indexed', function() {
html10n.localize([language, navigator.language, navigator.userLanguage, 'en']) html10n.localize([language, navigator.language, navigator.userLanguage, 'en'])
}) })

View File

@ -156,10 +156,7 @@ var padeditbar = (function()
else if (cmd == 'insertorderedlist') ace.ace_doInsertOrderedList(); else if (cmd == 'insertorderedlist') ace.ace_doInsertOrderedList();
else if (cmd == 'indent') else if (cmd == 'indent')
{ {
if (!ace.ace_doIndentOutdent(false)) ace.ace_doIndentOutdent(false);
{
ace.ace_doInsertUnorderedList();
}
} }
else if (cmd == 'outdent') else if (cmd == 'outdent')
{ {

View File

@ -70,10 +70,12 @@ exports.flatten = function (lst) {
exports.callAll = function (hook_name, args) { exports.callAll = function (hook_name, args) {
if (!args) args = {}; if (!args) args = {};
if (exports.plugins.hooks[hook_name] === undefined) return []; if (exports.plugins){
return _.flatten(_.map(exports.plugins.hooks[hook_name], function (hook) { if (exports.plugins.hooks[hook_name] === undefined) return [];
return hookCallWrapper(hook, hook_name, args); return _.flatten(_.map(exports.plugins.hooks[hook_name], function (hook) {
}), true); return hookCallWrapper(hook, hook_name, args);
}), true);
}
} }
exports.aCallAll = function (hook_name, args, cb) { exports.aCallAll = function (hook_name, args, cb) {

View File

@ -29,6 +29,7 @@ var createCookie = require('./pad_utils').createCookie;
var readCookie = require('./pad_utils').readCookie; var readCookie = require('./pad_utils').readCookie;
var randomString = require('./pad_utils').randomString; var randomString = require('./pad_utils').randomString;
var _ = require('./underscore'); var _ = require('./underscore');
var hooks = require('./pluginfw/hooks');
var token, padId, export_links; var token, padId, export_links;
@ -108,6 +109,7 @@ function init() {
exports.socket = socket; // make the socket available exports.socket = socket; // make the socket available
hooks.aCallAll("postTimesliderInit");
}); });
} }

View File

@ -40,8 +40,10 @@
<% e.end_block(); %> <% e.end_block(); %>
<link rel="localizations" type="application/l10n+json" href="../../locales.json" /> <link rel="localizations" type="application/l10n+json" href="../../locales.json" />
<% e.begin_block("timesliderScripts"); %>
<script type="text/javascript" src="../../static/js/html10n.js"></script> <script type="text/javascript" src="../../static/js/html10n.js"></script>
<script type="text/javascript" src="../../static/js/l10n.js"></script> <script type="text/javascript" src="../../static/js/l10n.js"></script>
<% e.end_block(); %>
</head> </head>
<% e.begin_block("timesliderBody"); %> <% e.begin_block("timesliderBody"); %>