summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan <mu.stefan@googlemail.com>2016-12-20 21:31:11 +0100
committerStefan <mu.stefan@googlemail.com>2016-12-20 21:31:11 +0100
commitaefa61779777983fb1ef78d8d3c65e226202a4de (patch)
treee39db901f012354652125d7792c9648a288e7375
parent009b61b33843a5c03587b7e12e7d411dea0ca51e (diff)
parent368bbe48368b74ca701625fa1f182699e984898d (diff)
downloadetherpad-lite-aefa61779777983fb1ef78d8d3c65e226202a4de.zip
Merge branch 'develop' into improve_cookies
-rw-r--r--README.md2
-rwxr-xr-xbin/buildForWindows.sh2
-rw-r--r--bin/migrateDirtyDBtoRealDB.js4
-rw-r--r--doc/api/editbar.md2
-rw-r--r--doc/api/hooks_client-side.md18
-rw-r--r--doc/api/http_api.md9
-rw-r--r--settings.json.template9
-rw-r--r--src/locales/ar.json23
-rw-r--r--src/locales/az.json2
-rw-r--r--src/locales/azb.json30
-rw-r--r--src/locales/de.json5
-rw-r--r--src/locales/diq.json40
-rw-r--r--src/locales/dty.json69
-rw-r--r--src/locales/eo.json5
-rw-r--r--src/locales/hsb.json3
-rw-r--r--src/locales/hu.json10
-rw-r--r--src/locales/hy.json58
-rw-r--r--src/locales/ko.json4
-rw-r--r--src/locales/ku-latn.json2
-rw-r--r--src/locales/lb.json26
-rw-r--r--src/locales/lt.json39
-rw-r--r--src/locales/mn.json15
-rw-r--r--src/locales/ne.json12
-rw-r--r--src/locales/pa.json5
-rw-r--r--src/locales/qqq.json2
-rw-r--r--src/locales/sl.json9
-rw-r--r--src/locales/sq.json54
-rw-r--r--src/locales/zh-hans.json2
-rw-r--r--src/node/handler/ExportHandler.js4
-rw-r--r--src/node/hooks/express/adminsettings.js8
-rw-r--r--src/node/hooks/express/padreadonly.js4
-rw-r--r--src/node/hooks/express/specialpages.js7
-rw-r--r--src/node/hooks/i18n.js2
-rw-r--r--src/node/utils/ExportHtml.js111
-rw-r--r--src/node/utils/ExportTxt.js12
-rw-r--r--src/node/utils/Settings.js5
-rw-r--r--src/node/utils/caching_middleware.js3
-rw-r--r--src/node/utils/path_exists.js15
-rw-r--r--src/package.json4
-rw-r--r--src/static/css/admin.css6
-rw-r--r--src/static/js/ace2_inner.js71
-rw-r--r--src/static/js/admin/plugins.js4
-rw-r--r--src/static/js/admin/settings.js10
-rw-r--r--src/static/js/linestylefilter.js2
-rw-r--r--src/static/js/pad.js34
-rw-r--r--src/static/js/pad_editbar.js4
-rw-r--r--src/static/js/pad_editor.js7
-rw-r--r--src/static/js/pad_utils.js2
-rw-r--r--src/static/js/pluginfw/plugins.js5
-rw-r--r--src/templates/admin/index.html1
-rw-r--r--src/templates/admin/plugins-info.html1
-rw-r--r--src/templates/admin/plugins.html1
-rw-r--r--src/templates/admin/settings.html6
-rw-r--r--src/templates/export_html.html144
-rw-r--r--src/templates/index.html35
-rw-r--r--src/templates/javascript.html73
-rw-r--r--src/templates/pad.html8
-rw-r--r--src/templates/timeslider.html5
-rw-r--r--tests/frontend/helper.js77
-rw-r--r--tests/frontend/specs/drag_and_drop.js160
-rw-r--r--tests/frontend/specs/helper.js115
-rw-r--r--tests/frontend/specs/indentation.js45
-rw-r--r--tests/frontend/specs/urls_become_clickable.js23
63 files changed, 1191 insertions, 284 deletions
diff --git a/README.md b/README.md
index cc90800f..afec716e 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ Also, check out the **[FAQ](https://github.com/ether/etherpad-lite/wiki/FAQ)**,
# Installation
-Etherpad works with node v0.10+ and io.js.
+Etherpad works with node v0.10+ (except 6.0 and 6.1).
## Windows
diff --git a/bin/buildForWindows.sh b/bin/buildForWindows.sh
index 8e921d84..5ba4dd75 100755
--- a/bin/buildForWindows.sh
+++ b/bin/buildForWindows.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-NODE_VERSION="4.4.3"
+NODE_VERSION="6.9.1"
#Move to the folder where ep-lite is installed
cd `dirname $0`
diff --git a/bin/migrateDirtyDBtoRealDB.js b/bin/migrateDirtyDBtoRealDB.js
index 393c3081..c616714a 100644
--- a/bin/migrateDirtyDBtoRealDB.js
+++ b/bin/migrateDirtyDBtoRealDB.js
@@ -7,8 +7,8 @@ require("ep_etherpad-lite/node_modules/npm").load({}, function(er,npm) {
// file before using this script, just to be safe.
var settings = require("ep_etherpad-lite/node/utils/Settings");
- var dirty = require("dirty")('var/dirty.db');
- var ueberDB = require("../src/node_modules/ueberDB");
+ var dirty = require("../src/node_modules/dirty")('var/dirty.db');
+ var ueberDB = require("../src/node_modules/ueberdb2");
var log4js = require("../src/node_modules/log4js");
var dbWrapperSettings = {
"cache": "0", // The cache slows things down when you're mostly writing.
diff --git a/doc/api/editbar.md b/doc/api/editbar.md
index ce89c0b7..d4ad4c64 100644
--- a/doc/api/editbar.md
+++ b/doc/api/editbar.md
@@ -12,7 +12,7 @@ Shows the dropdown `div.popup` whose `id` equals `dropdown`.
Register a handler for a specific command. Commands are fired if the corresponding button is clicked or the corresponding select is changed.
## registerAceCommand(cmd, callback)
-Creates an ace callstack and calls the callback with an ace instance: `callback(cmd, ace)`.
+Creates an ace callstack and calls the callback with an ace instance (and a toolbar item, if applicable): `callback(cmd, ace, item)`.
Example:
```
diff --git a/doc/api/hooks_client-side.md b/doc/api/hooks_client-side.md
index b22db5da..9af03569 100644
--- a/doc/api/hooks_client-side.md
+++ b/doc/api/hooks_client-side.md
@@ -134,6 +134,20 @@ Things in context:
This hook is made available to edit the edit events that might occur when changes are made. Currently you can change the editor information, some of the meanings of the edit, and so on. You can also make internal changes (internal to your plugin) that use the information provided by the edit event.
+## aceRegisterNonScrollableEditEvents
+Called from: src/static/js/ace2_inner.js
+
+Things in context: None
+
+When aceEditEvent (documented above) finishes processing the event, it scrolls the viewport to make caret visible to the user, but if you don't want that behavior to happen you can use this hook to register which edit events should not scroll viewport. The return value of this hook should be a list of event names.
+
+Example:
+```
+exports.aceRegisterNonScrollableEditEvents = function(){
+ return [ 'repaginate', 'updatePageCount' ];
+}
+```
+
## aceRegisterBlockElements
Called from: src/static/js/ace2_inner.js
@@ -166,11 +180,11 @@ Called from: src/static/js/pad_editbar.js
Things in context:
1. ace - the ace object that is applied to this editor.
-2. toolbar - Editbar instance. See below for the Editbar documentation.
+2. toolbar - Editbar instance. See below for the Editbar documentation.
Can be used to register custom actions to the toolbar.
-Usage examples:
+Usage examples:
* [https://github.com/tiblu/ep_authorship_toggle]()
diff --git a/doc/api/http_api.md b/doc/api/http_api.md
index 8d1b64f1..93a9b399 100644
--- a/doc/api/http_api.md
+++ b/doc/api/http_api.md
@@ -363,6 +363,15 @@ returns an object of diffs from 2 points in a pad
* `{"code":0,"message":"ok","data":{"html":"<style>\n.authora_HKIv23mEbachFYfH {background-color: #a979d9}\n.authora_n4gEeMLsv1GivNeh {background-color: #a9b5d9}\n.removed {text-decoration: line-through; -ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)'; filter: alpha(opacity=80); opacity: 0.8; }\n</style>Welcome to Etherpad!<br><br>This 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!<br><br>Get involved with Etherpad at <a href=\"http&#x3a;&#x2F;&#x2F;etherpad&#x2e;org\">http:&#x2F;&#x2F;etherpad.org</a><br><span class=\"authora_HKIv23mEbachFYfH\">aw</span><br><br>","authors":["a.HKIv23mEbachFYfH",""]}}`
* `{"code":4,"message":"no or wrong API Key","data":null}`
+#### restoreRevision(padId, rev)
+ * API >= 1.2.11
+
+Restores revision from past as new changeset
+
+*Example returns:*
+ * {code:0, message:"ok", data:null}
+ * {code: 1, message:"padID does not exist", data: null}
+
### Chat
#### getChatHistory(padID, [start, end])
* API >= 1.2.7
diff --git a/settings.json.template b/settings.json.template
index 9eaec478..6af5f78a 100644
--- a/settings.json.template
+++ b/settings.json.template
@@ -3,7 +3,7 @@
Please edit settings.json, not settings.json.template
- To still commit settings without credentials you can
+ To still commit settings without credentials you can
store any credential settings in credentials.json
*/
{
@@ -18,6 +18,9 @@
"ip": "0.0.0.0",
"port" : 9001,
+ // Option to hide/show the settings.json in admin page, default option is set to true
+ "showSettingsInAdminPage" : true,
+
/*
// Node native SSL support
// this is disabled by default
@@ -192,9 +195,9 @@
, "level": "error" // filters out all log messages that have a lower level than "error"
, "appender":
{ "type": "smtp"
- , "subject": "An error occured in your EPL instance!"
+ , "subject": "An error occurred in your EPL instance!"
, "recipients": "bar@blurdybloop.com, baz@blurdybloop.com"
- , "sendInterval": 60*5 // in secs -- will buffer log messages; set to 0 to send a mail for every message
+ , "sendInterval": 300 // 60 * 5 = 5 minutes -- will buffer log messages; set to 0 to send a mail for every message
, "transport": "SMTP", "SMTP": { // see https://github.com/andris9/Nodemailer#possible-transport-methods
"host": "smtp.example.com", "port": 465,
"secureConnection": true,
diff --git a/src/locales/ar.json b/src/locales/ar.json
index 33c6beb3..1b9271d1 100644
--- a/src/locales/ar.json
+++ b/src/locales/ar.json
@@ -7,11 +7,12 @@
"Meno25",
"Test Create account",
"محمد أحمد عبد الفتاح",
- "Haytham morsy"
+ "Haytham morsy",
+ "ديفيد"
]
},
"index.newPad": "باد جديد",
- "index.createOpenPad": "أو صنع/فتح باد بوضع إسمه:",
+ "index.createOpenPad": "أو صنع/فتح باد بوضع اسمه:",
"pad.toolbar.bold.title": "سميك (Ctrl-B)",
"pad.toolbar.italic.title": "مائل (Ctrl-I)",
"pad.toolbar.underline.title": "تسطير (Ctrl-U)",
@@ -31,7 +32,7 @@
"pad.toolbar.showusers.title": "عرض المستخدمين على هذا الباد",
"pad.colorpicker.save": "تسجيل",
"pad.colorpicker.cancel": "إلغاء",
- "pad.loading": "جاري التحميل...",
+ "pad.loading": "جارٍ التحميل...",
"pad.noCookie": "الكوكيز غير متاحة. الرجاء السماح بتحميل الكوكيز على متصفحك!",
"pad.passwordRequired": "تحتاج إلى كلمة مرور للوصول إلى هذا الباد",
"pad.permissionDenied": "ليس لديك إذن لدخول هذا الباد",
@@ -64,24 +65,24 @@
"pad.modals.forcereconnect": "فرض إعادة الاتصال",
"pad.modals.userdup": "مفتوح في نافذة أخرى",
"pad.modals.userdup.explanation": "يبدو أن هذا الباد تم فتحه في أكثر من نافذة متصفح في هذا الحاسوب.",
- "pad.modals.userdup.advice": "إعادة الاتصال لإستعمال هذه النافذة بدلاً من الاخرى.",
+ "pad.modals.userdup.advice": "إعادة الاتصال لاستعمال هذه النافذة بدلاً من الأخرى.",
"pad.modals.unauth": "غير مخول",
- "pad.modals.unauth.explanation": "لقد تغيرت الأذونات الخاصة بك أثناء عرض هذه الصفحة. حاول إعادة الاتصال.",
+ "pad.modals.unauth.explanation": "لقد تغيرت الأذونات الخاصة بك أثناء عرض هذه الصفحة. أعد محاولة الاتصال.",
"pad.modals.looping.explanation": "هناك مشاكل في الاتصال مع ملقم التزامن.",
"pad.modals.looping.cause": "ربما كنت متصلاً من خلال وكيل أو جدار حماية غير متوافق.",
"pad.modals.initsocketfail": "لا يمكن الوصول إلى الخادم",
"pad.modals.initsocketfail.explanation": "تعذر الاتصال بخادم المزامنة.",
- "pad.modals.initsocketfail.cause": "وهذا على الأرجح بسبب مشكلة في المستعرض الخاص بك أو الاتصال بإنترنت.",
+ "pad.modals.initsocketfail.cause": "هذا على الأرجح بسبب مشكلة في المستعرض الخاص بك أو الاتصال بإنترنت.",
"pad.modals.slowcommit.explanation": "الخادم لا يستجيب.",
"pad.modals.slowcommit.cause": "يمكن أن يكون هذا بسبب مشاكل في الاتصال بالشبكة.",
- "pad.modals.badChangeset.explanation": "لقد صنفت إحدى عمليات التحرير التي قمت بها كعملية غير مسموح بها من قبل ملقم التزامن.",
+ "pad.modals.badChangeset.explanation": "لقد صُنفَت إحدى عمليات التحرير التي قمت بها كعملية غير مسموح بها من قبل ملقم التزامن.",
"pad.modals.badChangeset.cause": "يمكن أن يكون هذا بسبب تكوين ملقم خاطئ أو بسبب سلوك آخر غير متوقع. يرجى الاتصال بمسؤول الخدمة إذا كنت تعتقد بأن هناك خطأ ما. حاول إعادة الاتصال لمتابعة التحرير.",
"pad.modals.corruptPad.explanation": "الباد الذي تحاول الوصول إليه تالف.",
"pad.modals.corruptPad.cause": "قد يكون هذا بسبب تكوين ملقم خاطئ أو بسبب سلوك آخر غير متوقع. يرجى الاتصال بمسؤول الخدمة.",
"pad.modals.deleted": "محذوف.",
"pad.modals.deleted.explanation": "تمت إزالة هذا الباد",
- "pad.modals.disconnected": "لم تعد متّصل.",
- "pad.modals.disconnected.explanation": "تم فقدان الإتصال بالخادم",
+ "pad.modals.disconnected": "لم تعد متصلا.",
+ "pad.modals.disconnected.explanation": "تم فقدان الاتصال بالخادم",
"pad.modals.disconnected.cause": "قد يكون الخادم غير متوفر. يرجى إعلام مسؤول الخدمة إذا كان هذا لا يزال يحدث.",
"pad.share": "شارك هذه الباد",
"pad.share.readonly": "للقراءة فقط",
@@ -98,7 +99,7 @@
"timeslider.exportCurrent": "تصدير النسخة الحالية ك:",
"timeslider.version": "إصدار {{version}}",
"timeslider.saved": "محفوظ {{month}} {{day}}, {{year}}",
- "timeslider.playPause": "تشغيل / إيقاف مؤقت محتويات الباد",
+ "timeslider.playPause": "تشغيل / إيقاف مؤقت لمحتويات الباد",
"timeslider.backRevision": "عد إلى مراجعة في هذه الباد",
"timeslider.forwardRevision": "انطلق إلى مراجعة في هذه الباد",
"timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
@@ -127,7 +128,7 @@
"pad.impexp.importing": "الاستيراد...",
"pad.impexp.confirmimport": "استيراد ملف سيؤدي للكتابة فوق النص الحالي بالباد. هل أنت متأكد من أنك تريد المتابعة؟",
"pad.impexp.convertFailed": "لم نتمكن من استيراد هذا الملف. يرجى استخدام تنسيق مستند مختلف، أو النسخ واللصق يدوياً",
- "pad.impexp.padHasData": "لا يمكننا استيراد هذا الملف لأن هذه اللوحة تم بالفعل تغييره, الرجاء استيراد لوحة جديد",
+ "pad.impexp.padHasData": "لا يمكننا استيراد هذا الملف لأن هذا الباد تم بالفعل تغييره; الرجاء استيراد باد جديد",
"pad.impexp.uploadFailed": "فشل التحميل، الرجاء المحاولة مرة أخرى",
"pad.impexp.importfailed": "فشل الاستيراد",
"pad.impexp.copypaste": "الرجاء نسخ/لصق",
diff --git a/src/locales/az.json b/src/locales/az.json
index e27beaf8..48f0f841 100644
--- a/src/locales/az.json
+++ b/src/locales/az.json
@@ -97,6 +97,8 @@
"timeslider.version": "Versiya {{version}}",
"timeslider.saved": "Saxlanıldı {{day}} {{month}}, {{year}}",
"timeslider.playPause": "Geri oxutma / Lövhə Məzmunlarını Dayandır",
+ "timeslider.backRevision": "Sənədin bundan əvvəlki bir versiyasına qayıtmaq",
+ "timeslider.forwardRevision": "Sənədin bundan sonrakı bir versiyasına qayıtmaq",
"timeslider.dateformat": "{{day}} {{month}}, {{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Yanvar",
"timeslider.month.february": "Fevral",
diff --git a/src/locales/azb.json b/src/locales/azb.json
index 84f6cad8..f8d8f93b 100644
--- a/src/locales/azb.json
+++ b/src/locales/azb.json
@@ -16,25 +16,31 @@
"pad.toolbar.strikethrough.title": "خط یئمیش (Ctrl+5)",
"pad.toolbar.ol.title": "جوتدنمیش فهرست (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "جوتدنمه‌میش لیست (Ctrl+Shift+L)",
- "pad.toolbar.indent.title": "ایچری باتدیگی",
+ "pad.toolbar.indent.title": "ایچری باتما (TAB)",
"pad.toolbar.unindent.title": "ائشیگه چیخدیغی (Shift+TAB)",
"pad.toolbar.undo.title": "باطل ائتمک",
"pad.toolbar.redo.title": "یئنی دن",
"pad.toolbar.clearAuthorship.title": "یازیچی بوْیالارینی سیلمک (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "آیری قالیب لردن /ایچری توکمه / ائشیگه توکمه",
"pad.toolbar.timeslider.title": "زمان اسلایدی",
- "pad.toolbar.savedRevision.title": "نۆسخه‌نی قئید ائت",
+ "pad.toolbar.savedRevision.title": "نۆسخه‌نی ذخیره ائت",
"pad.toolbar.settings.title": "تنظیملر",
- "pad.toolbar.embed.title": "بو یادداشت دفترچه سین یئرلتمک",
+ "pad.toolbar.embed.title": "بو یادداشت دفترچه سین یئرلشدیر و پایلاش",
"pad.toolbar.showusers.title": "بو دفترچه یادداشت دا اولان کاربرلری گوستر",
- "pad.colorpicker.save": "قئید ائت",
+ "pad.colorpicker.save": "ذخیره ائت",
"pad.colorpicker.cancel": "وازگئچ",
"pad.loading": "یوکلنیر...",
+ "pad.noCookie": "کوکی تاپیلمادی. لوطفن براوزرینیزده کوکیلره ایجازه وئرین!",
+ "pad.passwordRequired": "بو نوت دفترچه سینه ال تاپماق اوچون بیر رمزه احتیاجینیز واردیر.",
+ "pad.permissionDenied": "بو نوت دفترچه سینه ال تاپماق اوچون ایجازه نیز یوخدور.",
+ "pad.wrongPassword": "سیزین رمزینیز دوز دئییل",
"pad.settings.padSettings": "یادداشت دفترچه سینین تنظیملر",
"pad.settings.myView": "منیم گورنتوم",
"pad.settings.stickychat": "نمایش صفحه سینده همیشه چت اولسون",
+ "pad.settings.chatandusers": "چت ایله ایشلدنلری گؤستر",
"pad.settings.colorcheck": "یازیچی رنگ لری",
"pad.settings.linenocheck": "خطوط شماره سی",
+ "pad.settings.rtlcheck": "ایچینده کیلری ساغدان یوخسا سولدان اوخوسون؟",
"pad.settings.fontType": "قلم نوعی",
"pad.settings.fontType.normal": "نورمال",
"pad.settings.fontType.monospaced": "مونو اسپئیس",
@@ -42,7 +48,9 @@
"pad.settings.language": "دیل:",
"pad.importExport.import_export": "ایچری توکمه /ائشیگه توکمه",
"pad.importExport.import": "سند یا دا متنی پرونده یوکله",
+ "pad.importExport.importSuccessful": "باشاریلی اولدو!",
"pad.importExport.export": "بو یادداشت دفترچه سی عنوانا ایچری توکمه",
+ "pad.importExport.exportetherpad": "اترپد",
"pad.importExport.exporthtml": "اچ تی ام ال",
"pad.importExport.exportplain": "ساده متن",
"pad.importExport.exportword": "مایکروسافت وورد",
@@ -51,6 +59,7 @@
"pad.modals.connected": "باغلاندی.",
"pad.modals.reconnecting": "یادداشت دفترچه‌نیزه یئنی‌دن باغلانمایا چالیشیلیر...",
"pad.modals.forcereconnect": "تکرار باغلانماق اوچون زوْرلاما",
+ "pad.modals.userdup": "آیری پنجره ده آچیلدی",
"pad.modals.userdup.advice": "بو پئنجره دن ایستفاده ائتمک اوچون یئنی دن متصیل اول",
"pad.modals.unauth": "اوْلماز",
"pad.modals.unauth.explanation": "سیزین ال چتما مسئله سی بو صفحه نین گورونوش زمانیندا دییشیلیب دیر .\nسعی ائدین یئنی دن متصیل اولاسینیز",
@@ -58,20 +67,25 @@
"pad.modals.looping.cause": "بلکه سیز دوز دئمیین بیر فایروال یادا پروکسی طریقی ایله متصیل اولوب سینیز",
"pad.modals.initsocketfail": "سرور الده دئییلدیر.",
"pad.modals.initsocketfail.explanation": "بیرلشدیریلمه سرور لرینه متصیل اولا بیلمه دی",
+ "pad.modals.slowcommit.explanation": "سرور جواب وئرمه ییر.",
"pad.modals.deleted": "سیلیندی.",
"pad.modals.deleted.explanation": "بۇ یادداشت دفترچه‌سی سیلینیبدیر.",
"pad.modals.disconnected": "سیزین باغلانتینیز کسیلیبدیر.",
"pad.modals.disconnected.explanation": "سروره باغلانتی کسیلیبدیر.",
+ "pad.share": "بو نوت دفترچه سینی پایلاش",
"pad.share.readonly": "ساده‌جه اوْخومالی",
"pad.share.link": "باغلانتی",
"pad.share.emebdcode": "یۇآرالی یئرلشدیرمک",
"pad.chat": "چت",
"pad.chat.title": "بو یادداشت دفترچه‌سینه چتی آچ.",
+ "pad.chat.loadmessages": "داها آرتیق پیام یوکله",
"timeslider.pageTitle": "{{appTitle}}زمان اسلایدری",
"timeslider.toolbar.returnbutton": "یادداشت دفترچه‌سینه قاییت.",
"timeslider.toolbar.authors": "یازیچیلار",
"timeslider.toolbar.authorsList": "یازیچی‌سیز",
"timeslider.toolbar.exportlink.title": "ائشیگه آپارماق",
+ "timeslider.exportCurrent": "موجود نوسخه نی بو عونوانلا ائشیگه چیخارت:",
+ "timeslider.version": "{{version}} ورژنی",
"timeslider.month.january": "ژانویه",
"timeslider.month.february": "فوریه",
"timeslider.month.march": "مارس",
@@ -84,8 +98,14 @@
"timeslider.month.october": "اوْکتوبر",
"timeslider.month.november": "نوْوامبر",
"timeslider.month.december": "دسامبر",
+ "pad.userlist.entername": "آدینیزی یازین",
"pad.userlist.unnamed": "آدسیز",
"pad.userlist.guest": "قوْناق",
"pad.userlist.deny": "دانماق",
- "pad.userlist.approve": "اوْنایلا"
+ "pad.userlist.approve": "اوْنایلا",
+ "pad.impexp.importbutton": "ایندی ایچری گتیر",
+ "pad.impexp.importing": "ایچری گتیریلیر...",
+ "pad.impexp.uploadFailed": "آپلود اولونمادی، یئنه چالیشین",
+ "pad.impexp.importfailed": "ایچری گتیرمه اولونمادی",
+ "pad.impexp.copypaste": "لوطفن کوپی ائدیب، یاپیشدیرین"
}
diff --git a/src/locales/de.json b/src/locales/de.json
index 29387fd5..f32b8cf6 100644
--- a/src/locales/de.json
+++ b/src/locales/de.json
@@ -6,11 +6,12 @@
"Nipsky",
"Wikinaut",
"Thargon",
- "Predatorix"
+ "Predatorix",
+ "Sebastian Wallroth"
]
},
"index.newPad": "Neues Pad",
- "index.createOpenPad": "oder Pad mit folgendem Namen öffnen:",
+ "index.createOpenPad": "oder ein Pad mit folgendem Namen erstellen/öffnen:",
"pad.toolbar.bold.title": "Fett (Strg-B)",
"pad.toolbar.italic.title": "Kursiv (Strg-I)",
"pad.toolbar.underline.title": "Unterstrichen (Strg-U)",
diff --git a/src/locales/diq.json b/src/locales/diq.json
index 2b37004d..e1546e94 100644
--- a/src/locales/diq.json
+++ b/src/locales/diq.json
@@ -3,10 +3,12 @@
"authors": [
"Erdemaslancan",
"Gorizon",
- "Mirzali"
+ "Mirzali",
+ "Kumkumuk"
]
},
"index.newPad": "Pedo newe",
+ "index.createOpenPad": "Yana eno bamaeya bloknot vıraz/ak:",
"pad.toolbar.bold.title": "Qalın (Ctrl-B)",
"pad.toolbar.italic.title": "Namıte (Ctrl-I)",
"pad.toolbar.underline.title": "Bınxetın (Ctrl-U)",
@@ -18,6 +20,7 @@
"pad.toolbar.undo.title": "Meke (Ctrl-Z)",
"pad.toolbar.redo.title": "Fına bıke (Ctrl-Y)",
"pad.toolbar.clearAuthorship.title": "Rengê Nuştoğiê Arıstey (Ctrl+Shift+C)",
+ "pad.toolbar.import_export.title": "Babaetna tewranê dosyaya azere/ateber ke",
"pad.toolbar.timeslider.title": "Ğızagê zemani",
"pad.toolbar.savedRevision.title": "Çımraviyarnayışi qeyd ke",
"pad.toolbar.settings.title": "Sazkerdışi",
@@ -26,9 +29,13 @@
"pad.colorpicker.save": "Qeyd ke",
"pad.colorpicker.cancel": "Bıtexelne",
"pad.loading": "Bar beno...",
+ "pad.noCookie": "Çerez nêvibeya. Rovıter de çereza aktiv kerê",
+ "pad.passwordRequired": "Ena bloknot resayışi rê parola icab krna",
+ "pad.permissionDenied": "Ena bloknot resayışi rê icazeta şıma çıni ya",
"pad.wrongPassword": "Parola şıma ğeleta",
"pad.settings.padSettings": "Sazkerdışê Pedi",
"pad.settings.myView": "Asayışê mı",
+ "pad.settings.stickychat": "Ekran de tım mıhebet bıkerê",
"pad.settings.chatandusers": "Werênayış û Karberan bımocne",
"pad.settings.colorcheck": "Rengê nuştekariye",
"pad.settings.linenocheck": "Nımreyê xeter",
@@ -41,20 +48,38 @@
"pad.importExport.import_export": "Zeredayış/Teberdayış",
"pad.importExport.import": "Dosya ya zi dokumanê meqaleyê de tesadufi bar ke",
"pad.importExport.importSuccessful": "Mıwafaq biye",
+ "pad.importExport.export": "Mewcud bloknoti ateberd:",
"pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Metno pan",
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)",
+ "pad.importExport.abiword.innerHTML": "Teyna duz metini yana html formati şıma şenê azete dê. Dehana vêşi xısusiyetanê azere kerdışi rê grey <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'i bar kerên</a>.",
"pad.modals.connected": "Gırediya.",
+ "pad.modals.reconnecting": "Bloknot da şıma rê fına irtibat kewê no",
"pad.modals.forcereconnect": "Mecbur anciya gırê de",
"pad.modals.userdup": "Zewbina pençere de bi a",
+ "pad.modals.userdup.explanation": "Ena bloknot ena komputer de yew ra zeder penceran dı akerde asena",
+ "pad.modals.userdup.advice": "Ena pencera ra kar finayışi rê fına irtibat kewê",
"pad.modals.unauth": "Selahiyetdar niyo",
+ "pad.modals.unauth.explanation": "Ena pela asenayış de mısadey şıma vuriyay. Fına irtibat kewtışi bıcerebne",
+ "pad.modals.looping.explanation": "Bahdê takêş kerdışi problemê irtibati esta",
+ "pad.modals.looping.cause": "Belki zi dêsê emeley hewl niyo yana şımayê proksi ya kenê dekewê de",
"pad.modals.initsocketfail": "Nêresneyêno ciyageyroği.",
+ "pad.modals.initsocketfail.explanation": "Rovıterê takêş kerdışi ya irtibato nêbeno.",
+ "pad.modals.initsocketfail.cause": "Ena probleme muhtemelen komputer yana grebıyayışa ibter da şıma ra bıya",
"pad.modals.slowcommit.explanation": "Server cewab nêdano.",
+ "pad.modals.slowcommit.cause": "Ena xeta gındık ta greyan de şıma ameya meydan",
+ "pad.modals.badChangeset.explanation": "Ena vurriyayışa şıma tereftê rovıterê tekêş kerdışi ra bêkaide deyne liste biya",
+ "pad.modals.badChangeset.cause": "Eno, xırab vıraziyena rovıteri yana nezanaye xırab yew faktori ra amrya meydan. Ena şıma çımdı xeta yena se idarekaran de sisteniya irtibat kewê. Dewam kerdışi re fına grebıyayışi bıcerebne",
+ "pad.modals.corruptPad.explanation": "Bloknota ke şımayê kenê cıresê xerpiyayi ya",
+ "pad.modals.corruptPad.cause": "Eno, xırab vıraziyena rovıteri yana nezanaye xırab yew faktori ra amrya meydan. Ena şıma çımdı xeta yena se idarekaran de sisteniya irtibat kewê",
"pad.modals.deleted": "Esteriya.",
"pad.modals.deleted.explanation": "Ena ped wedariye",
+ "pad.modals.disconnected": "İrtibata şıma reyê",
+ "pad.modals.disconnected.explanation": "Rovıteri ya irtibata şıma reyyê",
+ "pad.modals.disconnected.cause": "Qay rovıtero nêkarên o. Ena xerpey deqam kena se idarekaranê sistemiya irtibat kewê",
"pad.share": "Na ped vıla ke",
"pad.share.readonly": "Tenya bıwane",
"pad.share.link": "Gıre",
@@ -70,10 +95,13 @@
"timeslider.exportCurrent": "Versiyonê enewki teber de:",
"timeslider.version": "Versiyonê {{version}}",
"timeslider.saved": "{{day}} {{month}}, {{year}} de biyo qeyd",
+ "timeslider.playPause": "Zerrekê bloknoti kayfi/vındarn",
+ "timeslider.backRevision": "Peyser şo revizyona ena bloknoter",
+ "timeslider.forwardRevision": "Ena bloknot de şo revizyonê bini",
"timeslider.dateformat": "{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Çele",
"timeslider.month.february": "Zemherı",
- "timeslider.month.march": "Mert",
+ "timeslider.month.march": "Adar",
"timeslider.month.april": "Nisane",
"timeslider.month.may": "Gúlan",
"timeslider.month.june": "Heziran",
@@ -84,6 +112,8 @@
"timeslider.month.november": "Tışrino Peyên",
"timeslider.month.december": "Kanun",
"timeslider.unnamedauthors": "{{num}} unnamed {[plural(num) zu: nuştoğ, zewbi: nustoği ]}",
+ "pad.savedrevs.marked": "Eno vurriyayış henda qeyd bıyaye yew vurriyayış deyne nışan bıyo",
+ "pad.savedrevs.timeslider": "Xızberê zemani ziyer kerdış ra şıma şenê revizyonanê qeyd bıyayan bıvinê",
"pad.userlist.entername": "Nameyê xo cıkewe",
"pad.userlist.unnamed": "Name nébıyo",
"pad.userlist.guest": "Meyman",
@@ -92,7 +122,11 @@
"pad.editbar.clearcolors": "Wesiqa de renge nuştoğey bıesterneye?",
"pad.impexp.importbutton": "Nıka miyan ke",
"pad.impexp.importing": "Deyeno azere...",
+ "pad.impexp.confirmimport": "Yu dosya azere kerdış de mewcud bloknoti sero nuşiye no. Şıma qayılê dewam bıkerê?",
+ "pad.impexp.convertFailed": "Ena dosya azere kerdış mıkum niyo. Babetna namey dokumani weçinê yana xo desti kopya kerê u pronê.",
+ "pad.impexp.padHasData": "Ma nêşa dosya azere kem, çıkı ena bloknot xora vurriya ya. Xorê yewna bloknot azere kerê",
"pad.impexp.uploadFailed": "Barkerdış nêbi, kerem ke anciya bıcerebne",
"pad.impexp.importfailed": "Zer kerdış mıwafaq nebı",
- "pad.impexp.copypaste": "Reca keme kopya pronayış bıkeri"
+ "pad.impexp.copypaste": "Reca keme kopya pronayış bıkeri",
+ "pad.impexp.exportdisabled": "Formatta {{type}} ya ateber kerdış dewra vıciya yo. Qandé teferruati idarekarana irtibat kewê"
}
diff --git a/src/locales/dty.json b/src/locales/dty.json
index fde36512..c0d439e6 100644
--- a/src/locales/dty.json
+++ b/src/locales/dty.json
@@ -2,7 +2,8 @@
"@metadata": {
"authors": [
"रमेश सिंह बोहरा",
- "राम प्रसाद जोशी"
+ "राम प्रसाद जोशी",
+ "Nirajan pant"
]
},
"index.newPad": "नयाँ प्याड",
@@ -18,6 +19,7 @@
"pad.toolbar.undo.title": "खारेजी (Ctrl-Z)",
"pad.toolbar.redo.title": "दोसर्या:लागु (Ctrl-Y)",
"pad.toolbar.clearAuthorship.title": "लेखकीय रङ्ग हटाउन्या (Ctrl+Shift+C)",
+ "pad.toolbar.import_export.title": "विविध फाइल फर्म्याटअन बठेइ/मी आयात/निर्यात",
"pad.toolbar.timeslider.title": "टाइमस्लाइडर",
"pad.toolbar.savedRevision.title": "पुनरावलोकन संग्रहा गद्य्य",
"pad.toolbar.settings.title": "सेटिङ्गहरू",
@@ -26,6 +28,7 @@
"pad.colorpicker.save": "सङ्ग्रह गद्या",
"pad.colorpicker.cancel": "खारेजी",
"pad.loading": "लोड हुन्नाछ....",
+ "pad.noCookie": "कुकी पाउन नाइ सकियो। तमरा ब्राउजरमी कुकी राख्दाइ अनुमति दिय!",
"pad.passwordRequired": "यो प्यड खोल्लाकी पासवर्ड चाहिन्छ",
"pad.permissionDenied": "तमलाईँ यै प्याड खोल्लाकी अनुमति नाइथिन",
"pad.wrongPassword": "तमरो पासवर्ड गलत थ्यो",
@@ -49,16 +52,78 @@
"pad.importExport.exportword": "माइक्रोसफ्ट वर्ड",
"pad.importExport.exportpdf": "पिडिएफ",
"pad.importExport.exportopen": "ओडिएफ(खुल्ला कागजात ढाँचा)",
+ "pad.importExport.abiword.innerHTML": "तम सादा पाठ या HTML ढाँचा बठेइ मात्तरी आयात अरीसकन्छऽ। विस्तारित आयात विशेषता खिलाई कृपया <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>।",
"pad.modals.connected": "जोडीयाको",
"pad.modals.reconnecting": "तमरो प्याडमि आजि: जडान हुन्नाछ",
+ "pad.modals.forcereconnect": "बलात् पुन:जडान",
+ "pad.modals.userdup": "अर्खा विण्डोमी खुलिरैछ",
+ "pad.modals.userdup.explanation": "यो प्याड येइ कम्प्युटरमी एक़ है बर्ता ब्राउजर सञ्झ्यालमी खोल्याऽ धेकीँछ।",
+ "pad.modals.userdup.advice": "बरु यो विण्डो प्रयोग अद्दाइ दोसर्‍याँ जोणिय।",
+ "pad.modals.unauth": "अनुमति नदियीयाऽ",
+ "pad.modals.unauth.explanation": "येइ पन्ना हेरनज्याँ तमरा अधिकार बदेलिया। दोसर्‍याँ जोणिन्या प्रयास अरऽ।",
+ "pad.modals.looping.explanation": "सिक्रोनाइजेसन सर्भर सित सञ्चार समस्या धेकिन्नाछ़।",
+ "pad.modals.looping.cause": "शायद तम यक असंगत फायरवाल या प्रोक्सी का माध्यम बठेइ जोणीरैछऽ।",
"pad.modals.initsocketfail": "सर्भरमा पहुँच पुर्‍याउन नाइसकियो ।",
+ "pad.modals.initsocketfail.explanation": "सिङ्क्रोनाइजेसन सर्भर सित जोणीन नाइ सकियो?",
+ "pad.modals.initsocketfail.cause": "यो शायद तमरा ब्राउजर या इन्टरनेट जडान सित सम्बन्धित समस्याऽ कारणले होइ सकन्छ़।",
+ "pad.modals.slowcommit.explanation": "सर्भर प्रत्युत्तर दिन्नारेन।",
+ "pad.modals.slowcommit.cause": "यो नेटवर्क कनेक्टिविटी सङ्ङ सम्बन्धित समस्याऽ कारण ले होइसकन्छ।",
+ "pad.modals.badChangeset.explanation": "तमले अर्‍याऽ यक सम्पादन समक्रमण सर्भर हताँ अवैध वर्गीकृत अरियाऽ थ्यो।",
+ "pad.modals.badChangeset.cause": "यो यक गलत सर्भर विन्यास या केइ और अप्रत्याशित चालचलनाऽ कारण़ ले होइसकन्छ। यदि तमलाई यो गल्ती हो भण्ण्या लागन्छ भँण्या, कृपया सेवा व्यवस्थापकलाई सम्पर्क अरऽ। सम्पादन चालु राख्दाइ दोसर्‍याँ जोणिन्या प्रयास अरऽ।",
+ "pad.modals.corruptPad.explanation": "तमले उपयोग अद्द़ खोज्याऽ प्याड बिगण्योऽ छ।",
+ "pad.modals.corruptPad.cause": "यो गलत सर्भर विन्यास या केइ और नसोच्याऽ चालचलनले होइसकन्छ। कृपया सेवा व्यवस्थापकलाई सम्पर्क अरऽ।",
"pad.modals.deleted": "मेटियाको",
"pad.modals.deleted.explanation": "यो प्याड हटाइसक्याको छ ।",
"pad.modals.disconnected": "तमरो जडान अवरुद्ध भयो ।",
"pad.modals.disconnected.explanation": "तमरो सर्भरसितको जडान अवरुद्ध भयो",
+ "pad.modals.disconnected.cause": "सर्भर अनुपलब्ध होइसकन्छ। यदि यो हुनोइ रयाबर कृपया सेवा व्यवस्थापकलाई सूचित अरऽ।",
"pad.share": "यस प्यडलाई बाड्न्या",
"pad.share.readonly": "पड्या मात्तरै",
"pad.share.link": "लिङ्क",
"pad.share.emebdcode": "URL थप्प्या",
- "pad.chat": "कुरणिकानी"
+ "pad.chat": "कुरणिकानी",
+ "pad.chat.title": "येइ प्याड खिलाइ गफ खोलऽ",
+ "pad.chat.loadmessages": "जेदा सन्देश लोड अरऽ",
+ "timeslider.pageTitle": "{{appTitle}} समय स्लाइडर",
+ "timeslider.toolbar.returnbutton": "प्याडमी फर्कऽ",
+ "timeslider.toolbar.authors": "लेखकअन:",
+ "timeslider.toolbar.authorsList": "लेखकअन आथीनन",
+ "timeslider.toolbar.exportlink.title": "निर्यात",
+ "timeslider.exportCurrent": "हालआ शंसोधनलाई इस्याँ निर्यात अरऽ:",
+ "timeslider.version": "संस्करण {{version}}",
+ "timeslider.saved": "भँणार अरीयाऽ {{month}} {{day}}, {{year}}",
+ "timeslider.playPause": "प्याडआ सामाग्रीइनलाई प्लेब्याक/पउज अरऽ",
+ "timeslider.backRevision": "येइ प्याडमी यक शंसोधन पछा जाऽ",
+ "timeslider.forwardRevision": "येइ शंसोधनमी यक शंसोधन अघा जाऽ",
+ "timeslider.dateformat": "{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
+ "timeslider.month.january": "जनवरी",
+ "timeslider.month.february": "फेब्रुअरी",
+ "timeslider.month.march": "मार्च",
+ "timeslider.month.april": "अप्रिल",
+ "timeslider.month.may": "मे",
+ "timeslider.month.june": "जुन",
+ "timeslider.month.july": "जुलाई",
+ "timeslider.month.august": "अगस्ट",
+ "timeslider.month.september": "सेप्टेम्बर",
+ "timeslider.month.october": "अक्टोबर",
+ "timeslider.month.november": "नोभेम्बर",
+ "timeslider.month.december": "डिसेम्बर",
+ "timeslider.unnamedauthors": "{{num}} बिननाउँइको {[plural(num) one: author, other: authors ]}",
+ "pad.savedrevs.marked": "आब येइ संशोधनलाई सङ्ग्रहित संशोधनआ रूपमी चिनो लायियो",
+ "pad.savedrevs.timeslider": "समयस्लाइडर भेटिबर तम भँणार अरीयाऽ शंसोधनअनलाई हेरि सकन्छऽ",
+ "pad.userlist.entername": "तमरो नाउँ हाल",
+ "pad.userlist.unnamed": "बिननाउँइको",
+ "pad.userlist.guest": "पाउनो",
+ "pad.userlist.deny": "अस्वीकार",
+ "pad.userlist.approve": "अनुमोदन",
+ "pad.editbar.clearcolors": "सङताइ कागताजमी है लेखक रङ्ङअन साप अद्द्या?",
+ "pad.impexp.importbutton": "ऐलै आयार अरऽ",
+ "pad.impexp.importing": "आयात अद्दाछ़...",
+ "pad.impexp.confirmimport": "फाइल आयात़ ले प्याडओ अइलओ पाठ बदेलिन्या हो। तम ऐतिऱ बड्ड चाहन्छ भणिबर पक्का छऽ?",
+ "pad.impexp.convertFailed": "एइ फाइललाई आयात अद्द नाइसक्यो। कृपया जुदोइ कागजात फर्याट प्रयोग अरऽ या नकल पेस्ट अरऽ",
+ "pad.impexp.padHasData": "हम एइ फाइलाई आयात अद्दाइ असमर्थ छौँ क्याइकि एइ प्याडमी पैली अरीयाऽ फेलबदेल छन्, कृपया नयाँ प्याडमी आयात अरऽ",
+ "pad.impexp.uploadFailed": "अपलोड असफल, कृपया दोसर्‍याँ प्रयास अर:",
+ "pad.impexp.importfailed": "आयात असफल",
+ "pad.impexp.copypaste": "कृपया नकल सार अर:",
+ "pad.impexp.exportdisabled": "{{type}} फर्म्याटमी निर्यात अक्षम अरीरैछ। विवरण खिलाइ कृपया तमरा संयन्त्र प्रशासकलाई सम्पर्क अर:।"
}
diff --git a/src/locales/eo.json b/src/locales/eo.json
index c4526728..786d3bbe 100644
--- a/src/locales/eo.json
+++ b/src/locales/eo.json
@@ -3,7 +3,8 @@
"authors": [
"Eliovir",
"Mschmitt",
- "Objectivesea"
+ "Objectivesea",
+ "Robin van der Vliet"
]
},
"index.newPad": "Nova Teksto",
@@ -120,7 +121,7 @@
"pad.userlist.approve": "Aprobi",
"pad.editbar.clearcolors": "Forigi kolorojn de aŭtoreco en la tuta dokumento?",
"pad.impexp.importbutton": "Enporti Nun",
- "pad.impexp.importing": "Enportanta...",
+ "pad.impexp.importing": "Enportante...",
"pad.impexp.confirmimport": "Enporti dosieron superskribos la nunan tekston en la redaktilo. Ĉu vi certe volas daŭrigi?",
"pad.impexp.convertFailed": "Ni ne kapablis enporti tiun dosieron. Bonvolu uzi alian dokumentformaton aŭ permane kopii kaj alglui.",
"pad.impexp.padHasData": "Ni ne kapablis enporti tiun dosieron ĉar la teksto jam estas ŝanĝita. Bonvolu enporti en novan tekston.",
diff --git a/src/locales/hsb.json b/src/locales/hsb.json
index d4d3ef76..798c596e 100644
--- a/src/locales/hsb.json
+++ b/src/locales/hsb.json
@@ -92,6 +92,9 @@
"timeslider.exportCurrent": "Aktualnu wersiju eksportować jako:",
"timeslider.version": "Wersija {{version}}",
"timeslider.saved": "Składowany {{day}}. {{month}} {{year}}",
+ "timeslider.playPause": "Wobdźěłanje wothrać/pawzować",
+ "timeslider.backRevision": "Wo jednu wersiju w tutym dokumenće wróćo hić",
+ "timeslider.forwardRevision": "Wo jednu wersiju w tutym dokumenće doprědka hić",
"timeslider.dateformat": "{{day}}. {{month}} {{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "januara",
"timeslider.month.february": "februara",
diff --git a/src/locales/hu.json b/src/locales/hu.json
index c4d06c27..f34c76ca 100644
--- a/src/locales/hu.json
+++ b/src/locales/hu.json
@@ -64,7 +64,7 @@
"pad.modals.userdup.explanation": "Úgy tűnik, ez a notesz több különböző böngészőablakban is meg van nyitva a számítógépeden.",
"pad.modals.userdup.advice": "Kapcsolódj újra, ha ezt az ablakot akarod használni.",
"pad.modals.unauth": "Nincs rá jogosultságod",
- "pad.modals.unauth.explanation": "A jogosultságaid megváltoztak, miközben ezt az oldalt nézted. Próbálj meg újrakapcsolódni.",
+ "pad.modals.unauth.explanation": "A jogosultságaid megváltoztak, miközben ezt az oldalt nézted. Próbálj meg újrakapcsolódni!",
"pad.modals.looping.explanation": "Nem sikerült a kommunikáció a szinkronizációs szerverrel.",
"pad.modals.looping.cause": "Talán egy túl szigorú tűzfalon vagy proxyn keresztül kapcsolódtál az internetre.",
"pad.modals.initsocketfail": "A szerver nem érhető el.",
@@ -96,6 +96,9 @@
"timeslider.exportCurrent": "Jelenlegi változat exportálása így:",
"timeslider.version": "{{version}} verzió",
"timeslider.saved": "{{year}}. {{month}} {{day}}-n elmentve",
+ "timeslider.playPause": "Notesz tartalom visszajátszása / leállítása",
+ "timeslider.backRevision": "Egy revízióval vissza a noteszben",
+ "timeslider.forwardRevision": "Egy revízióval előre a noteszben",
"timeslider.dateformat": "{{year}}/{{month}}/{{day}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "január",
"timeslider.month.february": "február",
@@ -109,8 +112,9 @@
"timeslider.month.october": "október",
"timeslider.month.november": "november",
"timeslider.month.december": "december",
- "timeslider.unnamedauthors": "{{num}} névtelen {[plural(num), one: szerző, other: szerző]}",
+ "timeslider.unnamedauthors": "{{num}} névtelen {[plural(num), one: szerző, other: szerzők]}",
"pad.savedrevs.marked": "Ez a revízió mostantól mentettként jelölve",
+ "pad.savedrevs.timeslider": "A mentett revíziókat az időcsúszkán tudod megnézni",
"pad.userlist.entername": "Add meg a nevedet",
"pad.userlist.unnamed": "névtelen",
"pad.userlist.guest": "Vendég",
@@ -121,7 +125,7 @@
"pad.impexp.importing": "Importálás…",
"pad.impexp.confirmimport": "Egy fájl importálása felülírja a jelenlegi szöveget a noteszben. Biztos hogy folytatod?",
"pad.impexp.convertFailed": "Nem tudtuk importálni ezt a fájlt. Kérjük, használj másik dokumentum formátumot, vagy kézzel másold és illeszd be a tartalmat",
- "pad.impexp.padHasData": "Nem tudjuk importálni ezt a fájlt, mert ez a Pad már megváltozott, kérjük, importálj egy új padra",
+ "pad.impexp.padHasData": "Nem tudjuk importálni ezt a fájlt, mert ez a notesz már megváltozott, kérjük, importálj egy új noteszba.",
"pad.impexp.uploadFailed": "A feltöltés sikertelen, próbáld meg újra",
"pad.impexp.importfailed": "Az importálás nem sikerült",
"pad.impexp.copypaste": "Kérjük másold be",
diff --git a/src/locales/hy.json b/src/locales/hy.json
new file mode 100644
index 00000000..672905c5
--- /dev/null
+++ b/src/locales/hy.json
@@ -0,0 +1,58 @@
+{
+ "@metadata": {
+ "authors": [
+ "Kareyac"
+ ]
+ },
+ "pad.toolbar.underline.title": "ընդգծելով (Ctrl-U)",
+ "pad.toolbar.undo.title": "Չեղարկել (Ctrl-Z)",
+ "pad.toolbar.redo.title": "Վերադարձնել (Ctrl-Y)",
+ "pad.toolbar.clearAuthorship.title": "Մաքրել փաստաթղթի գույներ (Ctrl+Shift+C)",
+ "pad.toolbar.savedRevision.title": "Պահպանել տարբերակը",
+ "pad.toolbar.settings.title": "Կարգավորումներ",
+ "pad.toolbar.embed.title": "Կիսվել և ներդնել այդ փաստաթուղթը",
+ "pad.toolbar.showusers.title": "Ցույց տալ մասնակիցներին այս փաստաթղթում",
+ "pad.colorpicker.save": "Պահպանել",
+ "pad.colorpicker.cancel": "Չեղարկել",
+ "pad.loading": "Բեռնվում է…",
+ "pad.wrongPassword": "Սխալ գաղտնաբառ",
+ "pad.settings.myView": "Իմ տեսարան",
+ "pad.settings.rtlcheck": "Կարդալ բովանդակությունը աջից ձախ",
+ "pad.settings.fontType": "Տառատեսակի տեսակը",
+ "pad.settings.globalView": "Ընդհանուր տեսքը",
+ "pad.settings.language": "Լեզու",
+ "pad.importExport.import_export": "Ներմուծում/արտահանում",
+ "pad.importExport.import": "Բեռնել ցանկացած տեքստային ֆայլը կամ փաստաթուղթ",
+ "pad.importExport.importSuccessful": "Հաջողություն",
+ "pad.importExport.export": "Արտահանել ընթացիկ փաստաթուղթ է որպես",
+ "pad.importExport.exportplain": "Պարզ տեքստ",
+ "pad.importExport.exportpdf": "PDF",
+ "pad.modals.connected": "Կապված է",
+ "pad.modals.forcereconnect": "Հարկադիր վերամիավորել",
+ "pad.modals.userdup": "Բաց է մյուս պատուհանում",
+ "pad.modals.initsocketfail": "Սերվերը անհասանելի է ։",
+ "pad.modals.slowcommit.explanation": "Սերվերը չի պատասխանում։",
+ "pad.modals.deleted": "Ջնջված է",
+ "pad.share.readonly": "Միայն կարդալու",
+ "pad.share.link": "Հղում",
+ "timeslider.toolbar.authors": "Հեղինակներ",
+ "timeslider.month.january": "Հունվար",
+ "timeslider.month.february": "Փետրվար",
+ "timeslider.month.march": "Մարտ",
+ "timeslider.month.april": "Ապրիլ",
+ "timeslider.month.may": "Մայիս",
+ "timeslider.month.june": "Հունիս",
+ "timeslider.month.july": "Հուլիս",
+ "timeslider.month.august": "Օգոստոս",
+ "timeslider.month.september": "Սեպտեմբեր",
+ "timeslider.month.october": "Հոկտեմբեր",
+ "timeslider.month.november": "Նոյեմբեր",
+ "timeslider.month.december": "Դեկտեմբեր",
+ "pad.userlist.entername": "Մուտքագրեք ձեր անունը",
+ "pad.userlist.unnamed": "անանուն",
+ "pad.userlist.guest": "Հյուր",
+ "pad.userlist.deny": "Մերժել",
+ "pad.userlist.approve": "Հաստատել",
+ "pad.impexp.importbutton": "Ներմուծել հիմա",
+ "pad.impexp.copypaste": "Խնդրում ենք պատճենել"
+}
diff --git a/src/locales/ko.json b/src/locales/ko.json
index 9d413061..d0ba7bdc 100644
--- a/src/locales/ko.json
+++ b/src/locales/ko.json
@@ -11,7 +11,7 @@
},
"index.newPad": "새 패드",
"index.createOpenPad": "또는 다음 이름으로 패드 만들기/열기:",
- "pad.toolbar.bold.title": "굵은꼴 (Ctrl+B)",
+ "pad.toolbar.bold.title": "굵게 (Ctrl+B)",
"pad.toolbar.italic.title": "기울임꼴 (Ctrl+I)",
"pad.toolbar.underline.title": "밑줄 (Ctrl+U)",
"pad.toolbar.strikethrough.title": "취소선 (Ctrl+5)",
@@ -38,7 +38,7 @@
"pad.settings.padSettings": "패드 설정",
"pad.settings.myView": "내 보기",
"pad.settings.stickychat": "화면에 항상 대화 보기",
- "pad.settings.chatandusers": "채트와 사용자 보이기",
+ "pad.settings.chatandusers": "채트와 사용자 보기",
"pad.settings.colorcheck": "저자 색",
"pad.settings.linenocheck": "줄 번호",
"pad.settings.rtlcheck": "우횡서(오른쪽에서 왼쪽으로)입니까?",
diff --git a/src/locales/ku-latn.json b/src/locales/ku-latn.json
index 2aa4fda7..725a84d7 100644
--- a/src/locales/ku-latn.json
+++ b/src/locales/ku-latn.json
@@ -22,7 +22,7 @@
"pad.toolbar.savedRevision.title": "Sererastkirinê tomar bike",
"pad.toolbar.settings.title": "Eyar",
"pad.colorpicker.save": "Tomar bike",
- "pad.colorpicker.cancel": "Beta bike",
+ "pad.colorpicker.cancel": "Betal bike",
"pad.loading": "Tê barkirin...",
"pad.settings.padSettings": "Eyarên bloknotê",
"pad.settings.myView": "Dîmena min",
diff --git a/src/locales/lb.json b/src/locales/lb.json
index 99bfe0b5..50cebaf2 100644
--- a/src/locales/lb.json
+++ b/src/locales/lb.json
@@ -8,10 +8,14 @@
},
"index.newPad": "Neie Pad",
"index.createOpenPad": "oder maacht ee Pad mat dësem Numm op:",
+ "pad.toolbar.bold.title": "Fett (Strg-B)",
+ "pad.toolbar.italic.title": "Schréi (Ctrl+I)",
"pad.toolbar.underline.title": "Ënnerstrach (Ctrl+U)",
"pad.toolbar.strikethrough.title": "Duerchgestrach (Ctrl+5)",
"pad.toolbar.ol.title": "Numeréiert Lëscht (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Net-numeréiert Lëscht (Ctrl+Shift+L)",
+ "pad.toolbar.indent.title": "Aréckelen (TAB)",
+ "pad.toolbar.unindent.title": "Erausréckelen (Shift+TAB)",
"pad.toolbar.undo.title": "Réckgängeg (Ctrl-Z)",
"pad.toolbar.redo.title": "Widderhuelen (Ctrl-Y)",
"pad.toolbar.savedRevision.title": "Versioun späicheren",
@@ -25,23 +29,38 @@
"pad.permissionDenied": "Dir hutt net déi néideg Rechter fir dëse Pad opzemaachen",
"pad.wrongPassword": "Äert Passwuert ass falsch",
"pad.settings.myView": "Méng Usiicht",
+ "pad.settings.linenocheck": "Zeilennummeren",
+ "pad.settings.rtlcheck": "Inhalt vu riets no lénks liesen?",
+ "pad.settings.fontType": "Schrëftart:",
"pad.settings.fontType.normal": "Normal",
+ "pad.settings.globalView": "Global Vue",
"pad.settings.language": "Sprooch:",
"pad.importExport.import_export": "Import/Export",
+ "pad.importExport.import": "Text-Fichier oder Dokument eroplueden",
"pad.importExport.importSuccessful": "Erfollegräich",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
+ "pad.importExport.exportplain": "Kloertext",
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.modals.connected": "Verbonnen.",
+ "pad.modals.userdup": "An enger anerer Fënster opgemaach",
"pad.modals.unauth": "Net autoriséiert",
+ "pad.modals.unauth.explanation": "Är Rechter hu geännert während deem Dir dës säit gekuckt hutt. Probéiert fir Iech nei ze connectéieren.",
+ "pad.modals.looping.explanation": "Et gëtt Kommunikatiounsproblemer mam Synchronisatiouns-Server.",
+ "pad.modals.initsocketfail": "De Server kann net erreecht ginn.",
"pad.modals.slowcommit.explanation": "De Server äntwert net.",
"pad.modals.deleted": "Geläscht.",
+ "pad.modals.disconnected": "Äre Verbindung ass ofgebrach.",
+ "pad.modals.disconnected.explanation": "D'Verbindung mam Server ass verluergaang.",
"pad.share.readonly": "Nëmme liesen",
"pad.share.link": "Link",
+ "pad.chat": "Chat",
"pad.chat.loadmessages": "Méi Message lueden",
"timeslider.toolbar.authors": "Auteuren:",
"timeslider.toolbar.authorsList": "Keng Auteuren",
+ "timeslider.toolbar.exportlink.title": "Exportéieren",
"timeslider.exportCurrent": "Exportéiert déi aktuell Versioun als:",
"timeslider.version": "Versioun {{version}}",
"timeslider.saved": "Gespäichert de(n) {{day}} {{month}} {{year}}",
@@ -58,9 +77,14 @@
"timeslider.month.october": "Oktober",
"timeslider.month.november": "November",
"timeslider.month.december": "Dezember",
+ "pad.savedrevs.marked": "Dës Versioun ass elo als gespäichert Versioun markéiert",
"pad.userlist.entername": "Gitt Ären Numm an",
+ "pad.userlist.unnamed": "anonym",
"pad.userlist.guest": "Gaascht",
+ "pad.userlist.deny": "Refuséieren",
"pad.userlist.approve": "Zoustëmmen",
"pad.impexp.importbutton": "Elo importéieren",
- "pad.impexp.importing": "Importéieren..."
+ "pad.impexp.importing": "Importéieren...",
+ "pad.impexp.uploadFailed": "D'Eroplueden huet net funktionéiert, probéiert w.e.g. nach eng Kéier",
+ "pad.impexp.importfailed": "Den Import huet net funktionéiert"
}
diff --git a/src/locales/lt.json b/src/locales/lt.json
index 524146de..f0f02d1e 100644
--- a/src/locales/lt.json
+++ b/src/locales/lt.json
@@ -3,9 +3,12 @@
"authors": [
"Eitvys200",
"Mantak111",
- "I-svetaines"
+ "I-svetaines",
+ "Zygimantus"
]
},
+ "index.newPad": "Naujas bloknotas",
+ "index.createOpenPad": "arba sukurkite/atidarykite Bloknotą su pavadinimu:",
"pad.toolbar.bold.title": "Paryškintasis (Ctrl-B)",
"pad.toolbar.italic.title": "Pasvirasis (Ctrl-I)",
"pad.toolbar.underline.title": "Pabraukimas (Ctrl-U)",
@@ -13,9 +16,10 @@
"pad.toolbar.ol.title": "Numeruotas sąrašas (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Nenumeruotas Sąrašas (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Įtrauka",
+ "pad.toolbar.unindent.title": "Atvirkštinė įtrauka (Shift+TAB)",
"pad.toolbar.undo.title": "Anuliuoti (Ctrl-Z)",
"pad.toolbar.redo.title": "Perdaryti (Ctrl-Y)",
- "pad.toolbar.clearAuthorship.title": "Tvarkyti autorystės spalvas",
+ "pad.toolbar.clearAuthorship.title": "Valyti Autorystės Spalvas (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Importuoti/Eksportuoti iš/į įvairius failų formatus",
"pad.toolbar.timeslider.title": "Laiko slankiklis",
"pad.toolbar.savedRevision.title": "Išsaugoti peržiūrą",
@@ -50,29 +54,49 @@
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Atvirasis dokumento formatas)",
+ "pad.importExport.abiword.innerHTML": "Galite importuoti tik iš paprasto teksto ar HTML formato. Dėl išplėstinių importavimo funkcijų prašome <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\">įdiegti abiword</a>.",
"pad.modals.connected": "Prisijungta.",
"pad.modals.reconnecting": "Iš naujo prisijungiama prie Jūsų bloknoto",
"pad.modals.forcereconnect": "Priversti prisijungti iš naujo",
"pad.modals.userdup": "Atidaryta kitame lange",
"pad.modals.userdup.explanation": "Šis bloknotas, atrodo yra atidarytas daugiau nei viename šio kompiuterio naršyklės lange.",
+ "pad.modals.userdup.advice": "Prisijunkite iš naujo, kad vietoj to naudotumėte šį langą.",
"pad.modals.unauth": "Neleidžiama",
"pad.modals.unauth.explanation": "Jūsų teiisės pasikeitė kol žiūrėjote šį puslapį. Bandykite prisijungti iš naujo.",
"pad.modals.looping.explanation": "Yra komunikacijos problemų su sinchronizacijos serveriu.",
+ "pad.modals.looping.cause": "Galbūt prisijungėte per nesuderinamą ugniasienę ar proxy.",
"pad.modals.initsocketfail": "Serveris yra nepasiekiamas.",
+ "pad.modals.initsocketfail.explanation": "Nepavyko prisijungti prie sinchronizacijos serverio.",
+ "pad.modals.initsocketfail.cause": "Tai tikriausiai nutiko dėl problemų su jūsų naršykle ar jūsų interneto ryšiu.",
"pad.modals.slowcommit.explanation": "Serveris neatsako.",
+ "pad.modals.slowcommit.cause": "Tai gali būti dėl problemų su tinklo ryšiu.",
+ "pad.modals.badChangeset.explanation": "Pakeitimas, kurį atlikote buvo klasifikuotas sinchorizacijos serverio kaip neteisėtas.",
+ "pad.modals.badChangeset.cause": "Tai galėjo nutikti dėl neteisingos serverio konfigūracijos ar kitos netikėtos elgsenos. Prašome susisiekti su paslaugos administratoriumi jei manote, kad tai klaida. Pabandykite prisijungti iš naujo, kad tęstumėte redagavimą.",
+ "pad.modals.corruptPad.explanation": "Bloknotas, kurį bandote pasiekti yra sugadintas.",
+ "pad.modals.corruptPad.cause": "Tai gali nutikti dėl neteisingos serverio konfigūracijos ar kitos netikėtos elgsenos. Prašome susisiekti su paslaugos administratoriumi.",
"pad.modals.deleted": "Ištrintas.",
+ "pad.modals.deleted.explanation": "Bloknotas buvo pašalintas.",
"pad.modals.disconnected": "Jūs atsijungėte.",
+ "pad.modals.disconnected.explanation": "Ryšys su serveriu nutrūko",
+ "pad.modals.disconnected.cause": "Gali būti, kad serveris yra nepasiekiamas. Prašome informuoti paslaugos administratorių jei tai tęsiasi.",
+ "pad.share": "Dalintis šiuo bloknotu",
"pad.share.readonly": "Tik skaityti",
"pad.share.link": "Nuoroda",
"pad.share.emebdcode": "Įterptasis URL",
"pad.chat": "Pokalbiai",
+ "pad.chat.title": "Atverti šio bloknoto pokalbį.",
"pad.chat.loadmessages": "Įkrauti daugiau pranešimų",
+ "timeslider.pageTitle": "{{appTitle}} Laiko slinkiklis",
+ "timeslider.toolbar.returnbutton": "Grįžti į bloknotą",
"timeslider.toolbar.authors": "Autoriai:",
"timeslider.toolbar.authorsList": "Nėra autorių",
"timeslider.toolbar.exportlink.title": "Eksportuoti",
"timeslider.exportCurrent": "Eksportuoti dabartinę versiją kaip:",
"timeslider.version": "Versija {{version}}",
"timeslider.saved": "Išsaugota {{year}},{{month}} {{day}}",
+ "timeslider.playPause": "Atkurti / Pristabdyti Bloknoto Turinį",
+ "timeslider.backRevision": "Grįžti viena Bloknoto peržiūra atgal",
+ "timeslider.forwardRevision": "Eiti viena Bloknoto peržiūra į priekį",
"timeslider.dateformat": "{{year}}-{{month}}-{{day}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Sausis",
"timeslider.month.february": "Vasaris",
@@ -86,15 +110,22 @@
"timeslider.month.october": "Spalis",
"timeslider.month.november": "Lapkritis",
"timeslider.month.december": "Gruodis",
- "timeslider.unnamedauthors": "{{num}} bevardžiai(-ių) autoriai(-ių)",
+ "timeslider.unnamedauthors": "{{num}} {[plural(num) one: bevardis autorius, other: bevardžiai autoriai ]}",
+ "pad.savedrevs.marked": "Peržiūrą dabar pažymėta kaip išsaugota peržiūra",
+ "pad.savedrevs.timeslider": "Galite peržiūrėti išsaugotas peržiūras apsilankydami laiko slinkiklyje",
"pad.userlist.entername": "Įveskite savo vardą",
"pad.userlist.unnamed": "bevardis",
"pad.userlist.guest": "Svečias",
"pad.userlist.deny": "Neigti",
"pad.userlist.approve": "Patvirtinti",
+ "pad.editbar.clearcolors": "Išvalyti autorystės spalvas visame dokumente?",
"pad.impexp.importbutton": "Importuoti dabar",
"pad.impexp.importing": "Importuojama...",
+ "pad.impexp.confirmimport": "Failo importavimas pakeis dabartinį bloknoto tekstą. Ar tikrai norite tęsti?",
+ "pad.impexp.convertFailed": "Mums nepavyko importuoti šio failo. Prašome naudoti kitokį dokumento formatą arba nukopijuoti ir įklijuoti rankiniu būdu",
+ "pad.impexp.padHasData": "Mums nepavyko importuoti šio failo, nes šis Bloknotas jau turėjo pakeitimų, prašome importuoti į naują bloknotą",
"pad.impexp.uploadFailed": "Įkėlimas nepavyko, bandykite dar kartą",
"pad.impexp.importfailed": "Importuoti nepavyko",
- "pad.impexp.copypaste": "Prašome nukopijuoti ir įklijuoti"
+ "pad.impexp.copypaste": "Prašome nukopijuoti ir įklijuoti",
+ "pad.impexp.exportdisabled": "Eksportavimas {{type}} formatu yra išjungtas. Prašome susisiekti su savo sistemos administratoriumi dėl informacijos."
}
diff --git a/src/locales/mn.json b/src/locales/mn.json
index 4b418bef..6242d591 100644
--- a/src/locales/mn.json
+++ b/src/locales/mn.json
@@ -2,7 +2,8 @@
"@metadata": {
"authors": [
"MongolWiki",
- "Wisdom"
+ "Wisdom",
+ "Munkhzaya.E"
]
},
"pad.toolbar.bold.title": "Болд тескт (Ctrl-B)",
@@ -11,13 +12,20 @@
"pad.toolbar.strikethrough.title": "Дундуураа зураастай",
"pad.toolbar.ol.title": "Эрэмбэлэгдсэн жагсаалт",
"pad.toolbar.ul.title": "Эрэмбэлээгүй жагсаалт",
+ "pad.toolbar.indent.title": "Догол мөр (TAB)",
+ "pad.toolbar.unindent.title": "Догол мөрийг буцаах (Shift+TAB)",
"pad.toolbar.undo.title": "Буцаах (Ctrl-Z)",
- "pad.toolbar.redo.title": "Undo -ын эсрэг (Ctrl-Y)",
+ "pad.toolbar.redo.title": "Давтах (Ctrl-Y)",
+ "pad.toolbar.clearAuthorship.title": "Зохиогчийн өнгийг буцаах (Ctrl+Shift+C)",
+ "pad.toolbar.timeslider.title": "Засварласан түүх",
+ "pad.toolbar.savedRevision.title": "Хувилбарыг хадгалах",
"pad.toolbar.settings.title": "Тохиргоо",
"pad.colorpicker.save": "Хадгалах",
"pad.colorpicker.cancel": "Цуцлах",
"pad.loading": "Уншиж байна...",
+ "pad.wrongPassword": "Таны оруулсан нууц үг буруу байна",
"pad.settings.padSettings": "Падын тохиргоо",
+ "pad.settings.myView": "Өөрийн харагдац",
"pad.settings.linenocheck": "Мөрийн дугаар",
"pad.settings.fontType": "Фонтын төрөл:",
"pad.settings.fontType.normal": "Ердийн",
@@ -26,7 +34,10 @@
"pad.importExport.import_export": "Импорт/Экспорт",
"pad.importExport.import": "Бичвэр, текст файл оруулах",
"pad.importExport.importSuccessful": "Амжилттай!",
+ "pad.importExport.exportetherpad": "Etherpad",
+ "pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Цулгаа бичвэр",
+ "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF файл",
"pad.importExport.exportopen": "ODF файл",
"pad.modals.connected": "Холбогдсон.",
diff --git a/src/locales/ne.json b/src/locales/ne.json
index 1179c93b..3e23659a 100644
--- a/src/locales/ne.json
+++ b/src/locales/ne.json
@@ -28,8 +28,8 @@
"pad.colorpicker.cancel": "रद्द",
"pad.loading": "लोड हुदैछ...",
"pad.passwordRequired": "यो प्यड खोल्न पासवर्ड चाहिन्छ",
- "pad.permissionDenied": "तपाईँलाई यस प्याड खोल्न अनुमति छैन",
- "pad.wrongPassword": "तपाईँको पासवर्ड गलत थियो",
+ "pad.permissionDenied": "तपाईंलाई यो प्याड खोल्न अनुमति छैन",
+ "pad.wrongPassword": "तपाईंको पासवर्ड गलत थियो",
"pad.settings.padSettings": "प्याड सेटिङ्गहरू",
"pad.settings.myView": "मेरो दृष्य",
"pad.settings.stickychat": "पर्दामा सधै च्याट गर्ने",
@@ -53,7 +53,7 @@
"pad.importExport.exportpdf": "पिडिएफ",
"pad.importExport.exportopen": "ओडिएफ(खुल्ला कागजात ढाँचा)",
"pad.modals.connected": "जोडीएको।",
- "pad.modals.reconnecting": "तपाईँको प्याडमा पुन: जडान गर्दै",
+ "pad.modals.reconnecting": "तपाईंको प्याडमा पुन: जडान गर्दै",
"pad.modals.forcereconnect": "जडानको लागि जोडगर्ने",
"pad.modals.userdup": "अर्को सन्झ्यालमा खोल्ने",
"pad.modals.unauth": "अनुमती नदिइएको",
@@ -61,8 +61,8 @@
"pad.modals.slowcommit.explanation": "सर्भरसँग सम्पर्क हुने सकेन ।",
"pad.modals.deleted": "मेटिएको ।",
"pad.modals.deleted.explanation": "यो प्याड हटाइसकेको छ ।",
- "pad.modals.disconnected": "तपाईँको जडान अवरुद्ध भयो ।",
- "pad.modals.disconnected.explanation": "तपाईँको सर्भरसँगको जडान अवरुद्ध भयो",
+ "pad.modals.disconnected": "तपाईंको जडान अवरुद्ध भयो ।",
+ "pad.modals.disconnected.explanation": "तपाईंको सर्भरसँगको जडान अवरुद्ध भयो",
"pad.share": "यस प्यडलाई बाड्ने",
"pad.share.readonly": "पढ्ने मात्र",
"pad.share.link": "लिङ्क",
@@ -96,7 +96,7 @@
"timeslider.month.december": "डिसेम्बर",
"timeslider.unnamedauthors": "{{num}} unnamed {[plural(num) one: author, other: authors ]}",
"pad.savedrevs.marked": "यस संस्करणलाई संग्रहितको रुपमा चिनो लगाइएको छैन",
- "pad.userlist.entername": "तपाईँको नाम लेख्नुहोस्",
+ "pad.userlist.entername": "तपाईंको नाम लेख्नुहोस्",
"pad.userlist.unnamed": "नाम नखुलाइएको",
"pad.userlist.guest": "पाहुना",
"pad.userlist.deny": "अस्वीकार गर्ने",
diff --git a/src/locales/pa.json b/src/locales/pa.json
index 531e4ac8..f1e8ffc9 100644
--- a/src/locales/pa.json
+++ b/src/locales/pa.json
@@ -3,7 +3,8 @@
"authors": [
"Aalam",
"Babanwalia",
- "ਪ੍ਰਚਾਰਕ"
+ "ਪ੍ਰਚਾਰਕ",
+ "Tow"
]
},
"index.newPad": "ਨਵਾਂ ਪੈਡ",
@@ -112,6 +113,7 @@
"timeslider.month.december": "ਦਸੰਬਰ",
"timeslider.unnamedauthors": "{{num}} ਬੇਨਾਮ {[plural(num) one: ਲੇਖਕ, other: ਲੇਖਕ ]}",
"pad.savedrevs.marked": "ਇਹ ਰੀਵਿਜ਼ਨ ਨੂੰ ਹੁਣ ਸੰਭਾਲੇ ਹੋਏ ਰੀਵਿਜ਼ਨ ਵਜੋਂ ਮੰਨਿਆ ਗਿਆ ਹੈ",
+ "pad.savedrevs.timeslider": "ਤੁਸੀੰ ਸਾੰਭੀਆੰ ਹੋਈਆੰ ਵਰਜਨਾੰ ਸਮਾੰਸਲਾਈਡਰ ਤੇ ਜਾ ਕੇ ਵੇਖ ਸਕਦੇ ਹੋ",
"pad.userlist.entername": "ਆਪਣਾ ਨਾਂ ਦਿਉ",
"pad.userlist.unnamed": "ਬੇਨਾਮ",
"pad.userlist.guest": "ਮਹਿਮਾਨ",
@@ -122,6 +124,7 @@
"pad.impexp.importing": "...ਇੰਪੋਰਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ",
"pad.impexp.confirmimport": "ਕੋਈ ਫ਼ਾਈਲ ਦਰਾਮਦ ਕਾਰਨ ਨਾਲ਼ ਪੈਡ ਦੀ ਮੌਜੂਦਾ ਲਿਖਤ ਉੱਤੇ ਲਿਖਿਆ ਜਾਵੇਗਾ। ਕੀ ਤੁਸੀਂ ਸੱਚੀਂ ਇਹ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?",
"pad.impexp.convertFailed": "ਅਸੀਂ ਇਸ ਫ਼ਾਈਲ ਦੀ ਦਰਾਮਦ ਨਹੀਂ ਕਰ ਸਕੇ। ਮਿਹਰਬਾਨੀ ਕਰਕੇ ਕੋਈ ਵੱਖਰੀ ਦਸਤਾਵੇਜ਼ੀ ਰੂਪ-ਰੇਖਾ ਵਰਤੋ ਜਾਂ ਹੱਥੀਂ ਨਕਲ-ਚੇਪੀ ਕਰੋ।",
+ "pad.impexp.padHasData": "ਅਸੀ ਇਸ ਫਾਈਲ ਨੂੰ ਆਯਾਤ ਨਹੀੰ ਕਰ ਸਕੇ ਕਿਉੰਕਿ ਇਸ ਪੈਡ ਉੱਤੇ ਪਹਿਲਾੰ ਹੀ ਤਬਦੀਲੀਆੰ ਕੀਤੀਆੰ ਜਾ ਚੁਕੀਆੰ ਹਨ, ਕਿਰਪਾ ਕਰਕੇ ਨਵੇੰ ਪੈਡ ਵਿਚ ਆਯਾਤ ਕਰੋ",
"pad.impexp.uploadFailed": "ਅੱਪਲੋਡ ਲਈ ਫੇਲ੍ਹ ਹੈ, ਫੇਰ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਜੀ।",
"pad.impexp.importfailed": "ਇੰਪੋਰਟ ਫੇਲ੍ਹ ਹੈ",
"pad.impexp.copypaste": "ਕਾਪੀ ਕਰੋ ਚੇਪੋ ਜੀ",
diff --git a/src/locales/qqq.json b/src/locales/qqq.json
index 39389924..0beec0cc 100644
--- a/src/locales/qqq.json
+++ b/src/locales/qqq.json
@@ -107,7 +107,7 @@
"pad.savedrevs.marked": "more like bookmarked, or tagged/starred",
"pad.userlist.entername": "Used as placeholder for the \"Name\" input box in the upper right corner of the screen.",
"pad.userlist.unnamed": "Displayed, if a user has not set a nick yet",
- "pad.userlist.guest": "Preceded by the link text which is labeled {{msg-etherpadlite|Pad.userlist.approve}}.",
+ "pad.userlist.guest": "Preceded by the link text which is labeled {{msg-etherpadlite|Pad.userlist.approve}}.\n{{Identical|Guest}}",
"pad.userlist.deny": "Used as link text.\n\nFollowed by the link which is labeled {{msg-etherpadlite|Pad.userlist.approve}}.",
"pad.userlist.approve": "Used as link text.\n\nPreceded by the link which is labeled {{msg-etherpadlite|Pad.userlist.deny}}.\n\nFollowed by the message {{msg-etherpadlite|Pad.userlist.guest}}.\n{{Identical|Approve}}",
"pad.editbar.clearcolors": "Used as confirmation message (JavaScript <code>confirm()</code> function).\n\nThis message means \"Are you sure you want to clear authorship colors on entire document?\".",
diff --git a/src/locales/sl.json b/src/locales/sl.json
index a51cb53d..5d2dd85e 100644
--- a/src/locales/sl.json
+++ b/src/locales/sl.json
@@ -6,7 +6,7 @@
"Skalcaa"
]
},
- "index.newPad": "Nova Ploščica",
+ "index.newPad": "Nov dokument",
"index.createOpenPad": "ali pa odpri dokument z imenom:",
"pad.toolbar.bold.title": "Krepko (Ctrl-B)",
"pad.toolbar.italic.title": "Ležeče (Ctrl-I)",
@@ -72,7 +72,7 @@
"pad.modals.slowcommit.cause": "Najverjetneje je prišlo do napake med vzpostavitvijo povezave.",
"pad.modals.badChangeset.explanation": "Urejanje, ki ste ga naredili, je sinhronizacijski strežnik označil kot nelegalno.",
"pad.modals.badChangeset.cause": "Razlog za to je morda napačna konfiguracija strežnika ali neko drugo nepričakovano vedenje. Prosimo, stopite v stik z upravljavcem storitve, če menite, da gre za napako. Poskusite se ponovno povezati, da nadaljujete z urejanjem.",
- "pad.modals.corruptPad.explanation": "Blok, do katerega želite dostopati, je poškodovan.",
+ "pad.modals.corruptPad.explanation": "Dokument, do katerega želite dostopati, je poškodovan.",
"pad.modals.corruptPad.cause": "Razlog za to je morda napačna konfiguracija strežnika ali neko drugo nepričakovano vedenje. Prosimo, stopite v stik z upravljavcem storitve.",
"pad.modals.deleted": "Izbrisano.",
"pad.modals.deleted.explanation": "Dokument je odstranjen.",
@@ -94,6 +94,9 @@
"timeslider.exportCurrent": "Izvozi trenutno različico kot:",
"timeslider.version": "Različica {{version}}",
"timeslider.saved": "Shranjeno {{day}}.{{month}}.{{year}}",
+ "timeslider.playPause": "Predvajaj/začasno ustavi vsebino dokumenta",
+ "timeslider.backRevision": "Pojdi eno redakcijo nazaj v tem dokumentu",
+ "timeslider.forwardRevision": "Pojdi redakcijo naprej v tem dokumentu",
"timeslider.dateformat": "{{day}}.{{month}}.{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Januar",
"timeslider.month.february": "Februar",
@@ -120,7 +123,7 @@
"pad.impexp.importing": "Poteka uvažanje ...",
"pad.impexp.confirmimport": "Uvoz datoteke prepiše obstoječe besedilo dokumenta. Ali ste prepričani, da želite nadaljevati?",
"pad.impexp.convertFailed": "Datoteke ni mogoče uvoziti. Uporabiti je treba enega izmed podprtih zapisov dokumentov ali pa vsebino prilepiti ročno.",
- "pad.impexp.padHasData": "Nismo mogli uvoziti datoteke, ker ta Ploščica že vsebuje spremembe. Prosimo, uvozite datoteko v novo ploščico",
+ "pad.impexp.padHasData": "Nismo mogli uvoziti datoteke, ker dokument že vsebuje spremembe. Prosimo, uvozite datoteko v nov dokument",
"pad.impexp.uploadFailed": "Nalaganje je spodletelo, poskusite znova.",
"pad.impexp.importfailed": "Uvoz je spodletel.",
"pad.impexp.copypaste": "Vsebino kopirajte in prilepite.",
diff --git a/src/locales/sq.json b/src/locales/sq.json
index 24494f79..d6d959ee 100644
--- a/src/locales/sq.json
+++ b/src/locales/sq.json
@@ -5,44 +5,44 @@
"Kosovastar"
]
},
- "index.newPad": "Bllok i ri",
- "index.createOpenPad": "ose krijoni/hapni një bllok me emrin:",
+ "index.newPad": "Bllok i Ri",
+ "index.createOpenPad": "ose krijoni/hapni një Bllok me emrin:",
"pad.toolbar.bold.title": "Të trasha (Ctrl-B)",
"pad.toolbar.italic.title": "Të pjerrëta (Ctrl-I)",
"pad.toolbar.underline.title": "Të nënvizuara (Ctrl-U)",
- "pad.toolbar.strikethrough.title": "Mbivijëzuar (Ctrl+5)",
+ "pad.toolbar.strikethrough.title": "Hequr vije (Ctrl+5)",
"pad.toolbar.ol.title": "Listë e renditur (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Listë e parenditur (Ctrl+Shift+L)",
- "pad.toolbar.indent.title": "E dhëmbëzuar (TAB)",
+ "pad.toolbar.indent.title": "Brendazi (TAB)",
"pad.toolbar.unindent.title": "Jashtazi (Shift+TAB)",
"pad.toolbar.undo.title": "Zhbëje (Ctrl-Z)",
"pad.toolbar.redo.title": "Ribëje (Ctrl-Y)",
- "pad.toolbar.clearAuthorship.title": "Hiqju Ngjyra Autorësish (Ctrl+Shift+C)",
+ "pad.toolbar.clearAuthorship.title": "Hiqu Ngjyra Autorësish (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Importoni/Eksportoni nga/në formate të tjera kartelash",
"pad.toolbar.timeslider.title": "Rrjedha kohore",
- "pad.toolbar.savedRevision.title": "Ruaje rishikimin",
+ "pad.toolbar.savedRevision.title": "Ruaje Rishikimin",
"pad.toolbar.settings.title": "Rregullime",
- "pad.toolbar.embed.title": "Ndajeni me të tjerët dhe trupëzojeni këtë bllok",
+ "pad.toolbar.embed.title": "Ndajeni me të tjerët dhe Trupëzojeni këtë bllok",
"pad.toolbar.showusers.title": "Shfaq përdoruesit në këtë bllok",
"pad.colorpicker.save": "Ruaje",
"pad.colorpicker.cancel": "Anuloje",
"pad.loading": "Po ngarkohet…",
"pad.noCookie": "S’u gjet dot cookie. Ju lutemi, lejoni cookie-t te shfletuesi juaj!",
"pad.passwordRequired": "Ju duhet një fjalëkalim që të mund të përdorni këtë bllok",
- "pad.permissionDenied": "Ju nuk keni leje t'i qaseni këtij blloku",
+ "pad.permissionDenied": "S’keni leje të hyni në këtë bllok",
"pad.wrongPassword": "Fjalëkalimi juaj qe gabim",
- "pad.settings.padSettings": "Rregullime blloku",
+ "pad.settings.padSettings": "Rregullime Blloku",
"pad.settings.myView": "Pamja ime",
"pad.settings.stickychat": "Fjalosje përherë në ekran",
- "pad.settings.chatandusers": "Shfaq fjalosje dhe përdorues",
+ "pad.settings.chatandusers": "Shfaq Fjalosje dhe Përdorues",
"pad.settings.colorcheck": "Ngjyra autorësish",
"pad.settings.linenocheck": "Numra rreshtash",
"pad.settings.rtlcheck": "Të lexohet lënda nga e djathta në të majtë?",
"pad.settings.fontType": "Lloj shkronjash:",
"pad.settings.fontType.normal": "Normale",
"pad.settings.fontType.monospaced": "Monospace",
- "pad.settings.globalView": "Pamje e përgjithshme",
- "pad.settings.language": "Gjuha:",
+ "pad.settings.globalView": "Pamje e Përgjithshme",
+ "pad.settings.language": "Gjuhë:",
"pad.importExport.import_export": "Import/Eksport",
"pad.importExport.import": "Ngarkoni cilëndo kartelë teksti ose dokument",
"pad.importExport.importSuccessful": "Me sukses!",
@@ -55,7 +55,7 @@
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Mund të importoni vetëm prej formati tekst i thjeshtë ose html. Për veçori më të thelluara importimi, ju lutemi, <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\">instaloni Abiword-in</a>.",
"pad.modals.connected": "I lidhur.",
- "pad.modals.reconnecting": "Po rilidheni te blloku juaj..",
+ "pad.modals.reconnecting": "Po rilidheni te blloku juaj…",
"pad.modals.forcereconnect": "Rilidhje e detyruar",
"pad.modals.userdup": "Hapur në një tjetër dritare",
"pad.modals.userdup.explanation": "Ky bllok duket se gjendet i hapur në më shumë se një dritare shfletuesi në këtë kompjuter.",
@@ -64,8 +64,8 @@
"pad.modals.unauth.explanation": "Lejet tuaja ndryshuan teksa shihnit këtë dritare. Provoni të rilidheni.",
"pad.modals.looping.explanation": "Ka probleme komunikimi me shërbyesin e njëkohësimit.",
"pad.modals.looping.cause": "Ndoshta jeni lidhur përmes një firewall-i ose ndërmjetësi të papërputhshëm.",
- "pad.modals.initsocketfail": "Shërbyesi (serveri) është i pakapshëm.",
- "pad.modals.initsocketfail.explanation": "Nuk u lidh dot te shërbyesi (serveri) i sinkronizimit.",
+ "pad.modals.initsocketfail": "Shërbyesi është i pakapshëm.",
+ "pad.modals.initsocketfail.explanation": "S’u lidh dot te shërbyesi i njëkohësimit.",
"pad.modals.initsocketfail.cause": "Ka gjasa që kjo vjen për shkak të një problemi me shfletuesin tuaj ose lidhjen tuaj në internet.",
"pad.modals.slowcommit.explanation": "Shërbyesi nuk po përgjigjet.",
"pad.modals.slowcommit.cause": "Kjo mund të vijë për shkak problemesh lidhjeje me rrjetin.",
@@ -88,15 +88,15 @@
"timeslider.pageTitle": "Rrjedhë kohore e {{appTitle}}",
"timeslider.toolbar.returnbutton": "Rikthehuni te blloku",
"timeslider.toolbar.authors": "Autorë:",
- "timeslider.toolbar.authorsList": "Nuk ka autorë",
- "timeslider.toolbar.exportlink.title": "Eksportoni",
+ "timeslider.toolbar.authorsList": "S’ka Autorë",
+ "timeslider.toolbar.exportlink.title": "Eksportoje",
"timeslider.exportCurrent": "Eksportojeni versionin e tanishëm si:",
"timeslider.version": "Versioni {{version}}",
- "timeslider.saved": "Ruajtur më {{month}} {{day}}, {{year}}",
- "timeslider.playPause": "Riluaj / Pusho përmbajtjet e bllokut",
- "timeslider.backRevision": "Kalo një rishikim mbrapsht te ky bllok",
- "timeslider.forwardRevision": "Kalo një rishikim përpara në këtë bllok",
- "timeslider.dateformat": "{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
+ "timeslider.saved": "Ruajtur më {{day}} {{month}}, {{year}}",
+ "timeslider.playPause": "Luaj / Pusho Lëndë Blloku",
+ "timeslider.backRevision": "Kalo një rishikim mbrapsht në këtë Bllok",
+ "timeslider.forwardRevision": "Kalo një rishikim përpara në këtë Bllok",
+ "timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Janar",
"timeslider.month.february": "Shkurt",
"timeslider.month.march": "Mars",
@@ -109,20 +109,20 @@
"timeslider.month.october": "Tetor",
"timeslider.month.november": "Nëntor",
"timeslider.month.december": "Dhjetor",
- "timeslider.unnamedauthors": "{{num}} i paemërt {[plural(num) një: autor, tjetër: autorë ]}",
+ "timeslider.unnamedauthors": "{{num}} i paemër {[plural(num) një: autor, tjetër:{{num}} autorë ]}",
"pad.savedrevs.marked": "Ky rishikim tani është shënuar si rishikim i ruajtur",
- "pad.savedrevs.timeslider": "Rishikimet e ruajtura mund t’i shihni duke vizituar rrjedhjen kohore",
+ "pad.savedrevs.timeslider": "Rishikimet e ruajtura mund t’i shihni duke vizituar rrjedhën kohore",
"pad.userlist.entername": "Jepni emrin tuaj",
"pad.userlist.unnamed": "pa emër",
"pad.userlist.guest": "Vizitor",
- "pad.userlist.deny": "Refuzo",
+ "pad.userlist.deny": "Hidhe poshtë",
"pad.userlist.approve": "Miratoje",
"pad.editbar.clearcolors": "Të hiqen ngjyra autorësish në krejt dokumentin?",
- "pad.impexp.importbutton": "Importoje tani",
+ "pad.impexp.importbutton": "Importoje Tani",
"pad.impexp.importing": "Po importohet…",
"pad.impexp.confirmimport": "Importimi i një kartele do të mbishkruajë tekstin e tanishëm të bllokut. Jeni i sigurt se doni të vazhdohet?",
"pad.impexp.convertFailed": "Nuk qemë në gjendje ta importonim këtë kartelë. Ju lutemi, përdorni një format tjetër dokumentesh ose kopjojeni dhe hidheni dorazi",
- "pad.impexp.padHasData": "Ne nuk ishim në gjendje për të importuar këtë skedë, sepse ky bllok tashmë ka pasur ndryshime, ju lutem importojeni tek një bllok i ri",
+ "pad.impexp.padHasData": "S’qemë në gjendje të importojmë këtë kartelë, ngaqë ky Bllok kish tashmë ndryshime, ju lutemi, importojeni tek një bllok i ri",
"pad.impexp.uploadFailed": "Ngarkimi dështoi, ju lutemi, riprovoni",
"pad.impexp.importfailed": "Importimi dështoi",
"pad.impexp.copypaste": "Ju lutemi, kopjojeni dhe ngjiteni",
diff --git a/src/locales/zh-hans.json b/src/locales/zh-hans.json
index 15f11591..b4ff306f 100644
--- a/src/locales/zh-hans.json
+++ b/src/locales/zh-hans.json
@@ -105,7 +105,7 @@
"timeslider.playPause": "回放 / 暂停Pad内容",
"timeslider.backRevision": "返回此Pad的一次修订",
"timeslider.forwardRevision": "前往此Pad的一次修订",
- "timeslider.dateformat": "{{year}}年{{month}}月{{day}}日 {{hours}}{{minutes}}{{seconds}}",
+ "timeslider.dateformat": "{{year}}年{{month}}月{{day}}日 {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "1月",
"timeslider.month.february": "2月",
"timeslider.month.march": "3月",
diff --git a/src/node/handler/ExportHandler.js b/src/node/handler/ExportHandler.js
index 8f91ced2..fe7ab3db 100644
--- a/src/node/handler/ExportHandler.js
+++ b/src/node/handler/ExportHandler.js
@@ -76,7 +76,7 @@ exports.doExport = function(req, res, padId, type)
}
else if(type == "txt")
{
- exporttxt.getPadTXTDocument(padId, req.params.rev, false, function(err, txt)
+ exporttxt.getPadTXTDocument(padId, req.params.rev, function(err, txt)
{
if(ERR(err)) return;
res.send(txt);
@@ -92,7 +92,7 @@ exports.doExport = function(req, res, padId, type)
//render the html document
function(callback)
{
- exporthtml.getPadHTMLDocument(padId, req.params.rev, false, function(err, _html)
+ exporthtml.getPadHTMLDocument(padId, req.params.rev, function(err, _html)
{
if(ERR(err, callback)) return;
html = _html;
diff --git a/src/node/hooks/express/adminsettings.js b/src/node/hooks/express/adminsettings.js
index 4986f093..73691837 100644
--- a/src/node/hooks/express/adminsettings.js
+++ b/src/node/hooks/express/adminsettings.js
@@ -30,7 +30,13 @@ exports.socketio = function (hook_name, args, cb) {
}
else
{
- socket.emit("settings", {results: data});
+ //if showSettingsInAdminPage is set to false, then return NOT_ALLOWED in the result
+ if(settings.showSettingsInAdminPage === false) {
+ socket.emit("settings", {results:'NOT_ALLOWED'});
+ }
+ else {
+ socket.emit("settings", {results: data});
+ }
}
});
});
diff --git a/src/node/hooks/express/padreadonly.js b/src/node/hooks/express/padreadonly.js
index 66be3339..bff8adf7 100644
--- a/src/node/hooks/express/padreadonly.js
+++ b/src/node/hooks/express/padreadonly.js
@@ -7,7 +7,7 @@ var exporthtml = require("../../utils/ExportHtml");
exports.expressCreateServer = function (hook_name, args, cb) {
//serve read only pad
args.app.get('/ro/:id', function(req, res)
- {
+ {
var html;
var padId;
@@ -40,7 +40,7 @@ exports.expressCreateServer = function (hook_name, args, cb) {
hasPadAccess(req, res, function()
{
//render the html document
- exporthtml.getPadHTMLDocument(padId, null, false, function(err, _html)
+ exporthtml.getPadHTMLDocument(padId, null, function(err, _html)
{
if(ERR(err, callback)) return;
html = _html;
diff --git a/src/node/hooks/express/specialpages.js b/src/node/hooks/express/specialpages.js
index e8d7795a..2840f82c 100644
--- a/src/node/hooks/express/specialpages.js
+++ b/src/node/hooks/express/specialpages.js
@@ -16,6 +16,13 @@ exports.expressCreateServer = function (hook_name, args, cb) {
res.send(eejs.require("ep_etherpad-lite/templates/index.html"));
});
+ //serve javascript.html
+ args.app.get('/javascript', function(req, res)
+ {
+ res.send(eejs.require("ep_etherpad-lite/templates/javascript.html"));
+ });
+
+
//serve robots.txt
args.app.get('/robots.txt', function(req, res)
{
diff --git a/src/node/hooks/i18n.js b/src/node/hooks/i18n.js
index d0be2d6f..1b5b354d 100644
--- a/src/node/hooks/i18n.js
+++ b/src/node/hooks/i18n.js
@@ -5,7 +5,7 @@ var languages = require('languages4translatewiki')
, npm = require('npm')
, plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins.js').plugins
, semver = require('semver')
- , existsSync = fs.statSync || fs.existsSync || path.existsSync
+ , existsSync = require('../utils/path_exists')
;
diff --git a/src/node/utils/ExportHtml.js b/src/node/utils/ExportHtml.js
index 836165b1..bd177ac4 100644
--- a/src/node/utils/ExportHtml.js
+++ b/src/node/utils/ExportHtml.js
@@ -22,6 +22,7 @@ var ERR = require("async-stacktrace");
var _ = require('underscore');
var Security = require('ep_etherpad-lite/static/js/security');
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
+var eejs = require('ep_etherpad-lite/node/eejs');
var _analyzeLine = require('./ExportHelper')._analyzeLine;
var _encodeWhitespace = require('./ExportHelper')._encodeWhitespace;
@@ -478,7 +479,7 @@ function getHTMLFromAtext(pad, atext, authorColors)
return pieces.join('');
}
-exports.getPadHTMLDocument = function (padId, revNum, noDocType, callback)
+exports.getPadHTMLDocument = function (padId, revNum, callback)
{
padManager.getPad(padId, function (err, pad)
{
@@ -490,112 +491,16 @@ exports.getPadHTMLDocument = function (padId, revNum, noDocType, callback)
stylesForExport.forEach(function(css){
stylesForExportCSS += css;
});
- // Core inclusion of head etc.
- var head =
- (noDocType ? '' : '<!doctype html>\n') +
- '<html lang="en">\n' + (noDocType ? '' : '<head>\n' +
- '<title>' + Security.escapeHTML(padId) + '</title>\n' +
- '<meta name="generator" content="Etherpad">\n' +
- '<meta name="author" content="Etherpad">\n' +
- '<meta name="changedby" content="Etherpad">\n' +
- '<meta charset="utf-8">\n' +
- '<style> * { font-family: arial, sans-serif;\n' +
- 'font-size: 13px;\n' +
- 'line-height: 17px; }' +
- 'ul.indent { list-style-type: none; }' +
-
- 'ol { list-style-type: none; padding-left:0;}' +
- 'body > ol { counter-reset: first second third fourth fifth sixth seventh eigth ninth tenth eleventh twelth thirteenth fourteenth fifteenth sixteenth; }' +
- 'ol > li:before {' +
- 'content: counter(first) ". " ;'+
- 'counter-increment: first;}' +
-
- 'ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) ". " ;'+
- 'counter-increment: second;}' +
-
- 'ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) ". ";'+
- 'counter-increment: third;}' +
-
- 'ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) ". ";'+
- 'counter-increment: fourth;}' +
-
- 'ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) ". ";'+
- 'counter-increment: fifth;}' +
-
- 'ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) ". ";'+
- 'counter-increment: sixth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) ". ";'+
- 'counter-increment: seventh;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) ". ";'+
- 'counter-increment: eigth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) ". ";'+
- 'counter-increment: ninth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) ". ";'+
- 'counter-increment: tenth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) ". ";'+
- 'counter-increment: eleventh;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) ". ";'+
- 'counter-increment: twelth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) ". ";'+
- 'counter-increment: thirteenth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) ". ";'+
- 'counter-increment: fourteenth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) "." counter(fifteenth) ". ";'+
- 'counter-increment: fifteenth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) "." counter(fifteenth) "." counter(sixthteenth) ". ";'+
- 'counter-increment: sixthteenth;}' +
-
- 'ol{ text-indent: 0px; }' +
- 'ol > ol{ text-indent: 10px; }' +
- 'ol > ol > ol{ text-indent: 20px; }' +
- 'ol > ol > ol > ol{ text-indent: 30px; }' +
- 'ol > ol > ol > ol > ol{ text-indent: 40px; }' +
- 'ol > ol > ol > ol > ol > ol{ text-indent: 50px; }' +
- 'ol > ol > ol > ol > ol > ol > ol{ text-indent: 60px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 70px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 80px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 90px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 100px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 110px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol { text-indent: 120px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 130px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 140px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 150px; }' +
-
- stylesForExportCSS +
- '</style>\n' + '</head>\n') +
- '<body>';
- var foot = '</body>\n</html>\n';
getPadHTML(pad, revNum, function (err, html)
{
if(ERR(err, callback)) return;
- callback(null, head + html + foot);
+ var exportedDoc = eejs.require("ep_etherpad-lite/templates/export_html.html", {
+ body: html,
+ padId: Security.escapeHTML(padId),
+ extraCSS: stylesForExportCSS
+ });
+ callback(null, exportedDoc);
});
});
});
diff --git a/src/node/utils/ExportTxt.js b/src/node/utils/ExportTxt.js
index a6bec4a5..e3ce0152 100644
--- a/src/node/utils/ExportTxt.js
+++ b/src/node/utils/ExportTxt.js
@@ -192,7 +192,7 @@ function getTXTFromAtext(pad, atext, authorColors)
tags2close.push(i);
}
}
-
+
for (var i = 0; i < propVals.length; i++)
{
if (propVals[i] === ENTER || propVals[i] === STAY)
@@ -208,10 +208,10 @@ function getTXTFromAtext(pad, atext, authorColors)
{
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
+ // 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), "");
@@ -221,7 +221,7 @@ function getTXTFromAtext(pad, atext, authorColors)
assem.append(s);
} // end iteration over spans in line
-
+
var tags2close = [];
for (var i = propVals.length - 1; i >= 0; i--)
{
@@ -231,7 +231,7 @@ function getTXTFromAtext(pad, atext, authorColors)
propVals[i] = false;
}
}
-
+
} // end processNextChars
processNextChars(text.length - idx);
return(assem.toString());
@@ -271,7 +271,7 @@ function getTXTFromAtext(pad, atext, authorColors)
}
exports.getTXTFromAtext = getTXTFromAtext;
-exports.getPadTXTDocument = function (padId, revNum, noDocType, callback)
+exports.getPadTXTDocument = function (padId, revNum, callback)
{
padManager.getPad(padId, function (err, pad)
{
diff --git a/src/node/utils/Settings.js b/src/node/utils/Settings.js
index b765670a..24bc25c3 100644
--- a/src/node/utils/Settings.js
+++ b/src/node/utils/Settings.js
@@ -209,6 +209,11 @@ exports.requireAuthentication = false;
exports.requireAuthorization = false;
exports.users = {};
+/*
+* Show settings in admin page, by default it is true
+*/
+exports.showSettingsInAdminPage = true;
+
//checks if abiword is avaiable
exports.abiwordAvailable = function()
{
diff --git a/src/node/utils/caching_middleware.js b/src/node/utils/caching_middleware.js
index 91b8143b..65fe5d2f 100644
--- a/src/node/utils/caching_middleware.js
+++ b/src/node/utils/caching_middleware.js
@@ -21,8 +21,7 @@ var path = require('path');
var zlib = require('zlib');
var settings = require('./Settings');
var semver = require('semver');
-
-var existsSync = fs.statSync || fs.existsSync || path.existsSync;
+var existsSync = require('./path_exists');
var CACHE_DIR = path.normalize(path.join(settings.root, 'var/'));
CACHE_DIR = existsSync(CACHE_DIR) ? CACHE_DIR : undefined;
diff --git a/src/node/utils/path_exists.js b/src/node/utils/path_exists.js
new file mode 100644
index 00000000..c2d43f6c
--- /dev/null
+++ b/src/node/utils/path_exists.js
@@ -0,0 +1,15 @@
+var fs = require('fs');
+
+var check = function(path) {
+ var existsSync = fs.statSync || fs.existsSync || path.existsSync;
+
+ var result;
+ try {
+ result = existsSync(path);
+ } catch (e) {
+ result = false;
+ }
+ return result;
+}
+
+module.exports = check;
diff --git a/src/package.json b/src/package.json
index bdbf35c2..e280406f 100644
--- a/src/package.json
+++ b/src/package.json
@@ -16,7 +16,7 @@
"request" : "2.55.0",
"etherpad-require-kernel" : "1.0.9",
"resolve" : "1.1.7",
- "socket.io" : "1.4.5",
+ "socket.io" : "1.6.0",
"ueberdb2" : "0.3.0",
"express" : "4.13.4",
"express-session" : "1.13.0",
@@ -28,7 +28,7 @@
"log4js" : "0.6.35",
"cheerio" : "0.20.0",
"async-stacktrace" : "0.0.2",
- "npm" : "2.7.6",
+ "npm" : "4.0.2",
"ejs" : "2.4.1",
"graceful-fs" : "4.1.3",
"slide" : "1.1.6",
diff --git a/src/static/css/admin.css b/src/static/css/admin.css
index 97104de9..e9ba6014 100644
--- a/src/static/css/admin.css
+++ b/src/static/css/admin.css
@@ -38,6 +38,12 @@ div.innerwrapper {
padding-left: 265px;
}
+div.innerwrapper-err {
+ padding: 15px;
+ padding-left: 265px;
+ display: none;
+}
+
#wrapper {
background: none repeat scroll 0px 0px #FFFFFF;
box-shadow: 0px 1px 10px rgba(0, 0, 0, 0.2);
diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js
index f2c45f6a..0970666e 100644
--- a/src/static/js/ace2_inner.js
+++ b/src/static/js/ace2_inner.js
@@ -369,6 +369,19 @@ function Ace2Inner(){
return thisAuthor;
}
+ var _nonScrollableEditEvents = {
+ "applyChangesToBase": 1
+ };
+
+ _.each(hooks.callAll('aceRegisterNonScrollableEditEvents'), function(eventType) {
+ _nonScrollableEditEvents[eventType] = 1;
+ });
+
+ function isScrollableEditEvent(eventType)
+ {
+ return !_nonScrollableEditEvents[eventType];
+ }
+
var currentCallStack = null;
function inCallStack(type, action)
@@ -506,7 +519,7 @@ function Ace2Inner(){
{
updateBrowserSelectionFromRep();
}
- if ((cs.docTextChanged || cs.userChangedSelection) && cs.type != "applyChangesToBase")
+ if ((cs.docTextChanged || cs.userChangedSelection) && isScrollableEditEvent(cs.type))
{
scrollSelectionIntoView();
}
@@ -1442,16 +1455,6 @@ function Ace2Inner(){
var selection = getSelection();
p.end();
- function topLevel(n)
- {
- if ((!n) || n == root) return null;
- while (n.parentNode != root)
- {
- n = n.parentNode;
- }
- return n;
- }
-
if (selection)
{
var node1 = topLevel(selection.startPoint.node);
@@ -1473,12 +1476,8 @@ function Ace2Inner(){
var nds = root.getElementsByTagName("style");
for (var i = 0; i < nds.length; i++)
{
- var n = nds[i];
- while (n.parentNode && n.parentNode != root)
- {
- n = n.parentNode;
- }
- if (n.parentNode == root)
+ var n = topLevel(nds[i]);
+ if (n && n.parentNode == root)
{
observeChangesAroundNode(n);
}
@@ -5021,6 +5020,23 @@ function Ace2Inner(){
if(e.target.a || e.target.localName === "a"){
e.preventDefault();
}
+
+ // Bug fix: when user drags some content and drop it far from its origin, we
+ // need to merge the changes into a single changeset. So mark origin with <style>,
+ // in order to make content be observed by incorporateUserChanges() (see
+ // observeSuspiciousNodes() for more info)
+ var selection = getSelection();
+ if (selection){
+ var firstLineSelected = topLevel(selection.startPoint.node);
+ var lastLineSelected = topLevel(selection.endPoint.node);
+
+ var lineBeforeSelection = firstLineSelected.previousSibling;
+ var lineAfterSelection = lastLineSelected.nextSibling;
+
+ var neighbor = lineBeforeSelection || lineAfterSelection;
+ neighbor.appendChild(document.createElement('style'));
+ }
+
// Call drop hook
hooks.callAll('aceDrop', {
editorInfo: editorInfo,
@@ -5038,6 +5054,16 @@ function Ace2Inner(){
}
}
+ function topLevel(n)
+ {
+ if ((!n) || n == root) return null;
+ while (n.parentNode != root)
+ {
+ n = n.parentNode;
+ }
+ return n;
+ }
+
function handleIEOuterClick(evt)
{
if ((evt.target.tagName || '').toLowerCase() != "html")
@@ -5433,7 +5459,16 @@ function Ace2Inner(){
// and the line-numbers don't line up unless we pay
// attention to where the divs are actually placed...
// (also: padding on TTs/SPANs in IE...)
- h = b.nextSibling.offsetTop - b.offsetTop;
+ if (b === doc.body.firstChild) {
+ // It's the first line. For line number alignment purposes, its
+ // height is taken to be the top offset of the next line. If we
+ // didn't do this special case, we would miss out on any top margin
+ // included on the first line. The default stylesheet doesn't add
+ // extra margins, but plugins might.
+ h = b.nextSibling.offsetTop;
+ } else {
+ h = b.nextSibling.offsetTop - b.offsetTop;
+ }
}
if (h)
{
diff --git a/src/static/js/admin/plugins.js b/src/static/js/admin/plugins.js
index 48d1ab70..3f88d9b1 100644
--- a/src/static/js/admin/plugins.js
+++ b/src/static/js/admin/plugins.js
@@ -228,7 +228,7 @@ $(document).ready(function () {
if(data.code === "EPEERINVALID"){
alert("This plugin requires that you update Etherpad so it can operate in it's true glory");
}
- alert('An error occured while installing '+data.plugin+' \n'+data.error)
+ alert('An error occurred while installing '+data.plugin+' \n'+data.error)
$('#installed-plugins .'+data.plugin).remove()
}
@@ -241,7 +241,7 @@ $(document).ready(function () {
})
socket.on('finished:uninstall', function(data) {
- if(data.error) alert('An error occured while uninstalling the '+data.plugin+' \n'+data.error)
+ if(data.error) alert('An error occurred while uninstalling the '+data.plugin+' \n'+data.error)
// remove plugin from installed list
$('#installed-plugins .'+data.plugin).remove()
diff --git a/src/static/js/admin/settings.js b/src/static/js/admin/settings.js
index 42b038d5..6c1f5e23 100644
--- a/src/static/js/admin/settings.js
+++ b/src/static/js/admin/settings.js
@@ -14,12 +14,20 @@ $(document).ready(function () {
socket.on('settings', function (settings) {
+ /* Check whether the settings.json is authorized to be viewed */
+ if(settings.results === 'NOT_ALLOWED') {
+ $('.innerwrapper').hide();
+ $('.innerwrapper-err').show();
+ $('.err-message').html("Settings json is not authorized to be viewed in Admin page!!");
+ return;
+ }
+
/* Check to make sure the JSON is clean before proceeding */
if(isJSONClean(settings.results))
{
$('.settings').append(settings.results);
$('.settings').focus();
- $('.settings').autosize();
+ $('.settings').autosize();
}
else{
alert("YOUR JSON IS BAD AND YOU SHOULD FEEL BAD");
diff --git a/src/static/js/linestylefilter.js b/src/static/js/linestylefilter.js
index 93680515..3cf7a510 100644
--- a/src/static/js/linestylefilter.js
+++ b/src/static/js/linestylefilter.js
@@ -265,7 +265,7 @@ linestylefilter.getRegexpFilter = function(regExp, tag)
linestylefilter.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]/;
-linestylefilter.REGEX_URLCHAR = new RegExp('(' + /[-:@a-zA-Z0-9_.,~%+\/\\?=&#!;()\[\]$]/.source + '|' + linestylefilter.REGEX_WORDCHAR.source + ')');
+linestylefilter.REGEX_URLCHAR = new RegExp('(' + /[-:@a-zA-Z0-9_.,~%+\/\\?=&#!;()$]/.source + '|' + linestylefilter.REGEX_WORDCHAR.source + ')');
linestylefilter.REGEX_URL = new RegExp(/(?:(?:https?|s?ftp|ftps|file|nfs):\/\/|(about|geo|mailto|tel):|www\.)/.source + linestylefilter.REGEX_URLCHAR.source + '*(?![:.,;])' + linestylefilter.REGEX_URLCHAR.source, 'g');
linestylefilter.getURLFilter = linestylefilter.getRegexpFilter(
linestylefilter.REGEX_URL, 'url');
diff --git a/src/static/js/pad.js b/src/static/js/pad.js
index 597d084d..f6642654 100644
--- a/src/static/js/pad.js
+++ b/src/static/js/pad.js
@@ -194,40 +194,27 @@ function handshake()
// Allow deployers to host Etherpad on a non-root path
'path': exports.baseURL + "socket.io",
'resource': resource,
- 'max reconnection attempts': 3,
- 'sync disconnect on unload' : false
+ 'reconnectionAttempts': 5,
+ 'reconnection' : true,
+ 'reconnectionDelay' : 1000,
+ 'reconnectionDelayMax' : 5000
});
- var disconnectTimeout;
-
socket.once('connect', function () {
sendClientReady(false);
});
socket.on('reconnect', function () {
- //reconnect is before the timeout, lets stop the timeout
- if(disconnectTimeout)
- {
- clearTimeout(disconnectTimeout);
- }
-
pad.collabClient.setChannelState("CONNECTED");
pad.sendClientReady(true);
});
- socket.on('disconnect', function (reason) {
- if(reason == "booted"){
- pad.collabClient.setChannelState("DISCONNECTED");
- } else {
- function disconnectEvent()
- {
- pad.collabClient.setChannelState("DISCONNECTED", "reconnect_timeout");
- }
-
- pad.collabClient.setChannelState("RECONNECTING");
-
- disconnectTimeout = setTimeout(disconnectEvent, 20000);
- }
+ socket.on('reconnecting', function() {
+ pad.collabClient.setChannelState("RECONNECTING");
+ });
+
+ socket.on('reconnect_failed', function(error) {
+ pad.collabClient.setChannelState("DISCONNECTED", "reconnect_timeout");
});
var initalized = false;
@@ -731,6 +718,7 @@ var pad = {
var wasConnecting = (padconnectionstatus.getStatus().what == 'connecting');
if (newState == "CONNECTED")
{
+ padeditor.enable();
padconnectionstatus.connected();
}
else if (newState == "RECONNECTING")
diff --git a/src/static/js/pad_editbar.js b/src/static/js/pad_editbar.js
index d44e5d66..dd1c377a 100644
--- a/src/static/js/pad_editbar.js
+++ b/src/static/js/pad_editbar.js
@@ -242,9 +242,9 @@ var padeditbar = (function()
});
},
registerAceCommand: function (cmd, callback) {
- this.registerCommand(cmd, function (cmd, ace) {
+ this.registerCommand(cmd, function (cmd, ace, item) {
ace.callWithAce(function (ace) {
- callback(cmd, ace);
+ callback(cmd, ace, item);
}, cmd, true);
});
},
diff --git a/src/static/js/pad_editor.js b/src/static/js/pad_editor.js
index 6616ebe8..3e6b49d3 100644
--- a/src/static/js/pad_editor.js
+++ b/src/static/js/pad_editor.js
@@ -198,6 +198,13 @@ var padeditor = (function()
self.ace = null;
}
},
+ enable: function()
+ {
+ if (self.ace)
+ {
+ self.ace.setEditable(true);
+ }
+ },
disable: function()
{
if (self.ace)
diff --git a/src/static/js/pad_utils.js b/src/static/js/pad_utils.js
index eafa14bb..b83f21cf 100644
--- a/src/static/js/pad_utils.js
+++ b/src/static/js/pad_utils.js
@@ -523,7 +523,7 @@ function setupGlobalExceptionHandler() {
//show javascript errors to the user
$("#editorloadingbox").css("padding", "10px");
$("#editorloadingbox").css("padding-top", "45px");
- $("#editorloadingbox").html("<div style='text-align:left;color:red;font-size:16px;'><b>An error occured</b><br>The error was reported with the following id: '" + errorId + "'<br><br><span style='color:black;font-weight:bold;font-size:16px'>Please press and hold Ctrl and press F5 to reload this page, if the problem persists please send this error message to your webmaster: </span><div style='color:black;font-size:14px'>'"
+ $("#editorloadingbox").html("<div style='text-align:left;color:red;font-size:16px;'><b>An error occurred</b><br>The error was reported with the following id: '" + errorId + "'<br><br><span style='color:black;font-weight:bold;font-size:16px'>Please press and hold Ctrl and press F5 to reload this page, if the problem persists please send this error message to your webmaster: </span><div style='color:black;font-size:14px'>'"
+ "ErrorId: " + errorId + "<br>URL: " + window.location.href + "<br>UserAgent: " + userAgent + "<br>" + msg + " in " + url + " at line " + linenumber + "'</div></div>");
}
diff --git a/src/static/js/pluginfw/plugins.js b/src/static/js/pluginfw/plugins.js
index dfdf941e..0d0fa1ed 100644
--- a/src/static/js/pluginfw/plugins.js
+++ b/src/static/js/pluginfw/plugins.js
@@ -117,13 +117,14 @@ exports.getPackages = function (cb) {
delete packages[name].parent;
}
- if (deps[name].dependencies !== undefined) flatten(deps[name].dependencies);
+ // I don't think we need recursion
+ //if (deps[name].dependencies !== undefined) flatten(deps[name].dependencies);
});
}
var tmp = {};
tmp[data.name] = data;
- flatten(tmp);
+ flatten(tmp[undefined].dependencies);
cb(null, packages);
});
};
diff --git a/src/templates/admin/index.html b/src/templates/admin/index.html
index f6e9e29e..45755a49 100644
--- a/src/templates/admin/index.html
+++ b/src/templates/admin/index.html
@@ -20,5 +20,6 @@
</ul>
</div>
</div>
+ <div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
</body>
</html>
diff --git a/src/templates/admin/plugins-info.html b/src/templates/admin/plugins-info.html
index 5d39c388..8dd0bf88 100644
--- a/src/templates/admin/plugins-info.html
+++ b/src/templates/admin/plugins-info.html
@@ -41,5 +41,6 @@
</div>
</div>
+ <div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
</body>
</html>
diff --git a/src/templates/admin/plugins.html b/src/templates/admin/plugins.html
index 71c4dbcc..0fff7843 100644
--- a/src/templates/admin/plugins.html
+++ b/src/templates/admin/plugins.html
@@ -112,5 +112,6 @@
</div>
</div>
+ <div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
</body>
</html>
diff --git a/src/templates/admin/settings.html b/src/templates/admin/settings.html
index 3b8615fc..74f35521 100644
--- a/src/templates/admin/settings.html
+++ b/src/templates/admin/settings.html
@@ -44,6 +44,12 @@
<a href='https://github.com/ether/etherpad-lite/wiki/Example-Production-Settings.JSON'>Example production settings template</a>
<a href='https://github.com/ether/etherpad-lite/wiki/Example-Development-Settings.JSON'>Example development settings template</a>
</div>
+
+ <div class="innerwrapper-err" >
+ <h2 class="err-message"></h2>
+ </div>
+
</div>
+ <div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
</body>
</html>
diff --git a/src/templates/export_html.html b/src/templates/export_html.html
new file mode 100644
index 00000000..b29941c9
--- /dev/null
+++ b/src/templates/export_html.html
@@ -0,0 +1,144 @@
+<!doctype html>
+<html lang="en">
+<head>
+<title><%- padId %></title>
+<meta name="generator" content="Etherpad">
+<meta name="author" content="Etherpad">
+<meta name="changedby" content="Etherpad">
+<meta charset="utf-8">
+<style>
+* {
+ font-family: arial, sans-serif;
+ font-size: 13px;
+ line-height: 17px;
+}
+ul.indent {
+ list-style-type: none;
+}
+ol {
+ list-style-type: none;
+ padding-left: 0;
+}
+body > ol {
+ counter-reset: first second third fourth fifth sixth seventh eigth ninth tenth eleventh twelth thirteenth fourteenth fifteenth sixteenth;
+}
+ol > li:before {
+ content: counter(first) ". ";
+ counter-increment: first;
+}
+ol > ol > li:before {
+ content: counter(first) "." counter(second) ". ";
+ counter-increment: second;
+}
+ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) ". ";
+ counter-increment: third;
+}
+ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) ". ";
+ counter-increment: fourth;
+}
+ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) ". ";
+ counter-increment: fifth;
+}
+ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) ". ";
+ counter-increment: sixth;
+}
+ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) ". ";
+ counter-increment: seventh;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) ". ";
+ counter-increment: eigth;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) ". ";
+ counter-increment: ninth;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) ". ";
+ counter-increment: tenth;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) ". ";
+ counter-increment: eleventh;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) ". ";
+ counter-increment: twelth;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) ". ";
+ counter-increment: thirteenth;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) ". ";
+ counter-increment: fourteenth;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) "." counter(fifteenth) ". ";
+ counter-increment: fifteenth;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) "." counter(fifteenth) "." counter(sixthteenth) ". ";
+ counter-increment: sixthteenth;
+}
+ol {
+ text-indent: 0px;
+}
+ol > ol {
+ text-indent: 10px;
+}
+ol > ol > ol {
+ text-indent: 20px;
+}
+ol > ol > ol > ol {
+ text-indent: 30px;
+}
+ol > ol > ol > ol > ol {
+ text-indent: 40px;
+}
+ol > ol > ol > ol > ol > ol {
+ text-indent: 50px;
+}
+ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 60px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 70px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 80px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 90px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 100px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 110px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 120px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 130px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 140px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 150px;
+}
+<%- extraCSS %>
+</style>
+</head>
+<body>
+<%- body %>
+<div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
+</body>
+</html>
diff --git a/src/templates/index.html b/src/templates/index.html
index 0b0be79b..e1f59c1e 100644
--- a/src/templates/index.html
+++ b/src/templates/index.html
@@ -29,7 +29,8 @@
*/
</script>
- <meta charset="utf-8">
+ <meta charset="utf-8">
+ <meta name="referrer" content="no-referrer">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<link rel="shortcut icon" href="<%=settings.favicon%>">
@@ -121,7 +122,7 @@
input[type="text"] {
border-radius: 3px;
box-sizing: border-box;
- -moz-box-sizing: border-box;
+ -moz-box-sizing: border-box;
line-height:36px; /* IE8 hack */
padding: 0px 45px 0 10px;
*padding: 0; /* IE7 hack */
@@ -148,22 +149,22 @@
margin-top: 0;
}
#inner {
- width: 95%;
+ width: 95%;
}
#label {
text-align: center;
}
}
</style>
- <link href="static/custom/index.css" rel="stylesheet">
+ <link href="static/custom/index.css" rel="stylesheet">
<div id="wrapper">
<% e.begin_block("indexWrapper"); %>
<div id="inner">
<buttOn id="button" onclick="go2Random()" data-l10n-id="index.newPad"></button>
- <label id="label" for="padname" data-l10n-id="index.createOpenPad"></label>
- <form action="#" onsubmit="go2Name();return false;">
- <input type="text" id="padname" maxlength="50" autofocus x-webkit-speech>
+ <label id="label" for="padname" data-l10n-id="index.createOpenPad"></label>
+ <form action="#" onsubmit="go2Name();return false;">
+ <input type="text" id="padname" maxlength="50" autofocus x-webkit-speech>
<button type="submit">OK</button>
</form>
</div>
@@ -171,33 +172,35 @@
</div>
<script src="static/custom/index.js"></script>
- <script>
-
- function go2Name()
+ <script>
+ // @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7&dn=apache-2.0.txt
+ function go2Name()
{
var padname = document.getElementById("padname").value;
padname.length > 0 ? window.location = "p/" + padname : alert("Please enter a name")
}
-
- function go2Random()
+
+ function go2Random()
{
window.location = "p/" + randomPadName();
}
-
- function randomPadName()
+
+ function randomPadName()
{
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var string_length = 10;
var randomstring = '';
- for (var i = 0; i < string_length; i++)
+ for (var i = 0; i < string_length; i++)
{
var rnum = Math.floor(Math.random() * chars.length);
randomstring += chars.substring(rnum, rnum + 1);
}
return randomstring;
}
-
+
// start the custom js
if (typeof customStart == "function") customStart();
+ // @license-end
</script>
+ <div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
</html>
diff --git a/src/templates/javascript.html b/src/templates/javascript.html
new file mode 100644
index 00000000..29031c4b
--- /dev/null
+++ b/src/templates/javascript.html
@@ -0,0 +1,73 @@
+<!doctype html>
+<html>
+ <head>
+ <title>JavaScript license information</title>
+ <meta charset="utf-8">
+ <meta name="robots" content="noindex, nofollow">
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
+ </head>
+ <body>
+ <table id="jslicense-labels1">
+ <tr>
+ <td><a href="/static/js/jquery-2.1.1.min.js">jquery-2.1.1.min.js</a></td>
+ <td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
+ <td><a href="/static/js/jquery.js">jquery.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/html10n.js">html10n.js</a></td>
+ <td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
+ <td><a href="/static/js/html10n.js">html10n.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/l10n.js">l10n.js</a></td>
+ <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache-2.0-only</a></td>
+ <td><a href="/static/js/l10n.js">l10n.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/socket.io.js">socket.io.js</a></td>
+ <td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
+ <td><a href="/static/js/socket.io.js">socket.io.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/require-kernel.js">require-kernel.js</a></td>
+ <td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
+ <td><a href="/static/js/require-kernel.js">require-kernel.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/custom/index.js">index.js</a></td>
+ <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache-2.0-only</a></td>
+ <td><a href="/static/custom/index.js">index.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/custom/timeslider.js">timeslider.js</a></td>
+ <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache-2.0-only</a></td>
+ <td><a href="/static/custom/timeslider.js">timeslider.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/custom/pad.js">pad.js</a></td>
+ <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache-2.0-only</a></td>
+ <td><a href="/static/custom/pad.js">pad.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/admin/plugins.js">plugins.js</a></td>
+ <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache-2.0-only</a></td>
+ <td><a href="/static/js/admin/plugins.js">plugins.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/admin/minify.json.js">minify.json.js</a></td>
+ <td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
+ <td><a href="/static/js/admin/minify.json.js">minify.json.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/admin/settings.js">settings.js</a></td>
+ <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache-2.0-only</a></td>
+ <td><a href="/static/js/admin/settings.js">settings.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/admin/jquery.autosize.js">jquery.autosize.js</a></td>
+ <td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
+ <td><a href="/static/js/admin/jquery.autosize.js">jquery.autosize.js</a></td>
+ </tr>
+ </table>
+ </body>
+</html>
diff --git a/src/templates/pad.html b/src/templates/pad.html
index 767c1ec9..3d89f9d0 100644
--- a/src/templates/pad.html
+++ b/src/templates/pad.html
@@ -36,6 +36,7 @@
<meta charset="utf-8">
<meta name="robots" content="noindex, nofollow">
+ <meta name="referrer" content="no-referrer">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<link rel="shortcut icon" href="<%=settings.faviconPad%>">
@@ -350,19 +351,21 @@
<% e.begin_block("scripts"); %>
<script type="text/javascript">
+ // @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7&dn=apache-2.0.txt
(function() {
// Display errors on page load to the user
// (Gets overridden by padutils.setupGlobalExceptionHandler)
var originalHandler = window.onerror;
window.onerror = function(msg, url, line) {
var box = document.getElementById('editorloadingbox');
- box.innerHTML = '<p><b>An error occured while loading the pad</b></p>'
+ box.innerHTML = '<p><b>An error occurred while loading the pad</b></p>'
+ '<p><b>'+msg+'</b> '
+ '<small>in '+ url +' (line '+ line +')</small></p>';
// call original error handler
if(typeof(originalHandler) == 'function') originalHandler.call(null, arguments);
};
})();
+ // @license-end
</script>
<script type="text/javascript" src="../static/js/require-kernel.js"></script>
@@ -378,6 +381,7 @@
<!-- Bootstrap page -->
<script type="text/javascript">
+ // @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7&dn=apache-2.0.txt
var clientVars = {};
(function () {
var pathComponents = location.pathname.split('/');
@@ -415,6 +419,8 @@
padeditbar = require('ep_etherpad-lite/static/js/pad_editbar').padeditbar;
padimpexp = require('ep_etherpad-lite/static/js/pad_impexp').padimpexp;
}());
+ // @license-end
</script>
+ <div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
<% e.end_block(); %>
</html>
diff --git a/src/templates/timeslider.html b/src/templates/timeslider.html
index f52c0c50..395d0c47 100644
--- a/src/templates/timeslider.html
+++ b/src/templates/timeslider.html
@@ -31,6 +31,7 @@
<head>
<meta charset="utf-8">
<meta name="robots" content="noindex, nofollow">
+ <meta name="referrer" content="no-referrer">
<link rel="shortcut icon" href="<%=settings.faviconTimeslider%>">
<% e.begin_block("timesliderStyles"); %>
<link rel="stylesheet" href="../../static/css/pad.css">
@@ -230,6 +231,7 @@
<!-- Bootstrap -->
<script type="text/javascript" >
+ // @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7&dn=apache-2.0.txt
var clientVars = {};
var BroadcastSlider;
(function () {
@@ -266,8 +268,9 @@
padeditbar.init()
});
})();
+ // @license-end
</script>
<% e.end_block(); %>
+<div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
</body>
</html>
-
diff --git a/tests/frontend/helper.js b/tests/frontend/helper.js
index 7131119a..7a8d19b6 100644
--- a/tests/frontend/helper.js
+++ b/tests/frontend/helper.js
@@ -6,11 +6,11 @@ var helper = {};
helper.init = function(cb){
$iframeContainer = $("#iframe-container");
- $.get('/static/js/jquery.js').done(function(code){
+ $.get('/static/js/jquery.js').done(function(code){
// make sure we don't override existing jquery
jsLibraries["jquery"] = "if(typeof $ === 'undefined') {\n" + code + "\n}";
- $.get('/tests/frontend/lib/sendkeys.js').done(function(code){
+ $.get('/tests/frontend/lib/sendkeys.js').done(function(code){
jsLibraries["sendkeys"] = code;
cb();
@@ -32,7 +32,7 @@ var helper = {};
var getFrameJQuery = function($iframe){
/*
- I tried over 9000 ways to inject javascript into iframes.
+ I tried over 9000 ways to inject javascript into iframes.
This is the only way I found that worked in IE 7+8+9, FF and Chrome
*/
@@ -45,7 +45,7 @@ var helper = {};
win.eval(jsLibraries["jquery"]);
win.eval(jsLibraries["sendkeys"]);
-
+
win.$.window = win;
win.$.document = doc;
@@ -73,14 +73,14 @@ var helper = {};
if(!padName)
padName = "FRONTEND_TEST_" + helper.randomString(20);
$iframe = $("<iframe src='/p/" + padName + "'></iframe>");
-
+
//clean up inner iframe references
helper.padChrome$ = helper.padOuter$ = helper.padInner$ = null;
//clean up iframes properly to prevent IE from memoryleaking
$iframeContainer.find("iframe").purgeFrame().done(function(){
$iframeContainer.append($iframe);
- $iframe.one('load', function(){
+ $iframe.one('load', function(){
helper.waitFor(function(){
return !$iframe.contents().find("#editorloadingbox").is(":visible");
}, 50000).done(function(){
@@ -92,13 +92,13 @@ var helper = {};
helper.padChrome$.fx.off = true;
helper.padOuter$.fx.off = true;
helper.padInner$.fx.off = true;
-
+
opts.cb();
}).fail(function(){
throw new Error("Pad never loaded");
});
});
- });
+ });
return padName;
}
@@ -108,7 +108,7 @@ var helper = {};
var intervalTime = _intervalTime || 10;
var deferred = $.Deferred();
-
+
var _fail = deferred.fail;
var listenForFail = false;
deferred.fail = function(){
@@ -142,6 +142,65 @@ var helper = {};
return deferred;
}
+ helper.selectLines = function($startLine, $endLine, startOffset, endOffset){
+ // if no offset is provided, use beginning of start line and end of end line
+ startOffset = startOffset || 0;
+ endOffset = endOffset === undefined ? $endLine.text().length : endOffset;
+
+ var inner$ = helper.padInner$;
+ var selection = inner$.document.getSelection();
+ var range = selection.getRangeAt(0);
+
+ var start = getTextNodeAndOffsetOf($startLine, startOffset);
+ var end = getTextNodeAndOffsetOf($endLine, endOffset);
+
+ range.setStart(start.node, start.offset);
+ range.setEnd(end.node, end.offset);
+
+ selection.removeAllRanges();
+ selection.addRange(range);
+ }
+
+ var getTextNodeAndOffsetOf = function($targetLine, targetOffsetAtLine){
+ var $textNodes = $targetLine.find('*').contents().filter(function(){
+ return this.nodeType === Node.TEXT_NODE;
+ });
+
+ // search node where targetOffsetAtLine is reached, and its 'inner offset'
+ var textNodeWhereOffsetIs = null;
+ var offsetBeforeTextNode = 0;
+ var offsetInsideTextNode = 0;
+ $textNodes.each(function(index, element){
+ var elementTotalOffset = element.textContent.length;
+ textNodeWhereOffsetIs = element;
+ offsetInsideTextNode = targetOffsetAtLine - offsetBeforeTextNode;
+
+ var foundTextNode = offsetBeforeTextNode + elementTotalOffset >= targetOffsetAtLine;
+ if (foundTextNode){
+ return false; //stop .each by returning false
+ }
+
+ offsetBeforeTextNode += elementTotalOffset;
+ });
+
+ // edge cases
+ if (textNodeWhereOffsetIs === null){
+ // there was no text node inside $targetLine, so it is an empty line (<br>).
+ // Use beginning of line
+ textNodeWhereOffsetIs = $targetLine.get(0);
+ offsetInsideTextNode = 0;
+ }
+ // avoid errors if provided targetOffsetAtLine is higher than line offset (maxOffset).
+ // Use max allowed instead
+ var maxOffset = textNodeWhereOffsetIs.textContent.length;
+ offsetInsideTextNode = Math.min(offsetInsideTextNode, maxOffset);
+
+ return {
+ node: textNodeWhereOffsetIs,
+ offset: offsetInsideTextNode,
+ };
+ }
+
/* Ensure console.log doesn't blow up in IE, ugly but ok for a test framework imho*/
window.console = window.console || {};
window.console.log = window.console.log || function(){}
diff --git a/tests/frontend/specs/drag_and_drop.js b/tests/frontend/specs/drag_and_drop.js
new file mode 100644
index 00000000..bcec0bd2
--- /dev/null
+++ b/tests/frontend/specs/drag_and_drop.js
@@ -0,0 +1,160 @@
+// WARNING: drag and drop is only simulated on these tests, so manual testing might also be necessary
+describe('drag and drop', function() {
+ before(function(done) {
+ helper.newPad(function() {
+ createScriptWithSeveralLines(done);
+ });
+ this.timeout(60000);
+ });
+
+ context('when user drags part of one line and drops it far form its original place', function() {
+ before(function(done) {
+ selectPartOfSourceLine();
+ dragSelectedTextAndDropItIntoMiddleOfLine(TARGET_LINE);
+
+ // make sure DnD was correctly simulated
+ helper.waitFor(function() {
+ var $targetLine = getLine(TARGET_LINE);
+ var sourceWasMovedToTarget = $targetLine.text() === 'Target line [line 1]';
+ return sourceWasMovedToTarget;
+ }).done(done);
+ });
+
+ context('and user triggers UNDO', function() {
+ before(function() {
+ var $undoButton = helper.padChrome$(".buttonicon-undo");
+ $undoButton.click();
+ });
+
+ it('moves text back to its original place', function(done) {
+ // test text was removed from drop target
+ var $targetLine = getLine(TARGET_LINE);
+ expect($targetLine.text()).to.be('Target line []');
+
+ // test text was added back to original place
+ var $firstSourceLine = getLine(FIRST_SOURCE_LINE);
+ var $lastSourceLine = getLine(FIRST_SOURCE_LINE + 1);
+ expect($firstSourceLine.text()).to.be('Source line 1.');
+ expect($lastSourceLine.text()).to.be('Source line 2.');
+
+ done();
+ });
+ });
+ });
+
+ context('when user drags some lines far form its original place', function() {
+ before(function(done) {
+ selectMultipleSourceLines();
+ dragSelectedTextAndDropItIntoMiddleOfLine(TARGET_LINE);
+
+ // make sure DnD was correctly simulated
+ helper.waitFor(function() {
+ var $lineAfterTarget = getLine(TARGET_LINE + 1);
+ var sourceWasMovedToTarget = $lineAfterTarget.text() !== '...';
+ return sourceWasMovedToTarget;
+ }).done(done);
+ });
+
+ context('and user triggers UNDO', function() {
+ before(function() {
+ var $undoButton = helper.padChrome$(".buttonicon-undo");
+ $undoButton.click();
+ });
+
+ it('moves text back to its original place', function(done) {
+ // test text was removed from drop target
+ var $targetLine = getLine(TARGET_LINE);
+ expect($targetLine.text()).to.be('Target line []');
+
+ // test text was added back to original place
+ var $firstSourceLine = getLine(FIRST_SOURCE_LINE);
+ var $lastSourceLine = getLine(FIRST_SOURCE_LINE + 1);
+ expect($firstSourceLine.text()).to.be('Source line 1.');
+ expect($lastSourceLine.text()).to.be('Source line 2.');
+
+ done();
+ });
+ });
+ });
+
+ /* ********************* Helper functions/constants ********************* */
+ var TARGET_LINE = 2;
+ var FIRST_SOURCE_LINE = 5;
+
+ var getLine = function(lineNumber) {
+ var $lines = helper.padInner$('div');
+ return $lines.slice(lineNumber, lineNumber + 1);
+ }
+
+ var createScriptWithSeveralLines = function(done) {
+ // create some lines to be used on the tests
+ var $firstLine = helper.padInner$('div').first();
+ $firstLine.html('...<br>...<br>Target line []<br>...<br>...<br>Source line 1.<br>Source line 2.<br>');
+
+ // wait for lines to be split
+ helper.waitFor(function(){
+ var $lastSourceLine = getLine(FIRST_SOURCE_LINE + 1);
+ return $lastSourceLine.text() === 'Source line 2.';
+ }).done(done);
+ }
+
+ var selectPartOfSourceLine = function() {
+ var $sourceLine = getLine(FIRST_SOURCE_LINE);
+
+ // select 'line 1' from 'Source line 1.'
+ var start = 'Source '.length;
+ var end = start + 'line 1'.length;
+ helper.selectLines($sourceLine, $sourceLine, start, end);
+ }
+ var selectMultipleSourceLines = function() {
+ var $firstSourceLine = getLine(FIRST_SOURCE_LINE);
+ var $lastSourceLine = getLine(FIRST_SOURCE_LINE + 1);
+
+ helper.selectLines($firstSourceLine, $lastSourceLine);
+ }
+
+ var dragSelectedTextAndDropItIntoMiddleOfLine = function(targetLineNumber) {
+ // dragstart: start dragging content
+ triggerEvent('dragstart');
+
+ // drop: get HTML data from selected text
+ var draggedHtml = getHtmlFromSelectedText();
+ triggerEvent('drop');
+
+ // dragend: remove original content + insert HTML data into target
+ moveSelectionIntoTarget(draggedHtml, targetLineNumber);
+ triggerEvent('dragend');
+ }
+
+ var getHtmlFromSelectedText = function() {
+ var innerDocument = helper.padInner$.document;
+
+ var range = innerDocument.getSelection().getRangeAt(0);
+ var clonedSelection = range.cloneContents();
+ var span = innerDocument.createElement('span');
+ span.id = 'buffer';
+ span.appendChild(clonedSelection);
+ var draggedHtml = span.outerHTML;
+
+ return draggedHtml;
+ }
+
+ var triggerEvent = function(eventName) {
+ var event = helper.padInner$.Event(eventName);
+ helper.padInner$('#innerdocbody').trigger(event);
+ }
+
+ var moveSelectionIntoTarget = function(draggedHtml, targetLineNumber) {
+ var innerDocument = helper.padInner$.document;
+
+ // delete original content
+ innerDocument.execCommand('delete');
+
+ // set position to insert content on target line
+ var $target = getLine(targetLineNumber);
+ $target.sendkeys('{selectall}{rightarrow}{leftarrow}');
+
+ // insert content
+ innerDocument.execCommand('insertHTML', false, draggedHtml);
+ }
+});
diff --git a/tests/frontend/specs/helper.js b/tests/frontend/specs/helper.js
index d5bff629..bb47f4dc 100644
--- a/tests/frontend/specs/helper.js
+++ b/tests/frontend/specs/helper.js
@@ -55,7 +55,7 @@ describe("the test helper", function(){
it("takes an interval and checks on every interval", function(done){
this.timeout(4000);
var checks = 0;
-
+
helper.waitFor(function(){
checks++;
return false;
@@ -96,4 +96,117 @@ describe("the test helper", function(){
});
});
});
+
+ describe("the selectLines method", function(){
+ // function to support tests, use a single way to represent whitespaces
+ var cleanText = function(text){
+ return text
+ .replace(/\n/gi, "\\\\n") // avoid \n to be replaced by \s on next line
+ .replace(/\s/gi, " ")
+ .replace(/\\\\n/gi, "\n"); // move back \n to its original state
+ }
+
+ before(function(done){
+ helper.newPad(function() {
+ // create some lines to be used on the tests
+ var $firstLine = helper.padInner$("div").first();
+ $firstLine.sendkeys("{selectall}some{enter}short{enter}lines{enter}to test{enter}");
+
+ // wait for lines to be split
+ helper.waitFor(function(){
+ var $fourthLine = helper.padInner$("div").slice(3,4);
+ return $fourthLine.text() === "to test";
+ }).done(done);
+ });
+
+ this.timeout(60000);
+ });
+
+ it("changes editor selection to be between startOffset of $startLine and endOffset of $endLine", function(done){
+ var inner$ = helper.padInner$;
+
+ var startOffset = 2;
+ var endOffset = 4;
+
+ var $lines = inner$("div");
+ var $startLine = $lines.slice(1,2);
+ var $endLine = $lines.slice(3,4);
+
+ helper.selectLines($startLine, $endLine, startOffset, endOffset);
+
+ var selection = inner$.document.getSelection();
+ expect(cleanText(selection.toString())).to.be("ort \nlines \nto t");
+
+ done();
+ });
+
+ it("ends selection at beginning of $endLine when it is an empty line", function(done){
+ var inner$ = helper.padInner$;
+
+ var startOffset = 2;
+ var endOffset = 1;
+
+ var $lines = inner$("div");
+ var $startLine = $lines.slice(1,2);
+ var $endLine = $lines.slice(4,5);
+
+ helper.selectLines($startLine, $endLine, startOffset, endOffset);
+
+ var selection = inner$.document.getSelection();
+ expect(cleanText(selection.toString())).to.be("ort \nlines \nto test\n");
+
+ done();
+ });
+
+ it("ends selection at beginning of $endLine when its offset is zero", function(done){
+ var inner$ = helper.padInner$;
+
+ var startOffset = 2;
+ var endOffset = 0;
+
+ var $lines = inner$("div");
+ var $startLine = $lines.slice(1,2);
+ var $endLine = $lines.slice(3,4);
+
+ helper.selectLines($startLine, $endLine, startOffset, endOffset);
+
+ var selection = inner$.document.getSelection();
+ expect(cleanText(selection.toString())).to.be("ort \nlines \n");
+
+ done();
+ });
+
+ it("selects full line when offset is longer than line content", function(done){
+ var inner$ = helper.padInner$;
+
+ var startOffset = 2;
+ var endOffset = 50;
+
+ var $lines = inner$("div");
+ var $startLine = $lines.slice(1,2);
+ var $endLine = $lines.slice(3,4);
+
+ helper.selectLines($startLine, $endLine, startOffset, endOffset);
+
+ var selection = inner$.document.getSelection();
+ expect(cleanText(selection.toString())).to.be("ort \nlines \nto test");
+
+ done();
+ });
+
+ it("selects all text between beginning of $startLine and end of $endLine when no offset is provided", function(done){
+ var inner$ = helper.padInner$;
+
+ var $lines = inner$("div");
+ var $startLine = $lines.slice(1,2);
+ var $endLine = $lines.slice(3,4);
+
+ helper.selectLines($startLine, $endLine);
+
+ var selection = inner$.document.getSelection();
+ expect(cleanText(selection.toString())).to.be("short \nlines \nto test");
+
+ done();
+ });
+ });
});
diff --git a/tests/frontend/specs/indentation.js b/tests/frontend/specs/indentation.js
index de92cc8f..9294cefb 100644
--- a/tests/frontend/specs/indentation.js
+++ b/tests/frontend/specs/indentation.js
@@ -142,6 +142,51 @@ describe("indentation button", function(){
});
});
+ it("issue #2772 shows '*' when multiple indented lines receive a style and are outdented", function(done){
+ var inner$ = helper.padInner$;
+ var chrome$ = helper.padChrome$;
+
+ // make sure pad has more than one line
+ inner$("div").first().sendkeys("First{enter}Second{enter}");
+ helper.waitFor(function(){
+ return inner$("div").first().text().trim() === "First";
+ }).done(function(){
+ // indent first 2 lines
+ var $lines = inner$("div");
+ var $firstLine = $lines.first();
+ var $secondLine = $lines.slice(1,2);
+ helper.selectLines($firstLine, $secondLine);
+
+ var $indentButton = chrome$(".buttonicon-indent");
+ $indentButton.click();
+
+ helper.waitFor(function(){
+ return inner$("div").first().find("ul li").length === 1;
+ }).done(function(){
+ // apply bold
+ var $boldButton = chrome$(".buttonicon-bold");
+ $boldButton.click();
+
+ helper.waitFor(function(){
+ return inner$("div").first().find("b").length === 1;
+ }).done(function(){
+ // outdent first 2 lines
+ var $outdentButton = chrome$(".buttonicon-outdent");
+ $outdentButton.click();
+ helper.waitFor(function(){
+ return inner$("div").first().find("ul li").length === 0;
+ }).done(function(){
+ // check if '*' is displayed
+ var $secondLine = inner$("div").slice(1,2);
+ expect($secondLine.text().trim()).to.be("Second");
+
+ done();
+ });
+ });
+ });
+ });
+ });
+
/*
it("makes text indented and outdented", function() {
diff --git a/tests/frontend/specs/urls_become_clickable.js b/tests/frontend/specs/urls_become_clickable.js
index 2de60bf9..b989717e 100644
--- a/tests/frontend/specs/urls_become_clickable.js
+++ b/tests/frontend/specs/urls_become_clickable.js
@@ -44,4 +44,27 @@ describe("urls", function(){
}, 2000).done(done);
});
+ it("when you enter a url followed by a ], the ] is not included in the URL", function(done) {
+ var inner$ = helper.padInner$;
+ var chrome$ = helper.padChrome$;
+
+ //get the first text element out of the inner iframe
+ var firstTextElement = inner$("div").first();
+ var url = "http://etherpad.org/";
+
+ // simulate key presses to delete content
+ firstTextElement.sendkeys('{selectall}'); // select all
+ firstTextElement.sendkeys('{del}'); // clear the first line
+ firstTextElement.sendkeys(url); // insert a URL
+ firstTextElement.sendkeys(']'); // put a ] after it
+
+ helper.waitFor(function(){
+ if(inner$("div").first().find("a").length === 1){ // if it contains an A link
+ if(inner$("div").first().find("a")[0].href === url){
+ return true;
+ }
+ };
+ }, 2000).done(done);
+ });
+
});