From 8156930208c0a7d9a967528ca7dfbb5c7c8a4772 Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 26 Jan 2015 01:44:40 +0000 Subject: [PATCH 01/58] clean support for image hook --- src/static/js/contentcollector.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/static/js/contentcollector.js b/src/static/js/contentcollector.js index 1f0620fef..ca193f73e 100644 --- a/src/static/js/contentcollector.js +++ b/src/static/js/contentcollector.js @@ -458,6 +458,20 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas else { var tname = (dom.nodeTagName(node) || "").toLowerCase(); + + // Images shouldn't be defined as empty. + if (tname == "img"){ + isEmpty = false; + hooks.callAll('collectContentImage', { + cc: cc, + state: state, + tname: tname, + styl: styl, + cls: cls, + node: node + }); + } + if (tname == "br") { this.breakLine = true; From 18121a15071f775d6605719088ea147bb4cd1d14 Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 26 Jan 2015 02:32:58 +0000 Subject: [PATCH 02/58] much cleaner --- src/static/js/contentcollector.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/static/js/contentcollector.js b/src/static/js/contentcollector.js index ca193f73e..c0964c4a1 100644 --- a/src/static/js/contentcollector.js +++ b/src/static/js/contentcollector.js @@ -461,15 +461,14 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas // Images shouldn't be defined as empty. if (tname == "img"){ - isEmpty = false; - hooks.callAll('collectContentImage', { + var context = hooks.callAll('collectContentImage', { cc: cc, state: state, tname: tname, styl: styl, cls: cls, node: node - }); + }); } if (tname == "br") From c4f1189ebdc92f0da286c3939995f1564d5497dd Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 26 Jan 2015 02:39:43 +0000 Subject: [PATCH 03/58] even cleaner --- src/static/js/contentcollector.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/static/js/contentcollector.js b/src/static/js/contentcollector.js index c0964c4a1..2c8eefbfc 100644 --- a/src/static/js/contentcollector.js +++ b/src/static/js/contentcollector.js @@ -459,7 +459,6 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas { var tname = (dom.nodeTagName(node) || "").toLowerCase(); - // Images shouldn't be defined as empty. if (tname == "img"){ var context = hooks.callAll('collectContentImage', { cc: cc, @@ -470,8 +469,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas node: node }); } - - if (tname == "br") + else if (tname == "br") { this.breakLine = true; var tvalue = dom.nodeAttr(node, 'value'); From 2c3ce30fedf10e4bbdeeef6bd042a32dae0abd6e Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 26 Jan 2015 02:42:48 +0000 Subject: [PATCH 04/58] docs --- doc/api/hooks_client-side.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/doc/api/hooks_client-side.md b/doc/api/hooks_client-side.md index ca429a075..384085053 100644 --- a/doc/api/hooks_client-side.md +++ b/doc/api/hooks_client-side.md @@ -203,6 +203,28 @@ Things in context: This hook is called before the content of a node is collected by the usual methods. The cc object can be used to do a bunch of things that modify the content of the pad. See, for example, the heading1 plugin for etherpad original. +## collectContentImage +Called from: src/static/js/contentcollector.js + +Things in context: + +1. cc - the contentcollector object +2. state - the current state of the change being made +3. tname - the tag name of this node currently being processed +4. style - the style applied to the node (probably CSS) +5. cls - the HTML class string of the node + +This hook is called before the content of an image node is collected by the usual methods. The cc object can be used to do a bunch of things that modify the content of the pad. + +Example: + +``` +exports.collectContentImage = function(name, context){ + context.state.lineAttributes.img = context.node.outerHTML; +} + +``` + ## collectContentPost Called from: src/static/js/contentcollector.js From b8ac349b530a317675ac7bda5180c02248685f31 Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 26 Jan 2015 16:07:46 +0000 Subject: [PATCH 05/58] Update hooks_client-side.md --- doc/api/hooks_client-side.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/api/hooks_client-side.md b/doc/api/hooks_client-side.md index 384085053..8e2d3da79 100644 --- a/doc/api/hooks_client-side.md +++ b/doc/api/hooks_client-side.md @@ -213,6 +213,7 @@ Things in context: 3. tname - the tag name of this node currently being processed 4. style - the style applied to the node (probably CSS) 5. cls - the HTML class string of the node +6. node - the node being modified This hook is called before the content of an image node is collected by the usual methods. The cc object can be used to do a bunch of things that modify the content of the pad. From b6e7ddf8741b5b805fb8393ff08732685ef46b6a Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 26 Jan 2015 16:11:15 +0000 Subject: [PATCH 06/58] bump v --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index 0598a4b60..e9923a5af 100644 --- a/src/package.json +++ b/src/package.json @@ -55,5 +55,5 @@ "repository" : { "type" : "git", "url" : "http://github.com/ether/etherpad-lite.git" }, - "version" : "1.5.1" + "version" : "1.5.2" } From 78c3a8d65b1464ac04caeed3f5a8f4e55d989646 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Mon, 26 Jan 2015 22:58:30 +0100 Subject: [PATCH 07/58] Localisation updates from https://translatewiki.net. --- src/locales/ar.json | 5 ++++- src/locales/az.json | 2 +- src/locales/br.json | 3 +++ src/locales/hu.json | 2 ++ src/locales/lv.json | 15 ++++++++------- src/locales/oc.json | 11 +++++++---- src/locales/tr.json | 2 ++ src/locales/zh-hans.json | 4 ++-- 8 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/locales/ar.json b/src/locales/ar.json index b0d19fcc2..9d29b5211 100644 --- a/src/locales/ar.json +++ b/src/locales/ar.json @@ -4,7 +4,8 @@ "Ali1", "Tux-tn", "Alami", - "Meno25" + "Meno25", + "Test Create account" ] }, "index.newPad": "باد جديد", @@ -29,6 +30,7 @@ "pad.colorpicker.save": "تسجيل", "pad.colorpicker.cancel": "إلغاء", "pad.loading": "جاري التحميل...", + "pad.noCookie": "الكوكيز غير متاحة. الرجاء السماح بتحميل الكوكيز على متصفحك!", "pad.passwordRequired": "تحتاج إلى كلمة مرور للوصول إلى هذا الباد", "pad.permissionDenied": "ليس لديك إذن لدخول هذا الباد", "pad.wrongPassword": "كانت كلمة المرور خاطئة", @@ -118,6 +120,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/az.json b/src/locales/az.json index 99d3216aa..f5968ee4c 100644 --- a/src/locales/az.json +++ b/src/locales/az.json @@ -59,7 +59,7 @@ "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": "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.userdup.advice": "Bu pəncərəni istifadə etmək üçün yenidən qoşul.", "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.", "pad.modals.looping.explanation": "Sinxronlaşdırma serveri ilə kommunikasiya xətası var.", diff --git a/src/locales/br.json b/src/locales/br.json index 6e455d232..6bbd56d2b 100644 --- a/src/locales/br.json +++ b/src/locales/br.json @@ -29,6 +29,7 @@ "pad.colorpicker.save": "Enrollañ", "pad.colorpicker.cancel": "Nullañ", "pad.loading": "O kargañ...", + "pad.noCookie": "N'eus ket gallet kavout an toupin. Aotreit an toupinoù en ho merdeer, mar plij !", "pad.passwordRequired": "Ezhomm ho peus ur ger-tremen evit mont d'ar Pad-se", "pad.permissionDenied": "\nN'oc'h ket aotreet da vont d'ar pad-mañ", "pad.wrongPassword": "Fazius e oa ho ker-tremen", @@ -47,6 +48,7 @@ "pad.importExport.import": "Enkargañ un destenn pe ur restr", "pad.importExport.importSuccessful": "Deuet eo ganeoc'h !", "pad.importExport.export": "Ezporzhiañ ar pad bremañ evel :", + "pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "Testenn blaen", "pad.importExport.exportword": "Microsoft Word", @@ -117,6 +119,7 @@ "pad.impexp.importing": "Oc'h enporzhiañ...", "pad.impexp.confirmimport": "Ma vez enporzhiet ur restr e vo diverket ar pezh zo en teul a-vremañ. Ha sur oc'h e fell deoc'h mont betek penn ?", "pad.impexp.convertFailed": "N'eus ket bet gallet enporzhiañ ar restr. Ober gant ur furmad teul all pe eilañ/pegañ gant an dorn.", + "pad.impexp.padHasData": "N'hon eus ket gallet enporzhiañ ar restr-mañdre ma'z eus bet degaset kemmoù er bloc'h-se ; enporzhiit anezhi war-zu ur bloc'h nevez, mar plij.", "pad.impexp.uploadFailed": "C'hwitet eo bet an enporzhiañ. Klaskit en-dro.", "pad.impexp.importfailed": "C'hwitet eo an enporzhiadenn", "pad.impexp.copypaste": "Eilit/pegit, mar plij", diff --git a/src/locales/hu.json b/src/locales/hu.json index 3102790d7..287e79542 100644 --- a/src/locales/hu.json +++ b/src/locales/hu.json @@ -30,6 +30,7 @@ "pad.colorpicker.save": "Mentés", "pad.colorpicker.cancel": "Mégsem", "pad.loading": "Betöltés…", + "pad.noCookie": "Nem található a süti. Engedélyezd a böngésződben a sütik használatát!", "pad.passwordRequired": "Jelszóra van szükséged ezen notesz eléréséhez", "pad.permissionDenied": "Nincs engedélyed ezen notesz eléréséhez", "pad.wrongPassword": "A jelszó rossz volt", @@ -48,6 +49,7 @@ "pad.importExport.import": "Tetszőleges szövegfájl vagy dokumentum feltöltése", "pad.importExport.importSuccessful": "Siker!", "pad.importExport.export": "Jelenlegi notesz exportálása így:", + "pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "Sima szöveg", "pad.importExport.exportword": "Microsoft Word", diff --git a/src/locales/lv.json b/src/locales/lv.json index acdaaccd1..ee402d331 100644 --- a/src/locales/lv.json +++ b/src/locales/lv.json @@ -9,14 +9,14 @@ "pad.toolbar.bold.title": "Treknrakstā (CTRL + B)", "pad.toolbar.italic.title": "Slīpraksta (Ctrl-es)", "pad.toolbar.underline.title": "Pasvītrojuma (CTRL + U)", - "pad.toolbar.strikethrough.title": "Pārsvītrojums", - "pad.toolbar.ol.title": "Sakārtots saraksts", - "pad.toolbar.ul.title": "Nesakārtots saraksts", - "pad.toolbar.indent.title": "Atkāpe", - "pad.toolbar.unindent.title": "Izkāpe", + "pad.toolbar.strikethrough.title": "Pārsvītrojums (Ctrl+5)", + "pad.toolbar.ol.title": "Sakārtots saraksts (Ctrl+Shift+N)", + "pad.toolbar.ul.title": "Nesakārtots saraksts (Ctrl+Shift+L)", + "pad.toolbar.indent.title": "Atkāpe (TAB)", + "pad.toolbar.unindent.title": "Izkāpe (Shift+TAB)", "pad.toolbar.undo.title": "Atsaukt (CTRL + Z)", "pad.toolbar.redo.title": "Atcelt atsaukšanu (CTRL + Y)", - "pad.toolbar.clearAuthorship.title": "Notīrit autoru krāsas", + "pad.toolbar.clearAuthorship.title": "Notīrit autoru krāsas (Ctrl+Shift+C)", "pad.toolbar.import_export.title": "Importēšanas/eksportēšanas no un uz citu failu formātiem", "pad.toolbar.savedRevision.title": "Saglabāt pārskatīšanu", "pad.toolbar.settings.title": "Iestatījumi", @@ -46,6 +46,7 @@ "pad.importExport.exportword": "Programma Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open dokumenta formāts)", + "pad.modals.connected": "Pievienojies.", "pad.modals.userdup": "Atvērts citā logā", "pad.modals.unauth": "Nav atļauts", "pad.modals.looping.explanation": "Pastāv sakaru problēmas ar sinhronizācijas servera.", @@ -55,7 +56,7 @@ "pad.modals.deleted": "Dzēsts", "pad.modals.disconnected": "Jūs esat atvienots.", "pad.modals.disconnected.explanation": "Tika zaudēts savienojums ar serveri", - "pad.modals.disconnected.cause": "Iespējams, ka serveris nav pieejams. Lūgums paziņot mums, ja tas turpina notikt.", + "pad.modals.disconnected.cause": "Iespējams, ka serveris nav pieejams. Lūgums paziņot pakalpojuma administratoram, ja tas turpina notikt.", "pad.share": "Koplietot šo pad", "pad.share.readonly": "Tikai lasāms", "pad.share.link": "Saite", diff --git a/src/locales/oc.json b/src/locales/oc.json index 54a375bab..e62d387a5 100644 --- a/src/locales/oc.json +++ b/src/locales/oc.json @@ -9,14 +9,14 @@ "pad.toolbar.bold.title": "Gras (Ctrl-B)", "pad.toolbar.italic.title": "Italica (Ctrl-I)", "pad.toolbar.underline.title": "Soslinhat (Ctrl-U)", - "pad.toolbar.strikethrough.title": "Raiat", - "pad.toolbar.ol.title": "Lista ordenada", - "pad.toolbar.ul.title": "Lista amb de piuses", + "pad.toolbar.strikethrough.title": "Raiat (Ctrl+5)", + "pad.toolbar.ol.title": "Lista ordenada (Ctrl+Shift+N)", + "pad.toolbar.ul.title": "Lista pas ordenada (Ctrl+Shift+L)", "pad.toolbar.indent.title": "Indentar (TAB)", "pad.toolbar.unindent.title": "Desindentar (Maj+TAB)", "pad.toolbar.undo.title": "Anullar (Ctrl-Z)", "pad.toolbar.redo.title": "Restablir (Ctrl-Y)", - "pad.toolbar.clearAuthorship.title": "Escafar las colors qu'identifican los autors", + "pad.toolbar.clearAuthorship.title": "Escafar las colors qu'identifican los autors (Ctrl+Shift+C)", "pad.toolbar.import_export.title": "Importar/Exportar de/cap a un format de fichièr diferent", "pad.toolbar.timeslider.title": "Istoric dinamic", "pad.toolbar.savedRevision.title": "Enregistrar la revision", @@ -26,6 +26,7 @@ "pad.colorpicker.save": "Enregistrar", "pad.colorpicker.cancel": "Anullar", "pad.loading": "Cargament...", + "pad.noCookie": "Lo cookie a pas pogut èsser trobat. Autorizatz los cookies dins vòstre navigador !", "pad.passwordRequired": "Avètz besonh d'un senhal per accedir a aqueste Pad", "pad.permissionDenied": "Vos es pas permés d’accedir a aqueste Pad.", "pad.wrongPassword": "Senhal incorrècte", @@ -44,6 +45,7 @@ "pad.importExport.import": "Cargar un tèxte o un document", "pad.importExport.importSuccessful": "Capitat !", "pad.importExport.export": "Exportar lo Pad actual coma :", + "pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "Tèxte brut", "pad.importExport.exportword": "Microsoft Word", @@ -114,6 +116,7 @@ "pad.impexp.importing": "Impòrt en cors...", "pad.impexp.confirmimport": "Importar un fichièr espotirà lo tèxte actual del blòt. Sètz segur que lo volètz far ?", "pad.impexp.convertFailed": "Podèm pas importar aqueste fichièr. Utilizatz un autre format de document o fasètz un copiar/pegar manual", + "pad.impexp.padHasData": "Avèm pas pogut importar aqueste fichièr perque aqueste blòt a ja agut de modificacions ; importatz cap a un blòt novèl", "pad.impexp.uploadFailed": "Lo telecargament a fracassat, reensajatz", "pad.impexp.importfailed": "Fracàs de l'importacion", "pad.impexp.copypaste": "Copiatz/pegatz", diff --git a/src/locales/tr.json b/src/locales/tr.json index 54030fda1..b0b6dbee3 100644 --- a/src/locales/tr.json +++ b/src/locales/tr.json @@ -30,6 +30,7 @@ "pad.colorpicker.save": "Kaydet", "pad.colorpicker.cancel": "İptal", "pad.loading": "Yükleniyor...", + "pad.noCookie": "Çerez bulunamadı. Lütfen tarayıcınızda çerezlere izin veriniz!", "pad.passwordRequired": "Bu bloknota erişebilmeniz için parolaya ihtiyacınız var", "pad.permissionDenied": "Bu bloknota erişmeye izniniz yok", "pad.wrongPassword": "Parolanız yanlış", @@ -48,6 +49,7 @@ "pad.importExport.import": "Herhangi bir metin dosyası ya da belgesi yükle", "pad.importExport.importSuccessful": "Başarılı!", "pad.importExport.export": "Mevcut bloknotu şu olarak dışa aktar:", + "pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "Düz metin", "pad.importExport.exportword": "Microsoft Word", diff --git a/src/locales/zh-hans.json b/src/locales/zh-hans.json index bc1c97b5a..10727c5d3 100644 --- a/src/locales/zh-hans.json +++ b/src/locales/zh-hans.json @@ -101,8 +101,8 @@ "timeslider.version": "版本 {{version}}", "timeslider.saved": "在{{year}}年{{month}}{{day}}日保存", "timeslider.dateformat": "{{year}}年{{month}}{{day}}日 {{hours}}时:{{minutes}}分:{{seconds}}秒", - "timeslider.month.january": "一月", - "timeslider.month.february": "二月", + "timeslider.month.january": "1月", + "timeslider.month.february": "2月", "timeslider.month.march": "三月", "timeslider.month.april": "四月", "timeslider.month.may": "五月", From 8fbd7d83b637e113f8c86d577fad56bafd4d82c8 Mon Sep 17 00:00:00 2001 From: John McLear Date: Tue, 27 Jan 2015 19:16:36 +0000 Subject: [PATCH 08/58] content collector should also register the blocks, no idea why this wasnt in before --- src/static/js/contentcollector.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/static/js/contentcollector.js b/src/static/js/contentcollector.js index 2c8eefbfc..d34299cc6 100644 --- a/src/static/js/contentcollector.js +++ b/src/static/js/contentcollector.js @@ -87,6 +87,10 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas "li": 1 }; + _.each(hooks.callAll('aceRegisterBlockElements'), function(element){ + _blockElems[element] = 1; + }); + function isBlockElement(n) { return !!_blockElems[(dom.nodeTagName(n) || "").toLowerCase()]; From bdfce1cbefa74abb1b0e4d05bf5d5e12bbf5e4f0 Mon Sep 17 00:00:00 2001 From: John McLear Date: Tue, 27 Jan 2015 19:41:01 +0000 Subject: [PATCH 09/58] change to cc.. --- src/static/js/contentcollector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static/js/contentcollector.js b/src/static/js/contentcollector.js index d34299cc6..c85909e94 100644 --- a/src/static/js/contentcollector.js +++ b/src/static/js/contentcollector.js @@ -87,7 +87,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas "li": 1 }; - _.each(hooks.callAll('aceRegisterBlockElements'), function(element){ + _.each(hooks.callAll('ccRegisterBlockElements'), function(element){ _blockElems[element] = 1; }); From 0216a10a129210abbc36fdbbcd29acf445e75ff5 Mon Sep 17 00:00:00 2001 From: John McLear Date: Tue, 27 Jan 2015 20:10:38 +0000 Subject: [PATCH 10/58] better variable name --- src/static/js/contentcollector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static/js/contentcollector.js b/src/static/js/contentcollector.js index c85909e94..fcb299814 100644 --- a/src/static/js/contentcollector.js +++ b/src/static/js/contentcollector.js @@ -464,7 +464,7 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas var tname = (dom.nodeTagName(node) || "").toLowerCase(); if (tname == "img"){ - var context = hooks.callAll('collectContentImage', { + var collectContentImage = hooks.callAll('collectContentImage', { cc: cc, state: state, tname: tname, From b9b110c82fff4d2a6cded4bc674c707f6772b85b Mon Sep 17 00:00:00 2001 From: JulR43 Date: Wed, 28 Jan 2015 17:29:16 +0000 Subject: [PATCH 11/58] Change git-core to git git-core package is an obsolete transitional package, it was renamed git. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0cddb0b0f..48ff434e6 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,8 @@ Update to the latest version with `git pull origin`, then run `bin\installOnWind ## GNU/Linux and other UNIX-like systems You'll need gzip, git, curl, libssl develop libraries, python and gcc. -- *For Debian/Ubuntu*: `apt-get install gzip git-core curl python libssl-dev pkg-config build-essential` -- *For Fedora/CentOS*: `yum install gzip git-core curl python openssl-devel && yum groupinstall "Development Tools"` +- *For Debian/Ubuntu*: `apt-get install gzip git curl python libssl-dev pkg-config build-essential` +- *For Fedora/CentOS*: `yum install gzip git curl python openssl-devel && yum groupinstall "Development Tools"` - *For FreeBSD*: `portinstall node, npm, git (optional)` Additionally, you'll need [node.js](http://nodejs.org) installed, Ideally the latest stable version, we recommend installing/compiling nodejs from source (avoiding apt). From 35da64be5c5438f098ca14acf56ca601b224bb5a Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 28 Jan 2015 19:09:47 +0000 Subject: [PATCH 12/58] hrm bit of a hack, anyone any ideas on better way? --- src/static/js/contentcollector.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/static/js/contentcollector.js b/src/static/js/contentcollector.js index fcb299814..e428c63f9 100644 --- a/src/static/js/contentcollector.js +++ b/src/static/js/contentcollector.js @@ -324,7 +324,6 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas return [key, value]; }) ); - lines.appendText('*', Changeset.makeAttribsString('+', attributes , apool)); } cc.startNewLine = function(state) @@ -472,9 +471,13 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas cls: cls, node: node }); + }else{ + // THIS SEEMS VERY HACKY! -- Please submit a better fix! + delete state.lineAttributes.img } - else if (tname == "br") - { + + if (tname == "br") + { this.breakLine = true; var tvalue = dom.nodeAttr(node, 'value'); var induceLineBreak = hooks.callAll('collectContentLineBreak', { @@ -498,7 +501,6 @@ function makeContentCollector(collectStyles, abrowser, apool, domInterface, clas { var styl = dom.nodeAttr(node, "style"); var cls = dom.nodeProp(node, "className"); - var isPre = (tname == "pre"); if ((!isPre) && abrowser.safari) { From 9afcd8916782f2a6b53aae061cb7e719764e6ebb Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 4 Feb 2015 17:52:27 +0000 Subject: [PATCH 13/58] bump versions to see if it's stable --- src/package.json | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/package.json b/src/package.json index e9923a5af..17c747653 100644 --- a/src/package.json +++ b/src/package.json @@ -13,10 +13,10 @@ ], "dependencies" : { "etherpad-yajsml" : "0.0.2", - "request" : "2.51.0", + "request" : "2.53.0", "etherpad-require-kernel" : "1.0.7", - "resolve" : "1.0.0", - "socket.io" : "1.3.2", + "resolve" : "1.1.0", + "socket.io" : "1.3.3", "ueberDB" : "0.2.11", "express" : "3.8.1", "async" : "0.9.0", @@ -25,10 +25,9 @@ "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", + "npm" : "2.4.1", "ejs" : "1.0.0", "graceful-fs" : "3.0.5", "slide" : "1.1.6", @@ -41,13 +40,13 @@ "swagger-node-express" : "2.1.3", "channels" : "0.0.4", "jsonminify" : "0.2.3", - "measured" : "0.1.6", + "measured" : "1.0.0", "mocha" : "2.1.0", "supertest" : "0.15.0" }, "bin": { "etherpad-lite": "./node/server.js" }, "devDependencies": { - "wd" : "0.0.31" + "wd" : "0.3.11" }, "engines" : { "node" : ">=0.6.3", "npm" : ">=1.0" From b9802616b6cab99a43b470972f62f24fcc21f473 Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 4 Feb 2015 17:57:34 +0000 Subject: [PATCH 14/58] use latest cleanCSS --- src/node/utils/Minify.js | 5 +++-- src/package.json | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/node/utils/Minify.js b/src/node/utils/Minify.js index 7b868307d..da101f8d3 100644 --- a/src/node/utils/Minify.js +++ b/src/node/utils/Minify.js @@ -23,7 +23,7 @@ var ERR = require("async-stacktrace"); var settings = require('./Settings'); var async = require('async'); var fs = require('fs'); -var cleanCSS = require('clean-css'); +var CleanCSS = require('clean-css'); var jsp = require("uglify-js").parser; var pro = require("uglify-js").uglify; var path = require('path'); @@ -410,7 +410,8 @@ function compressJS(values) function compressCSS(values) { var complete = values.join("\n"); - return cleanCSS.process(complete); + var minimized = new CleanCSS().minify(complete).styles; + return minimized; } exports.minify = minify; diff --git a/src/package.json b/src/package.json index 17c747653..20ef953d8 100644 --- a/src/package.json +++ b/src/package.json @@ -21,7 +21,7 @@ "express" : "3.8.1", "async" : "0.9.0", "connect" : "2.7.11", - "clean-css" : "0.3.2", + "clean-css" : "3.0.8", "uglify-js" : "2.4.16", "formidable" : "1.0.16", "log4js" : "0.6.22", From 4c667ecef63bbc1029a8ea272f5fc4acc40b3731 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sat, 7 Feb 2015 23:23:33 +0000 Subject: [PATCH 15/58] fix scroll issue where focus is not well managed --- src/static/js/chat.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/static/js/chat.js b/src/static/js/chat.js index ce9a00337..bdb5ee09c 100644 --- a/src/static/js/chat.js +++ b/src/static/js/chat.js @@ -29,9 +29,11 @@ var chat = (function() var self = { show: function () { +console.log("here"); $("#chaticon").hide(); $("#chatbox").show(); $("#gritter-notice-wrapper").hide(); + console.log("scroll down 1"); self.scrollDown(); chatMentions = 0; Tinycon.setBubble(0); @@ -91,7 +93,9 @@ var chat = (function() { if($('#chatbox').css("display") != "none"){ if(!self.lastMessage || !self.lastMessage.position() || self.lastMessage.position().top < $('#chattext').height()) { - $('#chattext').animate({scrollTop: $('#chattext')[0].scrollHeight}, "slow"); + // if we use a slow animate here we can have a race condition when a users focus can not be moved away + // from the last message recieved. + $('#chattext').animate({scrollTop: $('#chattext')[0].scrollHeight}, "fast"); self.lastMessage = $('#chattext > p').eq(-1); } } @@ -195,6 +199,7 @@ var chat = (function() }); if(!isHistoryAdd) self.scrollDown(); + console.log("scroll down 2"); }, init: function(pad) { From fe4dd98a6e4df364523564daeb631898523bfdf4 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sat, 7 Feb 2015 23:24:24 +0000 Subject: [PATCH 16/58] remove console logs --- src/static/js/chat.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/static/js/chat.js b/src/static/js/chat.js index bdb5ee09c..5040ea59b 100644 --- a/src/static/js/chat.js +++ b/src/static/js/chat.js @@ -29,11 +29,9 @@ var chat = (function() var self = { show: function () { -console.log("here"); $("#chaticon").hide(); $("#chatbox").show(); $("#gritter-notice-wrapper").hide(); - console.log("scroll down 1"); self.scrollDown(); chatMentions = 0; Tinycon.setBubble(0); @@ -199,7 +197,6 @@ console.log("here"); }); if(!isHistoryAdd) self.scrollDown(); - console.log("scroll down 2"); }, init: function(pad) { From 1652ed42c508feaa15c4d7f482e57d2ae0d67be7 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sat, 7 Feb 2015 23:23:33 +0000 Subject: [PATCH 17/58] fix scroll issue where focus is not well managed remove console logs --- src/static/js/chat.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/static/js/chat.js b/src/static/js/chat.js index ce9a00337..5040ea59b 100644 --- a/src/static/js/chat.js +++ b/src/static/js/chat.js @@ -91,7 +91,9 @@ var chat = (function() { if($('#chatbox').css("display") != "none"){ if(!self.lastMessage || !self.lastMessage.position() || self.lastMessage.position().top < $('#chattext').height()) { - $('#chattext').animate({scrollTop: $('#chattext')[0].scrollHeight}, "slow"); + // if we use a slow animate here we can have a race condition when a users focus can not be moved away + // from the last message recieved. + $('#chattext').animate({scrollTop: $('#chattext')[0].scrollHeight}, "fast"); self.lastMessage = $('#chattext > p').eq(-1); } } From 7adcd5cba4e6569f34d43280cb740316914d35f8 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sun, 8 Feb 2015 14:34:48 +0000 Subject: [PATCH 18/58] cleaner fix for queue issue --- src/static/js/chat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static/js/chat.js b/src/static/js/chat.js index 5040ea59b..9cb5b401d 100644 --- a/src/static/js/chat.js +++ b/src/static/js/chat.js @@ -93,7 +93,7 @@ var chat = (function() if(!self.lastMessage || !self.lastMessage.position() || self.lastMessage.position().top < $('#chattext').height()) { // if we use a slow animate here we can have a race condition when a users focus can not be moved away // from the last message recieved. - $('#chattext').animate({scrollTop: $('#chattext')[0].scrollHeight}, "fast"); + $('#chattext').animate({scrollTop: $('#chattext')[0].scrollHeight}, { duration: 400, queue: false }); self.lastMessage = $('#chattext > p').eq(-1); } } From 4af46921e104016cd81cd20f2bff52651797655f Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 9 Feb 2015 17:37:20 +0000 Subject: [PATCH 19/58] better css --- src/static/css/pad.css | 5 +++-- src/static/js/pad_editbar.js | 11 +++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/static/css/pad.css b/src/static/css/pad.css index 70c15b515..e9a91f4e0 100644 --- a/src/static/css/pad.css +++ b/src/static/css/pad.css @@ -919,7 +919,8 @@ input[type=checkbox] { right:0px !important; border-radius:0px !important; width:182px !important; - margin:2px 0 0 0 !important; +/* Below makes UI look weird when X makes editbar flow onto two lines */ +/* margin:2px 0 0 0 !important;*/ border: none !important; border-bottom: 1px solid #ccc !important; height:155px !important; @@ -937,7 +938,7 @@ input[type=checkbox] { padding:0 !important; margin:0 !important; right:0 !important; - top: 200px !important; + top: 200px; width:182px !important; border: none !important; padding:5px !important; diff --git a/src/static/js/pad_editbar.js b/src/static/js/pad_editbar.js index e874614f3..56018b351 100644 --- a/src/static/js/pad_editbar.js +++ b/src/static/js/pad_editbar.js @@ -186,9 +186,20 @@ var padeditbar = (function() $('#editbar').css("height", editbarHeight); $('#editorcontainer').css("top", containerTop); + + // If sticky chat is enabled.. if($('#options-stickychat').is(":checked")){ $('#chatbox').css("top", $('#editorcontainer').offset().top + "px"); }; + + // If chat and Users is enabled.. + if($('#options-chatandusers').is(":checked")){ + $('#users').css("top", $('#editorcontainer').offset().top + "px"); + + // We also need to move the chatbox lower.. + $('#chatbox').css("top", 10 + $('#users').height() + $('#editorcontainer').offset().top + "px"); + } + }, registerDropdownCommand: function (cmd, dropdown) { dropdown = dropdown || cmd; From 8c6507e78c655f402269276f1f1730d431dd18e8 Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 9 Feb 2015 18:01:45 +0000 Subject: [PATCH 20/58] more styling stuff --- src/static/css/pad.css | 3 +-- src/static/js/chat.js | 3 ++- src/static/js/pad_editbar.js | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/static/css/pad.css b/src/static/css/pad.css index e9a91f4e0..19998418b 100644 --- a/src/static/css/pad.css +++ b/src/static/css/pad.css @@ -936,9 +936,8 @@ input[type=checkbox] { .chatAndUsersChat{ bottom:0px !important; padding:0 !important; - margin:0 !important; + margin: 165px 0px 0px 0px; right:0 !important; - top: 200px; width:182px !important; border: none !important; padding:5px !important; diff --git a/src/static/js/chat.js b/src/static/js/chat.js index 9cb5b401d..102f4637a 100644 --- a/src/static/js/chat.js +++ b/src/static/js/chat.js @@ -57,7 +57,8 @@ var chat = (function() }, chatAndUsers: function(fromInitialCall) { - if(!userAndChat || fromInitialCall){ + var toEnable = $('#options-chatandusers').is(":checked"); + if(toEnable || !userAndChat || fromInitialCall){ padcookie.setPref("chatAndUsers", true); chat.stickToScreen(true); $('#options-stickychat').prop('checked', true) diff --git a/src/static/js/pad_editbar.js b/src/static/js/pad_editbar.js index 56018b351..4fcb20ea6 100644 --- a/src/static/js/pad_editbar.js +++ b/src/static/js/pad_editbar.js @@ -195,9 +195,6 @@ var padeditbar = (function() // If chat and Users is enabled.. if($('#options-chatandusers').is(":checked")){ $('#users').css("top", $('#editorcontainer').offset().top + "px"); - - // We also need to move the chatbox lower.. - $('#chatbox').css("top", 10 + $('#users').height() + $('#editorcontainer').offset().top + "px"); } }, From 5245d2b797856beabd6d7f8d548ac938b867657a Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 9 Feb 2015 18:36:11 +0000 Subject: [PATCH 21/58] and even mroe polish --- src/static/css/pad.css | 2 +- src/static/js/chat.js | 6 +++--- src/static/js/pad_editbar.js | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/static/css/pad.css b/src/static/css/pad.css index 19998418b..95ad4f786 100644 --- a/src/static/css/pad.css +++ b/src/static/css/pad.css @@ -897,7 +897,7 @@ input[type=checkbox] { #connectivity, #users { position: absolute; - top: 36px; + top: 38px; right: 20px; display: none; z-index: 500; diff --git a/src/static/js/chat.js b/src/static/js/chat.js index 102f4637a..7fd687eab 100644 --- a/src/static/js/chat.js +++ b/src/static/js/chat.js @@ -22,7 +22,6 @@ var hooks = require('./pluginfw/hooks'); var chat = (function() { var isStuck = false; - var userAndChat = false; var gotInitialMessages = false; var historyPointer = 0; var chatMentions = 0; @@ -58,14 +57,15 @@ var chat = (function() chatAndUsers: function(fromInitialCall) { var toEnable = $('#options-chatandusers').is(":checked"); - if(toEnable || !userAndChat || fromInitialCall){ + if(toEnable || 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; + // redraw + padeditbar.redrawHeight() }else{ padcookie.setPref("chatAndUsers", false); $('#options-stickychat').prop("disabled", false); diff --git a/src/static/js/pad_editbar.js b/src/static/js/pad_editbar.js index 4fcb20ea6..4dc80860e 100644 --- a/src/static/js/pad_editbar.js +++ b/src/static/js/pad_editbar.js @@ -187,6 +187,9 @@ var padeditbar = (function() $('#editorcontainer').css("top", containerTop); + // make sure pop ups are in the right place + $('.popup').css("top", $('#editorcontainer').offset().top + "px"); + // If sticky chat is enabled.. if($('#options-stickychat').is(":checked")){ $('#chatbox').css("top", $('#editorcontainer').offset().top + "px"); From b216f9271b07b1171a2be36a6cb72989347a873d Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 9 Feb 2015 19:11:35 +0000 Subject: [PATCH 22/58] should be final logic for chatandusers --- src/static/js/chat.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/static/js/chat.js b/src/static/js/chat.js index 7fd687eab..811b13207 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; @@ -57,14 +58,16 @@ var chat = (function() chatAndUsers: function(fromInitialCall) { var toEnable = $('#options-chatandusers').is(":checked"); - if(toEnable || fromInitialCall){ + if(toEnable || !userAndChat || fromInitialCall){ padcookie.setPref("chatAndUsers", true); chat.stickToScreen(true); $('#options-stickychat').prop('checked', true) + $('#options-chatandusers').prop('checked', true) $('#options-stickychat').prop("disabled", "disabled"); $('#users').addClass("chatAndUsers"); $("#chatbox").addClass("chatAndUsersChat"); // redraw + userAndChat = true; padeditbar.redrawHeight() }else{ padcookie.setPref("chatAndUsers", false); From 26ae37572701a97bec4883d15a98b99971c6bda2 Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 9 Feb 2015 19:53:32 +0000 Subject: [PATCH 23/58] minor css polish for user input --- src/static/css/pad.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/static/css/pad.css b/src/static/css/pad.css index 95ad4f786..5e4c4d14e 100644 --- a/src/static/css/pad.css +++ b/src/static/css/pad.css @@ -373,7 +373,7 @@ li[data-key=showusers] > a #online_count { border-radius: 5px; } #myusernameform { - margin-left: 35px + margin-left: 30px } #myusernameedit { font-size: 1.3em; @@ -382,7 +382,7 @@ li[data-key=showusers] > a #online_count { height: 18px; margin: 0; border: 0; - width: 117px; + width: 122px; background: transparent; } #myusernameform input.editable { From 0ad09c17db0ec113c349857067ab3bdaeb70194d Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 9 Feb 2015 23:04:30 +0000 Subject: [PATCH 24/58] fix JS error in timeslider if offset doesn't exist --- src/static/js/pad_editbar.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/static/js/pad_editbar.js b/src/static/js/pad_editbar.js index 4dc80860e..7d0539af9 100644 --- a/src/static/js/pad_editbar.js +++ b/src/static/js/pad_editbar.js @@ -188,16 +188,22 @@ var padeditbar = (function() $('#editorcontainer').css("top", containerTop); // make sure pop ups are in the right place - $('.popup').css("top", $('#editorcontainer').offset().top + "px"); + if($('#editorcontainer').offset()){ + $('.popup').css("top", $('#editorcontainer').offset().top + "px"); + } // If sticky chat is enabled.. if($('#options-stickychat').is(":checked")){ - $('#chatbox').css("top", $('#editorcontainer').offset().top + "px"); + if($('#editorcontainer').offset()){ + $('#chatbox').css("top", $('#editorcontainer').offset().top + "px"); + } }; // If chat and Users is enabled.. if($('#options-chatandusers').is(":checked")){ - $('#users').css("top", $('#editorcontainer').offset().top + "px"); + if($('#editorcontainer').offset()){ + $('#users').css("top", $('#editorcontainer').offset().top + "px"); + } } }, From 275592e423d8adcd6349bbd6bbe5d1940427c65f Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 11 Feb 2015 02:07:20 +0000 Subject: [PATCH 25/58] seems right --- src/static/js/pad_impexp.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/static/js/pad_impexp.js b/src/static/js/pad_impexp.js index 77f1eb289..967615702 100644 --- a/src/static/js/pad_impexp.js +++ b/src/static/js/pad_impexp.js @@ -188,7 +188,8 @@ var padimpexp = (function() pad = _pad; //get /p/padname - var pad_root_path = new RegExp(/.*\/p\/[^\/]+/).exec(document.location.pathname); + // if /p/ isn't available due to a rewrite we use the clientVars padId + var pad_root_path = new RegExp(/.*\/p\/[^\/]+/).exec(document.location.pathname) || clientVars.padId; //get http://example.com/p/padname without Params var pad_root_url = document.location.protocol + '//' + document.location.host + document.location.pathname; From ddc69831b219b7e6bedee910fba805a26b0fb0ca Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 11 Feb 2015 17:59:05 +0000 Subject: [PATCH 26/58] working, need to test though --- src/node/hooks/express.js | 18 +----------------- src/node/hooks/express/adminplugins.js | 4 +++- src/node/utils/Settings.js | 21 +++++++++++++++++++++ src/templates/admin/plugins-info.html | 2 ++ 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/node/hooks/express.js b/src/node/hooks/express.js index e858b8008..3275bd3ff 100644 --- a/src/node/hooks/express.js +++ b/src/node/hooks/express.js @@ -10,24 +10,9 @@ var server; var serverName; exports.createServer = function () { - //try to get the git version - var version = ""; - try - { - var rootPath = path.resolve(npm.dir, '..'); - var ref = fs.readFileSync(rootPath + "/.git/HEAD", "utf-8"); - var refPath = rootPath + "/.git/" + ref.substring(5, ref.indexOf("\n")); - version = fs.readFileSync(refPath, "utf-8"); - version = version.substring(0, 7); - console.log("Your Etherpad git version is " + version); - } - catch(e) - { - console.warn("Can't get git version for server header\n" + e.message) - } console.log("Report bugs at https://github.com/ether/etherpad-lite/issues") - serverName = "Etherpad " + version + " (http://etherpad.org)"; + serverName = "Etherpad " + settings.getGitCommit() + " (http://etherpad.org)"; exports.restartServer(); @@ -38,7 +23,6 @@ exports.createServer = function () { else{ console.warn("Admin username and password not set in settings.json. To access admin please uncomment and edit 'users' in settings.json"); } - } exports.restartServer = function () { diff --git a/src/node/hooks/express/adminplugins.js b/src/node/hooks/express/adminplugins.js index 34eafd0be..5015cc5a4 100644 --- a/src/node/hooks/express/adminplugins.js +++ b/src/node/hooks/express/adminplugins.js @@ -1,4 +1,5 @@ var eejs = require('ep_etherpad-lite/node/eejs'); +var settings = require('ep_etherpad-lite/node/utils/Settings'); var installer = require('ep_etherpad-lite/static/js/pluginfw/installer'); var plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins'); var _ = require('underscore'); @@ -15,7 +16,8 @@ exports.expressCreateServer = function (hook_name, args, cb) { res.send( eejs.require("ep_etherpad-lite/templates/admin/plugins.html", render_args) ); }); args.app.get('/admin/plugins/info', function(req, res) { - res.send( eejs.require("ep_etherpad-lite/templates/admin/plugins-info.html", {}) ); + var gitCommit = settings.getGitCommit(); + res.send( eejs.require("ep_etherpad-lite/templates/admin/plugins-info.html", {gitCommit:gitCommit}) ); }); } diff --git a/src/node/utils/Settings.js b/src/node/utils/Settings.js index 05ae3bd84..1fb5bddfb 100644 --- a/src/node/utils/Settings.js +++ b/src/node/utils/Settings.js @@ -179,6 +179,25 @@ exports.abiwordAvailable = function() } }; +// Provide git version if available +exports.getGitCommit = function() { + var version = ""; + try + { + var rootPath = path.resolve(npm.dir, '..'); + var ref = fs.readFileSync(rootPath + "/.git/HEAD", "utf-8"); + var refPath = rootPath + "/.git/" + ref.substring(5, ref.indexOf("\n")); + version = fs.readFileSync(refPath, "utf-8"); + version = version.substring(0, 7); + console.log("Your Etherpad git version is " + version); + } + catch(e) + { + console.warn("Can't get git version for server header\n" + e.message) + } + return version; +} + exports.reloadSettings = function reloadSettings() { // Discover where the settings file lives var settingsFilename = argv.settings || "settings.json"; @@ -261,3 +280,5 @@ exports.reloadSettings = function reloadSettings() { // initially load settings exports.reloadSettings(); + + diff --git a/src/templates/admin/plugins-info.html b/src/templates/admin/plugins-info.html index 0ca6d0105..ac1d88bcf 100644 --- a/src/templates/admin/plugins-info.html +++ b/src/templates/admin/plugins-info.html @@ -22,6 +22,8 @@
+

Etherpad Git Commit

+
<%= gitCommit %>

Installed plugins

<%- plugins.formatPlugins().replace(", ","\n") %>
From d0caebc21f970a0a7d17f4b64b35e48bc0357621 Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 11 Feb 2015 18:05:01 +0000 Subject: [PATCH 27/58] may aswell make the git sha a link to the commit --- src/templates/admin/plugins-info.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/templates/admin/plugins-info.html b/src/templates/admin/plugins-info.html index ac1d88bcf..1b328a894 100644 --- a/src/templates/admin/plugins-info.html +++ b/src/templates/admin/plugins-info.html @@ -23,7 +23,7 @@

Etherpad Git Commit

-
<%= gitCommit %>
+

<%= gitCommit %>

Installed plugins

<%- plugins.formatPlugins().replace(", ","\n") %>
From e39b4428405d186796c56bb0fd18785bec0b5628 Mon Sep 17 00:00:00 2001 From: John McLear Date: Fri, 13 Feb 2015 01:25:29 +0000 Subject: [PATCH 28/58] bump v for #2505 fix --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index 20ef953d8..00876f2cf 100644 --- a/src/package.json +++ b/src/package.json @@ -14,7 +14,7 @@ "dependencies" : { "etherpad-yajsml" : "0.0.2", "request" : "2.53.0", - "etherpad-require-kernel" : "1.0.7", + "etherpad-require-kernel" : "1.0.8", "resolve" : "1.1.0", "socket.io" : "1.3.3", "ueberDB" : "0.2.11", From c191a8716ebee37f61cdd4b07aff41f52e90c604 Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Sat, 14 Feb 2015 16:41:50 +0100 Subject: [PATCH 29/58] totally wrong, introduced by myself in 3354b9406b94e1a04b5eee1c0152914dde73ba89 the first part is always false so the second part which is always true in case a cs deleted some lines was never triggered...sigh --- src/static/js/Changeset.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index 32da887df..fd658f869 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -927,16 +927,12 @@ exports.applyToText = function (cs, str) { break; case '-': removedLines += op.lines; - newlines = strIter.newlines() strIter.skip(op.chars); - if(!(newlines - strIter.newlines() == 0) && (newlines - strIter.newlines() != op.lines)){ - newlinefail = true - } break; case '=': newlines = strIter.newlines() assem.append(strIter.take(op.chars)); - if(!(newlines - strIter.newlines() == op.lines)){ + if(newlines - strIter.newlines() != op.lines){ newlinefail = true } break; From 4313bd27f84d29c604d593a69bd09aee5189b290 Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Sun, 15 Feb 2015 13:25:57 +0100 Subject: [PATCH 30/58] add a comment to make clear that the string in stringIterator does not change; only curIndex is increased. Newlines are counted between curIndex and the end of string. --- src/static/js/Changeset.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index fd658f869..a7ae8e713 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -507,6 +507,7 @@ exports.opAssembler = function () { */ exports.stringIterator = function (str) { var curIndex = 0; + // newLines is the number of \n between curIndex and str.length var newLines = str.split("\n").length - 1 function getnewLines(){ return newLines From b4d4b16b1f86e518be1df24c4fc5e67b923f4a4f Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Sun, 15 Feb 2015 14:56:20 +0100 Subject: [PATCH 31/58] off by 1 --- src/static/js/Changeset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index a7ae8e713..2f1a53bc3 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -910,7 +910,7 @@ exports.pack = function (oldLen, newLen, opsStr, bank) { * @params str {string} String to which a Changeset should be applied */ exports.applyToText = function (cs, str) { - var totalNrOfLines = str.split("\n").length; + var totalNrOfLines = str.split("\n").length - 1; var removedLines = 0; var unpacked = exports.unpack(cs); exports.assert(str.length == unpacked.oldLen, "mismatched apply: ", str.length, " / ", unpacked.oldLen); From ac2c7e96793f05485627199bc8fd28a4562803cf Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Sun, 15 Feb 2015 15:09:38 +0100 Subject: [PATCH 32/58] add newline counting for - and + op --- src/static/js/Changeset.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index 2f1a53bc3..a91bd1d7e 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -924,18 +924,30 @@ exports.applyToText = function (cs, str) { var op = csIter.next(); switch (op.opcode) { case '+': + //op is + and op.lines 0: no newlines must be in op.chars + //op is + and op.lines >0: op.chars must include op.lines newlines + if(op.lines != bankIter.peek(op.chars).split("\n").length - 1){ + newlinefail = true + } assem.append(bankIter.take(op.chars)); break; case '-': + //op is - and op.lines 0: no newlines must be in the deleted string + //op is - and op.lines >0: op.lines newlines must be in the deleted string + if(op.lines != strIter.peek(op.chars).split("\n").length - 1){ + newlinefail = true + } removedLines += op.lines; strIter.skip(op.chars); break; case '=': - newlines = strIter.newlines() - assem.append(strIter.take(op.chars)); - if(newlines - strIter.newlines() != op.lines){ + //op is = and op.lines 0: no newlines must be in the copied string + //op is = and op.lines >0: op.lines newlines must be in the copied string + if(op.lines != strIter.peek(op.chars).split("\n").length - 1){ newlinefail = true } + newlines = strIter.newlines() + assem.append(strIter.take(op.chars)); break; } } From e7f01fa49821020c606ccdd1237d7f6de559e7c0 Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Sun, 15 Feb 2015 15:12:24 +0100 Subject: [PATCH 33/58] remove unnecessary code; because we have checks in every op now we don't need this anymore --- src/static/js/Changeset.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index a91bd1d7e..f0c7d8b4c 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -910,14 +910,11 @@ exports.pack = function (oldLen, newLen, opsStr, bank) { * @params str {string} String to which a Changeset should be applied */ exports.applyToText = function (cs, str) { - var totalNrOfLines = str.split("\n").length - 1; - var removedLines = 0; var unpacked = exports.unpack(cs); exports.assert(str.length == unpacked.oldLen, "mismatched apply: ", str.length, " / ", unpacked.oldLen); var csIter = exports.opIterator(unpacked.ops); var bankIter = exports.stringIterator(unpacked.charBank); var strIter = exports.stringIterator(str); - var newlines = 0 var newlinefail = false var assem = exports.stringAssembler(); while (csIter.hasNext()) { @@ -937,7 +934,6 @@ exports.applyToText = function (cs, str) { if(op.lines != strIter.peek(op.chars).split("\n").length - 1){ newlinefail = true } - removedLines += op.lines; strIter.skip(op.chars); break; case '=': @@ -946,12 +942,10 @@ exports.applyToText = function (cs, str) { if(op.lines != strIter.peek(op.chars).split("\n").length - 1){ newlinefail = true } - newlines = strIter.newlines() assem.append(strIter.take(op.chars)); break; } } - exports.assert(totalNrOfLines >= removedLines,"cannot remove ", removedLines, " lines from text with ", totalNrOfLines, " lines"); assem.append(strIter.take(strIter.remaining())); return [assem.toString(),newlinefail]; }; From 1f6a9afae4ffbe05064c7a1630df7b0d0750d1e1 Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Sun, 15 Feb 2015 15:23:43 +0100 Subject: [PATCH 34/58] better error message --- src/static/js/Changeset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index f0c7d8b4c..4d0f76a92 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -1620,7 +1620,7 @@ exports.makeAText = function (text, attribs) { exports.applyToAText = function (cs, atext, pool) { var text = exports.applyToText(cs, atext.text) if(text[1]){ - throw new Error() + throw new Error("newline count is wrong, cs:",cs," and text:",atext) } return { text: text[0], From c6ef7f4867608706849ce57a211ccc63b52b6f5e Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Sun, 15 Feb 2015 15:26:07 +0100 Subject: [PATCH 35/58] string concat, not multiple arguments... --- src/static/js/Changeset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index 4d0f76a92..31b1323c2 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -1620,7 +1620,7 @@ exports.makeAText = function (text, attribs) { exports.applyToAText = function (cs, atext, pool) { var text = exports.applyToText(cs, atext.text) if(text[1]){ - throw new Error("newline count is wrong, cs:",cs," and text:",atext) + throw new Error("newline count is wrong, cs:"+cs+" and text:"+atext) } return { text: text[0], From b9dd983f810455639e7b4d17f1327c329af8d9b8 Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Sun, 15 Feb 2015 15:27:27 +0100 Subject: [PATCH 36/58] print the actual text... --- src/static/js/Changeset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index 31b1323c2..93a7c5581 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -1620,7 +1620,7 @@ exports.makeAText = function (text, attribs) { exports.applyToAText = function (cs, atext, pool) { var text = exports.applyToText(cs, atext.text) if(text[1]){ - throw new Error("newline count is wrong, cs:"+cs+" and text:"+atext) + throw new Error("newline count is wrong, cs:"+cs+" and text:"+atext.text) } return { text: text[0], From 440f74b2c104e050a4ec502403dc68192759f020 Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Sun, 15 Feb 2015 15:47:45 +0100 Subject: [PATCH 37/58] we do not have the text/padid, but at least we can print the changeset --- src/static/js/Changeset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index 93a7c5581..6ccfe70f3 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -1239,7 +1239,7 @@ exports.mutateAttributionLines = function (cs, lines, pool) { } } - exports.assert(!lineAssem, "line assembler not finished"); + exports.assert(!lineAssem, "line assembler not finished:"+cs); mut.close(); //dmesg("-> "+lines.toSource()); From 66582b19e7a196b77df1e9a912db020189a93014 Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Sun, 15 Feb 2015 16:21:07 +0100 Subject: [PATCH 38/58] 51c14d994756e60333b0b60eccb7255cf0c86461 changed the return value of applyToText to an array that includes if there was an error in the newline part of an changeset op. easysync_tests need to know this too --- src/node/easysync_tests.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/node/easysync_tests.js b/src/node/easysync_tests.js index 374e949fd..93e661b0e 100644 --- a/src/node/easysync_tests.js +++ b/src/node/easysync_tests.js @@ -149,7 +149,7 @@ function runTests() { var correctText = correct.join(''); //print(literal(cs)); - var outText = Changeset.applyToText(cs, inText); + var outText = Changeset.applyToText(cs, inText)[0]; assertEqualStrings(correctText, outText); } @@ -585,9 +585,9 @@ function runTests() { var change123a = Changeset.checkRep(Changeset.compose(change1, change23, p)); assertEqualStrings(change123, change123a); - assertEqualStrings(text2, Changeset.applyToText(change12, startText)); - assertEqualStrings(text3, Changeset.applyToText(change23, text1)); - assertEqualStrings(text3, Changeset.applyToText(change123, startText)); + assertEqualStrings(text2, Changeset.applyToText(change12, startText)[0]); + assertEqualStrings(text3, Changeset.applyToText(change23, text1)[0]); + assertEqualStrings(text3, Changeset.applyToText(change123, startText)[0]); } for (var i = 0; i < 30; i++) testCompose(i); @@ -699,7 +699,7 @@ function runTests() { print("> testMakeSplice"); var t = "a\nb\nc\n"; - var t2 = Changeset.applyToText(Changeset.makeSplice(t, 5, 0, "def"), t); + var t2 = Changeset.applyToText(Changeset.makeSplice(t, 5, 0, "def"), t)[0]; assertEqualStrings("a\nb\ncdef\n", t2); })(); From 0505a4735686322639981f0564757e4543f2706d Mon Sep 17 00:00:00 2001 From: Stefan Date: Sun, 15 Feb 2015 22:21:41 +0100 Subject: [PATCH 39/58] Support node version 0.12.x --- bin/installDeps.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/installDeps.sh b/bin/installDeps.sh index fcf213e48..04c4a02a9 100755 --- a/bin/installDeps.sh +++ b/bin/installDeps.sh @@ -50,9 +50,9 @@ NODE_V_MINOR=$(echo $NODE_VERSION | cut -d "." -f 1-2) 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 +if [ ! $NODE_V_MINOR = "v0.8" ] && [ ! $NODE_V_MINOR = "v0.10" ] && [ ! $NODE_V_MINOR = "v0.11" ] && [ ! $NODE_V_MINOR = "v0.12" ]; then 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 + 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, v0.11.x or v0.12.x" >&2 exit 1 fi fi From 83e1bf0dc4259fed5578174a9dfcf1682acc8854 Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Mon, 16 Feb 2015 03:33:57 +0100 Subject: [PATCH 40/58] add semicolons --- src/static/js/Changeset.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index 6ccfe70f3..ff4d16c66 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -915,7 +915,7 @@ exports.applyToText = function (cs, str) { var csIter = exports.opIterator(unpacked.ops); var bankIter = exports.stringIterator(unpacked.charBank); var strIter = exports.stringIterator(str); - var newlinefail = false + var newlinefail = false; var assem = exports.stringAssembler(); while (csIter.hasNext()) { var op = csIter.next(); @@ -924,7 +924,7 @@ exports.applyToText = function (cs, str) { //op is + and op.lines 0: no newlines must be in op.chars //op is + and op.lines >0: op.chars must include op.lines newlines if(op.lines != bankIter.peek(op.chars).split("\n").length - 1){ - newlinefail = true + newlinefail = true; } assem.append(bankIter.take(op.chars)); break; @@ -932,7 +932,7 @@ exports.applyToText = function (cs, str) { //op is - and op.lines 0: no newlines must be in the deleted string //op is - and op.lines >0: op.lines newlines must be in the deleted string if(op.lines != strIter.peek(op.chars).split("\n").length - 1){ - newlinefail = true + newlinefail = true; } strIter.skip(op.chars); break; @@ -940,7 +940,7 @@ exports.applyToText = function (cs, str) { //op is = and op.lines 0: no newlines must be in the copied string //op is = and op.lines >0: op.lines newlines must be in the copied string if(op.lines != strIter.peek(op.chars).split("\n").length - 1){ - newlinefail = true + newlinefail = true; } assem.append(strIter.take(op.chars)); break; @@ -1620,7 +1620,7 @@ exports.makeAText = function (text, attribs) { exports.applyToAText = function (cs, atext, pool) { var text = exports.applyToText(cs, atext.text) if(text[1]){ - throw new Error("newline count is wrong, cs:"+cs+" and text:"+atext.text) + throw new Error("newline count is wrong, cs:"+cs+" and text:"+atext.text); } return { text: text[0], From 59328aa33a5448d4a3b881de5e33bd93662e2d2c Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Mon, 16 Feb 2015 06:22:49 +0100 Subject: [PATCH 41/58] Revert "51c14d994756e60333b0b60eccb7255cf0c86461 changed the return value of" This reverts commit 66582b19e7a196b77df1e9a912db020189a93014. --- src/node/easysync_tests.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/node/easysync_tests.js b/src/node/easysync_tests.js index 93e661b0e..374e949fd 100644 --- a/src/node/easysync_tests.js +++ b/src/node/easysync_tests.js @@ -149,7 +149,7 @@ function runTests() { var correctText = correct.join(''); //print(literal(cs)); - var outText = Changeset.applyToText(cs, inText)[0]; + var outText = Changeset.applyToText(cs, inText); assertEqualStrings(correctText, outText); } @@ -585,9 +585,9 @@ function runTests() { var change123a = Changeset.checkRep(Changeset.compose(change1, change23, p)); assertEqualStrings(change123, change123a); - assertEqualStrings(text2, Changeset.applyToText(change12, startText)[0]); - assertEqualStrings(text3, Changeset.applyToText(change23, text1)[0]); - assertEqualStrings(text3, Changeset.applyToText(change123, startText)[0]); + assertEqualStrings(text2, Changeset.applyToText(change12, startText)); + assertEqualStrings(text3, Changeset.applyToText(change23, text1)); + assertEqualStrings(text3, Changeset.applyToText(change123, startText)); } for (var i = 0; i < 30; i++) testCompose(i); @@ -699,7 +699,7 @@ function runTests() { print("> testMakeSplice"); var t = "a\nb\nc\n"; - var t2 = Changeset.applyToText(Changeset.makeSplice(t, 5, 0, "def"), t)[0]; + var t2 = Changeset.applyToText(Changeset.makeSplice(t, 5, 0, "def"), t); assertEqualStrings("a\nb\ncdef\n", t2); })(); From c9a5167b41f2a5b247a0a59cd42dd77f29123e71 Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Mon, 16 Feb 2015 06:27:18 +0100 Subject: [PATCH 42/58] throw in applyToText and not in applyToAText --- src/static/js/Changeset.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index ff4d16c66..df180f9cf 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -915,7 +915,6 @@ exports.applyToText = function (cs, str) { var csIter = exports.opIterator(unpacked.ops); var bankIter = exports.stringIterator(unpacked.charBank); var strIter = exports.stringIterator(str); - var newlinefail = false; var assem = exports.stringAssembler(); while (csIter.hasNext()) { var op = csIter.next(); @@ -924,7 +923,7 @@ exports.applyToText = function (cs, str) { //op is + and op.lines 0: no newlines must be in op.chars //op is + and op.lines >0: op.chars must include op.lines newlines if(op.lines != bankIter.peek(op.chars).split("\n").length - 1){ - newlinefail = true; + throw new Error("newline count is wrong in op +; cs:"+cs+" and text:"+str); } assem.append(bankIter.take(op.chars)); break; @@ -932,7 +931,7 @@ exports.applyToText = function (cs, str) { //op is - and op.lines 0: no newlines must be in the deleted string //op is - and op.lines >0: op.lines newlines must be in the deleted string if(op.lines != strIter.peek(op.chars).split("\n").length - 1){ - newlinefail = true; + throw new Error("newline count is wrong in op -; cs:"+cs+" and text:"+str); } strIter.skip(op.chars); break; @@ -940,14 +939,14 @@ exports.applyToText = function (cs, str) { //op is = and op.lines 0: no newlines must be in the copied string //op is = and op.lines >0: op.lines newlines must be in the copied string if(op.lines != strIter.peek(op.chars).split("\n").length - 1){ - newlinefail = true; + throw new Error("newline count is wrong in op =; cs:"+cs+" and text:"+str); } assem.append(strIter.take(op.chars)); break; } } assem.append(strIter.take(strIter.remaining())); - return [assem.toString(),newlinefail]; + return assem.toString(); }; /** @@ -1618,12 +1617,8 @@ exports.makeAText = function (text, attribs) { * @param pool {AttribPool} Attribute Pool to add to */ exports.applyToAText = function (cs, atext, pool) { - var text = exports.applyToText(cs, atext.text) - if(text[1]){ - throw new Error("newline count is wrong, cs:"+cs+" and text:"+atext.text); - } return { - text: text[0], + text: exports.applyToText(cs, atext.text), attribs: exports.applyToAttribution(cs, atext.attribs, pool) }; }; From 37924e441a3c0432088d3c33f544c8c7cefc92eb Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Mon, 16 Feb 2015 09:01:30 +0100 Subject: [PATCH 43/58] add try-catch clause around calls to applyToAText --- src/node/utils/padDiff.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/node/utils/padDiff.js b/src/node/utils/padDiff.js index 88fa5cbad..24d5bb0c2 100644 --- a/src/node/utils/padDiff.js +++ b/src/node/utils/padDiff.js @@ -101,8 +101,12 @@ PadDiff.prototype._createClearStartAtext = function(rev, callback){ return callback(err); } + try { //apply the clearAuthorship changeset var newAText = Changeset.applyToAText(changeset, atext, self._pad.pool); + } catch(err) { + return callback(err) + } callback(null, newAText); }); @@ -209,10 +213,14 @@ PadDiff.prototype._createDiffAtext = function(callback) { if(superChangeset){ var deletionChangeset = self._createDeletionChangeset(superChangeset,atext,self._pad.pool); - //apply the superChangeset, which includes all addings - atext = Changeset.applyToAText(superChangeset,atext,self._pad.pool); - //apply the deletionChangeset, which adds a deletions - atext = Changeset.applyToAText(deletionChangeset,atext,self._pad.pool); + try { + //apply the superChangeset, which includes all addings + atext = Changeset.applyToAText(superChangeset,atext,self._pad.pool); + //apply the deletionChangeset, which adds a deletions + atext = Changeset.applyToAText(deletionChangeset,atext,self._pad.pool); + } catch(err) { + return callback(err) + } } callback(err, atext); From ec6a2b5ba906565124b8cfc4eaffe1a08bb06d18 Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 16 Feb 2015 23:02:19 +0000 Subject: [PATCH 44/58] allow for load testing connections to hit by a setting --- settings.json.template | 3 +++ src/node/hooks/express/socketio.js | 8 ++++++-- src/node/utils/Settings.js | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/settings.json.template b/settings.json.template index 3f84af9b8..124345e2b 100644 --- a/settings.json.template +++ b/settings.json.template @@ -108,6 +108,9 @@ // restrict socket.io transport methods "socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"], + + // Allow Load Testing tools to hit the Etherpad Instance. Warning this will disable security on the instance. + "loadTest": false, /* The toolbar buttons configuration. "toolbar": { diff --git a/src/node/hooks/express/socketio.js b/src/node/hooks/express/socketio.js index b70aa50ed..35d6d074d 100644 --- a/src/node/hooks/express/socketio.js +++ b/src/node/hooks/express/socketio.js @@ -23,8 +23,12 @@ exports.expressCreateServer = function (hook_name, args, cb) { io.use(function(socket, accept) { var data = socket.request; - if (!data.headers.cookie) return accept('No session cookie transmitted.', false); - + // Use a setting if we want to allow load Testing + if(!data.headers.cookie && settings.loadTest){ + accept(null, true); + }else{ + if (!data.headers.cookie) return accept('No session cookie transmitted.', false); + } // Use connect's cookie parser, because it knows how to parse signed cookies connect.cookieParser(webaccess.secret)(data, {}, function(err){ if(err) { diff --git a/src/node/utils/Settings.js b/src/node/utils/Settings.js index 1fb5bddfb..5382d819a 100644 --- a/src/node/utils/Settings.js +++ b/src/node/utils/Settings.js @@ -144,6 +144,11 @@ exports.loglevel = "INFO"; */ exports.disableIPlogging = false; +/** + * Disable Load Testing + */ +exports.loadTest = false; + /* * log4js appender configuration */ From abb9b6d8330c22f10d55931690004a4fb4d1e6e1 Mon Sep 17 00:00:00 2001 From: Siebrand Mazeland Date: Thu, 19 Feb 2015 13:02:42 +0100 Subject: [PATCH 45/58] Localisation updates from https://translatewiki.net. --- src/locales/awa.json | 69 ++++++++++++++++++++ src/locales/be-tarask.json | 2 + src/locales/cs.json | 10 ++- src/locales/de.json | 4 +- src/locales/el.json | 2 + src/locales/en-gb.json | 127 +++++++++++++++++++++++++++++++++++++ src/locales/es.json | 9 ++- src/locales/eu.json | 4 +- src/locales/fr.json | 2 + src/locales/gl.json | 6 +- src/locales/he.json | 5 ++ src/locales/it.json | 5 +- src/locales/ksh.json | 5 ++ src/locales/mk.json | 2 + src/locales/nl.json | 5 ++ src/locales/pt-br.json | 5 +- src/locales/ru.json | 1 + src/locales/sr-ec.json | 59 +++++++++++++++++ src/locales/sv.json | 2 + src/locales/zh-hans.json | 4 +- 20 files changed, 315 insertions(+), 13 deletions(-) create mode 100644 src/locales/awa.json create mode 100644 src/locales/en-gb.json create mode 100644 src/locales/sr-ec.json diff --git a/src/locales/awa.json b/src/locales/awa.json new file mode 100644 index 000000000..f8c0d501c --- /dev/null +++ b/src/locales/awa.json @@ -0,0 +1,69 @@ +{ + "@metadata": { + "authors": [ + "1AnuraagPandey" + ] + }, + "index.newPad": "नयाँ प्याड", + "pad.toolbar.bold.title": "मोट (Ctrl-B)", + "pad.toolbar.italic.title": "तिरछा (Ctrl+I)", + "pad.toolbar.underline.title": "निम्न रेखाङ्कन (Ctrl-U)", + "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.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.colorcheck": "लेखकीय रङ्ग", + "pad.settings.linenocheck": "हरफ संख्या", + "pad.settings.fontType": "फन्ट प्रकार:", + "pad.settings.fontType.normal": "साधारण", + "pad.settings.fontType.monospaced": "मोनोस्पेस", + "pad.settings.globalView": "विश्वव्यापी दृष्य", + "pad.settings.language": "भाषा", + "pad.importExport.import_export": "आयात/निर्यात", + "pad.importExport.importSuccessful": "सफल!", + "pad.importExport.exporthtml": "HTML", + "pad.importExport.exportplain": "सामान्य पाठ", + "pad.importExport.exportword": "माइक्रोसफ्ट वर्ड", + "pad.importExport.exportpdf": "पिडिएफ", + "pad.importExport.exportopen": "ओडिएफ(खुल्ला कागजात ढाँचा)", + "pad.modals.unauth": "अनाधिकृत", + "pad.modals.initsocketfail": "सर्भरमा पहुँच से बहरे है ।", + "pad.share.readonly": "पढय वाला खाली", + "pad.share.link": "लिङ्क", + "pad.share.emebdcode": "URL जोडा जाय", + "pad.chat": "बातचीत", + "timeslider.pageTitle": "{{appTitle}} समय रेखा", + "timeslider.toolbar.authors": "लेखक:", + "timeslider.toolbar.exportlink.title": "निर्यात", + "timeslider.version": "संस्करण {{version}}", + "timeslider.dateformat": "{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}", + "timeslider.month.january": "जनवरी", + "timeslider.month.february": "फेब्रुअरी", + "timeslider.month.march": "मार्च", + "timeslider.month.april": "अप्रैल", + "timeslider.month.may": "मई", + "timeslider.month.june": "जून", + "timeslider.month.july": "जुलाई", + "timeslider.month.august": "अगस्त", + "timeslider.month.september": "सेप्टेम्बर", + "timeslider.month.october": "अक्टूबर", + "timeslider.month.november": "नोभेम्बर", + "timeslider.month.december": "डिसेम्बर", + "timeslider.unnamedauthors": "{{num}} unnamed {[plural(num) one: author, other: authors ]}", + "pad.userlist.unnamed": "बेनामी", + "pad.userlist.guest": "पहुना", + "pad.userlist.deny": "अस्वीकार", + "pad.userlist.approve": "स्वीकृत", + "pad.impexp.importing": "आयात होत है...", + "pad.impexp.importfailed": "आयात असफल रहा", + "pad.impexp.copypaste": "कृपया कपी पेस्ट कीन जाय" +} diff --git a/src/locales/be-tarask.json b/src/locales/be-tarask.json index f67d10fe5..3c7898580 100644 --- a/src/locales/be-tarask.json +++ b/src/locales/be-tarask.json @@ -35,6 +35,7 @@ "pad.settings.padSettings": "Налады дакумэнта", "pad.settings.myView": "Мой выгляд", "pad.settings.stickychat": "Заўсёды паказваць чат", + "pad.settings.chatandusers": "Паказаць чат і ўдзельнікаў", "pad.settings.colorcheck": "Колеры аўтарства", "pad.settings.linenocheck": "Нумары радкоў", "pad.settings.rtlcheck": "Тэкст справа-налева", @@ -108,6 +109,7 @@ "timeslider.month.december": "сьнежань", "timeslider.unnamedauthors": "{{num}} {[plural(num) one: безыменны аўтар, few: безыменныя аўтары, many: безыменных аўтараў, other: безыменных аўтараў ]}", "pad.savedrevs.marked": "Гэтая вэрсія цяпер пазначаная як захаваная", + "pad.savedrevs.timeslider": "Вы можаце пабачыць захаваныя вэрсіі з дапамогай шкалы часу", "pad.userlist.entername": "Увядзіце вашае імя", "pad.userlist.unnamed": "безыменны", "pad.userlist.guest": "Госьць", diff --git a/src/locales/cs.json b/src/locales/cs.json index 2a6b5fec1..19552ffd5 100644 --- a/src/locales/cs.json +++ b/src/locales/cs.json @@ -13,11 +13,11 @@ "pad.toolbar.bold.title": "Tučný text (Ctrl-B)", "pad.toolbar.italic.title": "Kurzíva (Ctrl-I)", "pad.toolbar.underline.title": "Podtržené písmo (Ctrl-U)", - "pad.toolbar.strikethrough.title": "Přeskrtnuté písmo", + "pad.toolbar.strikethrough.title": "Přeškrtnuto (Ctrl+5)", "pad.toolbar.ol.title": "Číslovaný seznam", "pad.toolbar.ul.title": "Nečíslovaný seznam", - "pad.toolbar.indent.title": "Odsazení", - "pad.toolbar.unindent.title": "Předsazení", + "pad.toolbar.indent.title": "Odsazení (TAB)", + "pad.toolbar.unindent.title": "Předsazení (Shift+TAB)", "pad.toolbar.undo.title": "Zpět (Ctrl-Z)", "pad.toolbar.redo.title": "Opakovat (Ctrl-Y)", "pad.toolbar.clearAuthorship.title": "Vymazat barvy autorů", @@ -30,12 +30,14 @@ "pad.colorpicker.save": "Uložit", "pad.colorpicker.cancel": "Zrušit", "pad.loading": "Načítání...", + "pad.noCookie": "Nelze nalézt cookie. Povolte prosím cookie ve Vašem prohlížeči.", "pad.passwordRequired": "Pro přístup k tomuto Padu je třeba znát heslo", "pad.permissionDenied": "Nemáte oprávnění pro přístup k tomuto Padu", "pad.wrongPassword": "Nesprávné heslo", "pad.settings.padSettings": "Nastavení Padu", "pad.settings.myView": "Vlastní pohled", "pad.settings.stickychat": "Chat vždy na obrazovce", + "pad.settings.chatandusers": "Ukázat Chat a Uživatele", "pad.settings.colorcheck": "Barvy autorů", "pad.settings.linenocheck": "Čísla řádků", "pad.settings.rtlcheck": "Číst obsah zprava doleva?", @@ -109,6 +111,7 @@ "timeslider.month.december": "prosinec", "timeslider.unnamedauthors": "{{num}} {[ plural(num) one: nejmenovaný Autor, few: nejmenovaní Autoři, other: nejmenovaných Autorů ]}", "pad.savedrevs.marked": "Tato revize je nyní označena jako uložená", + "pad.savedrevs.timeslider": "Návštěvou časové osy zobrazíte uložené revize", "pad.userlist.entername": "Zadejte své jméno", "pad.userlist.unnamed": "nejmenovaný", "pad.userlist.guest": "Host", @@ -119,6 +122,7 @@ "pad.impexp.importing": "Importování…", "pad.impexp.confirmimport": "Import souboru přepíše aktuální text v padu. Opravdu chcete tuto akci provést?", "pad.impexp.convertFailed": "Tento soubor nelze importovat. Použijte prosím jiný formát dokumentu nebo nakopírujte text ručně", + "pad.impexp.padHasData": "Tento soubor jsme nebyly schopni importovat, protože tento Pad již obsahoval změny. Importujte ho prosím do nového padu", "pad.impexp.uploadFailed": "Nahrávání selhalo, zkuste to znovu", "pad.impexp.importfailed": "Import selhal", "pad.impexp.copypaste": "Vložte prosím kopii", diff --git a/src/locales/de.json b/src/locales/de.json index a2bca7237..4888b8e89 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -36,6 +36,7 @@ "pad.settings.padSettings": "Pad Einstellungen", "pad.settings.myView": "Eigene Ansicht", "pad.settings.stickychat": "Chat immer anzeigen", + "pad.settings.chatandusers": "Chat und Benutzer anzeigen", "pad.settings.colorcheck": "Autorenfarben anzeigen", "pad.settings.linenocheck": "Zeilennummern", "pad.settings.rtlcheck": "Inhalt von rechts nach links lesen?", @@ -109,6 +110,7 @@ "timeslider.month.december": "Dezember", "timeslider.unnamedauthors": "{{num}} {[plural(num) one: unbenannter Autor, other: unbenannte Autoren ]}", "pad.savedrevs.marked": "Diese Version wurde jetzt als gespeicherte Version gekennzeichnet", + "pad.savedrevs.timeslider": "Du kannst gespeicherte Versionen durch das Besuchen der Pad-Versionsgeschichte ansehen", "pad.userlist.entername": "Geben Sie Ihren Namen ein", "pad.userlist.unnamed": "unbenannt", "pad.userlist.guest": "Gast", @@ -119,7 +121,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.padHasData": "Wir konnten diese Datei nicht importieren, da dieses Pad bereits Änderungen enthält. Bitte importiere sie in ein neues 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/el.json b/src/locales/el.json index 740da95c0..f18c71e47 100644 --- a/src/locales/el.json +++ b/src/locales/el.json @@ -37,6 +37,7 @@ "pad.settings.padSettings": "Ρυθμίσεις Pad", "pad.settings.myView": "Η προβολή μου", "pad.settings.stickychat": "Να είναι πάντα ορατή η συνομιλία", + "pad.settings.chatandusers": "Εμφάνιση Συνομιλίας και Χρηστών", "pad.settings.colorcheck": "Χρώματα συντάκτη", "pad.settings.linenocheck": "Αριθμοί γραμμών", "pad.settings.rtlcheck": "Διαβάζεται το περιεχόμενο από δεξιά προς τα αριστερά;", @@ -110,6 +111,7 @@ "timeslider.month.december": "Δεκεμβρίου", "timeslider.unnamedauthors": "{{num}} {[plural(num) one: ανώνυμος συντάκτης, other: ανώνυμοι συντάκτες]}", "pad.savedrevs.marked": "Αυτή η έκδοση επισημάνθηκε ως αποθηκευμένη έκδοση", + "pad.savedrevs.timeslider": "Μπορείτε να δείτε αποθηκευμένες αναθεωρήσεις στο χρονοδιάγραμμα", "pad.userlist.entername": "Εισάγετε το όνομά σας", "pad.userlist.unnamed": "ανώνυμος", "pad.userlist.guest": "Επισκέπτης", diff --git a/src/locales/en-gb.json b/src/locales/en-gb.json new file mode 100644 index 000000000..258b43316 --- /dev/null +++ b/src/locales/en-gb.json @@ -0,0 +1,127 @@ +{ + "@metadata": { + "authors": [ + "Chase me ladies, I'm the Cavalry", + "Shirayuki" + ] + }, + "index.newPad": "New Pad", + "index.createOpenPad": "or create/open a Pad with the name:", + "pad.toolbar.bold.title": "Bold (Ctrl+B)", + "pad.toolbar.italic.title": "Italic (Ctrl+I)", + "pad.toolbar.underline.title": "Underline (Ctrl+U)", + "pad.toolbar.strikethrough.title": "Strikethrough (Ctrl+5)", + "pad.toolbar.ol.title": "Ordered list (Ctrl+Shift+N)", + "pad.toolbar.ul.title": "Unordered List (Ctrl+Shift+L)", + "pad.toolbar.indent.title": "Indent (Tab)", + "pad.toolbar.unindent.title": "Outdent (Shift+Tab)", + "pad.toolbar.undo.title": "Undo (Ctrl+Z)", + "pad.toolbar.redo.title": "Redo (Ctrl+Y)", + "pad.toolbar.clearAuthorship.title": "Clear Authorship Colours (Ctrl+Shift+C)", + "pad.toolbar.import_export.title": "Import/Export from/to different file formats", + "pad.toolbar.timeslider.title": "Timeslider", + "pad.toolbar.savedRevision.title": "Save Revision", + "pad.toolbar.settings.title": "Settings", + "pad.toolbar.embed.title": "Share and Embed this pad", + "pad.toolbar.showusers.title": "Show the users on this pad", + "pad.colorpicker.save": "Save", + "pad.colorpicker.cancel": "Cancel", + "pad.loading": "Loading...", + "pad.noCookie": "Cookie could not be found. Please allow cookies in your browser!", + "pad.passwordRequired": "You need a password to access this pad", + "pad.permissionDenied": "You do not have permission to access this pad", + "pad.wrongPassword": "Your password was wrong", + "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 colours", + "pad.settings.linenocheck": "Line numbers", + "pad.settings.rtlcheck": "Read content from right to left?", + "pad.settings.fontType": "Font type:", + "pad.settings.fontType.normal": "Normal", + "pad.settings.fontType.monospaced": "Monospace", + "pad.settings.globalView": "Global View", + "pad.settings.language": "Language:", + "pad.importExport.import_export": "Import/Export", + "pad.importExport.import": "Upload any text file or document", + "pad.importExport.importSuccessful": "Successful!", + "pad.importExport.export": "Export current pad as:", + "pad.importExport.exportetherpad": "Etherpad", + "pad.importExport.exporthtml": "HTML", + "pad.importExport.exportplain": "Plain text", + "pad.importExport.exportword": "Microsoft Word", + "pad.importExport.exportpdf": "PDF", + "pad.importExport.exportopen": "ODF (Open Document Format)", + "pad.importExport.abiword.innerHTML": "You only can import from plain text or HTML formats. For more advanced import features please install abiword.", + "pad.modals.connected": "Connected.", + "pad.modals.reconnecting": "Reconnecting to your pad..", + "pad.modals.forcereconnect": "Force reconnect", + "pad.modals.userdup": "Opened in another window", + "pad.modals.userdup.explanation": "This pad seems to be opened in more than one browser window on this computer.", + "pad.modals.userdup.advice": "Reconnect to use this window instead.", + "pad.modals.unauth": "Not authorised", + "pad.modals.unauth.explanation": "Your permissions have changed while viewing this page. Try to reconnect.", + "pad.modals.looping.explanation": "There are communication problems with the synchronisation server.", + "pad.modals.looping.cause": "Perhaps you connected through an incompatible firewall or proxy.", + "pad.modals.initsocketfail": "Server is unreachable.", + "pad.modals.initsocketfail.explanation": "Couldn't connect to the synchronisation server.", + "pad.modals.initsocketfail.cause": "This is probably due to a problem with your browser or your internet connection.", + "pad.modals.slowcommit.explanation": "The server is not responding.", + "pad.modals.slowcommit.cause": "This could be due to problems with network connectivity.", + "pad.modals.badChangeset.explanation": "An edit you have made was classified illegal by the synchronisation server.", + "pad.modals.badChangeset.cause": "This could be due to a wrong server configuration or some other unexpected behaviour. Please contact the service administrator, if you feel this is an error. Try to reconnect in order to continue editing.", + "pad.modals.corruptPad.explanation": "The pad you are trying to access is corrupt.", + "pad.modals.corruptPad.cause": "This may be due to a wrong server configuration or some other unexpected behaviour. Please contact the service administrator.", + "pad.modals.deleted": "Deleted.", + "pad.modals.deleted.explanation": "This pad has been removed.", + "pad.modals.disconnected": "You have been disconnected.", + "pad.modals.disconnected.explanation": "The connection to the server was lost", + "pad.modals.disconnected.cause": "The server may be unavailable. Please notify the service administrator if this continues to happen.", + "pad.share": "Share this pad", + "pad.share.readonly": "Read only", + "pad.share.link": "Link", + "pad.share.emebdcode": "Embed URL", + "pad.chat": "Chat", + "pad.chat.title": "Open the chat for this pad.", + "pad.chat.loadmessages": "Load more messages", + "timeslider.pageTitle": "{{appTitle}} Timeslider", + "timeslider.toolbar.returnbutton": "Return to pad", + "timeslider.toolbar.authors": "Authors:", + "timeslider.toolbar.authorsList": "No Authors", + "timeslider.toolbar.exportlink.title": "Export", + "timeslider.exportCurrent": "Export current version as:", + "timeslider.version": "Version {{version}}", + "timeslider.saved": "Saved {{month}} {{day}}, {{year}}", + "timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}", + "timeslider.month.january": "January", + "timeslider.month.february": "February", + "timeslider.month.march": "March", + "timeslider.month.april": "April", + "timeslider.month.may": "May", + "timeslider.month.june": "June", + "timeslider.month.july": "July", + "timeslider.month.august": "August", + "timeslider.month.september": "September", + "timeslider.month.october": "October", + "timeslider.month.november": "November", + "timeslider.month.december": "December", + "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", + "pad.userlist.deny": "Deny", + "pad.userlist.approve": "Approve", + "pad.editbar.clearcolors": "Clear authorship colours on entire document?", + "pad.impexp.importbutton": "Import Now", + "pad.impexp.importing": "Importing...", + "pad.impexp.confirmimport": "Importing a file will overwrite the current text of the pad. Are you sure you want to proceed?", + "pad.impexp.convertFailed": "We were not able to import this file. Please use a different document format or copy & paste manually", + "pad.impexp.padHasData": "We were not able to import this file because this Pad has already had changes, please import to a new pad", + "pad.impexp.uploadFailed": "The upload failed, please try again", + "pad.impexp.importfailed": "Import failed", + "pad.impexp.copypaste": "Please copy & paste", + "pad.impexp.exportdisabled": "Exporting as {{type}} format is disabled. Please contact your system administrator for details." +} diff --git a/src/locales/es.json b/src/locales/es.json index 5547d3278..21eb60a78 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -10,7 +10,8 @@ "VegaDark", "Vivaelcelta", "Xuacu", - "Macofe" + "Macofe", + "Fitoschido" ] }, "index.newPad": "Nuevo pad", @@ -42,6 +43,7 @@ "pad.settings.padSettings": "Configuración del pad", "pad.settings.myView": "Preferencias personales", "pad.settings.stickychat": "Chat siempre en pantalla", + "pad.settings.chatandusers": "Mostrar el chat y los usuarios", "pad.settings.colorcheck": "Colores de autoría", "pad.settings.linenocheck": "Números de línea", "pad.settings.rtlcheck": "¿Leer contenido de derecha a izquierda?", @@ -56,11 +58,11 @@ "pad.importExport.export": "Exporta el pad actual como:", "pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exporthtml": "HTML", - "pad.importExport.exportplain": "Texto plano", + "pad.importExport.exportplain": "Texto sin formato", "pad.importExport.exportword": "Microsoft Word", "pad.importExport.exportpdf": "PDF", "pad.importExport.exportopen": "ODF (Open Document Format)", - "pad.importExport.abiword.innerHTML": "Sólo puedes importar formatos de texto plano o html. Para funciones más avanzadas instala abiword.", + "pad.importExport.abiword.innerHTML": "Solo es posible importar texto sin formato o en HTML. Para obtener funciones de importación más avanzadas es necesario instalar AbiWord.", "pad.modals.connected": "Conectado.", "pad.modals.reconnecting": "Reconectando a tu pad..", "pad.modals.forcereconnect": "Forzar reconexión", @@ -115,6 +117,7 @@ "timeslider.month.december": "diciembre", "timeslider.unnamedauthors": "{{num}} {[ plural(num) one: autor desconocido, other: autores desconocidos]}", "pad.savedrevs.marked": "Revisión guardada", + "pad.savedrevs.timeslider": "Puedes ver revisiones guardadas visitando la línea de tiempo", "pad.userlist.entername": "Escribe tu nombre", "pad.userlist.unnamed": "anónimo", "pad.userlist.guest": "Invitado", diff --git a/src/locales/eu.json b/src/locales/eu.json index f12b8d21e..9cd06076c 100644 --- a/src/locales/eu.json +++ b/src/locales/eu.json @@ -1,7 +1,8 @@ { "@metadata": { "authors": [ - "Theklan" + "Theklan", + "Subi" ] }, "index.newPad": "Pad berria", @@ -44,6 +45,7 @@ "pad.importExport.import": "Igo edozein testu fitxategi edo dokumentu", "pad.importExport.importSuccessful": "Arrakastatsua!", "pad.importExport.export": "Oraingo pad hau honela esportatu:", + "pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "Testu laua", "pad.importExport.exportword": "Microsoft Word", diff --git a/src/locales/fr.json b/src/locales/fr.json index 92fcb193a..ba289e3b1 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -50,6 +50,7 @@ "pad.settings.padSettings": "Paramètres du pad", "pad.settings.myView": "Ma vue", "pad.settings.stickychat": "Toujours afficher le chat", + "pad.settings.chatandusers": "Afficher la discussion et les utilisateurs", "pad.settings.colorcheck": "Couleurs d’identification", "pad.settings.linenocheck": "Numéros de lignes", "pad.settings.rtlcheck": "Le contenu doit-il être lu de droite à gauche ?", @@ -123,6 +124,7 @@ "timeslider.month.december": "décembre", "timeslider.unnamedauthors": "{{num}} {[plural(num) one: auteur anonyme, other: auteurs anonymes ]}", "pad.savedrevs.marked": "Cette révision est maintenant marquée comme révision enregistrée", + "pad.savedrevs.timeslider": "Vous pouvez voir les révisions enregistrées en visitant l’ascenseur temporel", "pad.userlist.entername": "Entrez votre nom", "pad.userlist.unnamed": "anonyme", "pad.userlist.guest": "Invité", diff --git a/src/locales/gl.json b/src/locales/gl.json index b0ca6532e..381296aaa 100644 --- a/src/locales/gl.json +++ b/src/locales/gl.json @@ -27,13 +27,14 @@ "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.noCookie": "Non se puido atopar a cookie. 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", "pad.settings.padSettings": "Configuracións do documento", "pad.settings.myView": "A miña vista", "pad.settings.stickychat": "Chat sempre visible", + "pad.settings.chatandusers": "Mostrar o chat e os usuarios", "pad.settings.colorcheck": "Cores de identificación", "pad.settings.linenocheck": "Números de liña", "pad.settings.rtlcheck": "Quere ler o contido da dereita á esquerda?", @@ -107,6 +108,7 @@ "timeslider.month.december": "decembro", "timeslider.unnamedauthors": "{{num}} {[plural(num) one: autor anónimo, other: autores anónimos ]}", "pad.savedrevs.marked": "Esta revisión está agora marcada como revisión gardada", + "pad.savedrevs.timeslider": "Pode consultar as revisións gardadas visitando a liña do tempo", "pad.userlist.entername": "Insira o seu nome", "pad.userlist.unnamed": "anónimo", "pad.userlist.guest": "Convidado", @@ -117,7 +119,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.padHasData": "Non puidemos importar este ficheiro porque este documento xa sufriu cambios; importe a un novo documento.", "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/he.json b/src/locales/he.json index 573bc5f61..4222e1533 100644 --- a/src/locales/he.json +++ b/src/locales/he.json @@ -29,12 +29,14 @@ "pad.colorpicker.save": "שמירה", "pad.colorpicker.cancel": "ביטול", "pad.loading": "טעינה...", + "pad.noCookie": "העוגייה לא נמצאה. נא לאפשר עוגיות בדפדפן שלך!", "pad.passwordRequired": "דרושה ססמה כדי לגשת לפנקס הזה", "pad.permissionDenied": "אין לך הרשאה לגשת לפנקס הזה", "pad.wrongPassword": "ססמתך הייתה שגויה", "pad.settings.padSettings": "הגדרות פנקס", "pad.settings.myView": "התצוגה שלי", "pad.settings.stickychat": "השיחה תמיד על המסך", + "pad.settings.chatandusers": "הצגת צ'אט ומשתמשים", "pad.settings.colorcheck": "צביעה לפי מחבר", "pad.settings.linenocheck": "מספרי שורות", "pad.settings.rtlcheck": "לקרוא את התוכן מימין לשמאל?", @@ -47,6 +49,7 @@ "pad.importExport.import": "העלאת כל קובץ טקסט או מסמך", "pad.importExport.importSuccessful": "זה עבד!", "pad.importExport.export": "ייצוא הפנקס הנוכחי בתור:", + "pad.importExport.exportetherpad": "את'רפד", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "טקסט רגיל", "pad.importExport.exportword": "מיקרוסופט וורד", @@ -107,6 +110,7 @@ "timeslider.month.december": "דצמבר", "timeslider.unnamedauthors": "{[plural(num) one: יוצר אחד, other: {{num}} יוצרים ]} ללא שם", "pad.savedrevs.marked": "גרסה זו מסומנת כגרסה שמורה", + "pad.savedrevs.timeslider": "אפשר להציג גרסאות שמורות באמצעות ביקור בגולל הזמן", "pad.userlist.entername": "נא להזין את שמך", "pad.userlist.unnamed": "ללא שם", "pad.userlist.guest": "אורח", @@ -117,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/it.json b/src/locales/it.json index 02ae8a9f7..a6c30d963 100644 --- a/src/locales/it.json +++ b/src/locales/it.json @@ -5,7 +5,8 @@ "Gianfranco", "Muxator", "Vituzzu", - "Macofe" + "Macofe", + "Nivit" ] }, "index.newPad": "Nuovo Pad", @@ -36,6 +37,7 @@ "pad.settings.padSettings": "Impostazioni del Pad", "pad.settings.myView": "Mia visualizzazione", "pad.settings.stickychat": "Chat sempre sullo schermo", + "pad.settings.chatandusers": "Mostra chat e utenti", "pad.settings.colorcheck": "Colori che indicano gli autori", "pad.settings.linenocheck": "Numeri di riga", "pad.settings.rtlcheck": "Leggere il contenuto da destra a sinistra?", @@ -48,6 +50,7 @@ "pad.importExport.import": "Carica un file di testo o un documento", "pad.importExport.importSuccessful": "Riuscito!", "pad.importExport.export": "Esportare il Pad corrente come:", + "pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "Solo testo", "pad.importExport.exportword": "Microsoft Word", diff --git a/src/locales/ksh.json b/src/locales/ksh.json index 8443e0ec9..f851bbf1d 100644 --- a/src/locales/ksh.json +++ b/src/locales/ksh.json @@ -26,12 +26,14 @@ "pad.colorpicker.save": "Faßhallde", "pad.colorpicker.cancel": "Ophüüre", "pad.loading": "Ben aam Laade …", + "pad.noCookie": "Dat Pläzje wood nit jevonge. Don dat en Dingem Brauser zohlohße!", "pad.passwordRequired": "Do bruchs e Paßwoot för heh dat Pädd.", "pad.permissionDenied": "Do häs nit dat Rääsch, op heh dat Pädd zohzejriife.", "pad.wrongPassword": "Ding Paßwoot wohr verkeht.", "pad.settings.padSettings": "Däm Pädd sing Enschtällonge", "pad.settings.myView": "Aanseesch", "pad.settings.stickychat": "Donn der Klaaf emmer aanzeije", + "pad.settings.chatandusers": "Dunn de Metmaacher un der Klaaf aanzeije", "pad.settings.colorcheck": "Färve för de Schriiver", "pad.settings.linenocheck": "Nommere för de Reije", "pad.settings.rtlcheck": "Schreff vun Rääschß noh Lenks?", @@ -44,6 +46,7 @@ "pad.importExport.import": "Donn jeede Täx udder jeede Zoot Dokemänt huhlaade", "pad.importExport.importSuccessful": "Jeschaff!", "pad.importExport.export": "Don dat Pädd äxpoteere alß:", + "pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "Eijfach Täx", "pad.importExport.exportword": "Microsoft Word", @@ -104,6 +107,7 @@ "timeslider.month.december": "Dezämber", "timeslider.unnamedauthors": "{[plural(num) zero: keine, one: eine, other: {{num}} ]} nahmeloose Schriiver", "pad.savedrevs.marked": "Heh di Väsjohn es jäz faßjehallde.", + "pad.savedrevs.timeslider": "Mer kann de faßjehallde Väsjohne belohre beim Verjangeheid afschpelle", "pad.userlist.entername": "Jif Dinge Nahme en", "pad.userlist.unnamed": "nahmeloßß", "pad.userlist.guest": "Jaßß", @@ -114,6 +118,7 @@ "pad.impexp.importing": "Ben aam Empotteere …", "pad.impexp.confirmimport": "En Dattei ze empotteere määt der janze Täx em Pädd fott. Wells De dat verfaftesch hann?", "pad.impexp.convertFailed": "Mer kunnte di Dattei nit empoteere. Nemm en ander Dattei-Fommaat udder donn dä Täx vun Hand kopeere un ennföhje.", + "pad.impexp.padHasData": "Mer kunnte di Dattei nit empottehre weil et Pädd alt Veränderonge metjemaht hät. Donn se en e neu Pädd empottehre.", "pad.impexp.uploadFailed": "Dat Huhlaade es donävve jejange. Bes esu johd un probeer et norr_ens.", "pad.impexp.importfailed": "Et Empoteere es donävve jejange.", "pad.impexp.copypaste": "Bes esu johd un donn et koppeere un enfööje", diff --git a/src/locales/mk.json b/src/locales/mk.json index 9fc6b817c..a924875ad 100644 --- a/src/locales/mk.json +++ b/src/locales/mk.json @@ -34,6 +34,7 @@ "pad.settings.padSettings": "Поставки на тетратката", "pad.settings.myView": "Мој поглед", "pad.settings.stickychat": "Разговорите секогаш на екранот", + "pad.settings.chatandusers": "Прикажи разговор и корисници", "pad.settings.colorcheck": "Авторски бои", "pad.settings.linenocheck": "Броеви на редовите", "pad.settings.rtlcheck": "Содржините да се читаат од десно на лево?", @@ -107,6 +108,7 @@ "timeslider.month.december": "декември", "timeslider.unnamedauthors": "{{num}} {[plural(num) one: неименуван автор, other: неименувани автори ]}", "pad.savedrevs.marked": "Оваа преработка сега е означена како зачувана", + "pad.savedrevs.timeslider": "Можете да ги погледате зачуваните преработки посетувајќи го времеследниот лизгач", "pad.userlist.entername": "Внесете го вашето име", "pad.userlist.unnamed": "без име", "pad.userlist.guest": "Гостин", diff --git a/src/locales/nl.json b/src/locales/nl.json index ed69527e3..183d0fa98 100644 --- a/src/locales/nl.json +++ b/src/locales/nl.json @@ -28,12 +28,14 @@ "pad.colorpicker.save": "Opslaan", "pad.colorpicker.cancel": "Annuleren", "pad.loading": "Bezig met laden…", + "pad.noCookie": "Er kon geen cookie gevonden worden. Zorg ervoor dat uw browser cookies accepteert.", "pad.passwordRequired": "U hebt een wachtwoord nodig om toegang te krijgen tot deze pad", "pad.permissionDenied": "U hebt geen rechten om deze pad te bekijken", "pad.wrongPassword": "U hebt een onjuist wachtwoord ingevoerd", "pad.settings.padSettings": "Padinstellingen", "pad.settings.myView": "Mijn overzicht", "pad.settings.stickychat": "Chat altijd zichtbaar", + "pad.settings.chatandusers": "Chat en gebruikers weergeven", "pad.settings.colorcheck": "Kleuren auteurs", "pad.settings.linenocheck": "Regelnummers", "pad.settings.rtlcheck": "Inhoud van rechts naar links lezen?", @@ -46,6 +48,7 @@ "pad.importExport.import": "Upload een tekstbestand of document", "pad.importExport.importSuccessful": "Afgerond", "pad.importExport.export": "Huidige pad exporteren als", + "pad.importExport.exportetherpad": "Etherpad", "pad.importExport.exporthtml": "HTML", "pad.importExport.exportplain": "Tekst zonder opmaak", "pad.importExport.exportword": "Microsoft Word", @@ -106,6 +109,7 @@ "timeslider.month.december": "december", "timeslider.unnamedauthors": "{{num}} onbekende {[plural(num) one: auteur, other: auteurs ]}", "pad.savedrevs.marked": "Deze versie is nu gemarkeerd als opgeslagen versie", + "pad.savedrevs.timeslider": "U kunt opgeslagen versies bekijken via de tijdschuiver.", "pad.userlist.entername": "Geef uw naam op", "pad.userlist.unnamed": "zonder naam", "pad.userlist.guest": "Gast", @@ -116,6 +120,7 @@ "pad.impexp.importing": "Bezig met importeren…", "pad.impexp.confirmimport": "Door een bestand te importeren overschrijft u de huidige tekst van de pad. Wilt u echt doorgaan?", "pad.impexp.convertFailed": "Het was niet mogelijk dit bestand te importeren. Gebruik een andere documentopmaak of kopieer en plak de inhoud handmatig", + "pad.impexp.padHasData": "Het was niet mogelijk dit bestand te importeren omdat er al wijzigingen aan de etherpad zijn gemaakt. Importeer naar een nieuwe etherpad.", "pad.impexp.uploadFailed": "Het uploaden is mislukt. Probeer het opnieuw", "pad.impexp.importfailed": "Importeren is mislukt", "pad.impexp.copypaste": "Gebruik kopiëren en plakken", diff --git a/src/locales/pt-br.json b/src/locales/pt-br.json index e8eb79eef..1fd145bc2 100644 --- a/src/locales/pt-br.json +++ b/src/locales/pt-br.json @@ -11,7 +11,8 @@ "Dianakc", "Macofe", "Rodrigo codignoli", - "Webysther" + "Webysther", + "Fasouzafreitas" ] }, "index.newPad": "Nova Nota", @@ -43,6 +44,7 @@ "pad.settings.padSettings": "Configurações da Nota", "pad.settings.myView": "Minha Visão", "pad.settings.stickychat": "Conversa sempre visível", + "pad.settings.chatandusers": "Mostrar o chat e os usuários", "pad.settings.colorcheck": "Cores de autoria", "pad.settings.linenocheck": "Números de linha", "pad.settings.rtlcheck": "Ler conteúdo da direita para esquerda?", @@ -116,6 +118,7 @@ "timeslider.month.december": "Dezembro", "timeslider.unnamedauthors": "{{num}} {[plural(num) one: autor anônimo, other: autores anônimos ]}", "pad.savedrevs.marked": "Esta revisão foi marcada como salva", + "pad.savedrevs.timeslider": "Pode consultar as revisões salvas visitando a linha do tempo", "pad.userlist.entername": "Insira o seu nome", "pad.userlist.unnamed": "Sem título", "pad.userlist.guest": "Convidado", diff --git a/src/locales/ru.json b/src/locales/ru.json index f96f2338c..bd2143a19 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -48,6 +48,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", diff --git a/src/locales/sr-ec.json b/src/locales/sr-ec.json new file mode 100644 index 000000000..9fd20b189 --- /dev/null +++ b/src/locales/sr-ec.json @@ -0,0 +1,59 @@ +{ + "@metadata": { + "authors": [ + "Aktron", + "Milicevic01", + "Милан Јелисавчић" + ] + }, + "index.newPad": "Нови Пад", + "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.indent.title": "Увлачење (TAB)", + "pad.toolbar.undo.title": "Опозови (Ctrl+Z)", + "pad.toolbar.settings.title": "Подешавања", + "pad.colorpicker.save": "Сачувај", + "pad.colorpicker.cancel": "Откажи", + "pad.loading": "Учитавање...", + "pad.wrongPassword": "Ваша лозинка није исправна", + "pad.settings.myView": "Мој приказ", + "pad.settings.fontType": "Врста фонта:", + "pad.settings.fontType.normal": "Нормално", + "pad.settings.fontType.monospaced": "Monospace", + "pad.settings.globalView": "Глобални приказ", + "pad.settings.language": "Језик:", + "pad.importExport.import_export": "Увоз/извоз", + "pad.importExport.import": "Отпремите било коју текстуалну датотеку или документ", + "pad.importExport.importSuccessful": "Успело!", + "pad.importExport.exporthtml": "HTML", + "pad.importExport.exportplain": "чист текст", + "pad.importExport.exportpdf": "PDF", + "pad.modals.connected": "Повезано.", + "pad.modals.slowcommit.explanation": "Сервер не одговара.", + "pad.modals.deleted": "Обрисано.", + "pad.share": "Дели овај пад", + "pad.share.readonly": "Само за читање", + "pad.share.link": "Веза", + "pad.chat": "Ћаскање", + "pad.chat.title": "Отворите ћаскање за овај пад.", + "pad.chat.loadmessages": "Учитајте више порука.", + "timeslider.month.january": "јануар", + "timeslider.month.february": "фебруар", + "timeslider.month.march": "март", + "timeslider.month.april": "април", + "timeslider.month.may": "мај", + "timeslider.month.june": "јун", + "timeslider.month.july": "јул", + "timeslider.month.august": "август", + "timeslider.month.september": "септембар", + "timeslider.month.october": "октобар", + "timeslider.month.november": "новембар", + "timeslider.month.december": "децембар", + "pad.userlist.approve": "одобрено", + "pad.impexp.importbutton": "Увези одмах", + "pad.impexp.importing": "Увожење..." +} diff --git a/src/locales/sv.json b/src/locales/sv.json index a53146bf6..ae9b1f9a0 100644 --- a/src/locales/sv.json +++ b/src/locales/sv.json @@ -35,6 +35,7 @@ "pad.settings.padSettings": "Blockinställningar", "pad.settings.myView": "Min vy", "pad.settings.stickychat": "Chatten alltid på skärmen", + "pad.settings.chatandusers": "Visa chatt och användare", "pad.settings.colorcheck": "Författarskapsfärger", "pad.settings.linenocheck": "Radnummer", "pad.settings.rtlcheck": "Vill du läsa innehållet från höger till vänster?", @@ -108,6 +109,7 @@ "timeslider.month.december": "december", "timeslider.unnamedauthors": "{{num}} {[plural(num) one: namnlös författare, other: namnlösa författare]}", "pad.savedrevs.marked": "Denna version är nu markerad som en sparad version", + "pad.savedrevs.timeslider": "Du kan se sparade versioner med tidsreglaget", "pad.userlist.entername": "Ange ditt namn", "pad.userlist.unnamed": "namnlös", "pad.userlist.guest": "Gäst", diff --git a/src/locales/zh-hans.json b/src/locales/zh-hans.json index 10727c5d3..4af3cb48b 100644 --- a/src/locales/zh-hans.json +++ b/src/locales/zh-hans.json @@ -42,6 +42,7 @@ "pad.settings.padSettings": "记事本设置", "pad.settings.myView": "我的视窗", "pad.settings.stickychat": "总是显示聊天屏幕", + "pad.settings.chatandusers": "显示聊天和用户", "pad.settings.colorcheck": "作者颜色", "pad.settings.linenocheck": "行号", "pad.settings.rtlcheck": "从右到左阅读内容吗?", @@ -100,7 +101,7 @@ "timeslider.exportCurrent": "当前版本导出为:", "timeslider.version": "版本 {{version}}", "timeslider.saved": "在{{year}}年{{month}}{{day}}日保存", - "timeslider.dateformat": "{{year}}年{{month}}{{day}}日 {{hours}}时:{{minutes}}分:{{seconds}}秒", + "timeslider.dateformat": "{{year}}年{{month}}月{{day}}日 {{hours}}时:{{minutes}}分:{{seconds}}秒", "timeslider.month.january": "1月", "timeslider.month.february": "2月", "timeslider.month.march": "三月", @@ -115,6 +116,7 @@ "timeslider.month.december": "十二月", "timeslider.unnamedauthors": "{{num}}个匿名作者", "pad.savedrevs.marked": "这一修订现在被标记为已保存的修订版本", + "pad.savedrevs.timeslider": "您可以使用时间滑块查阅已保存的版本", "pad.userlist.entername": "输入您的姓名", "pad.userlist.unnamed": "匿名", "pad.userlist.guest": "访客", From d5bec1701e10c2d0b5f1ffa96fd5ce4e86728e88 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sat, 21 Feb 2015 12:33:30 +0000 Subject: [PATCH 46/58] fix export of bad pads and also limit import to files --- src/node/utils/ExportEtherpad.js | 2 +- src/node/utils/ImportEtherpad.js | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/node/utils/ExportEtherpad.js b/src/node/utils/ExportEtherpad.js index 4f91e4e39..b7d438523 100644 --- a/src/node/utils/ExportEtherpad.js +++ b/src/node/utils/ExportEtherpad.js @@ -48,7 +48,7 @@ exports.getPadRaw = function(padId, callback){ // Get the author info db.get("globalAuthor:"+authorId, function(e, authorEntry){ - authorEntry.padIDs = padId; + if(authorEntry && authorEntry.padIDs) authorEntry.padIDs = padId; if(!e) data["globalAuthor:"+authorId] = authorEntry; }); diff --git a/src/node/utils/ImportEtherpad.js b/src/node/utils/ImportEtherpad.js index 1574a3a9d..37863bfff 100644 --- a/src/node/utils/ImportEtherpad.js +++ b/src/node/utils/ImportEtherpad.js @@ -21,9 +21,22 @@ var db = require("../db/DB").db; exports.setPadRaw = function(padId, records, callback){ records = JSON.parse(records); + // !! HACK !! + // If you have a really large pad it will cause a Maximum Range Stack crash + // This is a temporary patch for that so things are kept stable. + var recordCount = Object.keys(records).length; + if(recordCount >= 50000){ + console.warn("Etherpad file is too large to import.. We need to fix this. See https://github.com/ether/etherpad-lite/issues/2524"); + return callback("tooLarge", false); + } + async.eachSeries(Object.keys(records), function(key, cb){ var value = records[key] + if(!value){ + cb(); // null values are bad. + } + // Author data if(value.padIDs){ // rewrite author pad ids @@ -34,7 +47,9 @@ exports.setPadRaw = function(padId, records, callback){ db.get(key, function(err, author){ if(author){ // Yes, add the padID to the author.. - author.padIDs.push(padId); + if( Object.prototype.toString.call(author) === '[object Array]'){ + author.padIDs.push(padId); + } value = author; }else{ // No, create a new array with the author info in From 1c044588e6d9b0ee721f5c68e94c480028ce6467 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sun, 22 Feb 2015 17:56:44 +0000 Subject: [PATCH 47/58] mobile stylings for chat always on screen --- src/static/css/pad.css | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/static/css/pad.css b/src/static/css/pad.css index 5e4c4d14e..c9ebff4a5 100644 --- a/src/static/css/pad.css +++ b/src/static/css/pad.css @@ -1014,12 +1014,16 @@ input[type=checkbox] { top: 72px !important; } } + +/* Mobile devices */ @media only screen and (min-device-width: 320px) and (max-device-width: 720px) { #users { top: auto; right:0px !important; bottom: 33px; border-radius: 0px !important; + height: 55px !important; + overflow: auto; } #mycolorpicker { left: -73px; @@ -1099,7 +1103,8 @@ input[type=checkbox] { } #chatbox{ position:absolute; - bottom:33px; + bottom:33px !important; + margin: 65px 0 0 0; } #gritter-notice-wrapper{ bottom:43px !important; From 4166f190780f196a24248ec2733e97d7c0ba76ec Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Sun, 22 Feb 2015 22:32:18 +0100 Subject: [PATCH 48/58] Set correct API version in doc The doc says current version is 1.2.9, but there is getPadID which uses 1.2.10 API. --- doc/api/http_api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/http_api.md b/doc/api/http_api.md index 6cbe6e6b6..84a4ec7e2 100644 --- a/doc/api/http_api.md +++ b/doc/api/http_api.md @@ -61,7 +61,7 @@ Portal submits content into new blog post ## Usage ### API version -The latest version is `1.2.9` +The latest version is `1.2.10` The current version can be queried via /api. From a08c50a77dc897009f9e40d9d0bdab0a219d59fa Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Tue, 24 Feb 2015 23:42:35 +0100 Subject: [PATCH 49/58] Fixes #1870 Add two functions to API : * getSavedRevisionsCount * listSavedRevisions --- doc/api/http_api.md | 20 +++++++++++++++++- src/node/db/API.js | 38 ++++++++++++++++++++++++++++++++++ src/node/db/Pad.js | 12 +++++++++++ src/node/handler/APIHandler.js | 2 ++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/doc/api/http_api.md b/doc/api/http_api.md index 84a4ec7e2..d6432e3cd 100644 --- a/doc/api/http_api.md +++ b/doc/api/http_api.md @@ -61,7 +61,7 @@ Portal submits content into new blog post ## Usage ### API version -The latest version is `1.2.10` +The latest version is `1.2.11` The current version can be queried via /api. @@ -402,6 +402,24 @@ returns the number of revisions of this pad * `{code: 0, message:"ok", data: {revisions: 56}}` * `{code: 1, message:"padID does not exist", data: null}` +#### getSavedRevisionsCount(padID) + * API >= 1.2.11 + +returns the number of saved revisions of this pad + +*Example returns:* + * `{code: 0, message:"ok", data: {savedRevisions: 42}}` + * `{code: 1, message:"padID does not exist", data: null}` + +#### listSavedRevisions(padID) + * API >= 1.2.11 + +returns the list of saved revisions of this pad + +*Example returns:* + * `{code: 0, message:"ok", data: {savedRevisions: [2, 42, 1337]}}` + * `{code: 1, message:"padID does not exist", data: null}` + #### padUsersCount(padID) * API >= 1 diff --git a/src/node/db/API.js b/src/node/db/API.js index 81dedcfef..ab8a1d405 100644 --- a/src/node/db/API.js +++ b/src/node/db/API.js @@ -517,6 +517,44 @@ exports.getRevisionsCount = function(padID, callback) }); } +/** +getSavedRevisionsCount(padID) returns the number of saved revisions of this pad + +Example returns: + +{code: 0, message:"ok", data: {savedRevisions: 42}} +{code: 1, message:"padID does not exist", data: null} +*/ +exports.getSavedRevisionsCount = function(padID, callback) +{ + //get the pad + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + + callback(null, {savedRevisions: pad.getSavedRevisionsNumber()}); + }); +} + +/** +listSavedRevisions(padID) returns the list of saved revisions of this pad + +Example returns: + +{code: 0, message:"ok", data: {savedRevisions: [2, 42, 1337]}} +{code: 1, message:"padID does not exist", data: null} +*/ +exports.listSavedRevisions = function(padID, callback) +{ + //get the pad + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + + callback(null, {savedRevisions: pad.getSavedRevisionsList()}); + }); +} + /** getLastEdited(padID) returns the timestamp of the last revision of the pad diff --git a/src/node/db/Pad.js b/src/node/db/Pad.js index 2f5860f8f..7a02e0fbd 100644 --- a/src/node/db/Pad.js +++ b/src/node/db/Pad.js @@ -54,6 +54,18 @@ Pad.prototype.getHeadRevisionNumber = function getHeadRevisionNumber() { return this.head; }; +Pad.prototype.getSavedRevisionsNumber = function getSavedRevisionsNumber() { + return this.savedRevisions.length; +}; + +Pad.prototype.getSavedRevisionsList = function getSavedRevisionsList() { + var savedRev = new Array(); + for(var rev in this.savedRevisions){ + savedRev.push(this.savedRevisions[rev].revNum); + } + return savedRev; +}; + Pad.prototype.getPublicStatus = function getPublicStatus() { return this.publicStatus; }; diff --git a/src/node/handler/APIHandler.js b/src/node/handler/APIHandler.js index a26dd2cfb..a68a4472d 100644 --- a/src/node/handler/APIHandler.js +++ b/src/node/handler/APIHandler.js @@ -368,6 +368,8 @@ var version = , "setHTML" : ["padID", "html"] , "getAttributePool" : ["padID"] , "getRevisionsCount" : ["padID"] + , "getSavedRevisionsCount" : ["padID"] + , "listSavedRevisions" : ["padID"] , "getRevisionChangeset" : ["padID", "rev"] , "getLastEdited" : ["padID"] , "deletePad" : ["padID"] From 845788c39df0b9674c516e7673a8ba7bb43495b1 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Wed, 25 Feb 2015 01:04:27 +0100 Subject: [PATCH 50/58] Add a saveRevision API function Calling saveRevision create an author which name is "API" --- doc/api/http_api.md | 9 +++++ src/node/db/API.js | 73 ++++++++++++++++++++++++++++++++++ src/node/handler/APIHandler.js | 1 + 3 files changed, 83 insertions(+) diff --git a/doc/api/http_api.md b/doc/api/http_api.md index d6432e3cd..2ae674d8c 100644 --- a/doc/api/http_api.md +++ b/doc/api/http_api.md @@ -420,6 +420,15 @@ returns the list of saved revisions of this pad * `{code: 0, message:"ok", data: {savedRevisions: [2, 42, 1337]}}` * `{code: 1, message:"padID does not exist", data: null}` +#### saveRevision(padID [, rev]) + * API >= 1.2.11 + +saves a revision + +*Example returns:* + * `{code: 0, message:"ok", data: null}` + * `{code: 1, message:"padID does not exist", data: null}` + #### padUsersCount(padID) * API >= 1 diff --git a/src/node/db/API.js b/src/node/db/API.js index ab8a1d405..69a380c7f 100644 --- a/src/node/db/API.js +++ b/src/node/db/API.js @@ -555,6 +555,79 @@ exports.listSavedRevisions = function(padID, callback) }); } +/** +saveRevision(padID) returns the list of saved revisions of this pad + +Example returns: + +{code: 0, message:"ok", data: null} +{code: 1, message:"padID does not exist", data: null} +*/ +exports.saveRevision = function(padID, rev, callback) +{ + //check if rev is set + if(typeof rev == "function") + { + callback = rev; + rev = undefined; + } + + //check if rev is a number + if(rev !== undefined && typeof rev != "number") + { + //try to parse the number + if(!isNaN(parseInt(rev))) + { + rev = parseInt(rev); + } + else + { + callback(new customError("rev is not a number", "apierror")); + return; + } + } + + //ensure this is not a negativ number + if(rev !== undefined && rev < 0) + { + callback(new customError("rev is a negativ number","apierror")); + return; + } + + //ensure this is not a float value + if(rev !== undefined && !is_int(rev)) + { + callback(new customError("rev is a float value","apierror")); + return; + } + + //get the pad + getPadSafe(padID, true, function(err, pad) + { + if(ERR(err, callback)) return; + + //the client asked for a special revision + if(rev !== undefined) + { + //check if this is a valid revision + if(rev > pad.getHeadRevisionNumber()) + { + callback(new customError("rev is higher than the head revision of the pad","apierror")); + return; + } + } else { + rev = pad.getHeadRevisionNumber(); + } + + authorManager.createAuthor('API', function(err, author) { + if(ERR(err, callback)) return; + + pad.addSavedRevision(rev, author.authorID, 'Saved through API call'); + callback(); + }); + }); +} + /** getLastEdited(padID) returns the timestamp of the last revision of the pad diff --git a/src/node/handler/APIHandler.js b/src/node/handler/APIHandler.js index a68a4472d..232b0b466 100644 --- a/src/node/handler/APIHandler.js +++ b/src/node/handler/APIHandler.js @@ -370,6 +370,7 @@ var version = , "getRevisionsCount" : ["padID"] , "getSavedRevisionsCount" : ["padID"] , "listSavedRevisions" : ["padID"] + , "saveRevision" : ["padID", "rev"] , "getRevisionChangeset" : ["padID", "rev"] , "getLastEdited" : ["padID"] , "deletePad" : ["padID"] From 92022e493ee882f486e2ad9e5e0986b1af90f614 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Wed, 25 Feb 2015 01:05:58 +0100 Subject: [PATCH 51/58] Add backend tests for new API functions These new functions are: * getSavedRevisionsCount * listSavedRevisions * saveRevision + typo fixing in backend tests --- src/node/db/Pad.js | 3 + tests/backend/specs/api/pad.js | 143 ++++++++++++++++++++++++++------- 2 files changed, 117 insertions(+), 29 deletions(-) diff --git a/src/node/db/Pad.js b/src/node/db/Pad.js index 7a02e0fbd..538476002 100644 --- a/src/node/db/Pad.js +++ b/src/node/db/Pad.js @@ -63,6 +63,9 @@ Pad.prototype.getSavedRevisionsList = function getSavedRevisionsList() { for(var rev in this.savedRevisions){ savedRev.push(this.savedRevisions[rev].revNum); } + savedRev.sort(function(a, b) { + return a - b; + }); return savedRev; }; diff --git a/tests/backend/specs/api/pad.js b/tests/backend/specs/api/pad.js index 6010a11ce..52849c2ea 100644 --- a/tests/backend/specs/api/pad.js +++ b/tests/backend/specs/api/pad.js @@ -48,33 +48,38 @@ describe('Permission', function(){ -> deletePad -- This gives us a guaranteed clear environment -> createPad -> getRevisions -- Should be 0 - -> getHTML -- Should be the default pad text in HTML format - -> deletePad -- Should just delete a pad - -> getHTML -- Should return an error - -> createPad(withText) - -> getText -- Should have the text specified above as the pad text - -> setText - -> getText -- Should be the text set before - -> getRevisions -- Should be 0 still? - -> padUsersCount -- Should be 0 - -> getReadOnlyId -- Should be a value - -> listAuthorsOfPad(padID) -- should be empty array? - -> getLastEdited(padID) -- Should be when pad was made - -> setText(padId) - -> getLastEdited(padID) -- Should be when setText was performed - -> padUsers(padID) -- Should be when setText was performed - - -> setText(padId, "hello world") + -> getSavedRevisionsCount(padID) -- Should be 0 + -> listSavedRevisions(padID) -- Should be an empty array + -> getHTML -- Should be the default pad text in HTML format + -> deletePad -- Should just delete a pad + -> getHTML -- Should return an error + -> createPad(withText) + -> getText -- Should have the text specified above as the pad text + -> setText + -> getText -- Should be the text set before + -> getRevisions -- Should be 0 still? + -> saveRevision + -> getSavedRevisionsCount(padID) -- Should be 0 still? + -> listSavedRevisions(padID) -- Should be an empty array still ? + -> padUsersCount -- Should be 0 + -> getReadOnlyId -- Should be a value + -> listAuthorsOfPad(padID) -- should be empty array? -> getLastEdited(padID) -- Should be when pad was made - -> getText(padId) -- Should be "hello world" - -> movePad(padID, newPadId) -- Should provide consistant pad data - -> getText(newPadId) -- Should be "hello world" - -> 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 + -> setText(padId) + -> getLastEdited(padID) -- Should be when setText was performed + -> padUsers(padID) -- Should be when setText was performed + + -> setText(padId, "hello world") + -> getLastEdited(padID) -- Should be when pad was made + -> getText(padId) -- Should be "hello world" + -> movePad(padID, newPadId) -- Should provide consistant pad data + -> getText(newPadId) -- Should be "hello world" + -> 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 */ @@ -109,11 +114,35 @@ describe('getRevisionsCount', function(){ }); }) +describe('getSavedRevisionsCount', function(){ + it('gets saved revisions count of Pad', function(done) { + api.get(endPoint('getSavedRevisionsCount')+"&padID="+testPadId) + .expect(function(res){ + if(res.body.code !== 0) throw new Error("Unable to get Saved Revisions Count"); + if(res.body.data.savedRevisions !== 0) throw new Error("Incorrect Saved Revisions Count"); + }) + .expect('Content-Type', /json/) + .expect(200, done) + }); +}) + +describe('listSavedRevisions', function(){ + it('gets saved revision list of Pad', function(done) { + api.get(endPoint('listSavedRevisions')+"&padID="+testPadId) + .expect(function(res){ + if(res.body.code !== 0) throw new Error("Unable to get Saved Revisions List"); + if(!res.body.data.savedRevisions.equals([])) throw new Error("Incorrect Saved Revisions List"); + }) + .expect('Content-Type', /json/) + .expect(200, done) + }); +}) + describe('getHTML', function(){ it('get the HTML of Pad', function(done) { api.get(endPoint('getHTML')+"&padID="+testPadId) .expect(function(res){ - if(res.body.data.html.length <= 1) throw new Error("Unable to get Revision Count"); + if(res.body.data.html.length <= 1) throw new Error("Unable to get the HTML"); }) .expect('Content-Type', /json/) .expect(200, done) @@ -187,16 +216,50 @@ describe('getText', function(){ }) describe('getRevisionsCount', function(){ - it('gets Revision Coutn of a Pad', function(done) { + it('gets Revision Count of a Pad', function(done) { api.get(endPoint('getRevisionsCount')+"&padID="+testPadId) .expect(function(res){ - if(res.body.data.revisions !== 1) throw new Error("Unable to set text revision count") + if(res.body.data.revisions !== 1) throw new Error("Unable to get text revision count") }) .expect('Content-Type', /json/) .expect(200, done) }); }) +describe('saveRevision', function(){ + it('saves Revision', function(done) { + api.get(endPoint('saveRevision')+"&padID="+testPadId) + .expect(function(res){ + if(res.body.code !== 0) throw new Error("Unable to save Revision"); + }) + .expect('Content-Type', /json/) + .expect(200, done) + }); +}) + +describe('getSavedRevisionsCount', function(){ + it('gets saved revisions count of Pad', function(done) { + api.get(endPoint('getSavedRevisionsCount')+"&padID="+testPadId) + .expect(function(res){ + if(res.body.code !== 0) throw new Error("Unable to get Saved Revisions Count"); + if(res.body.data.savedRevisions !== 1) throw new Error("Incorrect Saved Revisions Count"); + }) + .expect('Content-Type', /json/) + .expect(200, done) + }); +}) + +describe('listSavedRevisions', function(){ + it('gets saved revision list of Pad', function(done) { + api.get(endPoint('listSavedRevisions')+"&padID="+testPadId) + .expect(function(res){ + if(res.body.code !== 0) throw new Error("Unable to get Saved Revisions List"); + if(!res.body.data.savedRevisions.equals([1])) throw new Error("Incorrect Saved Revisions List"); + }) + .expect('Content-Type', /json/) + .expect(200, done) + }); +}) describe('padUsersCount', function(){ it('gets User Count of a Pad', function(done) { api.get(endPoint('padUsersCount')+"&padID="+testPadId) @@ -461,3 +524,25 @@ function generateLongText(){ } return text; } + +// Need this to compare arrays (listSavedRevisions test) +Array.prototype.equals = function (array) { + // if the other array is a falsy value, return + if (!array) + return false; + // compare lengths - can save a lot of time + if (this.length != array.length) + return false; + for (var i = 0, l=this.length; i < l; i++) { + // Check if we have nested arrays + if (this[i] instanceof Array && array[i] instanceof Array) { + // recurse into the nested arrays + if (!this[i].equals(array[i])) + return false; + } else if (this[i] != array[i]) { + // Warning - two different object instances will never be equal: {x:20} != {x:20} + return false; + } + } + return true; +} From 38a4f1be5f08784d94080adf55f83d5f146364a1 Mon Sep 17 00:00:00 2001 From: John McLear Date: Thu, 26 Feb 2015 12:14:01 +0000 Subject: [PATCH 52/58] bump ueberdb --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index 00876f2cf..815d865fc 100644 --- a/src/package.json +++ b/src/package.json @@ -17,7 +17,7 @@ "etherpad-require-kernel" : "1.0.8", "resolve" : "1.1.0", "socket.io" : "1.3.3", - "ueberDB" : "0.2.11", + "ueberDB" : "0.2.12", "express" : "3.8.1", "async" : "0.9.0", "connect" : "2.7.11", From 063219bbce2103c39ac98b3f528b242d84753c13 Mon Sep 17 00:00:00 2001 From: Chris Ball Date: Fri, 27 Feb 2015 12:54:29 -0500 Subject: [PATCH 53/58] Trigger renumbering when deleting (via cut) the first item of a list Fixes #2514. --- src/static/js/ace2_inner.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index 4b84e784d..15747249d 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -3313,6 +3313,14 @@ function Ace2Inner(){ return [rep.lines.offsetOfIndex(lineRange[0]), rep.lines.offsetOfIndex(lineRange[1])]; } + function handleCut(evt) + { + inCallStackIfNecessary("handleCut", function() + { + doDeleteKey(evt); + }); + } + function handleClick(evt) { inCallStackIfNecessary("handleClick", function() @@ -4854,6 +4862,7 @@ function Ace2Inner(){ $(document).on("keypress", handleKeyEvent); $(document).on("keyup", handleKeyEvent); $(document).on("click", handleClick); + $(document).on("cut", handleCut); $(root).on("blur", handleBlur); if (browser.msie) { From 4e0353b3ef4e5b43278695c9a571c933c314e713 Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 2 Mar 2015 08:59:53 +0000 Subject: [PATCH 54/58] bump ueber --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index 815d865fc..e2d9e2996 100644 --- a/src/package.json +++ b/src/package.json @@ -17,7 +17,7 @@ "etherpad-require-kernel" : "1.0.8", "resolve" : "1.1.0", "socket.io" : "1.3.3", - "ueberDB" : "0.2.12", + "ueberDB" : "0.2.13", "express" : "3.8.1", "async" : "0.9.0", "connect" : "2.7.11", From 56dbad41ada0e1d848fb8fca4a1608d34b372b36 Mon Sep 17 00:00:00 2001 From: John McLear Date: Wed, 4 Mar 2015 17:46:49 +0000 Subject: [PATCH 55/58] a should always have white space pre-wrap stops caret walking in chrome on them --- src/static/css/iframe_editor.css | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/static/css/iframe_editor.css b/src/static/css/iframe_editor.css index 1f247e59a..eb69364bd 100644 --- a/src/static/css/iframe_editor.css +++ b/src/static/css/iframe_editor.css @@ -11,7 +11,10 @@ span { cursor: auto; } background: #acf; } -a { cursor: pointer !important; } +a { + cursor: pointer !important; + white-space:pre-wrap; +} ul, ol, li { padding: 0; From 7894545556226c4a17b45f6164d32041088cdb89 Mon Sep 17 00:00:00 2001 From: lid2000 Date: Fri, 13 Mar 2015 16:01:18 +1100 Subject: [PATCH 56/58] Return true from handleCut function --- src/static/js/ace2_inner.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index 15747249d..aa4bf6c7d 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -3319,6 +3319,7 @@ function Ace2Inner(){ { doDeleteKey(evt); }); + return true; } function handleClick(evt) From a0fb65205c7d7ff95f00eb9fd88e93b300f30c3d Mon Sep 17 00:00:00 2001 From: webzwo0i Date: Sat, 14 Mar 2015 00:02:23 +0100 Subject: [PATCH 57/58] oops, fix export with wildcards --- src/node/utils/ExportEtherpad.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/node/utils/ExportEtherpad.js b/src/node/utils/ExportEtherpad.js index b7d438523..46ae0d7af 100644 --- a/src/node/utils/ExportEtherpad.js +++ b/src/node/utils/ExportEtherpad.js @@ -23,9 +23,19 @@ exports.getPadRaw = function(padId, callback){ async.waterfall([ function(cb){ - // Get the Pad available content keys - db.findKeys("pad:"+padId+"*", null, function(err,records){ + // Get the Pad + db.findKeys("pad:"+padId, null, function(err,padcontent){ if(!err){ + cb(err, padcontent); + } + }) + }, + function(padcontent,cb){ + + // Get the Pad available content keys + db.findKeys("pad:"+padId+":*", null, function(err,records){ + if(!err){ + for (var key in padcontent) { records.push(padcontent[key]);} cb(err, records); } }) From c0260bcc40e93e9a47a20aada86a8513776f2e17 Mon Sep 17 00:00:00 2001 From: Stefan Date: Sun, 15 Mar 2015 14:28:47 +0100 Subject: [PATCH 58/58] Add changelog for v1.5.2 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75a9f3276..bf27f2921 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +# 1.5.2 + * NEW: Support for node version 0.12.x + * NEW: API endpoint saveRevision, getSavedRevisionCount and listSavedRevisions + * NEW: setting to allow load testing + * Fix: Rare scroll issue + * Fix: Handling of custom pad path + * Fix: Better error handling of imports and exports of type "etherpad" + * Fix: Walking caret in chrome + * Fix: Better handling for changeset problems + * SECURITY Fix: Information leak for etherpad exports (CVE-2015-2298) + # 1.5.1 * NEW: High resolution Icon * NEW: Use HTTPS for plugins.json download