diff --git a/CHANGELOG.md b/CHANGELOG.md
index 762ef39e3..75a9f3276 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,28 @@
+# 1.5.1
+ * NEW: High resolution Icon
+ * NEW: Use HTTPS for plugins.json download
+ * NEW: Add 'last update' column
+ * NEW: Show users and chat at the same time
+ * NEW: Support io.js
+ * Fix: removeAttributeOnLine now works properly
+ * Fix: Plugin search and list
+ * Fix: Issue where unauthed request could cause error
+ * Fix: Privacy issue with .etherpad export
+ * Fix: Freeze deps to improve bisectability
+ * Fix: IE, everything. IE is so broken.
+ * Fix: Timeslider proxy
+ * Fix: All backend tests pass
+ * Fix: Better support for Export into HTML
+ * Fix: Timeslider stars
+ * Fix: Translation update
+ * Fix: Check filesystem if Abiword exists
+ * Fix: Docs formatting
+ * Fix: Move Save Revision notification to a gritter message
+ * Fix: UeberDB MySQL Timeout issue
+ * Fix: Indented +9 list items
+ * Fix: Don't paste on middle click of link
+ * SECURITY Fix: Issue where a malformed URL could cause EP to disclose installation location
+
# 1.5.0
* NEW: Lots of performance improvements for page load times
* NEW: Hook for adding CSS to Exports
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 0110151c1..b6e1c2473 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,6 +1,31 @@
# Developer Guidelines
(Please talk to people on the mailing list before you change this page, see our section on [how to get in touch](https://github.com/ether/etherpad-lite#get-in-touch))
+## How to write a bug report
+
+* Please be polite, we all are humans and problems can occur.
+* Please add as much information as possible, for example
+ * client os(s) and version(s)
+ * browser(s) and version(s), is the problem reproduceable on different clients
+ * special environments like firewalls or antivirus
+ * host os and version
+ * npm and nodejs version
+ * Logfiles if available
+ * steps to reproduce
+ * what you expected to happen
+ * what actually happened
+* Please format logfiles and code examples with markdown see github Markdown help below the issue textarea for more information.
+
+If you send logfiles, please set the loglevel switch DEBUG in your settings.json file:
+
+```
+/* The log level we are using, can be: DEBUG, INFO, WARN, ERROR */
+ "loglevel": "DEBUG",
+```
+
+The logfile location is defined in startup script or the log is directly shown in the commandline after you have started etherpad.
+
+
## Important note for pull requests
**Pull requests should be issued against the develop branch**. We never pull directly into master.
diff --git a/bin/installDeps.sh b/bin/installDeps.sh
index 58eb32f2d..fcf213e48 100755
--- a/bin/installDeps.sh
+++ b/bin/installDeps.sh
@@ -10,28 +10,29 @@ fi
#Is gnu-grep (ggrep) installed on SunOS (Solaris)
if [ $(uname) = "SunOS" ]; then
- hash ggrep > /dev/null 2>&1 || {
+ hash ggrep > /dev/null 2>&1 || {
echo "Please install ggrep (pkg install gnu-grep)" >&2
- exit 1
+ exit 1
}
fi
#Is curl installed?
-hash curl > /dev/null 2>&1 || {
+hash curl > /dev/null 2>&1 || {
echo "Please install curl" >&2
- exit 1
+ exit 1
}
#Is node installed?
-hash node > /dev/null 2>&1 || {
+#not checking io.js, default installation creates a symbolic link to node
+hash node > /dev/null 2>&1 || {
echo "Please install node.js ( http://nodejs.org )" >&2
- exit 1
+ exit 1
}
#Is npm installed?
-hash npm > /dev/null 2>&1 || {
+hash npm > /dev/null 2>&1 || {
echo "Please install npm ( http://npmjs.org )" >&2
- exit 1
+ exit 1
}
#check npm version
@@ -39,15 +40,21 @@ NPM_VERSION=$(npm --version)
NPM_MAIN_VERSION=$(echo $NPM_VERSION | cut -d "." -f 1)
if [ $(echo $NPM_MAIN_VERSION) = "0" ]; then
echo "You're running a wrong version of npm, you're using $NPM_VERSION, we need 1.x or higher" >&2
- exit 1
+ exit 1
fi
#check node version
NODE_VERSION=$(node --version)
NODE_V_MINOR=$(echo $NODE_VERSION | cut -d "." -f 1-2)
+#iojs version checking added
+if hash iojs 2>/dev/null; then
+ IOJS_VERSION=$(iojs --version)
+fi
if [ ! $NODE_V_MINOR = "v0.8" ] && [ ! $NODE_V_MINOR = "v0.10" ] && [ ! $NODE_V_MINOR = "v0.11" ]; then
- echo "You're running a wrong version of node, you're using $NODE_VERSION, we need v0.8.x, v0.10.x or v0.11.x" >&2
- exit 1
+ if [ ! $IOJS_VERSION ]; then
+ echo "You're running a wrong version of node, or io.js is not installed. You're using $NODE_VERSION, we need v0.8.x, v0.10.x or v0.11.x" >&2
+ exit 1
+ fi
fi
#Get the name of the settings file
@@ -71,9 +78,9 @@ echo "Ensure that all dependencies are up to date... If this is the first time
[ -e ep_etherpad-lite ] || ln -s ../src ep_etherpad-lite
cd ep_etherpad-lite
npm install --loglevel warn
-) || {
+) || {
rm -rf node_modules
- exit 1
+ exit 1
}
echo "Ensure jQuery is downloaded and up to date..."
@@ -81,9 +88,9 @@ DOWNLOAD_JQUERY="true"
NEEDED_VERSION="1.9.1"
if [ -f "src/static/js/jquery.js" ]; then
if [ $(uname) = "SunOS" ]; then
- VERSION=$(cat src/static/js/jquery.js | head -n 3 | ggrep -o "v[0-9]\.[0-9]\(\.[0-9]\)\?");
+ VERSION=$(head -n 3 src/static/js/jquery.js | ggrep -o "v[0-9]\.[0-9]\(\.[0-9]\)\?")
else
- VERSION=$(cat src/static/js/jquery.js | head -n 3 | grep -o "v[0-9]\.[0-9]\(\.[0-9]\)\?");
+ VERSION=$(head -n 3 src/static/js/jquery.js | grep -o "v[0-9]\.[0-9]\(\.[0-9]\)\?")
fi
if [ ${VERSION#v} = $NEEDED_VERSION ]; then
@@ -106,7 +113,7 @@ do
if [ ! -f "src/static/custom/$f.js" ]; then
cp "src/static/custom/js.template" "src/static/custom/$f.js" || exit 1
fi
-
+
if [ ! -f "src/static/custom/$f.css" ]; then
cp "src/static/custom/css.template" "src/static/custom/$f.css" || exit 1
fi
diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md
index 251cbf11e..c7e7a43af 100644
--- a/doc/api/hooks_server-side.md
+++ b/doc/api/hooks_server-side.md
@@ -247,6 +247,30 @@ Things in context:
This hook will allow a plug-in developer to re-write each line when exporting to HTML.
+Example:
+```
+var Changeset = require("ep_etherpad-lite/static/js/Changeset");
+
+exports.getLineHTMLForExport = function (hook, context) {
+ var header = _analyzeLine(context.attribLine, context.apool);
+ if (header) {
+ return "<" + header + ">" + context.lineContents + "" + header + ">";
+ }
+}
+
+function _analyzeLine(alineAttrs, apool) {
+ var header = null;
+ if (alineAttrs) {
+ var opIter = Changeset.opIterator(alineAttrs);
+ if (opIter.hasNext()) {
+ var op = opIter.next();
+ header = Changeset.opAttributeValue(op, 'heading', apool);
+ }
+ }
+ return header;
+}
+```
+
## stylesForExport
Called from: src/node/utils/ExportHtml.js
@@ -314,7 +338,7 @@ exports.exportHtmlAdditionalTags = function(hook, pad, cb){
var padId = pad.id;
cb(["massive","jugs"]);
};
-
+```
## userLeave
Called from src/node/handler/PadMessageHandler.js
diff --git a/src/etherpad_icon.svg b/src/etherpad_icon.svg
new file mode 100644
index 000000000..ebdcde99b
--- /dev/null
+++ b/src/etherpad_icon.svg
@@ -0,0 +1,92 @@
+
+
+
+
diff --git a/src/locales/ar.json b/src/locales/ar.json
index b4ea58dd2..b0d19fcc2 100644
--- a/src/locales/ar.json
+++ b/src/locales/ar.json
@@ -3,7 +3,8 @@
"authors": [
"Ali1",
"Tux-tn",
- "Alami"
+ "Alami",
+ "Meno25"
]
},
"index.newPad": "باد جديد",
@@ -11,14 +12,14 @@
"pad.toolbar.bold.title": "سميك (Ctrl-B)",
"pad.toolbar.italic.title": "مائل (Ctrl-I)",
"pad.toolbar.underline.title": "تسطير (Ctrl-U)",
- "pad.toolbar.strikethrough.title": "شطب",
- "pad.toolbar.ol.title": "قائمة مرتبة",
- "pad.toolbar.ul.title": "قائمة غير مرتبة",
+ "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.unindent.title": "حذف الإزاحة",
"pad.toolbar.undo.title": "فك (Ctrl-Z)",
"pad.toolbar.redo.title": "تكرار (Ctrl-Y)",
- "pad.toolbar.clearAuthorship.title": "مسح ألوان التأليف",
+ "pad.toolbar.clearAuthorship.title": "مسح ألوان التأليف (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "استيراد/تصدير من/إلى تنسيقات ملفات مختلفة",
"pad.toolbar.timeslider.title": "متصفح التاريخ",
"pad.toolbar.savedRevision.title": "حفظ المراجعة",
@@ -46,6 +47,7 @@
"pad.importExport.import": "تحميل أي ملف نصي أو وثيقة",
"pad.importExport.importSuccessful": "ناجح!",
"pad.importExport.export": "تصدير الباد الحالي بصفة:",
+ "pad.importExport.exportetherpad": "إيثرباد",
"pad.importExport.exporthtml": "إتش تي إم إل",
"pad.importExport.exportplain": "نص عادي",
"pad.importExport.exportword": "مايكروسوفت وورد",
diff --git a/src/locales/az.json b/src/locales/az.json
index 25a8ecc2f..99d3216aa 100644
--- a/src/locales/az.json
+++ b/src/locales/az.json
@@ -3,35 +3,36 @@
"authors": [
"AZISS",
"Khan27",
- "Mushviq Abdulla"
+ "Mushviq Abdulla",
+ "Wertuose"
]
},
- "index.newPad": "Yeni Pad",
- "index.createOpenPad": "və ya Pad-ı adı ilə yarat/aç:",
+ "index.newPad": "Yeni lövhə",
+ "index.createOpenPad": "və ya lövhəni bu adla yarat/aç:",
"pad.toolbar.bold.title": "Qalın (Ctrl-B)",
"pad.toolbar.italic.title": "Kursiv (Ctrl-I)",
"pad.toolbar.underline.title": "Altından xətt çəkmə (Ctrl-U)",
- "pad.toolbar.strikethrough.title": "Pozulma",
- "pad.toolbar.ol.title": "Qaydaya salınmış siyahı",
- "pad.toolbar.ul.title": "Qaydaya salınmamış siyahı",
- "pad.toolbar.indent.title": "Abzas",
- "pad.toolbar.unindent.title": "Çıxıntı",
- "pad.toolbar.undo.title": "Geri Al (Ctrl-Z)",
- "pad.toolbar.redo.title": "Qaytarmaq (Ctrl-Y)",
+ "pad.toolbar.strikethrough.title": "Üstdən xətləmək (Ctrl+5)",
+ "pad.toolbar.ol.title": "Sıralanmış siyahı (Ctrl+Shift+N)",
+ "pad.toolbar.ul.title": "Sırasız siyahı (Ctrl+Shift+L)",
+ "pad.toolbar.indent.title": "Abzas (TAB)",
+ "pad.toolbar.unindent.title": "Çıxıntı (Shift+TAB)",
+ "pad.toolbar.undo.title": "Geri qaytar (Ctrl+Z)",
+ "pad.toolbar.redo.title": "Qaytar (Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "Müəlliflik Rənglərini Təmizlə",
"pad.toolbar.import_export.title": "Müxtəlif fayl formatların(a/dan) idxal/ixrac",
"pad.toolbar.timeslider.title": "Vaxt cədvəli",
"pad.toolbar.savedRevision.title": "Saxlanılan Düzəlişlər",
"pad.toolbar.settings.title": "Tənzimləmələr",
- "pad.toolbar.embed.title": "Bu pad-ı yayımla",
- "pad.toolbar.showusers.title": "Pad-da istifadəçiləri göstər",
+ "pad.toolbar.embed.title": "Bu lövhəni paylaş və qur",
+ "pad.toolbar.showusers.title": "Lövhədəki istifadəçiləri göstər",
"pad.colorpicker.save": "Saxla",
"pad.colorpicker.cancel": "İmtina",
"pad.loading": "Yüklənir...",
- "pad.passwordRequired": "Bu pad-a daxil olmaq üçün parol lazımdır",
- "pad.permissionDenied": "Bu pad-a daxil olmaq üçün icazəniz yoxdur",
+ "pad.passwordRequired": "Bu lövhəyə daxil olmaq üçün parol lazımdır",
+ "pad.permissionDenied": "Bu lövhəyə daxil olmaq üçün icazəniz yoxdur",
"pad.wrongPassword": "Sizin parolunuz səhvdir",
- "pad.settings.padSettings": "Pad Tənzimləmələri",
+ "pad.settings.padSettings": "Lövhə nizamlamaları",
"pad.settings.myView": "Mənim Görüntüm",
"pad.settings.stickychat": "Söhbət həmişə ekranda",
"pad.settings.colorcheck": "Müəlliflik rəngləri",
@@ -45,18 +46,19 @@
"pad.importExport.import_export": "İdxal/İxrac",
"pad.importExport.import": "Hər hansı bir mətn faylı və ya sənəd yüklə",
"pad.importExport.importSuccessful": "Uğurlu!",
- "pad.importExport.export": "Hazırki pad-ı ixrac etmək kimi:",
+ "pad.importExport.export": "Hazırkı lövhəni bu şəkildə ixrac et:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Adi mətn",
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
- "pad.importExport.exportopen": "ODF (Açıq Sənəd Formatı)",
+ "pad.importExport.exportopen": "ODF (açıq sənəd formatı)",
"pad.importExport.abiword.innerHTML": "Siz yalnız adi mətndən və ya HTML-dən idxal edə bilərsiniz. İdxalın daha mürəkkəb funksiyaları üçün, zəhmət olmasa, AbiWord-i quraşdırın.",
"pad.modals.connected": "Bağlandı.",
- "pad.modals.reconnecting": "Sizin pad yenidən qoşulur..",
+ "pad.modals.reconnecting": "Sizin lövhə yenidən qoşulur..",
"pad.modals.forcereconnect": "Məcbur təkrarən bağlan",
"pad.modals.userdup": "Başqa pəncərədə artıq açıqdır",
- "pad.modals.userdup.explanation": "Sənəd, ola bilsin ki, bu kompyuterdə, brauzerin bir neçə pəncərəsində açılmışdır.",
+ "pad.modals.userdup.explanation": "Bu lövhə, ola bilsin ki, bu kompüterdəki brauzerin bir neçə pəncərəsində açılmışdır.",
"pad.modals.userdup.advice": "Bu pəncərədən istifadəylə yenidən qoşulun.",
"pad.modals.unauth": "İcazəli deyil",
"pad.modals.unauth.explanation": "Bu səhifəyə baxdığınız vaxt sizin icazəniz dəyişilib. Bərpa etmək üşün yenidən cəhd edin.",
@@ -69,22 +71,22 @@
"pad.modals.slowcommit.cause": "Bu şəbəkə bağlantısında problemlər yarana bilər.",
"pad.modals.badChangeset.explanation": "Etdiyiniz bir redaktə sinxronizasiya serveri tərəfindən qeyri-leqal/qanundan kənar olaraq təsbit edildi.",
"pad.modals.badChangeset.cause": "Bu, yanlış server tərtibatı ya da başqa bir gözlənilməyən davranışlar nəticəsində ola bilər. Bu sizə bir xəta imiş kimi görünürsə lütfən servis nəzarətçisi ilə əlaqə yaradın. Redaktəyə davam etmək üçün yenidən qoşulmanı yoxlayın.",
- "pad.modals.corruptPad.explanation": "Əldə etməyə çalışdığınız sənəd zədəlidir.",
+ "pad.modals.corruptPad.explanation": "Daxil olmağa çalışdığınız lövhə zədəlidir.",
"pad.modals.corruptPad.cause": "Bu, yanlış server tərtibatı ya da başqa bir gözlənilməyən davranışlardan əmələ gələ bilər. Lütfən servis nəzarətçisi ilə əlaqə yaradın.",
"pad.modals.deleted": "Silindi.",
- "pad.modals.deleted.explanation": "Bu pad silindi.",
+ "pad.modals.deleted.explanation": "Bu lövhə silindi.",
"pad.modals.disconnected": "Əlaqə kəsilib.",
"pad.modals.disconnected.explanation": "Serverə qoşulma itirilib",
"pad.modals.disconnected.cause": "Server istifadə olunmur. Əgər problem təkrarlanacaqsa, bizə bildirin.",
- "pad.share": "Bu pad-ı yayımla",
+ "pad.share": "Bu lövhəni paylaş",
"pad.share.readonly": "Yalnız oxuyun",
"pad.share.link": "Keçid",
"pad.share.emebdcode": "URL-ni yayımla",
"pad.chat": "Söhbət",
- "pad.chat.title": "Bu pad üçün chat açın.",
+ "pad.chat.title": "Bu lövhə üçün çat açın.",
"pad.chat.loadmessages": "Daha çox mesaj yüklə",
"timeslider.pageTitle": "{{appTitle}} Vaxt cədvəli",
- "timeslider.toolbar.returnbutton": "Pad-a qayıt",
+ "timeslider.toolbar.returnbutton": "Lövhəyə qayıt",
"timeslider.toolbar.authors": "Müəlliflər:",
"timeslider.toolbar.authorsList": "Müəllif yoxdur",
"timeslider.toolbar.exportlink.title": "İxrac",
@@ -104,18 +106,19 @@
"timeslider.month.october": "Oktyabr",
"timeslider.month.november": "Noyabr",
"timeslider.month.december": "Dekabr",
- "timeslider.unnamedauthors": "{{num}} adsız müəlliflər",
+ "timeslider.unnamedauthors": "{{num}} adsız {[plural(num) one: müəllif, other: müəllif]}",
"pad.savedrevs.marked": "Bu versiya indi yaddaşa saxlanmış kimi nişanlandı",
- "pad.userlist.entername": "Adınızı daxil et",
+ "pad.userlist.entername": "Adınızı daxil edin",
"pad.userlist.unnamed": "adsız",
"pad.userlist.guest": "Qonaq",
"pad.userlist.deny": "İnkar etmək",
"pad.userlist.approve": "Təsdiqləmək",
- "pad.editbar.clearcolors": "Bütün sənədlərdə müəlliflik rənglərini təmizlə?",
- "pad.impexp.importbutton": "İndi idxal edin",
+ "pad.editbar.clearcolors": "Bütün sənədlərdə müəllif rəngləri təmizlənsin?",
+ "pad.impexp.importbutton": "İndi idxal et",
"pad.impexp.importing": "İdxal...",
- "pad.impexp.confirmimport": "Faylın idxalı cari mətni yeniləyəcək. Siz əminsinizmi ki, davam etmək istəyirsiniz?",
+ "pad.impexp.confirmimport": "Faylın idxalı lövhədəki cari mətni yeniləyəcək. Davam etmək istədiyinizə əminsinizmi?",
"pad.impexp.convertFailed": "Biz bu fayl idxal etmək mümkün deyil idi. Xahiş olunur müxtəlif sənəddən istifadə edin və ya kopyalayıb yapışdırmaq yolundan istifadə edin",
+ "pad.impexp.padHasData": "Biz bu faylı idxal edə bilmədik, çünki bu lövhədə düzəlişlər edilib, lütfən yeni lövhə idxal edin",
"pad.impexp.uploadFailed": "Yükləmədə səhv, xahiş olunur yenə cəhd edin",
"pad.impexp.importfailed": "İdxal zamanı səhv",
"pad.impexp.copypaste": "Xahiş edirik kopyalayıb yapışdırın",
diff --git a/src/locales/be-tarask.json b/src/locales/be-tarask.json
index 61a785399..f67d10fe5 100644
--- a/src/locales/be-tarask.json
+++ b/src/locales/be-tarask.json
@@ -28,6 +28,7 @@
"pad.colorpicker.save": "Захаваць",
"pad.colorpicker.cancel": "Скасаваць",
"pad.loading": "Загрузка...",
+ "pad.noCookie": "Кукі ня знойдзеныя. Калі ласка, дазвольце кукі ў вашым браўзэры!",
"pad.passwordRequired": "Для доступу да гэтага дакумэнта патрэбны пароль",
"pad.permissionDenied": "Вы ня маеце дазволу на доступ да гэтага дакумэнта",
"pad.wrongPassword": "Вы ўвялі няслушны пароль",
@@ -46,6 +47,7 @@
"pad.importExport.import": "Загрузіжайце любыя тэкставыя файлы або дакумэнты",
"pad.importExport.importSuccessful": "Пасьпяхова!",
"pad.importExport.export": "Экспартаваць бягучы дакумэнт як:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Просты тэкст",
"pad.importExport.exportword": "Microsoft Word",
@@ -116,6 +118,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/bgn.json b/src/locales/bgn.json
new file mode 100644
index 000000000..00efbf3f9
--- /dev/null
+++ b/src/locales/bgn.json
@@ -0,0 +1,75 @@
+{
+ "@metadata": {
+ "authors": [
+ "Baloch Afghanistan"
+ ]
+ },
+ "index.newPad": "یاداشتی نوکین کتابچه",
+ "index.createOpenPad": "یا جوڑ\t کورتین/پاچ کورتین یک کتابچه ئی یاداشتی بی نام:",
+ "pad.toolbar.bold.title": "پررنگ (Ctrl-B)",
+ "pad.toolbar.italic.title": "چوّٹ (Ctrl-I)",
+ "pad.toolbar.underline.title": "جهلگ خط (Ctrl-U)",
+ "pad.toolbar.strikethrough.title": "خط وارته (Ctrl+5)",
+ "pad.toolbar.ol.title": "ترتیب بوتگین لر لیست (Ctrl+Shift+N)",
+ "pad.toolbar.ul.title": "ترتیب نه بوتگین لر لیست (Ctrl+Shift+L)",
+ "pad.toolbar.indent.title": "بیئتئ بوتگین (TAB)",
+ "pad.toolbar.unindent.title": "در آتگی (Shift+TAB)",
+ "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": "تنظیمات",
+ "pad.colorpicker.save": "ذخیره",
+ "pad.colorpicker.cancel": "کنسیل",
+ "pad.loading": "لودینگ...",
+ "pad.wrongPassword": "شمی پاسورد جووان نه اینت",
+ "pad.settings.padSettings": "یاداشتئ دفترچه ئی تنظیمات",
+ "pad.settings.myView": "نئ دیست",
+ "pad.settings.stickychat": "هبر موچین وختا بی دیستئ تاکدیمئ سرا بیئت",
+ "pad.settings.colorcheck": "نویسوکی رنگ ئان",
+ "pad.settings.linenocheck": "خط ئانی نمبر",
+ "pad.settings.rtlcheck": "محتوایی وانتین شه راست بی چپا؟",
+ "pad.settings.fontType": "قلم رکم:",
+ "pad.settings.fontType.normal": "ساددگ",
+ "pad.settings.fontType.monospaced": "Monospace",
+ "pad.settings.globalView": "سراسرین دیست یا نما",
+ "pad.settings.language": "زبان:",
+ "pad.importExport.exporthtml": "HTML",
+ "pad.importExport.exportplain": "ساده گین متن",
+ "pad.importExport.exportword": "Microsoft Word",
+ "pad.importExport.exportpdf": "PDF",
+ "pad.importExport.exportopen": "ODF (پاچین سندئ قالب)",
+ "pad.importExport.abiword.innerHTML": "شما تا توانیت که شه ساده گین متنی ئین قالب یا اچتیامال بی تئ کنیت . په گیشتیرین کارا ئییان پیشرفته ئین بی تئ کورتینا AbiWord نصب کنیت.",
+ "pad.modals.connected": "وصل بوت.",
+ "pad.modals.userdup": "نوکین دروازه گئ پاچ کورتین",
+ "pad.modals.unauth": "مجاز نه اینت",
+ "pad.modals.deleted.explanation": "ای یاداشتی دفترچه پاک بوته.",
+ "pad.share.readonly": "فقط وانتین",
+ "pad.share.link": "لینک",
+ "pad.chat": "چت وهبر",
+ "timeslider.toolbar.exportlink.title": "دَر کورتین",
+ "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": "ڈ\tسمبر",
+ "timeslider.unnamedauthors": "{{num}} بی نامین نویسوک",
+ "pad.userlist.entername": "وتئ ناما نیویشته بکنیت",
+ "pad.userlist.unnamed": "بی نام",
+ "pad.userlist.guest": "مهمان",
+ "pad.userlist.deny": "رد کورتین",
+ "pad.userlist.approve": "قبول کورتین",
+ "pad.impexp.importbutton": "انون بی تئ کن",
+ "pad.impexp.importing": "بی بی تئ کورتینی حالا...",
+ "pad.impexp.uploadFailed": "آپلود انجام نه بوت، پدا کوشش کن",
+ "pad.impexp.copypaste": "کپی پیست کَنیت"
+}
diff --git a/src/locales/ca.json b/src/locales/ca.json
index 92da9d029..b7edc65b0 100644
--- a/src/locales/ca.json
+++ b/src/locales/ca.json
@@ -13,9 +13,9 @@
"pad.toolbar.bold.title": "Negreta (Ctrl-B)",
"pad.toolbar.italic.title": "Cursiva (Ctrl-I)",
"pad.toolbar.underline.title": "Subratllat (Ctrl-U)",
- "pad.toolbar.strikethrough.title": "Ratllat",
- "pad.toolbar.ol.title": "Llista ordenada",
- "pad.toolbar.ul.title": "Llista sense ordenar",
+ "pad.toolbar.strikethrough.title": "Ratllat (Ctrl+5)",
+ "pad.toolbar.ol.title": "Llista ordenada (Ctrl+Shift+N)",
+ "pad.toolbar.ul.title": "Llista sense ordenar (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Sagnat (TAB)",
"pad.toolbar.unindent.title": "Sagnat invers (Majúsc+TAB)",
"pad.toolbar.undo.title": "Desfés (Ctrl-Z)",
@@ -30,6 +30,7 @@
"pad.colorpicker.save": "Desa",
"pad.colorpicker.cancel": "Cancel·la",
"pad.loading": "S'està carregant...",
+ "pad.noCookie": "No s'ha trobat la galeta. Permeteu les galetes en el navegador!",
"pad.passwordRequired": "Us cal una contrasenya per a accedir a aquest pad",
"pad.permissionDenied": "No teniu permisos per a accedir a aquest pad",
"pad.wrongPassword": "La contrasenya és incorrecta",
@@ -48,6 +49,7 @@
"pad.importExport.import": "Puja qualsevol fitxer de text o document",
"pad.importExport.importSuccessful": "Hi ha hagut èxit!",
"pad.importExport.export": "Exporta el pad actual com a:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Text net",
"pad.importExport.exportword": "Microsoft Word",
@@ -118,6 +120,7 @@
"pad.impexp.importing": "Important...",
"pad.impexp.confirmimport": "En importar un fitxer se sobreescriurà el text actual del pad. Esteu segur que voleu continuar?",
"pad.impexp.convertFailed": "No és possible d'importar aquest fitxer. Si us plau, podeu provar d'utilitzar un format diferent o copiar i enganxar manualment.",
+ "pad.impexp.padHasData": "No vam poder importar el fitxer perquè el pad ja tenia canvis. Importeu-lo a un nou pad",
"pad.impexp.uploadFailed": "Ha fallat la càrrega. Torneu-ho a provar",
"pad.impexp.importfailed": "Ha fallat la importació",
"pad.impexp.copypaste": "Si us plau, copieu i enganxeu",
diff --git a/src/locales/cs.json b/src/locales/cs.json
index 1c1357c44..2a6b5fec1 100644
--- a/src/locales/cs.json
+++ b/src/locales/cs.json
@@ -48,6 +48,7 @@
"pad.importExport.import": "Nahrát libovolný textový soubor nebo dokument",
"pad.importExport.importSuccessful": "Úspěšně!",
"pad.importExport.export": "Exportovat stávající Pad jako:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Prostý text",
"pad.importExport.exportword": "Microsoft Word",
diff --git a/src/locales/de.json b/src/locales/de.json
index f05d43c3e..a2bca7237 100644
--- a/src/locales/de.json
+++ b/src/locales/de.json
@@ -29,6 +29,7 @@
"pad.colorpicker.save": "Speichern",
"pad.colorpicker.cancel": "Abbrechen",
"pad.loading": "Laden …",
+ "pad.noCookie": "Das Cookie konnte nicht gefunden werden. Bitte erlaube Cookies in deinem Browser!",
"pad.passwordRequired": "Sie benötigen ein Passwort, um auf dieses Pad zuzugreifen",
"pad.permissionDenied": "Sie haben keine Berechtigung, um auf dieses Pad zuzugreifen",
"pad.wrongPassword": "Ihr Passwort war falsch",
@@ -47,6 +48,7 @@
"pad.importExport.import": "Text-Datei oder Dokument hochladen",
"pad.importExport.importSuccessful": "Erfolgreich!",
"pad.importExport.export": "Aktuelles Pad exportieren als:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Textdatei",
"pad.importExport.exportword": "Microsoft Word",
@@ -117,6 +119,7 @@
"pad.impexp.importing": "Importiere …",
"pad.impexp.confirmimport": "Das Importieren einer Datei überschreibt den aktuellen Text des Pads. Wollen Sie wirklich fortfahren?",
"pad.impexp.convertFailed": "Wir können diese Datei nicht importieren. Bitte verwenden Sie ein anderes Dokumentformat oder übertragen Sie den Text manuell.",
+ "pad.impexp.padHasData": "Wir konnten diese Datei nicht importieren, da dieses Pad bereits Änderungen hat. Bitte importiere zu einem neuen Pad.",
"pad.impexp.uploadFailed": "Der Upload ist fehlgeschlagen. Bitte versuchen Sie es erneut.",
"pad.impexp.importfailed": "Import fehlgeschlagen",
"pad.impexp.copypaste": "Bitte kopieren und einfügen",
diff --git a/src/locales/diq.json b/src/locales/diq.json
index 61d401696..81a554772 100644
--- a/src/locales/diq.json
+++ b/src/locales/diq.json
@@ -48,6 +48,7 @@
"pad.modals.userdup": "Zewbina pençere de bi a",
"pad.modals.unauth": "Selahiyetdar niyo",
"pad.modals.initsocketfail": "Nêresneyêno ciyageyroği.",
+ "pad.modals.slowcommit.explanation": "Server cewab nêdano.",
"pad.modals.deleted": "Esteriya.",
"pad.modals.deleted.explanation": "Ena ped wedariye",
"pad.share": "Na ped vıla ke",
diff --git a/src/locales/el.json b/src/locales/el.json
index f20e1e87e..740da95c0 100644
--- a/src/locales/el.json
+++ b/src/locales/el.json
@@ -30,6 +30,7 @@
"pad.colorpicker.save": "Αποθήκευση",
"pad.colorpicker.cancel": "Άκυρο",
"pad.loading": "Φόρτωση...",
+ "pad.noCookie": "Το cookie δεν βρέθηκε. Παρακαλώ επιτρέψτε τα cookies στον περιηγητή σας!",
"pad.passwordRequired": "Χρειάζεστε κωδικό πρόσβασης για πρόσβαση σε αυτό το pad",
"pad.permissionDenied": "Δεν έχετε δικαίωμα πρόσβασης σε αυτό το pad",
"pad.wrongPassword": "Ο κωδικός σας ήταν λανθασμένος",
@@ -48,6 +49,7 @@
"pad.importExport.import": "Αποστολή οποιουδήποτε αρχείου κειμένου ή εγγράφου",
"pad.importExport.importSuccessful": "Επιτυχής!",
"pad.importExport.export": "Εξαγωγή τρέχοντος pad ως:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Απλό κείμενο",
"pad.importExport.exportword": "Microsoft Word",
@@ -118,6 +120,7 @@
"pad.impexp.importing": "Εισάγεται...",
"pad.impexp.confirmimport": "Η εισαγωγή ενός αρχείου θα αντικαταστήσει το κείμενο του pad. Είστε βέβαιοι ότι θέλετε να συνεχίσετε;",
"pad.impexp.convertFailed": "Δεν καταφέραμε να εισάγουμε αυτό το αρχείο. Παρακαλώ χρησιμοποιήστε διαφορετικό τύπο αρχείου ή αντιγράψτε και επικολλήστε χειροκίνητα",
+ "pad.impexp.padHasData": "Δεν μπορέσαμε να εισάγουμε το αρχείο επειδή το Pad είχε ήδη αλλαγές. Παρακαλούμε εισαγάγετε το αρχείο σε νέο pad",
"pad.impexp.uploadFailed": "Η αποστολή απέτυχε, παρακαλώ προσπαθήστε ξανά",
"pad.impexp.importfailed": "Η εισαγωγή απέτυχε",
"pad.impexp.copypaste": "Παρακαλώ αντιγράψτε και επικολλήστε",
diff --git a/src/locales/en.json b/src/locales/en.json
index 7f5846fd2..23bb3a040 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -32,6 +32,7 @@
"pad.settings.padSettings": "Pad Settings",
"pad.settings.myView": "My View",
"pad.settings.stickychat": "Chat always on screen",
+ "pad.settings.chatandusers": "Show Chat and Users",
"pad.settings.colorcheck": "Authorship colors",
"pad.settings.linenocheck": "Line numbers",
"pad.settings.rtlcheck": "Read content from right to left?",
@@ -120,6 +121,7 @@
"timeslider.unnamedauthors": "{{num}} unnamed {[plural(num) one: author, other: authors ]}",
"pad.savedrevs.marked": "This revision is now marked as a saved revision",
+ "pad.savedrevs.timeslider": "You can see saved revisions by visiting the timeslider",
"pad.userlist.entername": "Enter your name",
"pad.userlist.unnamed": "unnamed",
"pad.userlist.guest": "Guest",
diff --git a/src/locales/es.json b/src/locales/es.json
index df9a415ec..5547d3278 100644
--- a/src/locales/es.json
+++ b/src/locales/es.json
@@ -35,6 +35,7 @@
"pad.colorpicker.save": "Guardar",
"pad.colorpicker.cancel": "Cancelar",
"pad.loading": "Cargando...",
+ "pad.noCookie": "La cookie no se pudo encontrar. ¡Por favor, habilita las cookies en tu navegador!",
"pad.passwordRequired": "Necesitas una contraseña para acceder a este pad",
"pad.permissionDenied": "No tienes permiso para acceder a este pad",
"pad.wrongPassword": "La contraseña era incorrecta",
@@ -53,6 +54,7 @@
"pad.importExport.import": "Subir cualquier texto o documento",
"pad.importExport.importSuccessful": "¡Éxito!",
"pad.importExport.export": "Exporta el pad actual como:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Texto plano",
"pad.importExport.exportword": "Microsoft Word",
@@ -123,6 +125,7 @@
"pad.impexp.importing": "Importando...",
"pad.impexp.confirmimport": "Al importar un archivo se borrará el contenido actual del pad. ¿Estás seguro de que quieres continuar?",
"pad.impexp.convertFailed": "No pudimos importar este archivo. Inténtalo con un formato diferente o copia y pega manualmente.",
+ "pad.impexp.padHasData": "No hemos podido importar este archivo porque esta almohadilla ya ha tenido cambios, por favor, importa a una nueva almohadilla",
"pad.impexp.uploadFailed": "El envío falló. Intentalo de nuevo.",
"pad.impexp.importfailed": "Fallo al importar",
"pad.impexp.copypaste": "Intenta copiar y pegar",
diff --git a/src/locales/fa.json b/src/locales/fa.json
index 94f2d69f5..53fb55b21 100644
--- a/src/locales/fa.json
+++ b/src/locales/fa.json
@@ -31,6 +31,7 @@
"pad.colorpicker.save": "ذخیره",
"pad.colorpicker.cancel": "لغو",
"pad.loading": "در حال بارگذاری...",
+ "pad.noCookie": "کوکی یافت نشد. لطفاً اجازهٔ اجرای کوکی در مروگرتان را بدهید!",
"pad.passwordRequired": "برای دسترسی به این دفترچه یادداشت نیاز به یک گذرواژه دارید",
"pad.permissionDenied": "شما اجازهی دسترسی به این دفترچه یادداشت را ندارید",
"pad.wrongPassword": "گذرواژهی شما درست نیست",
@@ -49,6 +50,7 @@
"pad.importExport.import": "بارگذاری پروندهی متنی یا سند",
"pad.importExport.importSuccessful": "موفقیت آمیز بود!",
"pad.importExport.export": "برونریزی این دفترچه یادداشت با قالب:",
+ "pad.importExport.exportetherpad": "اترپد",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "متن ساده",
"pad.importExport.exportword": "Microsoft Word",
@@ -119,6 +121,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/fi.json b/src/locales/fi.json
index ee1775dc2..25e4d084d 100644
--- a/src/locales/fi.json
+++ b/src/locales/fi.json
@@ -10,7 +10,8 @@
"Tomi Toivio",
"Veikk0.ma",
"VezonThunder",
- "Macofe"
+ "Macofe",
+ "MrTapsa"
]
},
"index.newPad": "Uusi muistio",
@@ -35,6 +36,7 @@
"pad.colorpicker.save": "Tallenna",
"pad.colorpicker.cancel": "Peru",
"pad.loading": "Ladataan…",
+ "pad.noCookie": "Evästettä ei löytynyt. Ole hyvä, ja salli evästeet selaimessasi!",
"pad.passwordRequired": "Tämä muistio on suojattu salasanalla.",
"pad.permissionDenied": "Käyttöoikeutesi eivät riitä tämän muistion käyttämiseen.",
"pad.wrongPassword": "Väärä salasana",
diff --git a/src/locales/fr.json b/src/locales/fr.json
index 921d1eeb9..92fcb193a 100644
--- a/src/locales/fr.json
+++ b/src/locales/fr.json
@@ -43,6 +43,7 @@
"pad.colorpicker.save": "Enregistrer",
"pad.colorpicker.cancel": "Annuler",
"pad.loading": "Chargement…",
+ "pad.noCookie": "Le cookie n’a pas pu être trouvé. Veuillez autoriser les cookies dans votre navigateur !",
"pad.passwordRequired": "Vous avez besoin d'un mot de passe pour accéder à ce pad",
"pad.permissionDenied": "Il ne vous est pas permis d’accéder à ce pad",
"pad.wrongPassword": "Votre mot de passe est incorrect",
@@ -61,6 +62,7 @@
"pad.importExport.import": "Charger un texte ou un document",
"pad.importExport.importSuccessful": "Réussi !",
"pad.importExport.export": "Exporter le pad actuel comme :",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Texte brut",
"pad.importExport.exportword": "Microsoft Word",
@@ -131,6 +133,7 @@
"pad.impexp.importing": "Import en cours...",
"pad.impexp.confirmimport": "Importer un fichier écrasera le texte actuel du pad. Êtes-vous sûr de vouloir le faire ?",
"pad.impexp.convertFailed": "Nous ne pouvons pas importer ce fichier. Veuillez utiliser un autre format de document ou faire un copier/coller manuel",
+ "pad.impexp.padHasData": "Nous n’avons pas pu importer ce fichier parce que ce bloc a déjà eu des modifications ; veuillez importer vers un nouveau bloc",
"pad.impexp.uploadFailed": "Le téléchargement a échoué, veuillez réessayer",
"pad.impexp.importfailed": "Échec de l'importation",
"pad.impexp.copypaste": "Veuillez copier/coller",
diff --git a/src/locales/gl.json b/src/locales/gl.json
index a14fbb126..b0ca6532e 100644
--- a/src/locales/gl.json
+++ b/src/locales/gl.json
@@ -27,6 +27,7 @@
"pad.colorpicker.save": "Gardar",
"pad.colorpicker.cancel": "Cancelar",
"pad.loading": "Cargando...",
+ "pad.noCookie": "A cookie non se puido atopar. Por favor, habilite as cookies no seu navegador!",
"pad.passwordRequired": "Cómpre un contrasinal para acceder a este documento",
"pad.permissionDenied": "Non ten permiso para acceder a este documento",
"pad.wrongPassword": "O contrasinal era incorrecto",
@@ -45,6 +46,7 @@
"pad.importExport.import": "Cargar un ficheiro de texto ou documento",
"pad.importExport.importSuccessful": "Correcto!",
"pad.importExport.export": "Exportar o documento actual en formato:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Texto simple",
"pad.importExport.exportword": "Microsoft Word",
@@ -115,6 +117,7 @@
"pad.impexp.importing": "Importando...",
"pad.impexp.confirmimport": "A importación dun ficheiro ha sobrescribir o texto actual do documento. Está seguro de querer continuar?",
"pad.impexp.convertFailed": "Non somos capaces de importar o ficheiro. Utilice un formato de documento diferente ou copie e pegue manualmente",
+ "pad.impexp.padHasData": "Non puidemos importar este ficheiro porque este Pad xa tivo cambios, por favor, importe a un novo pad.",
"pad.impexp.uploadFailed": "Houbo un erro ao cargar o ficheiro; inténteo de novo",
"pad.impexp.importfailed": "Fallou a importación",
"pad.impexp.copypaste": "Copie e pegue",
diff --git a/src/locales/hu.json b/src/locales/hu.json
index 7efac2df2..3102790d7 100644
--- a/src/locales/hu.json
+++ b/src/locales/hu.json
@@ -118,6 +118,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.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/ia.json b/src/locales/ia.json
index 50a0690cc..e7f5cc2b2 100644
--- a/src/locales/ia.json
+++ b/src/locales/ia.json
@@ -26,6 +26,7 @@
"pad.colorpicker.save": "Salveguardar",
"pad.colorpicker.cancel": "Cancellar",
"pad.loading": "Cargamento…",
+ "pad.noCookie": "Le cookie non pote esser trovate. Per favor permitte le cookies in tu navigator!",
"pad.passwordRequired": "Un contrasigno es necessari pro acceder a iste pad",
"pad.permissionDenied": "Tu non ha le permission de acceder a iste pad",
"pad.wrongPassword": "Le contrasigno es incorrecte",
@@ -44,6 +45,7 @@
"pad.importExport.import": "Incargar qualcunque file de texto o documento",
"pad.importExport.importSuccessful": "Succedite!",
"pad.importExport.export": "Exportar le pad actual como:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Texto simple",
"pad.importExport.exportword": "Microsoft Word",
@@ -114,6 +116,7 @@
"pad.impexp.importing": "Importation in curso…",
"pad.impexp.confirmimport": "Le importation de un file superscribera le texto actual del pad. Es tu secur de voler continuar?",
"pad.impexp.convertFailed": "Nos non ha potite importar iste file. Per favor usa un altere formato de documento o copia e colla le texto manualmente.",
+ "pad.impexp.padHasData": "Nos non ha potite importar iste file perque iste Pad ha jam habite cambiamentos. Per favor importa lo a un nove pad.",
"pad.impexp.uploadFailed": "Le incargamento ha fallite. Per favor reproba.",
"pad.impexp.importfailed": "Importation fallite",
"pad.impexp.copypaste": "Per favor copia e colla",
diff --git a/src/locales/lb.json b/src/locales/lb.json
index 841add75f..68bdb418c 100644
--- a/src/locales/lb.json
+++ b/src/locales/lb.json
@@ -15,6 +15,7 @@
"pad.colorpicker.save": "Späicheren",
"pad.colorpicker.cancel": "Ofbriechen",
"pad.loading": "Lueden...",
+ "pad.noCookie": "Cookie gouf net fonnt. Erlaabt w.e.g. Cookien an Ärem Browser!",
"pad.wrongPassword": "Äert Passwuert ass falsch",
"pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Sprooch:",
diff --git a/src/locales/mk.json b/src/locales/mk.json
index fc18533fa..9fc6b817c 100644
--- a/src/locales/mk.json
+++ b/src/locales/mk.json
@@ -27,6 +27,7 @@
"pad.colorpicker.save": "Зачувај",
"pad.colorpicker.cancel": "Откажи",
"pad.loading": "Вчитувам...",
+ "pad.noCookie": "Не можев да го најдам колачето. Овозможете колачиња во вашиот прелистувач!",
"pad.passwordRequired": "Потребна е лозинка за пристап",
"pad.permissionDenied": "За овде не е потребна дозвола за пристап",
"pad.wrongPassword": "Погрешна лозинка",
@@ -45,6 +46,7 @@
"pad.importExport.import": "Подигање на било каква текстуална податотека или документ",
"pad.importExport.importSuccessful": "Успешно!",
"pad.importExport.export": "Извези ја тековната тетратка како",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Прост текст",
"pad.importExport.exportword": "Microsoft Word",
@@ -115,6 +117,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/ms.json b/src/locales/ms.json
index cf15be6e2..d099de060 100644
--- a/src/locales/ms.json
+++ b/src/locales/ms.json
@@ -26,6 +26,7 @@
"pad.colorpicker.save": "Simpan",
"pad.colorpicker.cancel": "Batalkan",
"pad.loading": "Sedang dimuatkan...",
+ "pad.noCookie": "Cookie tidak dapat dijumpai. Tolong benarkan cookie dalam pelayar anda!",
"pad.passwordRequired": "Anda memerlukan kata laluan untuk mengakses pad ini",
"pad.permissionDenied": "Anda tiada kebenaran untuk mengakses pad ini",
"pad.wrongPassword": "Kata laluan anda salah",
@@ -44,6 +45,7 @@
"pad.importExport.import": "Muat naik sebarang fail teks atau dokumen",
"pad.importExport.importSuccessful": "Berjaya!",
"pad.importExport.export": "Eksport pad semasa sebagai:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Teks biasa",
"pad.importExport.exportword": "Microsoft Word",
@@ -114,6 +116,7 @@
"pad.impexp.importing": "Sedang mengimport...",
"pad.impexp.confirmimport": "Mengimport fail akan menulis ganti teks semasa pada pad ini. Adakah anda benar-benar ingin teruskan?",
"pad.impexp.convertFailed": "Fail tidak dapat diimport. Sila gunakan format dokumen yang lain atau salin tampal secara manual",
+ "pad.impexp.padHasData": "Kami tidak dapat mengimport fail ini kerana Pad ini sudah mengalami perubahan. Sila import ke pad yang baru",
"pad.impexp.uploadFailed": "Muat naik gagal, sila cuba lagi",
"pad.impexp.importfailed": "Import gagal",
"pad.impexp.copypaste": "Sila salin tampal",
diff --git a/src/locales/nap.json b/src/locales/nap.json
index ffc7b740b..6cd1651b0 100644
--- a/src/locales/nap.json
+++ b/src/locales/nap.json
@@ -1,7 +1,8 @@
{
"@metadata": {
"authors": [
- "Chelin"
+ "Chelin",
+ "C.R."
]
},
"index.newPad": "Novo Pad",
@@ -21,23 +22,58 @@
"pad.toolbar.timeslider.title": "Presentazzione cronologgia",
"pad.toolbar.savedRevision.title": "Sarva revisione",
"pad.toolbar.settings.title": "Mpustaziune",
+ "pad.toolbar.embed.title": "Sparte e nzerta stu Pad",
+ "pad.toolbar.showusers.title": "Mmusta ll'utente ncopp'a stu Pad",
"pad.colorpicker.save": "Sarva",
"pad.colorpicker.cancel": "Canciella",
"pad.loading": "Carecamiento 'n curso…",
+ "pad.noCookie": "Cookie nun truvata. Pe' piacere premmettete 'e cookies dint' 'o navigatóre vuosto!",
"pad.passwordRequired": "Pe' accede a chisto Pad è necessaria 'na password",
"pad.permissionDenied": "Nun se dispunne d\"e permisse necessare pe' accede a chisto Pad",
"pad.wrongPassword": "'A password è sbagliata",
"pad.settings.padSettings": "Mpostazzione d\"o pad",
+ "pad.settings.myView": "Mia Veruta",
+ "pad.settings.stickychat": "Chat sempe ncopp' 'o schermo",
+ "pad.settings.colorcheck": "Auturevolezza pe' culure",
+ "pad.settings.linenocheck": "Nummere 'e riga",
+ "pad.settings.rtlcheck": "Lieggere 'e cuntenute 'a destra a smerza?",
+ "pad.settings.fontType": "Tipo 'e funte:",
"pad.settings.fontType.normal": "Nurmale",
+ "pad.settings.fontType.monospaced": "Monospace",
+ "pad.settings.globalView": "Visualizzazione globbale",
+ "pad.settings.language": "Llengua:",
+ "pad.importExport.import_export": "Mpurtaziune/sportaziune",
+ "pad.importExport.import": "Carreca coccherunto testo o documento",
+ "pad.importExport.importSuccessful": "Ngarrata!",
+ "pad.importExport.export": "Sportà stu Pad comme:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
+ "pad.importExport.exportplain": "Testo nurmale",
+ "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)",
+ "pad.importExport.abiword.innerHTML": "Putite surtanto mpurtà testo chiano o furmatte HTML. Pe n'avé sisteme cchiù annanze 'e mpurtazione pe' piacere installate Abiword.",
"pad.modals.connected": "Cunnesso.",
"pad.modals.reconnecting": "Ricunnessione ô pad 'n curso...",
"pad.modals.forcereconnect": "Forza 'a ricunnessione",
"pad.modals.userdup": "Aprito 'n n'ata fenesta",
+ "pad.modals.userdup.explanation": "Stu Pad pare fosse araputo dint'a cchiù 'e na fenesta 'e navigatore dint'a stu computer.",
+ "pad.modals.userdup.advice": "Riconnettateve pe' putè ausà mmece sta fenesta.",
"pad.modals.unauth": "Nun autorizzato",
+ "pad.modals.unauth.explanation": "'E premmesse vuoste so' cagnate pe' tramente ca se vereva sta paggena. Tentate 'e ve riconnettà.",
+ "pad.modals.looping.explanation": "Ce stanno probbleme 'e comunicazione c' 'o server 'e sincronizzaziona.",
+ "pad.modals.looping.cause": "Può darse ca ve site cullegato pe' mmiez' 'e nu firewall incompatibbele o proxy.",
+ "pad.modals.initsocketfail": "Nun se può arrevà 'o server.",
+ "pad.modals.initsocketfail.explanation": "Nun se può cunnettà 'o server e sincronizzaziona.",
+ "pad.modals.initsocketfail.cause": "Stu fatto è succiesso, probabbilmente pe' bbìa 'e nu probblema c' 'o navigatóre 'o ll'internet.",
+ "pad.modals.slowcommit.explanation": "'O server nun risponne.",
+ "pad.modals.slowcommit.cause": "Stu fatto può darse ca è causato pe' bbìa 'e prubbleme 'e connettività 'e rezza.",
+ "pad.modals.badChangeset.explanation": "Nu cagnamento ca stavate facenno è stato classeficato comme illegale p' 'o server 'e sincronizzaziona.",
+ "pad.modals.badChangeset.cause": "Chistu fatto può darse ca è causato pe' bbìa 'e na mpustazione errata d' 'o server o cocch'atu comportamento nun preveduto. Pe' piacere cuntattate l'ammenistratore d' 'o servizio, si se pienza ca chist'è n'errore. Tentate a ve riconnettà pe' cuntinuà 'a edità.",
+ "pad.modals.corruptPad.explanation": "'O pad addò vulevate trasì è scassato.",
"pad.modals.deleted": "Canciellato.",
+ "pad.share.link": "Jonta",
+ "pad.chat": "Chiàcchiera",
"timeslider.pageTitle": "Cronologgia {{appTitle}}",
"timeslider.toolbar.returnbutton": "Ritorna ô Pad",
"timeslider.toolbar.authors": "Auture:",
diff --git a/src/locales/pl.json b/src/locales/pl.json
index 7e68ca845..bcd7a0ef2 100644
--- a/src/locales/pl.json
+++ b/src/locales/pl.json
@@ -5,7 +5,8 @@
"Ty221",
"WTM",
"Woytecr",
- "Macofe"
+ "Macofe",
+ "Pan Cube"
]
},
"index.newPad": "Nowy dokument",
@@ -48,6 +49,7 @@
"pad.importExport.import": "Prześlij dowolny plik tekstowy lub dokument",
"pad.importExport.importSuccessful": "Sukces!",
"pad.importExport.export": "Eksportuj bieżący dokument jako:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Zwykły tekst",
"pad.importExport.exportword": "Microsoft Word",
diff --git a/src/locales/pt-br.json b/src/locales/pt-br.json
index 204d77929..e8eb79eef 100644
--- a/src/locales/pt-br.json
+++ b/src/locales/pt-br.json
@@ -10,7 +10,8 @@
"Rafaelff",
"Dianakc",
"Macofe",
- "Rodrigo codignoli"
+ "Rodrigo codignoli",
+ "Webysther"
]
},
"index.newPad": "Nova Nota",
@@ -35,6 +36,7 @@
"pad.colorpicker.save": "Salvar",
"pad.colorpicker.cancel": "Cancelar",
"pad.loading": "Carregando...",
+ "pad.noCookie": "Cookie não foi encontrado. Por favor, habilite cookies no seu navegador!",
"pad.passwordRequired": "Você precisa de uma senha para acessar esta Nota",
"pad.permissionDenied": "Você não tem permissão para acessar esta Nota",
"pad.wrongPassword": "Senha incorreta",
@@ -53,6 +55,7 @@
"pad.importExport.import": "Enviar um arquivo texto ou documento",
"pad.importExport.importSuccessful": "Completo!",
"pad.importExport.export": "Exportar a presente nota como:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Texto puro",
"pad.importExport.exportword": "Microsoft Word",
@@ -123,6 +126,7 @@
"pad.impexp.importing": "Importando...",
"pad.impexp.confirmimport": "Importar um arquivo sobrescreverá o atual texto da nota. Tem certeza de que deseja prosseguir?",
"pad.impexp.convertFailed": "Não foi possível importar este arquivo. Use outro formato ou copie e cole manualmente",
+ "pad.impexp.padHasData": "Não foi possível importar este arquivo porque este bloco de notas já tinha alterações, consulte como importar para um novo bloco de notas",
"pad.impexp.uploadFailed": "O envio falhou. Tente outra vez",
"pad.impexp.importfailed": "A importação falhou",
"pad.impexp.copypaste": "Copie e cole",
diff --git a/src/locales/pt.json b/src/locales/pt.json
index c7cfcb5cf..473980fd4 100644
--- a/src/locales/pt.json
+++ b/src/locales/pt.json
@@ -6,7 +6,8 @@
"Tuliouel",
"Waldir",
"Imperadeiro98",
- "Macofe"
+ "Macofe",
+ "Ti4goc"
]
},
"index.newPad": "Nova Nota",
@@ -105,6 +106,7 @@
"pad.impexp.importbutton": "Importar agora",
"pad.impexp.importing": "Importando...",
"pad.impexp.confirmimport": "A importação de um ficheiro irá substituir o texto atual do pad. Tem certeza que deseja continuar?",
+ "pad.impexp.padHasData": "Não fomos capazes de importar este ficheiro porque esta Almofada já tinha alterações, consulte importar para um novo bloco",
"pad.impexp.uploadFailed": "O upload falhou. Por favor, tente novamente",
"pad.impexp.importfailed": "A importação falhou",
"pad.impexp.copypaste": "Por favor, copie e cole"
diff --git a/src/locales/sv.json b/src/locales/sv.json
index bda3cb83b..a53146bf6 100644
--- a/src/locales/sv.json
+++ b/src/locales/sv.json
@@ -28,6 +28,7 @@
"pad.colorpicker.save": "Spara",
"pad.colorpicker.cancel": "Avbryt",
"pad.loading": "Läser in...",
+ "pad.noCookie": "Kunde inte hitta några kakor. Var god tillåt kakor i din webbläsare!",
"pad.passwordRequired": "Du behöver ett lösenord för att få tillgång till detta block",
"pad.permissionDenied": "Du har inte åtkomstbehörighet för detta block",
"pad.wrongPassword": "Ditt lösenord var fel",
@@ -46,6 +47,7 @@
"pad.importExport.import": "Ladda upp textfiler eller dokument",
"pad.importExport.importSuccessful": "Åtgärden slutfördes!",
"pad.importExport.export": "Export aktuellt block som:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Oformaterad text",
"pad.importExport.exportword": "Microsoft Word",
@@ -116,6 +118,7 @@
"pad.impexp.importing": "Importerar...",
"pad.impexp.confirmimport": "Att importera en fil kommer att skriva över den aktuella texten i blocket. Är du säker på att du vill fortsätta?",
"pad.impexp.convertFailed": "Vi kunde inte importera denna fil. Var god använd ett annat dokumentformat eller kopiera och klistra in den manuellt",
+ "pad.impexp.padHasData": "Vi kunde inte importera denna fil eftersom detta block redan har redigerats. Importera den till ett nytt block.",
"pad.impexp.uploadFailed": "Uppladdningen misslyckades, var god försök igen",
"pad.impexp.importfailed": "Importering misslyckades",
"pad.impexp.copypaste": "Var god kopiera och klistra in",
diff --git a/src/locales/zh-hans.json b/src/locales/zh-hans.json
index 104e850b3..bc1c97b5a 100644
--- a/src/locales/zh-hans.json
+++ b/src/locales/zh-hans.json
@@ -24,7 +24,7 @@
"pad.toolbar.indent.title": "增加缩进(TAB)",
"pad.toolbar.unindent.title": "减少缩进(Shift+TAB)",
"pad.toolbar.undo.title": "撤消 (Ctrl-Z)",
- "pad.toolbar.redo.title": "重做 (Ctrl-Y)",
+ "pad.toolbar.redo.title": "重做(Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "清除作者颜色(Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "从不同的文件格式导入/导出",
"pad.toolbar.timeslider.title": "时间轴",
@@ -35,6 +35,7 @@
"pad.colorpicker.save": "保存",
"pad.colorpicker.cancel": "取消",
"pad.loading": "载入中……",
+ "pad.noCookie": "无法找到Cookie。请在您的浏览器中允许Cookie!",
"pad.passwordRequired": "您需要密码才能访问这个记事本",
"pad.permissionDenied": "您没有访问这个记事本的权限",
"pad.wrongPassword": "您的密码错了",
@@ -53,6 +54,7 @@
"pad.importExport.import": "上载任何文本文件或档案",
"pad.importExport.importSuccessful": "成功!",
"pad.importExport.export": "当前记事本导出为:",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "纯文本",
"pad.importExport.exportword": "Microsoft Word",
@@ -123,6 +125,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/zh-hant.json b/src/locales/zh-hant.json
index 6d79268c2..a692d0ca4 100644
--- a/src/locales/zh-hant.json
+++ b/src/locales/zh-hant.json
@@ -96,13 +96,13 @@
"timeslider.saved": "{{year}}年{{month}}{{day}}日儲存",
"timeslider.dateformat": "{{year}}年{{month}}月{{day}}日 {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "1月",
- "timeslider.month.february": "2月",
+ "timeslider.month.february": "二月",
"timeslider.month.march": "3月",
"timeslider.month.april": "4月",
"timeslider.month.may": "5月",
"timeslider.month.june": "6月",
"timeslider.month.july": "7月",
- "timeslider.month.august": "8月",
+ "timeslider.month.august": "八月",
"timeslider.month.september": "9月",
"timeslider.month.october": "10月",
"timeslider.month.november": "11月",
diff --git a/src/node/db/API.js b/src/node/db/API.js
index a9df2a12f..81dedcfef 100644
--- a/src/node/db/API.js
+++ b/src/node/db/API.js
@@ -410,11 +410,16 @@ exports.setHTML = function(padID, html, callback)
if(ERR(err, callback)) return;
// add a new changeset with the new html to the pad
- importHtml.setPadHTML(pad, cleanText(html), callback);
-
- //update the clients on the pad
- padMessageHandler.updatePadClients(pad, callback);
-
+ importHtml.setPadHTML(pad, cleanText(html), function(e){
+ if(e){
+ callback(new customError("HTML is malformed","apierror"));
+ return;
+ }else{
+ //update the clients on the pad
+ padMessageHandler.updatePadClients(pad, callback);
+ return;
+ }
+ });
});
}
diff --git a/src/node/handler/ExportHandler.js b/src/node/handler/ExportHandler.js
index 0a0e51f1c..0654deb4d 100644
--- a/src/node/handler/ExportHandler.js
+++ b/src/node/handler/ExportHandler.js
@@ -158,8 +158,12 @@ exports.doExport = function(req, res, padId, type)
//if this is a html export, we can send this from here directly
if(type == "html")
{
- res.send(html);
- callback("stop");
+ // do any final changes the plugin might want to make cake
+ hooks.aCallFirst("exportHTMLSend", html, function(err, newHTML){
+ if(newHTML.length) html = newHTML;
+ res.send(html);
+ callback("stop");
+ });
}
else //write the html export to a file
{
diff --git a/src/node/handler/ImportHandler.js b/src/node/handler/ImportHandler.js
index a511637cc..676986510 100644
--- a/src/node/handler/ImportHandler.js
+++ b/src/node/handler/ImportHandler.js
@@ -232,11 +232,9 @@ exports.doImport = function(req, res, padId)
if(!directDatabaseAccess){
var fileEnding = path.extname(srcFile).toLowerCase();
if (abiword || fileEnding == ".htm" || fileEnding == ".html") {
- try{
- importHtml.setPadHTML(pad, text);
- }catch(e){
- apiLogger.warn("Error importing, possibly caused by malformed HTML");
- }
+ importHtml.setPadHTML(pad, text, function(e){
+ if(e) apiLogger.warn("Error importing, possibly caused by malformed HTML");
+ });
} else {
pad.setText(text);
}
diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js
index 3228330e3..7ea5039d8 100644
--- a/src/node/handler/PadMessageHandler.js
+++ b/src/node/handler/PadMessageHandler.js
@@ -257,11 +257,10 @@ exports.handleMessage = function(client, message)
// FIXME: Use a hook instead
// FIXME: Allow to override readwrite access with readonly
- // FIXME: A message might arrive but wont have an auth object, this is obviously bad so we should deny it
// Simulate using the load testing tool
if(!sessioninfos[client.id].auth){
console.error("Auth was never applied to a session. If you are using the stress-test tool then restart Etherpad and the Stress test tool.")
- callback();
+ return;
}else{
var auth = sessioninfos[client.id].auth;
var checkAccessCallback = function(err, statusObject)
diff --git a/src/node/hooks/express/adminplugins.js b/src/node/hooks/express/adminplugins.js
index 8e372f1c0..34eafd0be 100644
--- a/src/node/hooks/express/adminplugins.js
+++ b/src/node/hooks/express/adminplugins.js
@@ -83,7 +83,7 @@ exports.socketio = function (hook_name, args, cb) {
socket.on("install", function (plugin_name) {
installer.install(plugin_name, function (er) {
if(er) console.warn(er)
- socket.emit("finished:install", {plugin: plugin_name, error: er? er.message : null});
+ socket.emit("finished:install", {plugin: plugin_name, code: er? er.code : null, error: er? er.message : null});
});
});
diff --git a/src/node/hooks/express/static.js b/src/node/hooks/express/static.js
index c6a227451..e5a2bff00 100644
--- a/src/node/hooks/express/static.js
+++ b/src/node/hooks/express/static.js
@@ -2,7 +2,7 @@ var minify = require('../../utils/Minify');
var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins");
var CachingMiddleware = require('../../utils/caching_middleware');
var settings = require("../../utils/Settings");
-var Yajsml = require('yajsml');
+var Yajsml = require('etherpad-yajsml');
var _ = require("underscore");
exports.expressCreateServer = function (hook_name, args, cb) {
diff --git a/src/node/utils/ExportEtherpad.js b/src/node/utils/ExportEtherpad.js
index 36df452da..4f91e4e39 100644
--- a/src/node/utils/ExportEtherpad.js
+++ b/src/node/utils/ExportEtherpad.js
@@ -48,6 +48,7 @@ exports.getPadRaw = function(padId, callback){
// Get the author info
db.get("globalAuthor:"+authorId, function(e, authorEntry){
+ authorEntry.padIDs = padId;
if(!e) data["globalAuthor:"+authorId] = authorEntry;
});
diff --git a/src/node/utils/ExportHelper.js b/src/node/utils/ExportHelper.js
index 3297c6d36..297c2d7a6 100644
--- a/src/node/utils/ExportHelper.js
+++ b/src/node/utils/ExportHelper.js
@@ -55,7 +55,7 @@ exports._analyzeLine = function(text, aline, apool){
var listType = Changeset.opAttributeValue(opIter.next(), 'list', apool);
if (listType){
lineMarker = 1;
- listType = /([a-z]+)([12345678])/.exec(listType);
+ listType = /([a-z]+)([0-9]+)/.exec(listType);
if (listType){
line.listTypeName = listType[1];
line.listLevel = Number(listType[2]);
diff --git a/src/node/utils/ExportHtml.js b/src/node/utils/ExportHtml.js
index c882e0ef6..9e1ba1249 100644
--- a/src/node/utils/ExportHtml.js
+++ b/src/node/utils/ExportHtml.js
@@ -30,8 +30,6 @@ function getPadHTML(pad, revNum, callback)
var html;
async.waterfall([
// fetch revision atext
-
-
function (callback)
{
if (revNum != undefined)
@@ -413,13 +411,16 @@ function getHTMLFromAtext(pad, atext, authorColors)
}
lists = []
- var lineContentFromHook = hooks.callAllStr("getLineHTMLForExport",
- {
+ var context = {
line: line,
+ lineContent: lineContent,
apool: apool,
attribLine: attribLines[i],
text: textLines[i]
- }, " ", " ", "");
+ }
+
+ var lineContentFromHook = hooks.callAllStr("getLineHTMLForExport", context, " ", " ", "");
+
if (lineContentFromHook)
{
pieces.push(lineContentFromHook, '');
@@ -470,7 +471,7 @@ exports.getPadHTMLDocument = function (padId, revNum, noDocType, callback)
'ul.indent { list-style-type: none; }' +
'ol { list-style-type: none; padding-left:0;}' +
- 'body > ol { counter-reset: first second; }' +
+ '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;}' +
@@ -504,15 +505,15 @@ exports.getPadHTMLDocument = function (padId, revNum, noDocType, callback)
'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(eight) "." counter(ninth) ". ";'+
+ '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(eighth) "." counter(ninth) "." counter(tenth) ". ";'+
+ '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(eighth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) ". ";'+
+ '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 {' +
diff --git a/src/node/utils/ImportEtherpad.js b/src/node/utils/ImportEtherpad.js
index 8daeb5363..1574a3a9d 100644
--- a/src/node/utils/ImportEtherpad.js
+++ b/src/node/utils/ImportEtherpad.js
@@ -24,12 +24,25 @@ exports.setPadRaw = function(padId, records, callback){
async.eachSeries(Object.keys(records), function(key, cb){
var value = records[key]
- // we know its an author
+ // Author data
if(value.padIDs){
// rewrite author pad ids
value.padIDs[padId] = 1;
var newKey = key;
+ // Does this author already exist?
+ db.get(key, function(err, author){
+ if(author){
+ // Yes, add the padID to the author..
+ author.padIDs.push(padId);
+ value = author;
+ }else{
+ // No, create a new array with the author info in
+ value.padIDs = [padId];
+ }
+ });
+
+ // Not author data, probably pad data
}else{
// we can split it to look to see if its pad data
var oldPadId = key.split(":");
diff --git a/src/node/utils/ImportHtml.js b/src/node/utils/ImportHtml.js
index 59802f9bf..33fd91c65 100644
--- a/src/node/utils/ImportHtml.js
+++ b/src/node/utils/ImportHtml.js
@@ -40,7 +40,7 @@ function setPadHTML(pad, html, callback)
cc.collectContent(doc);
}catch(e){
apiLogger.warn("HTML was not properly formed", e);
- return; // We don't process the HTML because it was bad..
+ return callback(e); // We don't process the HTML because it was bad..
}
var result = cc.finish();
@@ -91,6 +91,7 @@ function setPadHTML(pad, html, callback)
apiLogger.debug('The changeset: ' + theChangeset);
pad.setText("");
pad.appendRevision(theChangeset);
+ callback(null);
}
exports.setPadHTML = setPadHTML;
diff --git a/src/node/utils/Settings.js b/src/node/utils/Settings.js
index af7ede811..05ae3bd84 100644
--- a/src/node/utils/Settings.js
+++ b/src/node/utils/Settings.js
@@ -236,6 +236,19 @@ exports.reloadSettings = function reloadSettings() {
process.env['DEBUG'] = 'socket.io:' + exports.loglevel; // Used by SocketIO for Debug
log4js.replaceConsole();
+ if(exports.abiword){
+ // Check abiword actually exists
+ if(exports.abiword != null)
+ {
+ fs.exists(exports.abiword, function(exists) {
+ if (!exists) {
+ console.error("Abiword does not exist at this path, check your settings file");
+ exports.abiword = null;
+ }
+ });
+ }
+ }
+
if(!exports.sessionKey){ // If the secretKey isn't set we also create yet another unique value here
exports.sessionKey = randomString(32);
console.warn("You need to set a sessionKey value in settings.json, this will allow your users to reconnect to your Etherpad Instance if your instance restarts");
diff --git a/src/package.json b/src/package.json
index b92477d66..0598a4b60 100644
--- a/src/package.json
+++ b/src/package.json
@@ -1,48 +1,49 @@
{
"name" : "ep_etherpad-lite",
"description" : "A Etherpad based on node.js",
- "homepage" : "https://github.com/ether/etherpad-lite",
+ "homepage" : "http://etherpad.org",
"keywords" : ["etherpad", "realtime", "collaborative", "editor"],
- "author" : "Peter 'Pita' Martischka - Primary Technology Ltd",
+ "author" : "Etherpad Foundation",
"contributors" : [
{ "name": "John McLear" },
{ "name": "Hans Pinckaers" },
{ "name": "Robin Buse" },
- { "name": "Marcel Klehr" }
+ { "name": "Marcel Klehr" },
+ { "name": "Peter Martischka" }
],
"dependencies" : {
- "yajsml" : "1.1.6",
- "request" : ">=2.48.0",
- "etherpad-require-kernel" : ">=1.0.7",
- "resolve" : ">=1.0.0",
- "socket.io" : ">=1.2.0",
- "ueberDB" : ">=0.2.9",
- "express" : ">3.1.0 <3.9.0",
- "async" : ">=0.9.0",
- "connect" : "2.7.x",
+ "etherpad-yajsml" : "0.0.2",
+ "request" : "2.51.0",
+ "etherpad-require-kernel" : "1.0.7",
+ "resolve" : "1.0.0",
+ "socket.io" : "1.3.2",
+ "ueberDB" : "0.2.11",
+ "express" : "3.8.1",
+ "async" : "0.9.0",
+ "connect" : "2.7.11",
"clean-css" : "0.3.2",
- "uglify-js" : ">=2.4.15",
- "formidable" : ">=1.0.15",
- "log4js" : ">=0.6.21",
- "nodemailer" : "0.3.x",
- "cheerio" : ">=0.18.0",
- "async-stacktrace" : ">=0.0.2",
- "npm" : ">=2.1.x",
- "ejs" : ">=1.0.0",
- "graceful-fs" : ">=3.0.4",
- "slide" : ">=1.1.6",
- "semver" : ">=2.3.0",
+ "uglify-js" : "2.4.16",
+ "formidable" : "1.0.16",
+ "log4js" : "0.6.22",
+ "nodemailer" : "0.3.44",
+ "cheerio" : "0.18.0",
+ "async-stacktrace" : "0.0.2",
+ "npm" : "2.2.0",
+ "ejs" : "1.0.0",
+ "graceful-fs" : "3.0.5",
+ "slide" : "1.1.6",
+ "semver" : "4.2.0",
"security" : "1.0.0",
- "tinycon" : ">=0.0.1",
+ "tinycon" : "0.0.1",
"underscore" : "1.5.1",
- "unorm" : ">=1.3.3",
- "languages4translatewiki" : ">=0.1.3",
- "swagger-node-express" : ">=2.1.0",
- "channels" : "0.0.x",
- "jsonminify" : ">=0.2.3",
- "measured" : ">=0.1.6",
- "mocha" : ">=2.0.1",
- "supertest" : ">=0.15.0"
+ "unorm" : "1.3.3",
+ "languages4translatewiki" : "0.1.3",
+ "swagger-node-express" : "2.1.3",
+ "channels" : "0.0.4",
+ "jsonminify" : "0.2.3",
+ "measured" : "0.1.6",
+ "mocha" : "2.1.0",
+ "supertest" : "0.15.0"
},
"bin": { "etherpad-lite": "./node/server.js" },
"devDependencies": {
@@ -54,5 +55,5 @@
"repository" : { "type" : "git",
"url" : "http://github.com/ether/etherpad-lite.git"
},
- "version" : "1.5.0"
+ "version" : "1.5.1"
}
diff --git a/src/static/css/pad.css b/src/static/css/pad.css
index 4ba9f5750..70c15b515 100644
--- a/src/static/css/pad.css
+++ b/src/static/css/pad.css
@@ -914,6 +914,36 @@ input[type=checkbox] {
border-left: 1px solid #ccc !important;
width: 185px !important;
}
+.chatAndUsers{
+ display:block !important;
+ right:0px !important;
+ border-radius:0px !important;
+ width:182px !important;
+ margin:2px 0 0 0 !important;
+ border: none !important;
+ border-bottom: 1px solid #ccc !important;
+ height:155px !important;
+ border-left: 1px solid #ccc !important;
+}
+.chatAndUsers > #otherusers{
+ max-height: 100px;
+ overflow-y: auto;
+}
+.chatAndUsersChat > div > #titlecross{
+ display:none;
+}
+.chatAndUsersChat{
+ bottom:0px !important;
+ padding:0 !important;
+ margin:0 !important;
+ right:0 !important;
+ top: 200px !important;
+ width:182px !important;
+ border: none !important;
+ padding:5px !important;
+ border-left: 1px solid #ccc !important;
+}
+
@media screen and (max-width: 600px) {
.toolbar ul li.separator {
display: none;
diff --git a/src/static/css/timeslider.css b/src/static/css/timeslider.css
index 4c84a7fcc..49f894210 100644
--- a/src/static/css/timeslider.css
+++ b/src/static/css/timeslider.css
@@ -154,11 +154,17 @@ stepper:active{
top: 20px;
width: 25px;
}
+.star:before{
+ font-family: fontawesome-etherpad;
+ content: "\e835";
+ vertical-align:middle;
+ font-size:16px;
+}
#timeslider .star {
cursor: pointer;
height: 16px;
position: absolute;
- top: 40px;
+ top: 25px;
width: 15px;
}
#timeslider #timer {
diff --git a/src/static/favicon.ico b/src/static/favicon.ico
index df7b62899..938e95502 100644
Binary files a/src/static/favicon.ico and b/src/static/favicon.ico differ
diff --git a/src/static/js/AttributeManager.js b/src/static/js/AttributeManager.js
index a11f6cef6..974d8ad91 100644
--- a/src/static/js/AttributeManager.js
+++ b/src/static/js/AttributeManager.js
@@ -164,12 +164,20 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
var builder = Changeset.builder(this.rep.lines.totalWidth());
var hasMarker = this.lineHasMarker(lineNum);
var attribs
+ var foundAttrib = false
attribs = this.getAttributesOnLine(lineNum).map(function(attrib) {
- if(attrib[0] === attributeName) return [attributeName, null]
+ if(attrib[0] === attributeName) {
+ foundAttrib = true
+ return [attributeName, null] // remove this attrib from the linemarker
+ }
return attrib
})
+ if(!foundAttrib) {
+ return
+ }
+
if(hasMarker){
ChangesetUtils.buildKeepRange(this.rep, builder, loc, (loc = [lineNum, 0]));
// If length == 4, there's [author, lmkr, insertorder, + the attrib being removed] thus we can remove the marker entirely
diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js
index 86f69bab9..4b84e784d 100644
--- a/src/static/js/ace2_inner.js
+++ b/src/static/js/ace2_inner.js
@@ -21,6 +21,17 @@
*/
var _, $, jQuery, plugins, Ace2Common;
+var browser = require('./browser').browser;
+if(browser.msie){
+ // Honestly fuck IE royally.
+ // Basically every hack we have since V11 causes a problem
+ if(parseInt(browser.version) >= 11){
+ delete browser.msie;
+ browser.chrome = true;
+ browser.modernIE = true;
+ }
+}
+
Ace2Common = require('./ace2_common');
plugins = require('ep_etherpad-lite/static/js/pluginfw/client_plugins');
@@ -34,8 +45,7 @@ var isNodeText = Ace2Common.isNodeText,
binarySearchInfinite = Ace2Common.binarySearchInfinite,
htmlPrettyEscape = Ace2Common.htmlPrettyEscape,
noop = Ace2Common.noop;
- var hooks = require('./pluginfw/hooks');
- var browser = require('./browser').browser;
+var hooks = require('./pluginfw/hooks');
function Ace2Inner(){
@@ -1353,7 +1363,7 @@ function Ace2Inner(){
// (from how it looks in our representation) and record them in a way
// that can be used to "normalize" the document (apply the changes to our
// representation, and put the DOM in a canonical form).
- //top.console.log("observeChangesAroundNode(%o)", node);
+ // top.console.log("observeChangesAroundNode(%o)", node);
var cleanNode;
var hasAdjacentDirtyness;
if (!isNodeDirty(node))
@@ -1605,7 +1615,7 @@ function Ace2Inner(){
if (linesWrapped > 0)
{
- if(!browser.ie){
+ if(!browser.msie){
// chrome decides in it's infinite wisdom that its okay to put the browsers visisble window in the middle of the span
// an outcome of this is that the first chars of the string are no longer visible to the user.. Yay chrome..
// Move the browsers visible area to the left hand side of the span
@@ -1910,6 +1920,7 @@ function Ace2Inner(){
if (charsLeft === 0)
{
var index = 0;
+ browser.msie = false; // Temp fix to resolve enter and backspace issues..
if (browser.msie && line == (rep.lines.length() - 1) && lineNode.childNodes.length === 0)
{
// best to stay at end of last empty div in IE
@@ -2959,7 +2970,6 @@ function Ace2Inner(){
{
return "";
};
-
return result;
}
else
@@ -3583,7 +3593,7 @@ function Ace2Inner(){
// On Mac and Linux, move right moves to end of word and move left moves to start;
// on Windows, always move to start of word.
// On Windows, Firefox and IE disagree on whether to stop for punctuation (FF says no).
- if (browser.windows && forwardNotBack)
+ if (browser.msie && forwardNotBack)
{
while ((!isDone()) && isWordChar(nextChar()))
{
@@ -3624,7 +3634,6 @@ function Ace2Inner(){
evt.preventDefault();
return;
}
-
// Is caret potentially hidden by the chat button?
var myselection = document.getSelection(); // get the current caret selection
var caretOffsetTop = myselection.focusNode.parentNode.offsetTop | myselection.focusNode.offsetTop; // get the carets selection offset in px IE 214
@@ -3662,7 +3671,6 @@ function Ace2Inner(){
var specialHandled = false;
var isTypeForSpecialKey = ((browser.msie || browser.safari || browser.chrome) ? (type == "keydown") : (type == "keypress"));
var isTypeForCmdKey = ((browser.msie || browser.safari || browser.chrome) ? (type == "keydown") : (type == "keypress"));
-
var stopped = false;
inCallStackIfNecessary("handleKeyEvent", function()
@@ -3867,7 +3875,10 @@ function Ace2Inner(){
updateBrowserSelectionFromRep();
var myselection = document.getSelection(); // get the current caret selection, can't use rep. here because that only gives us the start position not the current
var caretOffsetTop = myselection.focusNode.parentNode.offsetTop || myselection.focusNode.offsetTop; // get the carets selection offset in px IE 214
- // top.console.log(caretOffsetTop);
+
+ // sometimes the first selection is -1 which causes problems (Especially with ep_page_view)
+ // so use focusNode.offsetTop value.
+ if(caretOffsetTop === -1) caretOffsetTop = myselection.focusNode.offsetTop;
setScrollY(caretOffsetTop); // set the scrollY offset of the viewport on the document
}, 200);
@@ -3909,10 +3920,10 @@ function Ace2Inner(){
// only move the viewport if we're at the bottom of the viewport, if we hit down any other time the viewport shouldn't change
// NOTE: This behavior only fires if Chrome decides to break the page layout after a paste, it's annoying but nothing I can do
var selection = getSelection();
- top.console.log("line #", rep.selStart[0]); // the line our caret is on
- top.console.log("firstvisible", visibleLineRange[0]); // the first visiblel ine
- top.console.log("lastVisible", visibleLineRange[1]); // the last visible line
- top.console.log(rep.selStart[0], visibleLineRange[1], rep.selStart[0], visibleLineRange[0]);
+ // top.console.log("line #", rep.selStart[0]); // the line our caret is on
+ // top.console.log("firstvisible", visibleLineRange[0]); // the first visiblel ine
+ // top.console.log("lastVisible", visibleLineRange[1]); // the last visible line
+ // top.console.log(rep.selStart[0], visibleLineRange[1], rep.selStart[0], visibleLineRange[0]);
var newY = viewport.top + lineHeight;
}
if(newY){
@@ -3946,7 +3957,7 @@ function Ace2Inner(){
}
// Is part of multi-keystroke international character on Firefox Mac
- var isFirefoxHalfCharacter = (browser.mozilla && evt.altKey && charCode === 0 && keyCode === 0);
+ var isFirefoxHalfCharacter = (browser.firefox && evt.altKey && charCode === 0 && keyCode === 0);
// Is part of multi-keystroke international character on Safari Mac
var isSafariHalfCharacter = (browser.safari && evt.altKey && keyCode == 229);
@@ -4261,12 +4272,6 @@ function Ace2Inner(){
end.collapse(false);
selection.startPoint = pointFromCollapsedRange(start);
selection.endPoint = pointFromCollapsedRange(end);
-/*if ((!selection.startPoint.node.isText) && (!selection.endPoint.node.isText)) {
- console.log(selection.startPoint.node.uniqueId()+","+
- selection.startPoint.index+" / "+
- selection.endPoint.node.uniqueId()+","+
- selection.endPoint.index);
-}*/
}
return selection;
}
@@ -4678,7 +4683,7 @@ function Ace2Inner(){
setIfNecessary(iframe.style, "width", newWidth + "px");
setIfNecessary(sideDiv.style, "height", newHeight + "px");
}
- if (browser.mozilla)
+ if (browser.firefox)
{
if (!doesWrap)
{
@@ -4855,8 +4860,16 @@ function Ace2Inner(){
$(document).on("click", handleIEOuterClick);
}
if (browser.msie) $(root).on("paste", handleIEPaste);
+
+ // Don't paste on middle click of links
+ $(root).on("paste", function(e){
+ if(e.target.a){
+ e.preventDefault();
+ }
+ })
+
// CompositionEvent is not implemented below IE version 8
- if ( !(browser.msie && browser.version < 9) && document.documentElement)
+ if ( !(browser.msie && parseInt(browser.version <= 9)) && document.documentElement)
{
$(document.documentElement).on("compositionstart", handleCompositionEvent);
$(document.documentElement).on("compositionend", handleCompositionEvent);
@@ -5095,7 +5108,7 @@ function Ace2Inner(){
{
return null;
}
- type = /([a-z]+)[0-9+]/.exec(type);
+ type = /([a-z]+)[0-9]+/.exec(type);
if(type[1] == "indent")
{
return null;
@@ -5104,7 +5117,7 @@ function Ace2Inner(){
//2-find the first line of the list
while(lineNum-1 >= 0 && (type=getLineListType(lineNum-1)))
{
- type = /([a-z]+)[0-9+]/.exec(type);
+ type = /([a-z]+)[0-9]+/.exec(type);
if(type[1] == "indent")
break;
lineNum--;
@@ -5124,7 +5137,7 @@ function Ace2Inner(){
while(listType = getLineListType(line))
{
//apply new num
- listType = /([a-z]+)([0-9+])/.exec(listType);
+ listType = /([a-z]+)([0-9]+)/.exec(listType);
curLevel = Number(listType[2]);
if(isNaN(curLevel) || listType[0] == "indent")
{
@@ -5319,20 +5332,9 @@ function Ace2Inner(){
{
var body = doc.getElementById("innerdocbody");
root = body; // defined as a var in scope outside
- if (browser.mozilla) $(root).addClass("mozilla");
+ if (browser.firefox) $(root).addClass("mozilla");
if (browser.safari) $(root).addClass("safari");
if (browser.msie) $(root).addClass("msie");
- if (browser.msie)
- {
- // cache CSS background images
- try
- {
- doc.execCommand("BackgroundImageCache", false, true);
- }
- catch (e)
- { /* throws an error in some IE 6 but not others! */
- }
- }
setClassPresence(root, "authorColors", true);
setClassPresence(root, "doesWrap", doesWrap);
diff --git a/src/static/js/admin/plugins.js b/src/static/js/admin/plugins.js
index 8a4c732e5..d337da03a 100644
--- a/src/static/js/admin/plugins.js
+++ b/src/static/js/admin/plugins.js
@@ -26,12 +26,11 @@ $(document).ready(function () {
$('#search-progress').show()
search.messages.show('fetching')
- storeScrollPosition()
search.searching = true
}
search.searching = false;
search.offset = 0;
- search.limit = 25;
+ search.limit = 999;
search.results = [];
search.sortBy = 'name';
search.sortDir = /*DESC?*/true;
@@ -43,7 +42,7 @@ $(document).ready(function () {
$('.search-results .messages .'+msg+' *').show()
},
hide: function(msg) {
- //$('.search-results .messages').hide()
+ $('.search-results .messages').hide()
$('.search-results .messages .'+msg+'').hide()
$('.search-results .messages .'+msg+' *').hide()
}
@@ -104,33 +103,16 @@ $(document).ready(function () {
})
}
- // Infinite scroll
- var scrollPosition
- function storeScrollPosition() {
- scrollPosition = $(window).scrollTop()
- }
- function restoreScrollPosition() {
- setTimeout(function() {
- $(window).scrollTop(scrollPosition)
- }, 0)
- }
-
- $(window).scroll(checkInfiniteScroll)
- function checkInfiniteScroll() {
- if(search.end || search.searching) return;// don't keep requesting if there are no more results
- setTimeout(function() {
- try{
- var top = $('.results>tr:last').offset().top
- if($(window).scrollTop()+$(window).height() > top) search(search.searchTerm)
- }catch(e){}
- }, 1)
- }
-
function updateHandlers() {
// Search
$("#search-query").unbind('keyup').keyup(function () {
search($("#search-query").val());
});
+
+ // Prevent form submit
+ $('#search-query').parent().bind('submit', function() {
+ return false;
+ });
// update & install
$(".do-install, .do-update").unbind('click').click(function (e) {
@@ -159,14 +141,14 @@ $(document).ready(function () {
// Sort
$('.sort.up').unbind('click').click(function() {
- search.sortBy = $(this).text().toLowerCase();
+ search.sortBy = $(this).attr('data-label').toLowerCase();
search.sortDir = false;
search.offset = 0;
search(search.searchTerm, search.results.length);
search.results = [];
})
$('.sort.down, .sort.none').unbind('click').click(function() {
- search.sortBy = $(this).text().toLowerCase();
+ search.sortBy = $(this).attr('data-label').toLowerCase();
search.sortDir = true;
search.offset = 0;
search(search.searchTerm, search.results.length);
@@ -176,6 +158,7 @@ $(document).ready(function () {
socket.on('results:search', function (data) {
if(!data.results.length) search.end = true;
+ if(data.query.offset == 0) search.results = [];
search.messages.hide('nothing-found')
search.messages.hide('fetching')
$("#search-query").removeAttr('disabled')
@@ -203,8 +186,6 @@ $(document).ready(function () {
}
search.messages.hide('fetching')
$('#search-progress').hide()
- restoreScrollPosition()
- checkInfiniteScroll()
search.searching = false
});
@@ -244,6 +225,9 @@ $(document).ready(function () {
socket.on('finished:install', function(data) {
if(data.error) {
+ 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)
$('#installed-plugins .'+data.plugin).remove()
}
diff --git a/src/static/js/broadcast.js b/src/static/js/broadcast.js
index a25d889b9..817155b55 100644
--- a/src/static/js/broadcast.js
+++ b/src/static/js/broadcast.js
@@ -66,18 +66,6 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
}
}
- // for IE
- if (browser.msie)
- {
- try
- {
- document.execCommand("BackgroundImageCache", false, true);
- }
- catch (e)
- {}
- }
-
-
//var socket;
var channelState = "DISCONNECTED";
diff --git a/src/static/js/chat.js b/src/static/js/chat.js
index 4cbbbaa78..ce9a00337 100644
--- a/src/static/js/chat.js
+++ b/src/static/js/chat.js
@@ -22,6 +22,7 @@ var hooks = require('./pluginfw/hooks');
var chat = (function()
{
var isStuck = false;
+ var userAndChat = false;
var gotInitialMessages = false;
var historyPointer = 0;
var chatMentions = 0;
@@ -54,6 +55,23 @@ var chat = (function()
isStuck = false;
}
},
+ chatAndUsers: function(fromInitialCall)
+ {
+ if(!userAndChat || fromInitialCall){
+ padcookie.setPref("chatAndUsers", true);
+ chat.stickToScreen(true);
+ $('#options-stickychat').prop('checked', true)
+ $('#options-stickychat').prop("disabled", "disabled");
+ $('#users').addClass("chatAndUsers");
+ $("#chatbox").addClass("chatAndUsersChat");
+ userAndChat = true;
+ }else{
+ padcookie.setPref("chatAndUsers", false);
+ $('#options-stickychat').prop("disabled", false);
+ $('#users').removeClass("chatAndUsers");
+ $("#chatbox").removeClass("chatAndUsersChat");
+ }
+ },
hide: function ()
{
// decide on hide logic based on chat window being maximized or not
diff --git a/src/static/js/collab_client.js b/src/static/js/collab_client.js
index 6089f1972..e5c0ec8b2 100644
--- a/src/static/js/collab_client.js
+++ b/src/static/js/collab_client.js
@@ -81,8 +81,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
onServerMessage: function()
{}
};
-
- if (browser.mozilla)
+ if (browser.firefox)
{
// Prevent "escape" from taking effect and canceling a comet connection;
// doesn't work if focus is on an iframe.
diff --git a/src/static/js/contentcollector.js b/src/static/js/contentcollector.js
index e90783ae0..1f0620fef 100644
--- a/src/static/js/contentcollector.js
+++ b/src/static/js/contentcollector.js
@@ -23,7 +23,7 @@
* limitations under the License.
*/
-var _MAX_LIST_LEVEL = 8;
+var _MAX_LIST_LEVEL = 16;
var UNorm = require('unorm');
var Changeset = require('./Changeset');
@@ -35,9 +35,10 @@ function sanitizeUnicode(s)
return UNorm.nfc(s);
}
-function makeContentCollector(collectStyles, browser, apool, domInterface, className2Author)
+function makeContentCollector(collectStyles, abrowser, apool, domInterface, className2Author)
{
- browser = browser || {};
+ abrowser = abrowser || {};
+ // I don't like the above.
var dom = domInterface || {
isNodeText: function(n)
@@ -484,7 +485,7 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class
var cls = dom.nodeProp(node, "className");
var isPre = (tname == "pre");
- if ((!isPre) && browser.safari)
+ if ((!isPre) && abrowser.safari)
{
isPre = (styl && /\bwhite-space:\s*pre\b/i.exec(styl));
}
@@ -523,7 +524,7 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class
}else{
var type = null;
}
- var rr = cls && /(?:^| )list-([a-z]+[12345678])\b/.exec(cls);
+ var rr = cls && /(?:^| )list-([a-z]+[0-9]+)\b/.exec(cls);
// lists do not need to have a type, so before we make a wrong guess, check if we find a better hint within the node's children
if(!rr && !type){
for (var i in node.children){
@@ -538,7 +539,16 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class
if(rr && rr[1]){
type = rr[1]
} else {
- type = (tname == "ul" ? (type.match("indent") || node.attribs.class && node.attribs.class.match("indent") ? "indent" : "bullet") : "number") + String(Math.min(_MAX_LIST_LEVEL, (state.listNesting || 0) + 1));
+ if(tname == "ul"){
+ if((type && type.match("indent")) || (node.attribs && node.attribs.class && node.attribs.class.match("indent"))){
+ type = "indent"
+ } else {
+ type = "bullet"
+ }
+ } else {
+ type = "number"
+ }
+ type = type + String(Math.min(_MAX_LIST_LEVEL, (state.listNesting || 0) + 1));
}
oldListTypeOrNull = (_enterList(state, type) || 'none');
}
@@ -601,7 +611,7 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class
}
}
}
- if (!browser.msie)
+ if (!abrowser.msie)
{
_reachBlockPoint(node, 1, state);
}
@@ -616,13 +626,11 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class
_ensureColumnZero(state);
}
}
-
- if (browser.msie)
+ if (abrowser.msie)
{
// in IE, a point immediately after a DIV appears on the next line
_reachBlockPoint(node, 1, state);
}
-
state.localAttribs = localAttribs;
};
// can pass a falsy value for end of doc
diff --git a/src/static/js/domline.js b/src/static/js/domline.js
index b1927b162..03f1b9c89 100644
--- a/src/static/js/domline.js
+++ b/src/static/js/domline.js
@@ -65,7 +65,6 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
lineMarker: 0
};
- var browser = (optBrowser || {});
var document = optDocument;
if (document)
@@ -93,8 +92,10 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
var perTextNodeProcess = (doesWrap ? _.identity : processSpaces);
var perHtmlLineProcess = (doesWrap ? processSpaces : _.identity);
var lineClass = 'ace-line';
+
result.appendSpan = function(txt, cls)
{
+
var processedMarker = false;
// Handle lineAttributeMarker, if present
if (cls.indexOf(lineAttributeMarker) >= 0)
@@ -225,7 +226,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
{
newHTML += ' ';
}
- else if (!browser.msie)
+ else if (!optBrowser.msie)
{
newHTML += ' ';
}
diff --git a/src/static/js/linestylefilter.js b/src/static/js/linestylefilter.js
index 675f19d02..17ab993b1 100644
--- a/src/static/js/linestylefilter.js
+++ b/src/static/js/linestylefilter.js
@@ -318,20 +318,20 @@ linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt)
return spanHandler;
};
-linestylefilter.getFilterStack = function(lineText, textAndClassFunc, browser)
+linestylefilter.getFilterStack = function(lineText, textAndClassFunc, abrowser)
{
var func = linestylefilter.getURLFilter(lineText, textAndClassFunc);
var hookFilters = hooks.callAll("aceGetFilterStack", {
linestylefilter: linestylefilter,
- browser: browser
+ browser: abrowser
});
_.map(hookFilters ,function(hookFilter)
{
func = hookFilter(lineText, func);
});
- if (browser !== undefined && browser.msie)
+ if (abrowser !== undefined && abrowser.msie)
{
// IE7+ will take an e-mail address like and linkify it to foo@bar.com.
// We then normalize it back to text with no angle brackets. It's weird. So always
diff --git a/src/static/js/pad.js b/src/static/js/pad.js
index ff62f86cc..77bfab7f1 100644
--- a/src/static/js/pad.js
+++ b/src/static/js/pad.js
@@ -120,6 +120,7 @@ var getParameters = [
{ name: "userColor", checkVal: null, callback: function(val) { settings.globalUserColor = decodeURIComponent(val); } },
{ name: "rtl", checkVal: "true", callback: function(val) { settings.rtlIsTrue = true } },
{ name: "alwaysShowChat", checkVal: "true", callback: function(val) { chat.stickToScreen(); } },
+ { name: "chatAndUsers", checkVal: "true", callback: function(val) { chat.chatAndUsers(); } },
{ name: "lang", checkVal: null, callback: function(val) { window.html10n.localize([val, 'en']); } }
];
@@ -494,7 +495,7 @@ var pad = {
pad.initTime = +(new Date());
pad.padOptions = clientVars.initialOptions;
- if ((!browser.msie) && (!(browser.mozilla && browser.version.indexOf("1.8.") == 0)))
+ if ((!browser.msie) && (!(browser.firefox && browser.version.indexOf("1.8.") == 0)))
{
document.domain = document.domain; // for comet
}
@@ -562,6 +563,10 @@ var pad = {
chat.stickToScreen(true); // stick it to the screen
$('#options-stickychat').prop("checked", true); // set the checkbox to on
}
+ if(padcookie.getPref("chatAndUsers")){ // if we have a cookie for always showing chat then show it
+ chat.chatAndUsers(true); // stick it to the screen
+ $('#options-chatandusers').prop("checked", true); // set the checkbox to on
+ }
if(padcookie.getPref("showAuthorshipColors") == false){
pad.changeViewOption('showAuthorColors', false);
}
@@ -779,6 +784,7 @@ var pad = {
handleIsFullyConnected: function(isConnected, isInitialConnect)
{
pad.determineChatVisibility(isConnected && !isInitialConnect);
+ pad.determineChatAndUsersVisibility(isConnected && !isInitialConnect);
pad.determineAuthorshipColorsVisibility();
},
determineChatVisibility: function(asNowConnectedFeedback){
@@ -791,6 +797,16 @@ var pad = {
$('#options-stickychat').prop("checked", false); // set the checkbox for off
}
},
+ determineChatAndUsersVisibility: function(asNowConnectedFeedback){
+ var chatAUVisCookie = padcookie.getPref('chatAndUsersVisible');
+ if(chatAUVisCookie){ // if the cookie is set for chat always visible
+ chat.chatAndUsers(true); // stick it to the screen
+ $('#options-chatandusers').prop("checked", true); // set the checkbox to on
+ }
+ else{
+ $('#options-chatandusers').prop("checked", false); // set the checkbox for off
+ }
+ },
determineAuthorshipColorsVisibility: function(){
var authColCookie = padcookie.getPref('showAuthorshipColors');
if (authColCookie){
diff --git a/src/static/js/pad_savedrevs.js b/src/static/js/pad_savedrevs.js
index e1552c27c..34323b22f 100644
--- a/src/static/js/pad_savedrevs.js
+++ b/src/static/js/pad_savedrevs.js
@@ -18,7 +18,16 @@ var pad;
exports.saveNow = function(){
pad.collabClient.sendMessage({"type": "SAVE_REVISION"});
- alert(_("pad.savedrevs.marked"));
+ $.gritter.add({
+ // (string | mandatory) the heading of the notification
+ title: _("pad.savedrevs.marked"),
+ // (string | mandatory) the text inside the notification
+ text: _("pad.savedrevs.timeslider") || "You can view saved revisions in the timeslider",
+ // (bool | optional) if you want it to fade out on its own or just sit there
+ sticky: false,
+ // (int | optional) the time you want it to be alive for before fading out
+ time: '2000'
+ });
}
exports.init = function(_pad){
diff --git a/src/static/js/pluginfw/installer.js b/src/static/js/pluginfw/installer.js
index 90bd9aa27..cd2ed3305 100644
--- a/src/static/js/pluginfw/installer.js
+++ b/src/static/js/pluginfw/installer.js
@@ -61,7 +61,7 @@ exports.availablePlugins = null;
var cacheTimestamp = 0;
exports.getAvailablePlugins = function(maxCacheAge, cb) {
- request("http://etherpad.org/plugins.json", function(er, response, plugins){
+ request("https://static.etherpad.org/plugins.json", function(er, response, plugins){
if (er) return cb && cb(er);
if(exports.availablePlugins && maxCacheAge && Math.round(+new Date/1000)-cacheTimestamp <= maxCacheAge) {
return cb && cb(null, exports.availablePlugins)
diff --git a/src/static/js/timeslider.js b/src/static/js/timeslider.js
index b3c10b8a3..ec237df5e 100644
--- a/src/static/js/timeslider.js
+++ b/src/static/js/timeslider.js
@@ -62,8 +62,8 @@ function init() {
var resource = exports.baseURL.substring(1) + 'socket.io';
//build up the socket io connection
- socket = io.connect(url, {resource: resource});
-
+ socket = io.connect(url, {path: exports.baseURL + 'socket.io', resource: resource});
+
//send the ready message once we're connected
socket.on('connect', function()
{
diff --git a/src/templates/admin/plugins.html b/src/templates/admin/plugins.html
index 96ed08fbe..71c4dbcc5 100644
--- a/src/templates/admin/plugins.html
+++ b/src/templates/admin/plugins.html
@@ -78,6 +78,7 @@
diff --git a/tests/backend/specs/api/pad.js b/tests/backend/specs/api/pad.js
index 52e7c9170..6010a11ce 100644
--- a/tests/backend/specs/api/pad.js
+++ b/tests/backend/specs/api/pad.js
@@ -12,6 +12,7 @@ var apiVersion = 1;
var testPadId = makeid();
var lastEdited = "";
var text = generateLongText();
+var ULhtml = '
one
2
UL2
';
describe('Connectivity', function(){
it('errors if can not connect', function(done) {
@@ -71,6 +72,9 @@ describe('Permission', function(){
-> movePad(newPadID, originalPadId) -- Should provide consistant pad data
-> getText(originalPadId) -- Should be "hello world"
-> getLastEdited(padID) -- Should not be 0
+ -> setHTML(padID) -- Should fail on invalid HTML
+ -> setHTML(padID) *3 -- Should fail on invalid HTML
+ -> getHTML(padID) -- Should return HTML close to posted HTML
*/
@@ -390,6 +394,44 @@ describe('getLastEdited', function(){
});
})
+describe('setHTML', function(){
+ it('Sets the HTML of a Pad attempting to pass ugly HTML', function(done) {
+ var html = "
Hello HTML
";
+ api.get(endPoint('setHTML')+"&padID="+testPadId+"&html="+html)
+ .expect(function(res){
+console.log(res.body.code);
+ if(res.body.code !== 1) throw new Error("Allowing crappy HTML to be imported")
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('setHTML', function(){
+ it('Sets the HTML of a Pad with a bunch of weird unordered lists inserted', function(done) {
+ api.get(endPoint('setHTML')+"&padID="+testPadId+"&html="+ULhtml)
+ .expect(function(res){
+ if(res.body.code !== 0) throw new Error("List HTML cant be imported")
+ })
+ .expect('Content-Type', /json/)
+ .expect(200, done)
+ });
+})
+
+describe('getHTML', function(){
+ it('Gets the HTML of a Pad with a bunch of weird unordered lists inserted', function(done) {
+ api.get(endPoint('getHTML')+"&padID="+testPadId)
+ .expect(function(res){
+ var ehtml = res.body.data.html.replace("