mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-27 10:56:16 -04:00
Merge branch 'develop' of github.com:ether/etherpad-lite into support-images
This commit is contained in:
commit
3f8e6faec0
30 changed files with 390 additions and 267 deletions
|
@ -294,15 +294,14 @@ returns the text of a pad formatted as HTML
|
|||
* `{code: 0, message:"ok", data: {html:"Welcome Text<br>More Text"}}`
|
||||
* `{code: 1, message:"padID does not exist", data: null}`
|
||||
|
||||
#### setHTML(padID, text)
|
||||
#### setHTML(padID, html)
|
||||
* API >= 1
|
||||
|
||||
sets the html of a pad
|
||||
sets the text of a pad based on HTML, HTML must be well formed. Malformed HTML will send a warning to the API log.
|
||||
|
||||
*Example returns:*
|
||||
* `{code: 0, message:"ok", data: null}`
|
||||
* `{code: 1, message:"padID does not exist", data: null}`
|
||||
* `{code: 1, message:"text too long", data: null}`
|
||||
|
||||
#### getAttributePool(padID)
|
||||
* API >= 1.2.8
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"1": "Xuacu"
|
||||
}
|
||||
"authors": [
|
||||
"Xuacu"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Nuevu bloc",
|
||||
"index.createOpenPad": "o crear/abrir un bloc col nome:",
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Christian List",
|
||||
"1": "Peter Alberti",
|
||||
"3": "Steenth"
|
||||
}
|
||||
"authors": [
|
||||
"Christian List",
|
||||
"Peter Alberti",
|
||||
"Steenth"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Ny Pad",
|
||||
"index.createOpenPad": "eller opret/åbn en Pad med navnet:",
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Metalhead64",
|
||||
"1": "Mklehr",
|
||||
"2": "Nipsky",
|
||||
"4": "Wikinaut"
|
||||
}
|
||||
"authors": [
|
||||
"Metalhead64",
|
||||
"Mklehr",
|
||||
"Nipsky",
|
||||
"Wikinaut"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Neues Pad",
|
||||
"index.createOpenPad": "Pad mit folgendem Namen öffnen:",
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Armando-Martin",
|
||||
"1": "Jacobo",
|
||||
"2": "Joker",
|
||||
"3": "Larjona",
|
||||
"4": "Mklehr",
|
||||
"5": "Rubenwap",
|
||||
"7": "VegaDark",
|
||||
"8": "Vivaelcelta",
|
||||
"9": "Xuacu"
|
||||
}
|
||||
"authors": [
|
||||
"Armando-Martin",
|
||||
"Jacobo",
|
||||
"Joker",
|
||||
"Larjona",
|
||||
"Mklehr",
|
||||
"Rubenwap",
|
||||
"VegaDark",
|
||||
"Vivaelcelta",
|
||||
"Xuacu"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Nuevo Pad",
|
||||
"index.createOpenPad": "o crea/abre un Pad con el nombre:",
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "BMRG14",
|
||||
"1": "Dalba",
|
||||
"2": "Ebraminio",
|
||||
"3": "Reza1615",
|
||||
"5": "ZxxZxxZ",
|
||||
"6": "الناز"
|
||||
}
|
||||
"authors": [
|
||||
"BMRG14",
|
||||
"Dalba",
|
||||
"Ebraminio",
|
||||
"Reza1615",
|
||||
"ZxxZxxZ",
|
||||
"الناز"
|
||||
]
|
||||
},
|
||||
"index.newPad": "دفترچه یادداشت تازه",
|
||||
"index.createOpenPad": "یا ایجاد/بازکردن یک دفترچه یادداشت با نام:",
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Artnay",
|
||||
"1": "Jl",
|
||||
"2": "Lliehu",
|
||||
"3": "Nedergard",
|
||||
"4": "Nike",
|
||||
"6": "Stryn",
|
||||
"7": "Veikk0.ma",
|
||||
"8": "VezonThunder"
|
||||
}
|
||||
"authors": [
|
||||
"Artnay",
|
||||
"Jl",
|
||||
"Lliehu",
|
||||
"Nedergard",
|
||||
"Nike",
|
||||
"Stryn",
|
||||
"Tomi Toivio",
|
||||
"Veikk0.ma",
|
||||
"VezonThunder"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Uusi muistio",
|
||||
"index.createOpenPad": "tai luo tai avaa muistio nimellä:",
|
||||
|
@ -19,8 +20,8 @@
|
|||
"pad.toolbar.strikethrough.title": "Yliviivaus",
|
||||
"pad.toolbar.ol.title": "Numeroitu lista",
|
||||
"pad.toolbar.ul.title": "Numeroimaton lista",
|
||||
"pad.toolbar.indent.title": "Sisennä",
|
||||
"pad.toolbar.unindent.title": "Ulonna",
|
||||
"pad.toolbar.indent.title": "Sisennä (TAB)",
|
||||
"pad.toolbar.unindent.title": "Ulonna (Shift+TAB)",
|
||||
"pad.toolbar.undo.title": "Kumoa (Ctrl-Z)",
|
||||
"pad.toolbar.redo.title": "Tee uudelleen (Ctrl-Y)",
|
||||
"pad.toolbar.clearAuthorship.title": "Poista kirjoittajavärit",
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Cquoi",
|
||||
"1": "Crochet.david",
|
||||
"2": "Gomoko",
|
||||
"3": "Goofy",
|
||||
"4": "Goofy-bz",
|
||||
"5": "Jean-Frédéric",
|
||||
"6": "Leviathan",
|
||||
"7": "McDutchie",
|
||||
"8": "Metroitendo",
|
||||
"9": "Od1n",
|
||||
"10": "Peter17",
|
||||
"11": "Quenenni",
|
||||
"12": "Rastus Vernon",
|
||||
"14": "Stephane Cottin",
|
||||
"15": "Tux-tn"
|
||||
}
|
||||
"authors": [
|
||||
"Cquoi",
|
||||
"Crochet.david",
|
||||
"Gomoko",
|
||||
"Goofy",
|
||||
"Goofy-bz",
|
||||
"Jean-Frédéric",
|
||||
"Leviathan",
|
||||
"McDutchie",
|
||||
"Metroitendo",
|
||||
"Od1n",
|
||||
"Peter17",
|
||||
"Quenenni",
|
||||
"Rastus Vernon",
|
||||
"Stephane Cottin",
|
||||
"Tux-tn"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Nouveau pad",
|
||||
"index.createOpenPad": "ou créer/ouvrir un pad intitulé :",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"1": "Toliño"
|
||||
}
|
||||
"authors": [
|
||||
"Toliño"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Novo documento",
|
||||
"index.createOpenPad": "ou cree/abra un documento co nome:",
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Amire80",
|
||||
"1": "Ofrahod",
|
||||
"3": "YaronSh",
|
||||
"4": "תומר ט"
|
||||
}
|
||||
"authors": [
|
||||
"Amire80",
|
||||
"Ofrahod",
|
||||
"YaronSh",
|
||||
"תומר ט"
|
||||
]
|
||||
},
|
||||
"index.newPad": "פנקס חדש",
|
||||
"index.createOpenPad": "ליצור או לפתוח פנקס בשם:",
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Dj",
|
||||
"1": "Misibacsi",
|
||||
"2": "R-Joe",
|
||||
"4": "Tgr"
|
||||
}
|
||||
"authors": [
|
||||
"Dj",
|
||||
"Misibacsi",
|
||||
"R-Joe",
|
||||
"Tgr"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Új notesz",
|
||||
"index.createOpenPad": "vagy notesz létrehozása ezen a néven:",
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Beta16",
|
||||
"1": "Gianfranco",
|
||||
"2": "Muxator",
|
||||
"4": "Vituzzu"
|
||||
}
|
||||
"authors": [
|
||||
"Beta16",
|
||||
"Gianfranco",
|
||||
"Muxator",
|
||||
"Vituzzu"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Nuovo Pad",
|
||||
"index.createOpenPad": "o creare o aprire un Pad con il nome:",
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Hym411",
|
||||
"2": "아라"
|
||||
}
|
||||
"authors": [
|
||||
"Hym411",
|
||||
"아라"
|
||||
]
|
||||
},
|
||||
"index.newPad": "새 패드",
|
||||
"index.createOpenPad": "또는 다음 이름으로 패드 만들기/열기:",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"1": "Purodha"
|
||||
}
|
||||
"authors": [
|
||||
"Purodha"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Neu Padd",
|
||||
"index.createOpenPad": "udder maach e Padd op med däm Naame:",
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Robby",
|
||||
"2": "Soued031"
|
||||
}
|
||||
"authors": [
|
||||
"Robby",
|
||||
"Soued031"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Neie Pad",
|
||||
"pad.toolbar.ol.title": "Numeréiert Lëscht",
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
"pad.toolbar.strikethrough.title": "Garis lorek",
|
||||
"pad.toolbar.ol.title": "Senarai tertib",
|
||||
"pad.toolbar.ul.title": "Senarai tak tertib",
|
||||
"pad.toolbar.indent.title": "Engsot ke dalam",
|
||||
"pad.toolbar.unindent.title": "Engsot ke luar",
|
||||
"pad.toolbar.indent.title": "Engsot ke dalam (TAB)",
|
||||
"pad.toolbar.unindent.title": "Engsot ke luar (Shift + TAB)",
|
||||
"pad.toolbar.undo.title": "Buat asal (Ctrl-Z)",
|
||||
"pad.toolbar.redo.title": "Buat semula (Ctrl-Y)",
|
||||
"pad.toolbar.clearAuthorship.title": "Padamkan Warna Pengarang",
|
||||
|
@ -66,11 +66,15 @@
|
|||
"pad.modals.initsocketfail.cause": "Ini mungkin disebabkan oleh masalah dengan pelayar atau sambungan internet anda.",
|
||||
"pad.modals.slowcommit.explanation": "Pelayan tidak membalas.",
|
||||
"pad.modals.slowcommit.cause": "Ini mungkin disebabkan oleh masalah dengan kesambungan rangkaian anda.",
|
||||
"pad.modals.badChangeset.explanation": "Suntingan yang telah anda lakukan telah dikira sebagai terlarang oleh pelayan penyegerakan.",
|
||||
"pad.modals.badChangeset.cause": "Ini mungkin disebabkan oleh konfigurasi pelayan salah atau sesuatu kelakuan yang tidak dijangka. Sila hubungi penyelia servis anda jika anda merasakan ini adalah satu kesilapan. Cuba sambungkan semula talian untuk terus menyuntung.",
|
||||
"pad.modals.corruptPad.explanation": "Pad yang anda cuba akses itu telah tercemar.",
|
||||
"pad.modals.corruptPad.cause": "Ini mungkin disebabkan oleh konfigurasi pelayan salah atau sesuatu kelakuan yang tidak dijangka. Sila hubungi penyelia servis anda.",
|
||||
"pad.modals.deleted": "Dihapuskan.",
|
||||
"pad.modals.deleted.explanation": "Pad ini telah dibuang.",
|
||||
"pad.modals.disconnected": "Sambungan anda telah diputuskan.",
|
||||
"pad.modals.disconnected.explanation": "Sambungan ke pelayan terputus",
|
||||
"pad.modals.disconnected.cause": "Pelayan mungkin tidak dapat dicapai. Sila beritahu kami jika masalah ini berterusan.",
|
||||
"pad.modals.disconnected.cause": "Pelayan mungkin tidak dapat dicapai. Sila beritahu penyelia servis jika masalah ini berterusan.",
|
||||
"pad.share": "Kongsikan pad ini",
|
||||
"pad.share.readonly": "Baca sahaja",
|
||||
"pad.share.link": "Pautan",
|
||||
|
|
86
src/locales/ne.json
Normal file
86
src/locales/ne.json
Normal file
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"सरोज कुमार ढकाल"
|
||||
]
|
||||
},
|
||||
"index.newPad": "नयाँ प्याड",
|
||||
"index.createOpenPad": "नाम सहितको नयाँ प्याड सिर्जना गर्ने / खोल्ने :",
|
||||
"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.timeslider.title": "टाइमस्लाइडर",
|
||||
"pad.toolbar.savedRevision.title": "पुनरावलोकन संग्रहगर्ने",
|
||||
"pad.toolbar.settings.title": "सेटिङ्गहरू",
|
||||
"pad.toolbar.embed.title": "यस प्याडलाई बाड्ने या इम्बेड गर्ने",
|
||||
"pad.toolbar.showusers.title": "यस प्याडमा रहेका प्रयोगकर्ता देखाउने",
|
||||
"pad.colorpicker.save": "संग्रह गर्ने",
|
||||
"pad.colorpicker.cancel": "रद्द",
|
||||
"pad.loading": "लोड हुदैछ...",
|
||||
"pad.passwordRequired": "यो प्यड खोल्न पासवर्ड चाहिन्छ",
|
||||
"pad.permissionDenied": "तपाईँलाई यस प्याड खोल्न अनुमति छैन",
|
||||
"pad.wrongPassword": "तपाईँको पासवर्ड गलत थियो",
|
||||
"pad.settings.padSettings": "प्याड सेटिङ्गहरू",
|
||||
"pad.settings.myView": "मेरो दृष्य",
|
||||
"pad.settings.stickychat": "पर्दामा सधै च्याट गर्ने",
|
||||
"pad.settings.colorcheck": "लेखकीय रङ्ग",
|
||||
"pad.settings.linenocheck": "हरफ संख्या",
|
||||
"pad.settings.rtlcheck": "के सामग्री दाहिने देखि देब्रे पढ्ने हो ?",
|
||||
"pad.settings.fontType": "फन्ट प्रकार:",
|
||||
"pad.settings.fontType.normal": "सामान्य",
|
||||
"pad.settings.fontType.monospaced": "मोनोस्पेस",
|
||||
"pad.settings.globalView": "विश्वव्यापी दृष्य",
|
||||
"pad.settings.language": "भाषा:",
|
||||
"pad.importExport.import_export": "आयात/निर्यात",
|
||||
"pad.importExport.import": "कुनै पनि पाठ रहेको फाइल या कागजात अपलोड गर्नुहोस्",
|
||||
"pad.importExport.importSuccessful": "सफल भयो!",
|
||||
"pad.importExport.export": "निम्न रुपमा प्याड निर्यात गर्ने :",
|
||||
"pad.importExport.exporthtml": "HTML",
|
||||
"pad.importExport.exportplain": "साधारण पाठ",
|
||||
"pad.importExport.exportword": "माइक्रोसफ्ट वर्ड",
|
||||
"pad.importExport.exportpdf": "पिडिएफ",
|
||||
"pad.importExport.exportopen": "ओडिएफ(खुल्ला कागजात ढाँचा)",
|
||||
"pad.importExport.exportdokuwiki": "डकुविकि",
|
||||
"pad.modals.connected": "जोडीएको।",
|
||||
"pad.modals.reconnecting": "तपाईँको प्याडमा पुन: जडान गर्दै",
|
||||
"pad.modals.deleted": "मेटिएको ।",
|
||||
"pad.modals.deleted.explanation": "यो प्याड हटाइसकेको छ ।",
|
||||
"pad.modals.disconnected": "तपाईँको जडान अवरुद्ध भयो ।",
|
||||
"pad.modals.disconnected.explanation": "तपाईँको सर्भरसँगको जडान अवरुद्ध भयो",
|
||||
"pad.share": "यस प्यडलाई बाड्ने",
|
||||
"pad.share.readonly": "पढ्ने मात्र",
|
||||
"pad.share.link": "लिङ्क",
|
||||
"pad.chat": "कुराकानी",
|
||||
"pad.chat.title": "यस प्याडको लागि कुराकानी खोल्ने",
|
||||
"pad.chat.loadmessages": "थप सन्देशहरू खोल्ने",
|
||||
"timeslider.toolbar.returnbutton": "प्याडमा फर्कनुहोस्",
|
||||
"timeslider.toolbar.authors": "लेखकहरु:",
|
||||
"timeslider.toolbar.authorsList": "कुनै पनि लेखकहरू छैनन्",
|
||||
"timeslider.toolbar.exportlink.title": "निर्यात",
|
||||
"timeslider.exportCurrent": "हालको संस्करण निम्म रुपमा निर्यात गर्ने :",
|
||||
"timeslider.version": "संस्करण {{version}}",
|
||||
"timeslider.saved": "सङ्ग्रह गरिएको {{month}} {{day}}, {{year}}",
|
||||
"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.savedrevs.marked": "यस संस्करणलाई संग्रहितको रुपमा चिनो लगाइएको छैन",
|
||||
"pad.userlist.entername": "तपाईँको नाम लेख्नुहोस्",
|
||||
"pad.userlist.unnamed": "नाम नखुलाइएको",
|
||||
"pad.userlist.guest": "पाहुना",
|
||||
"pad.userlist.deny": "अस्वीकार गर्ने",
|
||||
"pad.userlist.approve": "स्वीकृत गर्ने"
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"1": "Unhammer"
|
||||
}
|
||||
"authors": [
|
||||
"Unhammer"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Ny blokk",
|
||||
"index.createOpenPad": "eller opprett/opna ei blokk med namnet:",
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Rezonansowy",
|
||||
"2": "Ty221",
|
||||
"3": "WTM",
|
||||
"4": "Woytecr"
|
||||
}
|
||||
"authors": [
|
||||
"Rezonansowy",
|
||||
"Ty221",
|
||||
"WTM",
|
||||
"Woytecr"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Nowy dokument",
|
||||
"index.createOpenPad": "lub stwórz/otwórz dokument o nazwie:",
|
||||
|
@ -15,8 +15,8 @@
|
|||
"pad.toolbar.strikethrough.title": "Przekreślenie",
|
||||
"pad.toolbar.ol.title": "Lista uporządkowana",
|
||||
"pad.toolbar.ul.title": "Lista nieuporządkowana",
|
||||
"pad.toolbar.indent.title": "Wcięcie",
|
||||
"pad.toolbar.unindent.title": "Zmniejsz wcięcie",
|
||||
"pad.toolbar.indent.title": "Wcięcie (TAB)",
|
||||
"pad.toolbar.unindent.title": "Wcięcie (Shift + TAB)",
|
||||
"pad.toolbar.undo.title": "Cofnij (Ctrl-Z)",
|
||||
"pad.toolbar.redo.title": "Ponów (Ctrl-Y)",
|
||||
"pad.toolbar.clearAuthorship.title": "Usuń kolory autorów",
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Hamilton Abreu",
|
||||
"1": "Luckas",
|
||||
"3": "Tuliouel",
|
||||
"4": "Waldir"
|
||||
}
|
||||
"authors": [
|
||||
"Hamilton Abreu",
|
||||
"Luckas",
|
||||
"Tuliouel",
|
||||
"Waldir"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Nova Nota",
|
||||
"index.createOpenPad": "ou crie/abra uma Nota com o nome:",
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Lokal Profil",
|
||||
"2": "WikiPhoenix"
|
||||
}
|
||||
"authors": [
|
||||
"Lokal Profil",
|
||||
"WikiPhoenix"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Nytt block",
|
||||
"index.createOpenPad": "eller skapa/öppna ett block med namnet:",
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "JVRKPRASAD",
|
||||
"1": "Malkum",
|
||||
"3": "Veeven"
|
||||
}
|
||||
"authors": [
|
||||
"JVRKPRASAD",
|
||||
"Malkum",
|
||||
"Veeven"
|
||||
]
|
||||
},
|
||||
"index.newPad": "కొత్త పలక",
|
||||
"index.createOpenPad": "ఒక పేరుతో పలకని సృష్టించండి లేదా అదే పేరుతో ఉన్న పలకని తెరవండి",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"authors": [
|
||||
"Emperyan",
|
||||
"Erdemaslancan",
|
||||
"Joseph",
|
||||
"Meelo"
|
||||
]
|
||||
},
|
||||
|
@ -14,8 +15,8 @@
|
|||
"pad.toolbar.strikethrough.title": "Üstü Çizili",
|
||||
"pad.toolbar.ol.title": "Sıralı liste",
|
||||
"pad.toolbar.ul.title": "Sırasız Liste",
|
||||
"pad.toolbar.indent.title": "Girintiyi arttır",
|
||||
"pad.toolbar.unindent.title": "Girintiyi azalt",
|
||||
"pad.toolbar.indent.title": "Girintiyi arttır (TAB)",
|
||||
"pad.toolbar.unindent.title": "Girintiyi azalt (Shift+TAB)",
|
||||
"pad.toolbar.undo.title": "Geri Al (Ctrl-Z)",
|
||||
"pad.toolbar.redo.title": "Yenile (Ctrl-Y)",
|
||||
"pad.toolbar.clearAuthorship.title": "Yazarlık Renklerini Temizle",
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Andriykopanytsia",
|
||||
"1": "Base",
|
||||
"2": "Olvin",
|
||||
"4": "Steve.rusyn",
|
||||
"5": "SteveR"
|
||||
}
|
||||
"authors": [
|
||||
"Andriykopanytsia",
|
||||
"Base",
|
||||
"Olvin",
|
||||
"Steve.rusyn",
|
||||
"SteveR"
|
||||
]
|
||||
},
|
||||
"index.newPad": "Створити",
|
||||
"index.createOpenPad": "або створити/відкрити документ з назвою:",
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
"pad.toolbar.strikethrough.title": "删除线",
|
||||
"pad.toolbar.ol.title": "有序列表",
|
||||
"pad.toolbar.ul.title": "无序列表",
|
||||
"pad.toolbar.indent.title": "增加缩进",
|
||||
"pad.toolbar.unindent.title": "减少缩进",
|
||||
"pad.toolbar.indent.title": "增加缩进(TAB)",
|
||||
"pad.toolbar.unindent.title": "减少缩进(Shift+TAB)",
|
||||
"pad.toolbar.undo.title": "撤消 (Ctrl-Z)",
|
||||
"pad.toolbar.redo.title": "重做 (Ctrl-Y)",
|
||||
"pad.toolbar.clearAuthorship.title": "清除作者颜色",
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"authors": {
|
||||
"0": "Justincheng12345",
|
||||
"1": "Liuxinyu970226",
|
||||
"2": "Shangkuanlc",
|
||||
"3": "Shirayuki",
|
||||
"5": "Simon Shek"
|
||||
}
|
||||
"authors": [
|
||||
"Justincheng12345",
|
||||
"Liuxinyu970226",
|
||||
"Shangkuanlc",
|
||||
"Shirayuki",
|
||||
"Simon Shek"
|
||||
]
|
||||
},
|
||||
"index.newPad": "新Pad",
|
||||
"index.createOpenPad": "或創建/開啟以下名稱的pad:",
|
||||
|
|
|
@ -361,6 +361,8 @@ exports.getHTML = function(padID, rev, callback)
|
|||
exportHtml.getPadHTML(pad, rev, function(err, html)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
html = "<!DOCTYPE HTML><html><body>" +html; // adds HTML head
|
||||
html += "</body></html>";
|
||||
data = {html: html};
|
||||
callback(null, data);
|
||||
});
|
||||
|
@ -371,6 +373,8 @@ exports.getHTML = function(padID, rev, callback)
|
|||
exportHtml.getPadHTML(pad, undefined, function (err, html)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
html = "<!DOCTYPE HTML><html><body>" +html; // adds HTML head
|
||||
html += "</body></html>";
|
||||
data = {html: html};
|
||||
callback(null, data);
|
||||
});
|
||||
|
@ -378,15 +382,30 @@ exports.getHTML = function(padID, rev, callback)
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
setHTML(padID, html) sets the text of a pad based on HTML
|
||||
|
||||
Example returns:
|
||||
|
||||
{code: 0, message:"ok", data: null}
|
||||
{code: 1, message:"padID does not exist", data: null}
|
||||
*/
|
||||
exports.setHTML = function(padID, html, callback)
|
||||
{
|
||||
//html is required
|
||||
if(typeof html != "string")
|
||||
{
|
||||
callback(new customError("html is no string","apierror"));
|
||||
return;
|
||||
}
|
||||
|
||||
//get the pad
|
||||
getPadSafe(padID, true, function(err, pad)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
// add a new changeset with the new html to the pad
|
||||
importHtml.setPadHTML(pad, cleanText(html));
|
||||
importHtml.setPadHTML(pad, cleanText(html), callback);
|
||||
|
||||
//update the clients on the pad
|
||||
padMessageHandler.updatePadClients(pad, callback);
|
||||
|
|
|
@ -203,7 +203,11 @@ Pad.prototype.getInternalRevisionAText = function getInternalRevisionAText(targe
|
|||
{
|
||||
curRev++;
|
||||
var cs = changesets[curRev];
|
||||
atext = Changeset.applyToAText(cs, atext, apool);
|
||||
try{
|
||||
atext = Changeset.applyToAText(cs, atext, apool);
|
||||
}catch(e) {
|
||||
return callback(e)
|
||||
}
|
||||
}
|
||||
|
||||
callback(null);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* The MessageHandler handles all Messages that comes from Socket.IO and controls the sessions
|
||||
*/
|
||||
* The MessageHandler handles all Messages that comes from Socket.IO and controls the sessions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2009 Google Inc., 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
|
||||
|
@ -106,12 +106,12 @@ exports.kickSessionsFromPad = function(padID)
|
|||
* @param client the client that leaves
|
||||
*/
|
||||
exports.handleDisconnect = function(client)
|
||||
{
|
||||
{
|
||||
stats.meter('disconnects').mark();
|
||||
|
||||
|
||||
//save the padname of this session
|
||||
var session = sessioninfos[client.id];
|
||||
|
||||
|
||||
//if this connection was already etablished with a handshake, send a disconnect message to the others
|
||||
if(session && session.author)
|
||||
{
|
||||
|
@ -128,7 +128,7 @@ exports.handleDisconnect = function(client)
|
|||
authorManager.getAuthorColorId(session.author, function(err, color)
|
||||
{
|
||||
ERR(err);
|
||||
|
||||
|
||||
//prepare the notification for the other users on the pad, that this user left
|
||||
var messageToTheOtherUsers = {
|
||||
"type": "COLLABROOM",
|
||||
|
@ -142,14 +142,14 @@ exports.handleDisconnect = function(client)
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//Go trough all user that are still on the pad, and send them the USER_LEAVE message
|
||||
client.broadcast.to(session.padId).json.send(messageToTheOtherUsers);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//Delete the sessioninfos entrys of this session
|
||||
delete sessioninfos[client.id];
|
||||
delete sessioninfos[client.id];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,7 +158,7 @@ exports.handleDisconnect = function(client)
|
|||
* @param message the message from the client
|
||||
*/
|
||||
exports.handleMessage = function(client, message)
|
||||
{
|
||||
{
|
||||
if(message == null)
|
||||
{
|
||||
return;
|
||||
|
@ -174,7 +174,7 @@ exports.handleMessage = function(client, message)
|
|||
|
||||
var handleMessageHook = function(callback){
|
||||
var dropMessage = false;
|
||||
// Call handleMessage hook. If a plugin returns null, the message will be dropped. Note that for all messages
|
||||
// Call handleMessage hook. If a plugin returns null, the message will be dropped. Note that for all messages
|
||||
// handleMessage will be called, even if the client is not authorized
|
||||
hooks.aCallAll("handleMessage", { client: client, message: message }, function ( err, messages ) {
|
||||
if(ERR(err, callback)) return;
|
||||
|
@ -183,7 +183,7 @@ exports.handleMessage = function(client, message)
|
|||
dropMessage = true;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// If no plugins explicitly told us to drop the message, its ok to proceed
|
||||
if(!dropMessage){ callback() };
|
||||
});
|
||||
|
@ -259,7 +259,7 @@ exports.handleMessage = function(client, message)
|
|||
var checkAccessCallback = function(err, statusObject)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//access was granted
|
||||
if(statusObject.accessStatus == "grant")
|
||||
{
|
||||
|
@ -297,17 +297,17 @@ exports.handleMessage = function(client, message)
|
|||
function handleSaveRevisionMessage(client, message){
|
||||
var padId = sessioninfos[client.id].padId;
|
||||
var userId = sessioninfos[client.id].author;
|
||||
|
||||
|
||||
padManager.getPad(padId, function(err, pad)
|
||||
{
|
||||
if(ERR(err)) return;
|
||||
|
||||
|
||||
pad.addSavedRevision(pad.head, userId);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a custom message, different to the function below as it handles objects not strings and you can
|
||||
* Handles a custom message, different to the function below as it handles objects not strings and you can
|
||||
* direct the message to specific sessionID
|
||||
*
|
||||
* @param msg {Object} the message we're sending
|
||||
|
@ -356,10 +356,10 @@ function handleChatMessage(client, message)
|
|||
var userId = sessioninfos[client.id].author;
|
||||
var text = message.data.text;
|
||||
var padId = sessioninfos[client.id].padId;
|
||||
|
||||
|
||||
var pad;
|
||||
var userName;
|
||||
|
||||
|
||||
async.series([
|
||||
//get the pad
|
||||
function(callback)
|
||||
|
@ -385,7 +385,7 @@ function handleChatMessage(client, message)
|
|||
{
|
||||
//save the chat message
|
||||
pad.appendChatMessage(text, userId, time);
|
||||
|
||||
|
||||
var msg = {
|
||||
type: "COLLABROOM",
|
||||
data: {
|
||||
|
@ -396,10 +396,10 @@ function handleChatMessage(client, message)
|
|||
text: text
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//broadcast the chat message to everyone on the pad
|
||||
socketio.sockets.in(padId).json.send(msg);
|
||||
|
||||
|
||||
callback();
|
||||
}
|
||||
], function(err)
|
||||
|
@ -425,20 +425,20 @@ function handleGetChatMessages(client, message)
|
|||
messageLogger.warn("Dropped message, GetChatMessages Message has no start!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var start = message.data.start;
|
||||
var end = message.data.end;
|
||||
var count = start - count;
|
||||
|
||||
|
||||
if(count < 0 && count > 100)
|
||||
{
|
||||
messageLogger.warn("Dropped message, GetChatMessages Message, client requested invalid amout of messages!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var padId = sessioninfos[client.id].padId;
|
||||
var pad;
|
||||
|
||||
|
||||
async.series([
|
||||
//get the pad
|
||||
function(callback)
|
||||
|
@ -488,10 +488,10 @@ function handleSuggestUserName(client, message)
|
|||
messageLogger.warn("Dropped message, suggestUserName Message has no unnamedId!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var padId = sessioninfos[client.id].padId,
|
||||
clients = socketio.sockets.clients(padId);
|
||||
|
||||
|
||||
//search the author and send him this message
|
||||
for(var i = 0; i < clients.length; i++) {
|
||||
var session = sessioninfos[clients[i].id];
|
||||
|
@ -520,14 +520,14 @@ function handleUserInfoUpdate(client, message)
|
|||
messageLogger.warn("Dropped message, USERINFO_UPDATE Message has no colorId!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//Find out the author name of this session
|
||||
var author = sessioninfos[client.id].author;
|
||||
|
||||
|
||||
//Tell the authorManager about the new attributes
|
||||
authorManager.setAuthorColorId(author, message.data.userInfo.colorId);
|
||||
authorManager.setAuthorName(author, message.data.userInfo.name);
|
||||
|
||||
|
||||
var padId = sessioninfos[client.id].padId;
|
||||
|
||||
var infoMsg = {
|
||||
|
@ -545,7 +545,7 @@ function handleUserInfoUpdate(client, message)
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//Send the other clients on the pad the update message
|
||||
client.broadcast.to(padId).json.send(infoMsg);
|
||||
}
|
||||
|
@ -588,7 +588,7 @@ function handleUserChanges(data, cb)
|
|||
messageLogger.warn("Dropped message, USER_CHANGES Message has no changeset!");
|
||||
return cb();
|
||||
}
|
||||
|
||||
|
||||
//get all Vars we need
|
||||
var baseRev = message.data.baseRev;
|
||||
var wireApool = (new AttributePool()).fromJsonable(message.data.apool);
|
||||
|
@ -596,12 +596,12 @@ function handleUserChanges(data, cb)
|
|||
// The client might disconnect between our callbacks. We should still
|
||||
// finish processing the changeset, so keep a reference to the session.
|
||||
var thisSession = sessioninfos[client.id];
|
||||
|
||||
|
||||
var r, apool, pad;
|
||||
|
||||
// Measure time to process edit
|
||||
var stopWatch = stats.timer('edits').start();
|
||||
|
||||
|
||||
async.series([
|
||||
//get the pad
|
||||
function(callback)
|
||||
|
@ -617,7 +617,7 @@ function handleUserChanges(data, cb)
|
|||
function(callback)
|
||||
{
|
||||
//ex. _checkChangesetAndPool
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// Verify that the changeset has valid syntax and is in canonical form
|
||||
|
@ -644,9 +644,9 @@ function handleUserChanges(data, cb)
|
|||
if('author' == attr[0] && attr[1] != thisSession.author) throw new Error("Trying to submit changes as another author in changeset "+changeset);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//ex. adoptChangesetAttribs
|
||||
|
||||
|
||||
//Afaik, it copies the new attributes from the changeset, to the global Attribute Pool
|
||||
changeset = Changeset.moveOpsToNewPool(changeset, wireApool, pad.pool);
|
||||
}
|
||||
|
@ -657,7 +657,7 @@ function handleUserChanges(data, cb)
|
|||
stats.meter('failedChangesets').mark();
|
||||
return callback(new Error("Can't apply USER_CHANGES, because "+e.message));
|
||||
}
|
||||
|
||||
|
||||
//ex. applyUserChanges
|
||||
apool = pad.pool;
|
||||
r = baseRev;
|
||||
|
@ -671,7 +671,7 @@ function handleUserChanges(data, cb)
|
|||
function(callback)
|
||||
{
|
||||
r++;
|
||||
|
||||
|
||||
pad.getRevisionChangeset(r, function(err, c)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
@ -704,16 +704,16 @@ function handleUserChanges(data, cb)
|
|||
function (callback)
|
||||
{
|
||||
var prevText = pad.text();
|
||||
|
||||
if (Changeset.oldLen(changeset) != prevText.length)
|
||||
|
||||
if (Changeset.oldLen(changeset) != prevText.length)
|
||||
{
|
||||
client.json.send({disconnect:"badChangeset"});
|
||||
stats.meter('failedChangesets').mark();
|
||||
return callback(new Error("Can't apply USER_CHANGES "+changeset+" with oldLen " + Changeset.oldLen(changeset) + " to document of length " + prevText.length));
|
||||
}
|
||||
|
||||
|
||||
pad.appendRevision(changeset, thisSession.author);
|
||||
|
||||
|
||||
var correctionChangeset = _correctMarkersInPad(pad.atext, pad.pool);
|
||||
if (correctionChangeset) {
|
||||
pad.appendRevision(correctionChangeset);
|
||||
|
@ -724,7 +724,7 @@ function handleUserChanges(data, cb)
|
|||
var nlChangeset = Changeset.makeSplice(pad.text(), pad.text().length-1, 0, "\n");
|
||||
pad.appendRevision(nlChangeset);
|
||||
}
|
||||
|
||||
|
||||
exports.updatePadClients(pad, function(er) {
|
||||
ERR(er)
|
||||
});
|
||||
|
@ -739,16 +739,16 @@ function handleUserChanges(data, cb)
|
|||
}
|
||||
|
||||
exports.updatePadClients = function(pad, callback)
|
||||
{
|
||||
{
|
||||
//skip this step if noone is on this pad
|
||||
var roomClients = socketio.sockets.clients(pad.id);
|
||||
if(roomClients.length==0)
|
||||
return callback();
|
||||
|
||||
|
||||
// since all clients usually get the same set of changesets, store them in local cache
|
||||
// to remove unnecessary roundtrip to the datalayer
|
||||
// TODO: in REAL world, if we're working without datalayer cache, all requests to revisions will be fired
|
||||
// BEFORE first result will be landed to our cache object. The solution is to replace parallel processing
|
||||
// BEFORE first result will be landed to our cache object. The solution is to replace parallel processing
|
||||
// via async.forEach with sequential for() loop. There is no real benefits of running this in parallel,
|
||||
// but benefit of reusing cached revision object is HUGE
|
||||
var revCache = {};
|
||||
|
@ -763,7 +763,7 @@ exports.updatePadClients = function(pad, callback)
|
|||
async.whilst(
|
||||
function (){ return sessioninfos[sid] && sessioninfos[sid].rev < pad.getHeadRevisionNumber()},
|
||||
function(callback)
|
||||
{
|
||||
{
|
||||
var r = sessioninfos[sid].rev + 1;
|
||||
|
||||
async.waterfall([
|
||||
|
@ -772,7 +772,7 @@ exports.updatePadClients = function(pad, callback)
|
|||
callback(null, revCache[r]);
|
||||
else
|
||||
pad.getRevision(r, callback);
|
||||
},
|
||||
},
|
||||
function(revision, callback)
|
||||
{
|
||||
revCache[r] = revision;
|
||||
|
@ -800,8 +800,8 @@ exports.updatePadClients = function(pad, callback)
|
|||
author: author,
|
||||
currentTime: currentTime,
|
||||
timeDelta: currentTime - sessioninfos[sid].time
|
||||
}};
|
||||
|
||||
}};
|
||||
|
||||
client.json.send(wireMsg);
|
||||
}
|
||||
|
||||
|
@ -814,7 +814,7 @@ exports.updatePadClients = function(pad, callback)
|
|||
},
|
||||
callback
|
||||
);
|
||||
},callback);
|
||||
},callback);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -830,11 +830,11 @@ function _correctMarkersInPad(atext, apool) {
|
|||
var offset = 0;
|
||||
while (iter.hasNext()) {
|
||||
var op = iter.next();
|
||||
|
||||
|
||||
var hasMarker = _.find(AttributeManager.lineAttributes, function(attribute){
|
||||
return Changeset.opAttributeValue(op, attribute, apool);
|
||||
}) !== undefined;
|
||||
|
||||
|
||||
if (hasMarker) {
|
||||
for(var i=0;i<op.chars;i++) {
|
||||
if (offset > 0 && text.charAt(offset-1) != '\n') {
|
||||
|
@ -864,7 +864,7 @@ function _correctMarkersInPad(atext, apool) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Handles a CLIENT_READY. A CLIENT_READY is the first message from the client to the server. The Client sends his token
|
||||
* Handles a CLIENT_READY. A CLIENT_READY is the first message from the client to the server. The Client sends his token
|
||||
* and the pad it wants to enter. The Server answers with the inital values (clientVars) of the pad
|
||||
* @param client the client that send this message
|
||||
* @param message the message from the client
|
||||
|
@ -922,7 +922,7 @@ function handleClientReady(client, message)
|
|||
securityManager.checkAccess (padIds.padId, message.sessionID, message.token, message.password, function(err, statusObject)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
//access was granted
|
||||
if(statusObject.accessStatus == "grant")
|
||||
{
|
||||
|
@ -935,7 +935,7 @@ function handleClientReady(client, message)
|
|||
client.json.send({accessStatus: statusObject.accessStatus})
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
//get all authordata of this new user, and load the pad-object from the database
|
||||
function(callback)
|
||||
{
|
||||
|
@ -967,7 +967,7 @@ function handleClientReady(client, message)
|
|||
function(callback)
|
||||
{
|
||||
var authors = pad.getAllAuthors();
|
||||
|
||||
|
||||
async.parallel([
|
||||
//get timestamp of latest revission needed for timeslider
|
||||
function(callback)
|
||||
|
@ -993,7 +993,7 @@ function handleClientReady(client, message)
|
|||
}, callback);
|
||||
}
|
||||
], callback);
|
||||
|
||||
|
||||
},
|
||||
//glue the clientVars together, send them and tell the other clients that a new one is there
|
||||
function(callback)
|
||||
|
@ -1013,12 +1013,12 @@ function handleClientReady(client, message)
|
|||
roomClients[i].json.send({disconnect:"userdup"});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Save in sessioninfos that this session belonges to this pad
|
||||
sessioninfos[client.id].padId = padIds.padId;
|
||||
sessioninfos[client.id].readOnlyPadId = padIds.readOnlyPadId;
|
||||
sessioninfos[client.id].readonly = padIds.readonly;
|
||||
|
||||
|
||||
//Log creation/(re-)entering of a pad
|
||||
client.get('remoteAddress', function(er, ip) {
|
||||
//Anonymize the IP address if IP logging is disabled
|
||||
|
@ -1056,7 +1056,7 @@ function handleClientReady(client, message)
|
|||
client.json.send({disconnect:"corruptPad"});// pull the breaks
|
||||
return callback();
|
||||
}
|
||||
|
||||
|
||||
// Warning: never ever send padIds.padId to the client. If the
|
||||
// client is read only you would open a security hole 1 swedish
|
||||
// mile wide...
|
||||
|
@ -1085,7 +1085,7 @@ function handleClientReady(client, message)
|
|||
"padId": message.padId,
|
||||
"initialTitle": "Pad: " + message.padId,
|
||||
"opts": {},
|
||||
// tell the client the number of the latest chat-message, which will be
|
||||
// tell the client the number of the latest chat-message, which will be
|
||||
// used to request the latest 100 chat-messages later (GET_CHAT_MESSAGES)
|
||||
"chatHead": pad.chatHead,
|
||||
"numConnectedUsers": roomClients.length,
|
||||
|
@ -1093,7 +1093,7 @@ function handleClientReady(client, message)
|
|||
"readonly": padIds.readonly,
|
||||
"serverTimestamp": new Date().getTime(),
|
||||
"userId": author,
|
||||
"abiwordAvailable": settings.abiwordAvailable(),
|
||||
"abiwordAvailable": settings.abiwordAvailable(),
|
||||
"plugins": {
|
||||
"plugins": plugins.plugins,
|
||||
"parts": plugins.parts,
|
||||
|
@ -1106,18 +1106,18 @@ function handleClientReady(client, message)
|
|||
{
|
||||
clientVars.userName = authorName;
|
||||
}
|
||||
|
||||
|
||||
//call the clientVars-hook so plugins can modify them before they get sent to the client
|
||||
hooks.aCallAll("clientVars", { clientVars: clientVars, pad: pad }, function ( err, messages ) {
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
_.each(messages, function(newVars) {
|
||||
//combine our old object with the new attributes from the hook
|
||||
for(var attr in newVars) {
|
||||
clientVars[attr] = newVars[attr];
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//Join the pad and start receiving updates
|
||||
client.join(padIds.padId);
|
||||
//Send the clientVars to the Client
|
||||
|
@ -1126,9 +1126,9 @@ function handleClientReady(client, message)
|
|||
sessioninfos[client.id].rev = pad.getHeadRevisionNumber();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
sessioninfos[client.id].author = author;
|
||||
|
||||
|
||||
//prepare the notification for the other users on the pad, that this user joined
|
||||
var messageToTheOtherUsers = {
|
||||
"type": "COLLABROOM",
|
||||
|
@ -1142,7 +1142,7 @@ function handleClientReady(client, message)
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//Add the authorname of this new User, if avaiable
|
||||
if(authorName != null)
|
||||
{
|
||||
|
@ -1151,7 +1151,7 @@ function handleClientReady(client, message)
|
|||
|
||||
// notify all existing users about new user
|
||||
client.broadcast.to(padIds.padId).json.send(messageToTheOtherUsers);
|
||||
|
||||
|
||||
//Run trough all sessions of this pad
|
||||
async.forEach(socketio.sockets.clients(padIds.padId), function(roomClient, callback)
|
||||
{
|
||||
|
@ -1160,9 +1160,9 @@ function handleClientReady(client, message)
|
|||
//Jump over, if this session is the connection session
|
||||
if(roomClient.id == client.id)
|
||||
return callback();
|
||||
|
||||
|
||||
//Since sessioninfos might change while being enumerated, check if the
|
||||
|
||||
|
||||
//Since sessioninfos might change while being enumerated, check if the
|
||||
//sessionID is still assigned to a valid session
|
||||
if(sessioninfos[roomClient.id] !== undefined)
|
||||
author = sessioninfos[roomClient.id].author;
|
||||
|
@ -1178,7 +1178,7 @@ function handleClientReady(client, message)
|
|||
callback(null, historicalAuthorData[author]);
|
||||
else
|
||||
authorManager.getAuthor(author, callback);
|
||||
},
|
||||
},
|
||||
function (authorInfo, callback)
|
||||
{
|
||||
//Send the new User a Notification about this other user
|
||||
|
@ -1207,7 +1207,7 @@ function handleClientReady(client, message)
|
|||
}
|
||||
|
||||
/**
|
||||
* Handles a request for a rough changeset, the timeslider client needs it
|
||||
* Handles a request for a rough changeset, the timeslider client needs it
|
||||
*/
|
||||
function handleChangesetRequest(client, message)
|
||||
{
|
||||
|
@ -1237,7 +1237,7 @@ function handleChangesetRequest(client, message)
|
|||
messageLogger.warn("Dropped message, changeset request has no requestID!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var granularity = message.data.granularity;
|
||||
var start = message.data.start;
|
||||
var end = start + (100 * granularity);
|
||||
|
@ -1255,7 +1255,7 @@ function handleChangesetRequest(client, message)
|
|||
//build the requested rough changesets and send them back
|
||||
getChangesetInfo(padIds.padId, start, end, granularity, function(err, changesetInfo)
|
||||
{
|
||||
ERR(err);
|
||||
if(err) return console.error('Error while handling a changeset request for '+padIds.padId, err, message.data);
|
||||
|
||||
var data = changesetInfo;
|
||||
data.requestID = message.data.requestID;
|
||||
|
@ -1281,47 +1281,49 @@ function getChangesetInfo(padId, startNum, endNum, granularity, callback)
|
|||
var composedChangesets = {};
|
||||
var revisionDate = [];
|
||||
var lines;
|
||||
|
||||
var head_revision = 0;
|
||||
|
||||
async.series([
|
||||
//get the pad from the database
|
||||
function(callback)
|
||||
{
|
||||
padManager.getPad(padId, function(err, _pad)
|
||||
{
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
pad = _pad;
|
||||
head_revision = pad.getHeadRevisionNumber();
|
||||
callback();
|
||||
});
|
||||
},
|
||||
function(callback)
|
||||
{
|
||||
{
|
||||
//calculate the last full endnum
|
||||
var lastRev = pad.getHeadRevisionNumber();
|
||||
if (endNum > lastRev+1) {
|
||||
endNum = lastRev+1;
|
||||
}
|
||||
endNum = Math.floor(endNum / granularity)*granularity;
|
||||
|
||||
|
||||
var compositesChangesetNeeded = [];
|
||||
var revTimesNeeded = [];
|
||||
|
||||
|
||||
//figure out which composite Changeset and revTimes we need, to load them in bulk
|
||||
var compositeStart = startNum;
|
||||
while (compositeStart < endNum)
|
||||
while (compositeStart < endNum)
|
||||
{
|
||||
var compositeEnd = compositeStart + granularity;
|
||||
|
||||
|
||||
//add the composite Changeset we needed
|
||||
compositesChangesetNeeded.push({start: compositeStart, end: compositeEnd});
|
||||
|
||||
|
||||
//add the t1 time we need
|
||||
revTimesNeeded.push(compositeStart == 0 ? 0 : compositeStart - 1);
|
||||
//add the t2 time we need
|
||||
revTimesNeeded.push(compositeEnd - 1);
|
||||
|
||||
|
||||
compositeStart += granularity;
|
||||
}
|
||||
|
||||
|
||||
//get all needed db values parallel
|
||||
async.parallel([
|
||||
function(callback)
|
||||
|
@ -1358,58 +1360,57 @@ function getChangesetInfo(padId, startNum, endNum, granularity, callback)
|
|||
if(ERR(err, callback)) return;
|
||||
lines = _lines;
|
||||
callback();
|
||||
});
|
||||
});
|
||||
}
|
||||
], callback);
|
||||
},
|
||||
//doesn't know what happens here excatly :/
|
||||
function(callback)
|
||||
{
|
||||
{
|
||||
var compositeStart = startNum;
|
||||
|
||||
while (compositeStart < endNum)
|
||||
|
||||
while (compositeStart < endNum)
|
||||
{
|
||||
if (compositeStart + granularity > endNum)
|
||||
var compositeEnd = compositeStart + granularity;
|
||||
if (compositeEnd > endNum || compositeEnd > head_revision)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var compositeEnd = compositeStart + granularity;
|
||||
|
||||
|
||||
var forwards = composedChangesets[compositeStart + "/" + compositeEnd];
|
||||
var backwards = Changeset.inverse(forwards, lines.textlines, lines.alines, pad.apool());
|
||||
|
||||
|
||||
Changeset.mutateAttributionLines(forwards, lines.alines, pad.apool());
|
||||
Changeset.mutateTextLines(forwards, lines.textlines);
|
||||
|
||||
|
||||
var forwards2 = Changeset.moveOpsToNewPool(forwards, pad.apool(), apool);
|
||||
var backwards2 = Changeset.moveOpsToNewPool(backwards, pad.apool(), apool);
|
||||
|
||||
|
||||
var t1, t2;
|
||||
if (compositeStart == 0)
|
||||
if (compositeStart == 0)
|
||||
{
|
||||
t1 = revisionDate[0];
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
t1 = revisionDate[compositeStart - 1];
|
||||
}
|
||||
|
||||
|
||||
t2 = revisionDate[compositeEnd - 1];
|
||||
|
||||
|
||||
timeDeltas.push(t2 - t1);
|
||||
forwardsChangesets.push(forwards2);
|
||||
backwardsChangesets.push(backwards2);
|
||||
|
||||
|
||||
compositeStart += granularity;
|
||||
}
|
||||
|
||||
|
||||
callback();
|
||||
}
|
||||
], function(err)
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
|
||||
|
||||
callback(null, {forwardsChangesets: forwardsChangesets,
|
||||
backwardsChangesets: backwardsChangesets,
|
||||
apool: apool.toJsonable(),
|
||||
|
@ -1424,7 +1425,7 @@ function getChangesetInfo(padId, startNum, endNum, granularity, callback)
|
|||
* Tries to rebuild the getPadLines function of the original Etherpad
|
||||
* https://github.com/ether/pad/blob/master/etherpad/src/etherpad/control/pad/pad_changeset_control.js#L263
|
||||
*/
|
||||
function getPadLines(padId, revNum, callback)
|
||||
function getPadLines(padId, revNum, callback)
|
||||
{
|
||||
var atext;
|
||||
var result = {};
|
||||
|
@ -1435,7 +1436,7 @@ function getPadLines(padId, revNum, callback)
|
|||
function(callback)
|
||||
{
|
||||
padManager.getPad(padId, function(err, _pad)
|
||||
{
|
||||
{
|
||||
if(ERR(err, callback)) return;
|
||||
pad = _pad;
|
||||
callback();
|
||||
|
@ -1479,7 +1480,7 @@ function getPadLines(padId, revNum, callback)
|
|||
function composePadChangesets(padId, startNum, endNum, callback)
|
||||
{
|
||||
var pad;
|
||||
var changesets = [];
|
||||
var changesets = {};
|
||||
var changeset;
|
||||
|
||||
async.series([
|
||||
|
@ -1497,14 +1498,19 @@ function composePadChangesets(padId, startNum, endNum, callback)
|
|||
function(callback)
|
||||
{
|
||||
var changesetsNeeded=[];
|
||||
|
||||
//create a array for all changesets, we will
|
||||
|
||||
var headNum = pad.getHeadRevisionNumber();
|
||||
if (endNum > headNum)
|
||||
endNum = headNum;
|
||||
if (startNum < 0)
|
||||
startNum = 0;
|
||||
//create a array for all changesets, we will
|
||||
//replace the values with the changeset later
|
||||
for(var r=startNum;r<endNum;r++)
|
||||
{
|
||||
changesetsNeeded.push(r);
|
||||
}
|
||||
|
||||
|
||||
//get all changesets
|
||||
async.forEach(changesetsNeeded, function(revNum,callback)
|
||||
{
|
||||
|
@ -1521,13 +1527,13 @@ function composePadChangesets(padId, startNum, endNum, callback)
|
|||
{
|
||||
changeset = changesets[startNum];
|
||||
var pool = pad.apool();
|
||||
|
||||
|
||||
for(var r=startNum+1;r<endNum;r++)
|
||||
{
|
||||
var cs = changesets[r];
|
||||
changeset = Changeset.compose(changeset, cs, pool);
|
||||
}
|
||||
|
||||
|
||||
callback(null);
|
||||
}
|
||||
],
|
||||
|
|
|
@ -25,11 +25,6 @@ function setPadHTML(pad, html, callback)
|
|||
{
|
||||
var apiLogger = log4js.getLogger("ImportHtml");
|
||||
|
||||
// Clean the pad. This makes the rest of the code easier
|
||||
// by several orders of magnitude.
|
||||
pad.setText("");
|
||||
var padText = pad.text();
|
||||
|
||||
// Parse the incoming HTML with jsdom
|
||||
try{
|
||||
var doc = jsdom(html.replace(/>\n+</g, '><'));
|
||||
|
@ -44,8 +39,15 @@ function setPadHTML(pad, html, callback)
|
|||
// Convert a dom tree into a list of lines and attribute liens
|
||||
// using the content collector object
|
||||
var cc = contentcollector.makeContentCollector(true, null, pad.pool);
|
||||
cc.collectContent(doc.childNodes[0]);
|
||||
try{ // we use a try here because if the HTML is bad it will blow up
|
||||
cc.collectContent(doc.childNodes[0]);
|
||||
}catch(e){
|
||||
apiLogger.warn("HTML was not properly formed", e);
|
||||
return; // We don't process the HTML because it was bad..
|
||||
}
|
||||
|
||||
var result = cc.finish();
|
||||
|
||||
apiLogger.debug('Lines:');
|
||||
var i;
|
||||
for (i = 0; i < result.lines.length; i += 1)
|
||||
|
@ -90,6 +92,7 @@ function setPadHTML(pad, html, callback)
|
|||
// the changeset is ready!
|
||||
var theChangeset = builder.toString();
|
||||
apiLogger.debug('The changeset: ' + theChangeset);
|
||||
pad.setText("");
|
||||
pad.appendRevision(theChangeset);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue