Merge pull request #1304 from ether/release/releases-1.2.2
Version 1.2.2 releasepull/1305/head 1.2.2
commit
6a65a47444
|
@ -1,5 +1,6 @@
|
|||
node_modules
|
||||
settings.json
|
||||
!settings.json.template
|
||||
APIKEY.txt
|
||||
bin/abiword.exe
|
||||
bin/node.exe
|
||||
|
@ -12,3 +13,5 @@ src/static/js/jquery.js
|
|||
npm-debug.log
|
||||
*.DS_Store
|
||||
.ep_initialized
|
||||
*.crt
|
||||
*.key
|
||||
|
|
19
CHANGELOG.md
19
CHANGELOG.md
|
@ -1,3 +1,22 @@
|
|||
# 1.2.2
|
||||
* More translations and better language support. See https://translatewiki.net/wiki/Translating:Etherpad_lite for more details
|
||||
* Add a checkToken Method to the API
|
||||
* Bugfix for Internal Caching issue that was causing some 404s on images.
|
||||
* Bugfix for IE Import
|
||||
* Bugfix for Node 0.6 compatibility
|
||||
* Bugfix for multiple cookie support
|
||||
* Bugfix for API when requireAuth is enabled.
|
||||
* Plugin page now shows plugin version #
|
||||
* Show color of Author in Chat messages
|
||||
* Allow plugin search by description
|
||||
* Allow for different socket IO transports
|
||||
* Allow for custom favicon path
|
||||
* Control S now does Create new Revision functionality
|
||||
* Focus on password when required
|
||||
* Frontend Timeslider test
|
||||
* Allow for basic HTML etc. import without abiword
|
||||
* Native HTTPS support
|
||||
|
||||
# 1.2.1
|
||||
* Allow ! in urls inside the editor (Not Pad urls)
|
||||
* Allow comments in language files
|
||||
|
|
|
@ -28,8 +28,9 @@ documented codebase makes it easier for developers to improve the code and contr
|
|||
|
||||
|
||||
Etherpad Lite is designed to be easily embeddable and provides a [HTTP API](https://github.com/ether/etherpad-lite/wiki/HTTP-API)
|
||||
that allows your web application to manage pads, users and groups. It is recommended to use the client implementations available for this API, listed on [this wiki page](https://github.com/ether/etherpad-lite/wiki/HTTP-API-client-libraries).
|
||||
There is also a [jQuery plugin](https://github.com/johnyma22/etherpad-lite-jquery-plugin) that helps you to embed Pads into your website
|
||||
that allows your web application to manage pads, users and groups. It is recommended to use the [available client implementations]((https://github.com/ether/etherpad-lite/wiki/HTTP-API-client-libraries) in order to interact with this API. There is also a [jQuery plugin](https://github.com/johnyma22/etherpad-lite-jquery-plugin) that helps you to embed Pads into your website.
|
||||
There's also a full-featured plugin framework, allowing you to easily add your own features.
|
||||
Finally, Etherpad Lite comes with translations into tons of different languages!
|
||||
|
||||
**Visit [beta.etherpad.org](http://beta.etherpad.org) to test it live**
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ This load tester is extremely useful for testing how many dormant clients can co
|
|||
TODO:
|
||||
Emulate characters being typed into a pad
|
||||
|
||||
HOW TO USE (from @mjd75) proper formatting at: https://github.com/Pita/etherpad-lite/issues/360
|
||||
HOW TO USE (from @mjd75) proper formatting at: https://github.com/ether/etherpad-lite/issues/360
|
||||
|
||||
Server 1:
|
||||
Installed Node.js (etc), EtherPad Lite and MySQL
|
||||
|
|
|
@ -9,7 +9,7 @@ The API gives another web application control of the pads. The basic functions a
|
|||
|
||||
The API is designed in a way, so you can reuse your existing user system with their permissions, and map it to etherpad lite. Means: Your web application still has to do authentication, but you can tell etherpad lite via the api, which visitors should get which permissions. This allows etherpad lite to fit into any web application and extend it with real-time functionality. You can embed the pads via an iframe into your website.
|
||||
|
||||
Take a look at [HTTP API client libraries](https://github.com/Pita/etherpad-lite/wiki/HTTP-API-client-libraries) to see if a library in your favorite language.
|
||||
Take a look at [HTTP API client libraries](https://github.com/ether/etherpad-lite/wiki/HTTP-API-client-libraries) to see if a library in your favorite language.
|
||||
|
||||
## Examples
|
||||
|
||||
|
@ -60,9 +60,12 @@ Portal submits content into new blog post
|
|||
|
||||
## Usage
|
||||
|
||||
### API version
|
||||
The latest version is `1.2`
|
||||
|
||||
### Request Format
|
||||
|
||||
The API is accessible via HTTP. HTTP Requests are in the format /api/$APIVERSION/$FUNCTIONNAME. Parameters are transmitted via HTTP GET. $APIVERSION depends on the endpoints you want to use. The latest version is `1.1`
|
||||
The API is accessible via HTTP. HTTP Requests are in the format /api/$APIVERSION/$FUNCTIONNAME. Parameters are transmitted via HTTP GET. $APIVERSION depends on the endpoints you want to use.
|
||||
|
||||
### Response Format
|
||||
Responses are valid JSON in the following format:
|
||||
|
@ -407,3 +410,12 @@ sends a custom message of type `msg` to the pad
|
|||
*Example returns:*
|
||||
* `{code: 0, message:"ok", data: {}}`
|
||||
* `{code: 1, message:"padID does not exist", data: null}`
|
||||
|
||||
#### checkToken()
|
||||
* API >= 1.2
|
||||
|
||||
returns ok when api token is valid
|
||||
|
||||
*Example returns:*
|
||||
* `{"code":0,"message":"ok","data":null}`
|
||||
* `{"code":4,"message":"no or wrong API Key","data":null}`
|
||||
|
|
|
@ -1,19 +1,94 @@
|
|||
# Localization
|
||||
Etherpad lite provides a multi-language user interface, that's apart from your users' content, so users from different countries can collaborate on a single document, while still having the user interface displayed in their mother tongue.
|
||||
|
||||
|
||||
## Translating
|
||||
`/src/locales` contains files for all supported languages which contain the translated strings. To add support for a new language, copy the English language file named `en.ini` and translate it.
|
||||
Translation files are simply `*.ini` files and look like this:
|
||||
We rely on http://translatewiki.net to handle the translation process for us, so if you'd like to help...
|
||||
|
||||
```
|
||||
pad.modals.connected = Connecté.
|
||||
pad.modals.uderdup = Ouvrir dans une nouvelle fenêtre.
|
||||
pad.toolbar.unindent.title = Désindenter
|
||||
pad.toolbar.undo.title = Annuler (Ctrl-Z)
|
||||
timeslider.pageTitle = {{appTitle}} Curseur temporel
|
||||
1. sign up at http://translatewiki.net
|
||||
2. Visit our [TWN project page](https://translatewiki.net/wiki/Translating:Etherpad_lite)
|
||||
3. Click on `Translate Etherpad lite interface`
|
||||
4. Choose a target language, you'd like to translate our interface to, and hit `Fetch`
|
||||
5. Start translating!
|
||||
|
||||
Translations will be send back to us regularly and will eventually appear in the next release.
|
||||
|
||||
## Implementation
|
||||
|
||||
### Server-side
|
||||
`/src/locales` contains files for all supported languages which contain the translated strings. Translation files are simple `*.json` files and look like this:
|
||||
|
||||
```json
|
||||
{ "pad.modals.connected": "Connecté."
|
||||
, "pad.modals.uderdup": "Ouvrir dans une nouvelle fenêtre."
|
||||
, "pad.toolbar.unindent.title": "Désindenter"
|
||||
, "pad.toolbar.undo.title": "Annuler (Ctrl-Z)"
|
||||
, "timeslider.pageTitle": "{{appTitle}} Curseur temporel"
|
||||
, ...
|
||||
}
|
||||
```
|
||||
|
||||
There must be only one translation per line. Each translation consists of a key (the id of the string that is to be translated), an equal sign and the translated string. Anything after the equa sign will be used as the translated string (you may put some spaces after `=` for better readability, though). Terms in curly braces must not be touched but left as they are, since they represent a dynamically changing part of the string like a variable. Imagine a message welcoming a user: `Welcome, {{userName}}!` would be translated as `Ahoy, {{userName}}!` in pirate.
|
||||
Each translation consists of a key (the id of the string that is to be translated) and the translated string. Terms in curly braces must not be touched but left as they are, since they represent a dynamically changing part of the string like a variable. Imagine a message welcoming a user: `Welcome, {{userName}}!` would be translated as `Ahoy, {{userName}}!` in pirate.
|
||||
|
||||
## Under the hood
|
||||
We use a `language` cookie to save your language settings if you change them. If you don't, we autodetect your locale using information from your browser. Now, that we know your preferred language this information is feeded into a very nice library called [webL10n](https://github.com/fabi1cazenave/webL10n), which loads the appropriate translations and applies them to our templates, providing translation params, pluralization, include rules and even a nice javascript API along the way.
|
||||
### Client-side
|
||||
We use a `language` cookie to save your language settings if you change them. If you don't, we autodetect your locale using information from your browser. Now, that we know your preferred language this information is feeded into a very nice library called [html10n.js](https://github.com/marcelklehr/html10n.js), which loads the appropriate translations and applies them to our templates, providing translation params, pluralization, include rules and even a nice javascript API along the way.
|
||||
|
||||
|
||||
|
||||
## Localizing plugins
|
||||
|
||||
### 1. Mark the strings to translate
|
||||
|
||||
In the template files of your plugin, change all hardcoded messages/strings...
|
||||
|
||||
from:
|
||||
```html
|
||||
<option value="0">Heading 1</option>
|
||||
```
|
||||
to:
|
||||
```html
|
||||
<option data-l10n-id="ep_heading.h1" value="0"></option>
|
||||
```
|
||||
|
||||
In the javascript files of your plugin, chaneg all hardcoded messages/strings...
|
||||
|
||||
from:
|
||||
```js
|
||||
alert ('Chat');
|
||||
```
|
||||
to:
|
||||
```js
|
||||
alert(window._('pad.chat'));
|
||||
```
|
||||
### 2. Create translate files in the locales directory of your plugin
|
||||
|
||||
* The name of the file must be the language code of the language it contains translations for (see [supported lang codes](http://joker-x.github.com/languages4translatewiki/test/); e.g. en ? English, es ? Spanish...)
|
||||
* The extension of the file must be `.json`
|
||||
* The default language is English, so your plugin should always provide `en.json`
|
||||
* In order to avoid naming conflicts, your message keys should start with the name of your plugin followed by a dot (see below)
|
||||
|
||||
*ep_your-plugin/locales/en.json*
|
||||
```
|
||||
{ "ep_your-plugin.h1": "Heading 1"
|
||||
}
|
||||
```
|
||||
|
||||
*ep_your-plugin/locales/es.json*
|
||||
```
|
||||
{ "ep_your-plugin.h1": "Título 1"
|
||||
}
|
||||
```
|
||||
|
||||
Everytime the http server is started, it will auto-detect your messages and merge them automatically with the core messages.
|
||||
|
||||
### Overwrite core messages
|
||||
|
||||
You can overwrite Etherpad Lite's core messages in your plugin's locale files.
|
||||
For example, if you want to replace `Chat` with `Notes`, simply add...
|
||||
|
||||
*ep_your-plugin/locales/en.json*
|
||||
```
|
||||
{ "ep_your-plugin.h1": "Heading 1"
|
||||
, "pad.chat": "Notes"
|
||||
}
|
||||
```
|
|
@ -11,12 +11,13 @@ A basic plugin usually has the following folder structure:
|
|||
ep_<plugin>/
|
||||
| static/
|
||||
| templates/
|
||||
| locales/
|
||||
+ ep.json
|
||||
+ package.json
|
||||
```
|
||||
If your plugin includes client-side hooks, put them in `static/js/`. If you're adding in CSS or image files, you should put those files in `static/css/ `and `static/image/`, respectively, and templates go into `templates/`.
|
||||
If your plugin includes client-side hooks, put them in `static/js/`. If you're adding in CSS or image files, you should put those files in `static/css/ `and `static/image/`, respectively, and templates go into `templates/`. Translations go into `locales/`
|
||||
|
||||
A Standard directory structure like this makes it easier to navigate through your code. That said, do note, that this is not actually *required* to make your plugin run.
|
||||
A Standard directory structure like this makes it easier to navigate through your code. That said, do note, that this is not actually *required* to make your plugin run. If you want to make use of our i18n system, you need to put your translations into `locales/`, though, in order to have them intergated. (See "Localization" for more info on how to localize your plugin)
|
||||
|
||||
## Plugin definition
|
||||
Your plugin definition goes into `ep.json`. In this file you register your hooks, indicate the parts of your plugin and the order of execution. (A documentation of all available events to hook into can be found in chapter [hooks](#all_hooks).)
|
||||
|
|
|
@ -11,10 +11,24 @@
|
|||
// alternatively, set up a fully specified Url to your own favicon
|
||||
"favicon": "favicon.ico",
|
||||
|
||||
//Ip and port which etherpad should bind at
|
||||
//IP and port which etherpad should bind at
|
||||
"ip": "0.0.0.0",
|
||||
"port" : 9001,
|
||||
|
||||
|
||||
/*
|
||||
// Node native SSL support
|
||||
// this is disabled by default
|
||||
//
|
||||
// make sure to have the minimum and correct file access permissions set
|
||||
// so that the Etherpad server can access them
|
||||
|
||||
"ssl" : {
|
||||
"key" : "/path-to-your/epl-server.key",
|
||||
"cert" : "/path-to-your/epl-server.crt"
|
||||
},
|
||||
|
||||
*/
|
||||
|
||||
//The Type of the database. You can choose between dirty, postgres, sqlite and mysql
|
||||
//You shouldn't use "dirty" for for anything else than testing or development
|
||||
"dbType" : "dirty",
|
||||
|
@ -51,7 +65,7 @@
|
|||
"maxAge" : 21600, // 60 * 60 * 6 = 6 hours
|
||||
|
||||
/* This is the path to the Abiword executable. Setting it to null, disables abiword.
|
||||
Abiword is needed to enable the import/export of pads*/
|
||||
Abiword is needed to advanced import/export features of pads*/
|
||||
"abiword" : null,
|
||||
|
||||
/* This setting is used if you require authentication of all users.
|
||||
|
@ -77,5 +91,8 @@
|
|||
*/
|
||||
|
||||
/* The log level we are using, can be: DEBUG, INFO, WARN, ERROR */
|
||||
"loglevel": "INFO"
|
||||
"loglevel": "INFO",
|
||||
|
||||
// restrict socket.io transport methods
|
||||
"socketTransportProtocols" : ['xhr-polling', 'jsonp-polling', 'htmlfile']
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"index.newPad":"Nuwe pad","index.createOpenPad":"of skep/open 'n pad met die naam:","pad.toolbar.bold.title":"Vet (Ctrl-B)","pad.toolbar.italic.title":"Kursief (Ctrl-I)","pad.toolbar.underline.title":"Onderstreep (Ctrl-U)","pad.toolbar.strikethrough.title":"Deurgehaal","pad.toolbar.ol.title":"Geordende lys","pad.toolbar.ul.title":"Ongeordende lys","pad.toolbar.indent.title":"Indenteer","pad.toolbar.unindent.title":"Verklein indentering","pad.toolbar.undo.title":"Ongedaan maak (Ctrl-Z)","pad.toolbar.redo.title":"Herdoen (Ctrl-Y)","pad.toolbar.settings.title":"Voorkeure","pad.colorpicker.save":"Stoor","pad.colorpicker.cancel":"Kanselleer","pad.loading":"Laai...","pad.settings.myView":"My oorsig","pad.settings.fontType.normal":"Normaal","pad.settings.fontType.monospaced":"Monospasie","pad.importExport.exporthtml":"HTML","pad.importExport.exportpdf":"PDF","pad.importExport.exportdokuwiki":"DokuWiki","pad.modals.userdup.advice":"Maak weer 'n verbinding as u die venster wil gebruik.","pad.modals.unauth":"Nie toegestaan","pad.modals.looping":"Verbinding verbreek.","pad.modals.deleted":"Geskrap.","pad.share":"Deel die pad","pad.share.readonly":"Lees-alleen","pad.share.link":"Skakel","pad.share.emebdcode":"Inbed URL","pad.chat":"Klets","pad.chat.title":"Maak kletsblad vir die pad oop","timeslider.toolbar.returnbutton":"Terug na pad","timeslider.toolbar.authors":"Outeurs:","timeslider.toolbar.authorsList":"Geen outeurs","timeslider.exportCurrent":"Huidige weergawe eksporteer as:","timeslider.version":"Weergawe {{version}}","timeslider.saved":"Gestoor op {{day}} {{month}} {{year}}","timeslider.dateformat":"{{year}}-{{month}}-{{day}} {{hours}}:{{minutes}}:{{seconds}}","timeslider.month.january":"Januarie","timeslider.month.february":"Februarie","timeslider.month.march":"Maart","timeslider.month.april":"April","timeslider.month.may":"Mei","timeslider.month.june":"Junie","timeslider.month.july":"Julie","timeslider.month.august":"Augustus","timeslider.month.september":"September","timeslider.month.october":"Oktober","timeslider.month.november":"November","timeslider.month.december":"Desember","pad.userlist.entername":"Verskaf u naam","pad.userlist.unnamed":"sonder naam","pad.userlist.guest":"Gas","pad.userlist.deny":"Keur af","pad.userlist.approve":"Keur goed","pad.impexp.importbutton":"Voer nou in","pad.impexp.importing":"Besig met invoer...","pad.impexp.importfailed":"Invoer het gefaal"}
|
|
@ -0,0 +1 @@
|
|||
{"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":"إزاحة","pad.toolbar.unindent.title":"حذف الإزاحة","pad.toolbar.undo.title":"فك (Ctrl-Z)","pad.toolbar.redo.title":"تكرار (Ctrl-Y)","pad.toolbar.import_export.title":"استيراد/تصدير من/إلى تنسيقات ملفات مختلفة","pad.toolbar.timeslider.title":"متصفح التاريخ","pad.toolbar.savedRevision.title":"التنقيحات المحفوظة","pad.toolbar.settings.title":"الإعدادات","pad.colorpicker.save":"تسجيل","pad.colorpicker.cancel":"إلغاء","pad.loading":"جاري التحميل...","pad.settings.stickychat":"الدردشة دائما على الشاشة","pad.settings.linenocheck":"أرقام الأسطر","pad.settings.fontType":"نوع الخط:","pad.settings.fontType.normal":"عادي","pad.settings.fontType.monospaced":"ثابت العرض","pad.settings.language":"اللغة:","pad.importExport.import_export":"استيراد/تصدير","pad.importExport.import":"تحميل أي ملف نصي أو وثيقة","pad.importExport.exporthtml":"إتش تي إم إل","pad.importExport.exportplain":"نص عادي","pad.importExport.exportword":"مايكروسوفت وورد","pad.importExport.exportpdf":"صيغة المستندات المحمولة","pad.importExport.exportopen":"ODF (نسق المستند المفتوح)","pad.importExport.exportdokuwiki":"دوکوويكي","pad.modals.connected":"متصل.","pad.modals.forcereconnect":"فرض إعادة الاتصال","pad.modals.uderdup":"مفتوح في نافذة أخرى","pad.modals.unauth":"غير مخول","pad.modals.looping":"تم قطع الاتصال.","pad.modals.initsocketfail":"لا يمكن الوصول إلى الخادم","pad.modals.initsocketfail.explanation":"تعذر الاتصال بخادم المزامنة.","pad.modals.slowcommit":"تم قطع الاتصال.","pad.modals.slowcommit.explanation":"الخادم لا يستجيب.","pad.modals.slowcommit.cause":"يمكن أن يكون هذا بسبب مشاكل في الاتصال بالشبكة.","pad.modals.deleted":"محذوف.","pad.modals.disconnected":"لم تعد متّصل.","pad.modals.disconnected.explanation":"تم فقدان الإتصال بالخادم","pad.modals.disconnected.cause":"قد يكون الخادم غير متوفر. الرجاء إعلامنا إذا تكرر هذا.","pad.share.readonly":"للقراءة فقط","pad.share.link":"رابط","pad.chat":"دردشة","timeslider.toolbar.authors":"المؤلفون:","timeslider.toolbar.authorsList":"بدون مؤلفين","timeslider.exportCurrent":"تصدير النسخة الحالية ك:","timeslider.version":"إصدار {{version}}","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":"ديسمبر"}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"index.newPad":"یئنی یادداشت دفترچه سی","index.createOpenPad":"یا دا ایجاد /بیر پد آدلا برابر آچماق:","pad.toolbar.bold.title":"بویوت","pad.toolbar.italic.title":"مورب","pad.toolbar.underline.title":"خطدین آلتی","pad.toolbar.strikethrough.title":"خط یئمیش","pad.toolbar.ol.title":"جوتدنمیش فهرست","pad.toolbar.ul.title":"جوتدنممیش فهرست","pad.toolbar.indent.title":"ایچری باتدیگی","pad.toolbar.unindent.title":"ائشیگه چیخدیگی","pad.toolbar.undo.title":"باطل ائتمک","pad.toolbar.redo.title":"یئنی دن","pad.toolbar.clearAuthorship.title":"یازیچی رنگ لری پوزماق","pad.toolbar.import_export.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.settings.padSettings":"یادداشت دفترچه سینین تنظیملر","pad.settings.myView":"منیم گورنتوم","pad.settings.stickychat":"نمایش صفحه سینده همیشه چت اولسون","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.import":"سند یا دا متنی پرونده یوکله","pad.importExport.export":"بو یادداشت دفترچه سی عنوانا ایچری توکمه","pad.importExport.exporthtml":"اچ تی ام ال","pad.importExport.exportplain":"ساده متن","pad.importExport.exportword":"مایکروسافت وورد","pad.importExport.exportpdf":"پی دی اف","pad.importExport.exportopen":"او دی اف","pad.importExport.exportdokuwiki":"دوکو ویکی","pad.modals.connected":"متصل اولدی","pad.modals.reconnecting":"سیزین یادداشت دفترچه سینه یئنی دن متصیل اولدی","pad.modals.forcereconnect":"یئنی اتصال اوچون زورلاما","pad.modals.uderdup":"یئنی پنجرده آچیلدی","pad.modals.userdup.advice":"بو پئنجره دن ایستفاده ائتمک اوچون یئنی دن متصیل اول","pad.modals.unauth":"اولماز","pad.modals.unauth.explanation":"سیزین ال چتما مسئله سی بو صفحه نین گورونوش زمانیندا دییشیلیب دیر .","pad.modals.looping":"اتیصال قطع اولدی","pad.modals.looping.explanation":"ارتیباطی موشکیل بیر ائتمه سرور ده وار دیر","pad.modals.looping.cause":"بلکه سیز دوز دئمیین بیر فایروال یادا پروکسی طریقی ایله متصیل اولوب سینیز","pad.modals.initsocketfail":"دسترسی اولمویان سرور دیر","pad.modals.initsocketfail.explanation":"بیرلشدیریلمه سرور لرینه متصیل اولا بیلمه دی","pad.modals.deleted":"سیلیندی.","pad.modals.deleted.explanation":"بو یادداشت دفترچه سی سیلینیب دیر.","pad.modals.disconnected":"سیزین اتصالینیز قطع اولوب دور.","pad.modals.disconnected.explanation":"سروره اتصال قطع اولوب دور.","pad.share.readonly":"اوخومالی فقط","pad.share.link":"باغلانتی","pad.share.emebdcode":"نشانی نی یئرلتمک","pad.chat":"چت","pad.chat.title":"بو یادداشت دفترچه نی چت اوچون آچ","timeslider.pageTitle":"{{appTitle}}زمان اسلایدری","timeslider.toolbar.returnbutton":"یادداشت دفترچه سینه قاییت","timeslider.toolbar.authors":"یازیچیلار","timeslider.toolbar.authorsList":"یازیچی سیز"}
|
|
@ -1,32 +0,0 @@
|
|||
; Exported from translatewiki.net
|
||||
; Author: Nasir8891
|
||||
[bn]
|
||||
index.newPad = নতুন প্যাড
|
||||
index.createOpenPad = অথবা নাম লিখে প্যাড খুলুন/তৈরী করুন:
|
||||
pad.toolbar.bold.title = গাড় করা (Ctrl-B)
|
||||
pad.toolbar.italic.title = বাঁকা করা (Ctrl-I)
|
||||
pad.toolbar.settings.title = সেটিং
|
||||
pad.colorpicker.save = সংরক্ষণ
|
||||
pad.colorpicker.cancel = বাতিল
|
||||
pad.loading = লোডিং...
|
||||
pad.settings.language = ভাষা:
|
||||
pad.importExport.successful = সফল!
|
||||
; Fuzzy
|
||||
pad.importExport.export = এই প্যাডটি এক্সপোর্ট করুন
|
||||
pad.importExport.exporthtml = এইচটিএমএল
|
||||
pad.importExport.exportplain = সাধারণ লেখা
|
||||
pad.importExport.exportword = মাইক্রোসফট ওয়ার্ড
|
||||
pad.importExport.exportpdf = পিডিএফ
|
||||
pad.importExport.exportopen = ওডিএফ (ওপেন ডকুমেন্ট ফরম্যাট)
|
||||
pad.modals.deleted = অপসারিত।
|
||||
pad.modals.deleted.explanation = এই প্যাডটি অপসারণ করা হয়েছে।
|
||||
pad.modals.disconnected.explanation = সার্ভারের সাথে যোগাযোগ করা যাচ্ছে না
|
||||
pad.share = শেয়ার করুন
|
||||
pad.share.link = লিংক
|
||||
pad.share.emebdcode = ইউআরএল সংযোজন
|
||||
pad.chat = চ্যাট
|
||||
pad.chat.title = এই প্যাডের জন্য চ্যাট চালু করুন।
|
||||
timeslider.toolbar.returnbutton = প্যাডে ফিরে যাও
|
||||
timeslider.toolbar.authors = লেখকগণ:
|
||||
timeslider.toolbar.authorsList = কোনো লেখক নেই
|
||||
timeslider.exportCurrent = বর্তমান সংস্করণটি এক্সপোর্ট করুন:
|
|
@ -0,0 +1 @@
|
|||
{"index.newPad":"নতুন প্যাড","index.createOpenPad":"অথবা নাম লিখে প্যাড খুলুন/তৈরী করুন:","pad.toolbar.bold.title":"গাড় করা (Ctrl-B)","pad.toolbar.italic.title":"বাঁকা করা (Ctrl-I)","pad.toolbar.indent.title":"প্রান্তিককরণ","pad.toolbar.settings.title":"সেটিং","pad.colorpicker.save":"সংরক্ষণ","pad.colorpicker.cancel":"বাতিল","pad.loading":"লোডিং...","pad.settings.fontType.normal":"সাধারণ","pad.settings.language":"ভাষা:","pad.importExport.export":"এই প্যাডটি এক্সপোর্ট করুন","pad.importExport.exporthtml":"এইচটিএমএল","pad.importExport.exportplain":"সাধারণ লেখা","pad.importExport.exportword":"মাইক্রোসফট ওয়ার্ড","pad.importExport.exportpdf":"পিডিএফ","pad.importExport.exportopen":"ওডিএফ (ওপেন ডকুমেন্ট ফরম্যাট)","pad.modals.deleted":"অপসারিত।","pad.modals.deleted.explanation":"এই প্যাডটি অপসারণ করা হয়েছে।","pad.modals.disconnected.explanation":"সার্ভারের সাথে যোগাযোগ করা যাচ্ছে না","pad.share":"শেয়ার করুন","pad.share.link":"লিংক","pad.share.emebdcode":"ইউআরএল সংযোজন","pad.chat":"চ্যাট","pad.chat.title":"এই প্যাডের জন্য চ্যাট চালু করুন।","timeslider.toolbar.returnbutton":"প্যাডে ফিরে যাও","timeslider.toolbar.authors":"লেখকগণ:","timeslider.toolbar.authorsList":"কোনো লেখক নেই","timeslider.exportCurrent":"বর্তমান সংস্করণটি এক্সপোর্ট করুন:","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":"ডিসেম্বর"}
|
|
@ -0,0 +1 @@
|
|||
{"pad.toolbar.bold.title":"Negreta (Ctrl-B)","pad.toolbar.italic.title":"Cursiva (Ctrl-I)","pad.toolbar.ol.title":"Llista ordenada","pad.toolbar.ul.title":"Llista sense ordenar","pad.toolbar.undo.title":"Desfés (Ctrl-Z)","pad.toolbar.redo.title":"Refés (Ctrl-Y)","pad.toolbar.settings.title":"Configuració","pad.colorpicker.save":"Desa","pad.colorpicker.cancel":"Cancel·la","pad.loading":"S'està carregant...","pad.settings.fontType":"Tipus de lletra:","pad.settings.fontType.normal":"Normal","pad.settings.language":"Llengua:","pad.importExport.import_export":"Importació/exportació","pad.importExport.exporthtml":"HTML","pad.importExport.exportplain":"Text net","pad.modals.looping":"Desconnectat.","pad.modals.slowcommit.explanation":"El servidor no respon.","pad.share.readonly":"Només de lectura","pad.share.link":"Enllaç","pad.chat":"Xat","timeslider.toolbar.authors":"Autors:","timeslider.toolbar.authorsList":"No hi ha autors","timeslider.month.january":"Gener","timeslider.month.february":"Febrer","timeslider.month.march":"Març","timeslider.month.april":"Abril","timeslider.month.may":"Maig","timeslider.month.june":"Juny","timeslider.month.july":"Juliol","timeslider.month.august":"Agost","timeslider.month.september":"Setembre","timeslider.month.october":"Octubre","timeslider.month.november":"Novembre","timeslider.month.december":"Desembre","pad.userlist.deny":"Refusa","pad.userlist.approve":"Aprova","pad.impexp.importbutton":"Importa ara","pad.impexp.importing":"Important...","pad.impexp.convertFailed":"No és possible d'importar aquest fitxer. Si us plau, podeu provar d'utilitzar un format diferent o copiar i enganxar manualment.","pad.impexp.importfailed":"Ha fallat la importació","pad.impexp.copypaste":"Si us plau, copieu i enganxeu"}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,78 +0,0 @@
|
|||
; Exported from translatewiki.net
|
||||
[de]
|
||||
index.newPad = Neues Pad
|
||||
index.createOpenPad = Pad mit folgendem Namen öffnen
|
||||
pad.toolbar.bold.title = Fett (Strg-B)
|
||||
pad.toolbar.italic.title = Kursiv (Strg-I)
|
||||
pad.toolbar.underline.title = Unterstrichen (Strg-U)
|
||||
pad.toolbar.strikethrough.title = Durchgestrichen
|
||||
pad.toolbar.ol.title = Nummerierte Liste
|
||||
pad.toolbar.ul.title = Ungeordnete Liste
|
||||
pad.toolbar.indent.title = Einrücken
|
||||
pad.toolbar.unindent.title = Ausrücken
|
||||
pad.toolbar.undo.title = Rückgängig (Strg-Z)
|
||||
pad.toolbar.redo.title = Wiederholen (Strg-Y)
|
||||
pad.toolbar.clearAuthorship.title = Autorenfarben zurücksetzen
|
||||
pad.toolbar.import_export.title = Import/Export von verschiedenen Dateiformaten
|
||||
pad.toolbar.timeslider.title = Pad-Geschichte anzeigen
|
||||
pad.toolbar.savedRevision.title = Diese Revision markieren
|
||||
pad.toolbar.settings.title = Einstellungen
|
||||
pad.toolbar.embed.title = Dieses Pad teilen oder einbetten
|
||||
pad.toolbar.showusers.title = Verbundene Benutzer anzeigen
|
||||
pad.colorpicker.save = Speichern
|
||||
pad.colorpicker.cancel = Abbrechen
|
||||
pad.loading = Laden...
|
||||
pad.settings.padSettings = Pad Einstellungen
|
||||
pad.settings.myView = Eigene Ansicht
|
||||
pad.settings.stickychat = Chat immer anzeigen
|
||||
pad.settings.colorcheck = Autorenfarben anzeigen
|
||||
pad.settings.linenocheck = Zeilennummern
|
||||
pad.settings.fontType = Schriftart:
|
||||
pad.settings.fontType.normal = Normal
|
||||
pad.settings.fontType.monospaced = Monospace
|
||||
pad.settings.globalView = Gemeinsame Ansicht
|
||||
pad.settings.language = Sprache:
|
||||
pad.importExport.import_export = Import/Export
|
||||
pad.importExport.import = Datei oder Dokument hochladen
|
||||
pad.importExport.successful = Erfolgreich!
|
||||
; Fuzzy
|
||||
pad.importExport.export = Dieses Pad exportieren
|
||||
pad.importExport.exporthtml = HTML
|
||||
pad.importExport.exportplain = Reiner Text
|
||||
pad.importExport.exportword = Microsoft Word
|
||||
pad.importExport.exportpdf = PDf
|
||||
pad.importExport.exportopen = ODF (Open Document Format)
|
||||
pad.importExport.exportdokuwiki = DokuWiki
|
||||
pad.modals.connected = Verbunden.
|
||||
pad.modals.reconnecting = Wiederherstellen der Verbindung...
|
||||
pad.modals.forcereconnect = Erneut Verbinden
|
||||
pad.modals.uderdup = In einem anderen Fenster geöffnet
|
||||
pad.modals.userdup.explanation = Dieses Pad scheint in mehr als einem Browser-Fenster auf diesem Computer geöffnet zu sein.
|
||||
pad.modals.userdup.advice = Um dieses Fenster zu benutzen, verbinden Sie bitte erneut.
|
||||
pad.modals.unauth = Nicht Authorisiert.
|
||||
pad.modals.unauth.explanation = Ihre Befugnisse auf dieses Pad zuzugreifen haben sich geädert. Versuchen Sie, erneut zu verbinden.
|
||||
pad.modals.looping = Verbindung unterbrochen.
|
||||
pad.modals.looping.explanation = Es gibt Probleme bei der Kommunikation mit dem Synchronisationsserver.
|
||||
pad.modals.looping.cause = Möglicherweise verläuft Ihre Verbindung durch eine inkompatible Firewall oder einen inkompatiblen Proxy.
|
||||
pad.modals.initsocketfail = Server nicht erreichbar.
|
||||
pad.modals.initsocketfail.explanation = Es konnte keine Verbindung zum Synchronisationsserver hergestellt werden.
|
||||
pad.modals.initsocketfail.cause = Dies könnte an Ihrem Browser oder Ihrer Internet-Verbindung liegen.
|
||||
pad.modals.slowcommit = Verbindung unterbrochen.
|
||||
pad.modals.slowcommit.explanation = Der Server reagiert nicht.
|
||||
pad.modals.slowcommit.cause = Dies könnte an Problemen mit Netzwerk-Konnektivität liegen. Möglicherweise ist der Server aber auch überlastet.
|
||||
pad.modals.deleted = Entfernt.
|
||||
pad.modals.deleted.explanation = Dieses Pad wurde entfernt.
|
||||
pad.modals.disconnected = Verbindung unterbrochen.
|
||||
pad.modals.disconnected.explanation = Die Verbindung zum Synchronisationsserver wurde unterbrochen.
|
||||
pad.modals.disconnected.cause = Möglicherweise ist der Server nicht erreichbar. Bitte benachrichtigen Sie uns, falls dies weiterhin passiert.
|
||||
pad.share = Dieses Pad teilen
|
||||
pad.share.readonly = Eingeschränkter zugriff (Nur lesen)
|
||||
pad.share.link = Link
|
||||
pad.share.emebdcode = In Webseite einbetten
|
||||
pad.chat = Chat
|
||||
pad.chat.title = Den Chat für dieses Pad öffnen
|
||||
timeslider.pageTitle = {{appTitle}} Pad-Geschichte
|
||||
timeslider.toolbar.returnbutton = Zurück zum Pad
|
||||
timeslider.toolbar.authors = Autoren:
|
||||
timeslider.toolbar.authorsList = keine Autoren
|
||||
timeslider.exportCurrent = Exportiere diese Version als:
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"index.newPad":"Pedo newe","pad.toolbar.bold.title":"Qalın (Ctrl-B)","pad.toolbar.italic.title":"Namıte (Ctrl-I)","pad.toolbar.underline.title":"Bın xizkerden (Ctrl-U)","pad.toolbar.strikethrough.title":"Serê cı xizın","pad.toolbar.ol.title":"Lista ratnayi","pad.toolbar.indent.title":"Serinya satır","pad.toolbar.unindent.title":"Vıcente","pad.toolbar.undo.title":"Peyser bê (Ctrl-Z)","pad.toolbar.redo.title":"Ver şo (Ctrl-Y)","pad.toolbar.clearAuthorship.title":"Pak Rengê Nuştoğey","pad.toolbar.timeslider.title":"Ğızagê zemani","pad.toolbar.savedRevision.title":"Rewizyonê Qeydbiyayey","pad.toolbar.settings.title":"Sazkerdışi","pad.toolbar.embed.title":"Na ped degusnayiya","pad.colorpicker.save":"Qeyd ke","pad.colorpicker.cancel":"Bıterkne","pad.loading":"Bar beno...","pad.settings.padSettings":"Sazkerdışê Pedi","pad.settings.myView":"Asayışê mı","pad.settings.colorcheck":"Rengê nuştekariye","pad.settings.linenocheck":"Nımreyê xeter","pad.settings.fontType":"Babeta nuşti:","pad.settings.fontType.normal":"Normal","pad.settings.fontType.monospaced":"Yewca","pad.settings.globalView":"Asayışo Global","pad.settings.language":"Zıwan:","pad.importExport.import_export":"Zeredayış/Teberdayış","pad.importExport.exporthtml":"HTML","pad.importExport.exportplain":"Duz metin","pad.importExport.exportword":"Microsoft Word","pad.importExport.exportpdf":"PDF","pad.importExport.exportopen":"ODF (Open Document Format)","pad.importExport.exportdokuwiki":"DokuWiki","pad.modals.connected":"Gredeya","pad.modals.unauth":"Selahiyetdar niyo","pad.modals.looping":"Bêgıreyın.","pad.modals.initsocketfail":"Nêresneyêno ciyageyroği.","pad.modals.slowcommit":"Bêgıreyın.","pad.modals.deleted":"Esteriya.","pad.modals.deleted.explanation":"Ena ped wedariye","pad.share":"Na ped vıla ke","pad.share.readonly":"Tenya bıwane","pad.share.link":"Gıre","pad.share.emebdcode":"Degusnaye URL","pad.chat":"Mıhebet","pad.chat.title":"Qandê ena ped mıhebet ake.","timeslider.pageTitle":"Ğızagê zemani {{appTitle}}","timeslider.toolbar.returnbutton":"Peyser şo ped","timeslider.toolbar.authors":"Nuştoği:","timeslider.toolbar.authorsList":"Nuştoği çıniyê","timeslider.exportCurrent":"Versiyonê enewki teber de:","timeslider.version":"Versiyonê {{version}}","timeslider.saved":"{{day}} {{month}}, {{year}} de biyo qeyd","timeslider.dateformat":"{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}","timeslider.month.january":"Çele","timeslider.month.february":"Şıbate","timeslider.month.march":"Adar","timeslider.month.april":"Nisane","timeslider.month.may":"Gulane","timeslider.month.june":"Heziran","timeslider.month.july":"Temuze","timeslider.month.august":"Tebaxe","timeslider.month.september":"Keşkelun","timeslider.month.october":"Tışrino Verên","timeslider.month.november":"Tışrino Peyên","timeslider.month.december":"Kanun"}
|
File diff suppressed because one or more lines are too long
|
@ -1,77 +0,0 @@
|
|||
[*]
|
||||
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
|
||||
pad.toolbar.ol.title = Ordered list
|
||||
pad.toolbar.ul.title = Unordered List
|
||||
pad.toolbar.indent.title = Indent
|
||||
pad.toolbar.unindent.title = Outdent
|
||||
pad.toolbar.undo.title = Undo (Ctrl-Z)
|
||||
pad.toolbar.redo.title = Redo (Ctrl-Y)
|
||||
pad.toolbar.clearAuthorship.title = Clear Authorship Colors
|
||||
pad.toolbar.import_export.title = Import/Export from/to different file formats
|
||||
pad.toolbar.timeslider.title = Timeslider
|
||||
pad.toolbar.savedRevision.title = Saved Revisions
|
||||
pad.toolbar.settings.title = Settings
|
||||
pad.toolbar.embed.title = 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.settings.padSettings = Pad Settings
|
||||
pad.settings.myView = My View
|
||||
pad.settings.stickychat = Chat always on screen
|
||||
pad.settings.colorcheck = Authorship colors
|
||||
pad.settings.linenocheck = Line numbers
|
||||
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.successful = Successful!
|
||||
pad.importExport.export = Export current pad as:
|
||||
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.exportdokuwiki = DokuWiki
|
||||
pad.modals.connected = Connected.
|
||||
pad.modals.reconnecting = Reconnecting to your pad..
|
||||
pad.modals.forcereconnect = Force reconnect
|
||||
pad.modals.uderdup = 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 authorized
|
||||
pad.modals.unauth.explanation = Your permissions have changed while viewing this page. Try to reconnect.
|
||||
pad.modals.looping = Disconnected.
|
||||
pad.modals.looping.explanation = There are communication problems with the synchronization 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 synchronization server.
|
||||
pad.modals.initsocketfail.cause = This is probably due to a problem with your browser or your internet connection.
|
||||
pad.modals.slowcommit = Disconnected.
|
||||
pad.modals.slowcommit.explanation = The server is not responding.
|
||||
pad.modals.slowcommit.cause = This could be due to problems with network connectivity.
|
||||
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 us 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.
|
||||
|
||||
timeslider.pageTitle = {{appTitle}} Timeslider
|
||||
timeslider.toolbar.returnbutton = Return to pad
|
||||
timeslider.toolbar.authors = Authors:
|
||||
timeslider.toolbar.authorsList = No Authors
|
||||
timeslider.exportCurrent = Export current version as:
|
File diff suppressed because one or more lines are too long
|
@ -1,78 +0,0 @@
|
|||
; Exported from translatewiki.net
|
||||
[es]
|
||||
index.newPad = Nuevo Pad
|
||||
index.createOpenPad = o puedes crear/abrir un Pad con el nombre:
|
||||
pad.toolbar.bold.title = Negrita (Ctrl-B)
|
||||
pad.toolbar.italic.title = Cursiva (Ctrl-I)
|
||||
pad.toolbar.underline.title = Subrayado (Ctrl-U)
|
||||
pad.toolbar.strikethrough.title = Tachado
|
||||
pad.toolbar.ol.title = Lista ordenada
|
||||
pad.toolbar.ul.title = Lista desordenada
|
||||
pad.toolbar.indent.title = Sangrar
|
||||
pad.toolbar.unindent.title = Desangrar
|
||||
pad.toolbar.undo.title = Deshacer (Ctrl-Z)
|
||||
pad.toolbar.redo.title = Rehacer (Ctrl-Y)
|
||||
pad.toolbar.clearAuthorship.title = Eliminar los colores de los autores
|
||||
pad.toolbar.import_export.title = Importar/Exportar a diferentes formatos de archivos
|
||||
pad.toolbar.timeslider.title = Línea de tiempo
|
||||
pad.toolbar.savedRevision.title = Revisiones guardadas
|
||||
pad.toolbar.settings.title = Configuración
|
||||
pad.toolbar.embed.title = Incrustar este pad
|
||||
pad.toolbar.showusers.title = Mostrar los usuarios de este pad
|
||||
pad.colorpicker.save = Guardar
|
||||
pad.colorpicker.cancel = Cancelar
|
||||
pad.loading = Cargando...
|
||||
pad.settings.padSettings = Configuración del Pad
|
||||
pad.settings.myView = Mi vista
|
||||
pad.settings.stickychat = Chat siempre encima
|
||||
pad.settings.colorcheck = Color de autoría
|
||||
pad.settings.linenocheck = Números de línea
|
||||
pad.settings.fontType = Tipografía:
|
||||
pad.settings.fontType.normal = Normal
|
||||
pad.settings.fontType.monospaced = Monoespacio
|
||||
pad.settings.globalView = Vista global
|
||||
pad.settings.language = Idioma:
|
||||
pad.importExport.import_export = Importar/Exportar
|
||||
pad.importExport.import = Subir cualquier texto o documento
|
||||
pad.importExport.successful = ¡Operación exitosa!
|
||||
; Fuzzy
|
||||
pad.importExport.export = Exporta el pad actual como
|
||||
pad.importExport.exporthtml = HTML
|
||||
pad.importExport.exportplain = Texto plano
|
||||
pad.importExport.exportword = Microsoft Word
|
||||
pad.importExport.exportpdf = PDF
|
||||
pad.importExport.exportopen = ODF (Open Document Format)
|
||||
pad.importExport.exportdokuwiki = DokuWiki
|
||||
pad.modals.connected = Conectado.
|
||||
pad.modals.reconnecting = Reconectando a tu pad..
|
||||
pad.modals.forcereconnect = Reconexión forzosa
|
||||
pad.modals.uderdup = Abrir en otra ventana
|
||||
pad.modals.userdup.explanation = Este pad parece estar abierto en más de una ventana de tu navegador.
|
||||
pad.modals.userdup.advice = Reconectar para usar esta ventana.
|
||||
pad.modals.unauth = No autorizado.
|
||||
pad.modals.unauth.explanation = Los permisos han cambiado mientras estabas viendo esta página. Intenta reconectar de nuevo.
|
||||
pad.modals.looping = Desconectado.
|
||||
pad.modals.looping.explanation = Estamos teniendo problemas con la sincronización en el servidor.
|
||||
pad.modals.looping.cause = Quizás su conexión fluya a través de un proxy o un cortafuegos incompatible.
|
||||
pad.modals.initsocketfail = Servidor incalcanzable.
|
||||
pad.modals.initsocketfail.explanation = No se pudo conectar al sevidor de sincronización.
|
||||
pad.modals.initsocketfail.cause = Puede ser a causa de tu navegador o de una caída en tu conexión de Internet.
|
||||
pad.modals.slowcommit = Desconectado.
|
||||
pad.modals.slowcommit.explanation = El servidor no responde.
|
||||
pad.modals.slowcommit.cause = Puede deberse a problemas con tu conexión de red.
|
||||
pad.modals.deleted = Borrado.
|
||||
pad.modals.deleted.explanation = Este pad ha sido borrado.
|
||||
pad.modals.disconnected = Has sido desconectado.
|
||||
pad.modals.disconnected.explanation = Se perdió la conexión con el servidor
|
||||
pad.modals.disconnected.cause = El servidor podría no estar disponible. Contacte con nosotros si esto continúa sucediendo.
|
||||
pad.share = Compatir el pad
|
||||
pad.share.readonly = Sólo lectura
|
||||
pad.share.link = Enlace
|
||||
pad.share.emebdcode = Incrustar URL
|
||||
pad.chat = Chat
|
||||
pad.chat.title = Abrir el chat para este pad.
|
||||
timeslider.pageTitle = {{appTitle}} Línea de tiempo
|
||||
timeslider.toolbar.returnbutton = Volver al pad
|
||||
timeslider.toolbar.authors = Autores:
|
||||
timeslider.toolbar.authorsList = Sin autores
|
||||
timeslider.exportCurrent = Exportar la versión actual como:
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,49 +0,0 @@
|
|||
; Exported from translatewiki.net
|
||||
; Author: Nike
|
||||
[fi]
|
||||
index.newPad = Uusi muistio
|
||||
index.createOpenPad = tai avaa muistio nimellä:
|
||||
pad.toolbar.bold.title = Lihavointi (Ctrl-B)
|
||||
pad.toolbar.italic.title = Kursivointi (Ctrl-I)
|
||||
pad.toolbar.underline.title = Alleviivaus (Ctrl-U)
|
||||
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.undo.title = Kumoa (Ctrl-Z)
|
||||
pad.toolbar.redo.title = Tee uudelleen (Ctrl-Y)
|
||||
pad.toolbar.clearAuthorship.title = Poista kirjoittavärit
|
||||
pad.toolbar.import_export.title = Tuo tai vie eri muotoihin
|
||||
pad.toolbar.savedRevision.title = Tallennetut versiot
|
||||
pad.toolbar.settings.title = Asetukset
|
||||
pad.toolbar.embed.title = Upota muistio
|
||||
pad.toolbar.showusers.title = Näytä muistion käyttäjät
|
||||
pad.colorpicker.save = Tallenna
|
||||
pad.colorpicker.cancel = Peru
|
||||
pad.loading = Ladataan…
|
||||
pad.settings.padSettings = Muistion asetukset
|
||||
pad.settings.myView = Oma näkymä
|
||||
pad.settings.stickychat = Keskustelu aina näkyvissä
|
||||
pad.settings.colorcheck = Kirjoittavärit
|
||||
pad.settings.linenocheck = Rivinumerot
|
||||
pad.settings.fontType = Kirjasintyyppi:
|
||||
pad.settings.fontType.normal = normaali
|
||||
pad.settings.fontType.monospaced = tasalevyinen
|
||||
pad.settings.language = Kieli:
|
||||
pad.importExport.import_export = Tuonti/vienti
|
||||
pad.importExport.exporthtml = HTML
|
||||
pad.importExport.exportplain = Muotoilematon teksti
|
||||
pad.importExport.exportword = Microsoft Word
|
||||
pad.importExport.exportpdf = PDF
|
||||
pad.importExport.exportopen = ODF (Open Document Format)
|
||||
pad.importExport.exportdokuwiki = DokuWiki
|
||||
pad.modals.connected = Yhdistetty.
|
||||
pad.modals.reconnecting = Herätellään yhteyttä muistioon...
|
||||
pad.modals.forcereconnect = Pakota uudelleenyhdistäminen
|
||||
pad.share = Jaa muistio
|
||||
pad.share.readonly = Vain luku
|
||||
pad.share.link = Linkki
|
||||
pad.share.emebdcode = Upotusosoite
|
||||
pad.chat = Keskustelu
|
||||
timeslider.toolbar.returnbutton = Palaa muistioon
|
|
@ -0,0 +1 @@
|
|||
{"index.newPad":"Uusi muistio","index.createOpenPad":"tai luo tai avaa muistio nimellä:","pad.toolbar.bold.title":"Lihavointi (Ctrl-B)","pad.toolbar.italic.title":"Kursivointi (Ctrl-I)","pad.toolbar.underline.title":"Alleviivaus (Ctrl-U)","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.undo.title":"Kumoa (Ctrl-Z)","pad.toolbar.redo.title":"Tee uudelleen (Ctrl-Y)","pad.toolbar.clearAuthorship.title":"Poista kirjoittajavärit","pad.toolbar.import_export.title":"Tuo tai vie eri tiedostomuodoista tai -muotoihin","pad.toolbar.timeslider.title":"Aikajana","pad.toolbar.savedRevision.title":"Tallennetut versiot","pad.toolbar.settings.title":"Asetukset","pad.toolbar.embed.title":"Upota muistio","pad.toolbar.showusers.title":"Näytä muistion käyttäjät","pad.colorpicker.save":"Tallenna","pad.colorpicker.cancel":"Peruuta","pad.loading":"Ladataan…","pad.passwordRequired":"Tämä muistio on suojattu salasanalla.","pad.permissionDenied":"Käyttöoikeutesi eivät riitä tämän muistion käyttämiseen.","pad.wrongPassword":"Väärä salasana","pad.settings.padSettings":"Muistion asetukset","pad.settings.myView":"Oma näkymä","pad.settings.stickychat":"Keskustelu aina näkyvissä","pad.settings.colorcheck":"Kirjoittajavärit","pad.settings.linenocheck":"Rivinumerot","pad.settings.fontType":"Kirjasintyyppi:","pad.settings.fontType.normal":"normaali","pad.settings.fontType.monospaced":"tasalevyinen","pad.settings.globalView":"Yleisnäkymä","pad.settings.language":"Kieli:","pad.importExport.import_export":"Tuonti/vienti","pad.importExport.import":"Lähetä mikä tahansa tekstitiedosto tai asiakirja","pad.importExport.export":"Vie muistio muodossa:","pad.importExport.exporthtml":"HTML","pad.importExport.exportplain":"Muotoilematon teksti","pad.importExport.exportword":"Microsoft Word","pad.importExport.exportpdf":"PDF","pad.importExport.exportopen":"ODF (Open Document Format)","pad.importExport.exportdokuwiki":"DokuWiki","pad.modals.connected":"Yhdistetty.","pad.modals.reconnecting":"Muodostetaan yhteyttä muistioon uudelleen...","pad.modals.forcereconnect":"Pakota yhdistämään uudelleen","pad.modals.uderdup":"Avattu toisessa ikkunassa","pad.modals.userdup.explanation":"Tämä muistio vaikuttaa olevan avoinna useammassa eri selainikkunassa tällä koneella.","pad.modals.userdup.advice":"Yhdistä uudelleen, jos haluat käyttää tätä ikkunaa.","pad.modals.unauth":"Oikeudet eivät riitä","pad.modals.unauth.explanation":"Käyttöoikeutesi ovat muuttuneet katsellessasi tätä sivua. Yritä yhdistää uudelleen.","pad.modals.looping":"Yhteys katkaistu.","pad.modals.looping.explanation":"Synkronointipalvelimen kanssa on yhteysongelmia.","pad.modals.looping.cause":"Yhteytesi on mahdollisesti muodostettu yhteensopimattoman palomuurin tai välityspalvelimen kautta.","pad.modals.initsocketfail":"Palvelimeen ei saada yhteyttä.","pad.modals.initsocketfail.explanation":"Synkronointipalvelimeen ei saatu yhteyttä.","pad.modals.initsocketfail.cause":"Tämä johtuu mitä luultavimmin selaimestasi tai verkkoyhteydestäsi.","pad.modals.slowcommit":"Yhteys katkaistu.","pad.modals.slowcommit.explanation":"Palvelin ei vastaa.","pad.modals.slowcommit.cause":"Tämä saattaa johtua verkkoyhteyden ongelmista.","pad.modals.deleted":"Poistettu.","pad.modals.deleted.explanation":"Tämä muistio on poistettu.","pad.modals.disconnected":"Yhteytesi on katkaistu.","pad.modals.disconnected.explanation":"Yhteys palvelimeen katkesi","pad.modals.disconnected.cause":"Palvelin saattaa olla käyttämättömissä. Ilmoitathan meille, jos tämä ongelma toistuu.","pad.share":"Jaa muistio","pad.share.readonly":"Vain luku","pad.share.link":"Linkki","pad.share.emebdcode":"Upotusosoite","pad.chat":"Keskustelu","pad.chat.title":"Avaa keskustelu nykyisestä muistiosta.","timeslider.pageTitle":"{{appTitle}} -aikajana","timeslider.toolbar.returnbutton":"Palaa muistioon","timeslider.toolbar.authors":"Tekijät:","timeslider.toolbar.authorsList":"Ei tekijöitä","timeslider.exportCurrent":"Vie nykyinen versio muodossa:","timeslider.version":"Versio {{version}}","timeslider.saved":"Tallennettu {{day}}. {{month}}ta {{year}}","timeslider.dateformat":"{{day}}.{{month}}.{{year}} {{hours}}:{{minutes}}:{{seconds}}","timeslider.month.january":"tammikuu","timeslider.month.february":"helmikuu","timeslider.month.march":"maaliskuu","timeslider.month.april":"huhtikuu","timeslider.month.may":"toukokuu","timeslider.month.june":"kesäkuu","timeslider.month.july":"heinäkuu","timeslider.month.august":"elokuu","timeslider.month.september":"syyskuu","timeslider.month.october":"lokakuu","timeslider.month.november":"marraskuu","timeslider.month.december":"joulukuu"}
|
|
@ -1,78 +0,0 @@
|
|||
; Exported from translatewiki.net
|
||||
[fr]
|
||||
index.newPad = Nouveau Pad
|
||||
index.createOpenPad = ou créer/ouvrir un Pad intitulé
|
||||
pad.toolbar.bold.title = Gras (Ctrl-B)
|
||||
pad.toolbar.italic.title = Italique (Ctrl-I)
|
||||
pad.toolbar.underline.title = Souligner (Ctrl-U)
|
||||
pad.toolbar.strikethrough.title = Barrer
|
||||
pad.toolbar.ol.title = Liste ordonnée
|
||||
pad.toolbar.ul.title = Liste non-ordonnée
|
||||
pad.toolbar.indent.title = Indenter
|
||||
pad.toolbar.unindent.title = Désindenter
|
||||
pad.toolbar.undo.title = Annuler (Ctrl-Z)
|
||||
pad.toolbar.redo.title = Rétablir (Ctrl-Y)
|
||||
pad.toolbar.clearAuthorship.title = Effacer les couleurs identifiant les auteurs
|
||||
pad.toolbar.import_export.title = Importer/Exporter de/vers un format de fichier différent
|
||||
pad.toolbar.timeslider.title = Navigateur d'historique
|
||||
pad.toolbar.savedRevision.title = Versions enregistrées
|
||||
pad.toolbar.settings.title = Paramètres
|
||||
pad.toolbar.embed.title = Intégrer ce Pad
|
||||
pad.toolbar.showusers.title = Afficher les utilisateurs du Pad
|
||||
pad.colorpicker.save = Sauver
|
||||
pad.colorpicker.cancel = Annuler
|
||||
pad.loading = Chargement...
|
||||
pad.settings.padSettings = Paramètres du Pad
|
||||
pad.settings.myView = Ma vue
|
||||
pad.settings.stickychat = Messagerie toujours affichée
|
||||
pad.settings.colorcheck = Couleurs d'identification
|
||||
pad.settings.linenocheck = Numéros des lignes
|
||||
pad.settings.fontType = Type de police:
|
||||
pad.settings.fontType.normal = Normal
|
||||
pad.settings.fontType.monospaced = Monospace
|
||||
pad.settings.globalView = Vue d'ensemble
|
||||
pad.settings.language = Langue:
|
||||
pad.importExport.import_export = Importer/Exporter
|
||||
pad.importExport.import = Charger un texte ou un document
|
||||
pad.importExport.successful = Traitement effectué!
|
||||
; Fuzzy
|
||||
pad.importExport.export = Exporter ce Pad vers
|
||||
pad.importExport.exporthtml = HTML
|
||||
pad.importExport.exportplain = Texte brut
|
||||
pad.importExport.exportword = Microsoft Word
|
||||
pad.importExport.exportpdf = PDf
|
||||
pad.importExport.exportopen = ODF (Open Document Format)
|
||||
pad.importExport.exportdokuwiki = DokuWiki
|
||||
pad.modals.connected = Connecté.
|
||||
pad.modals.reconnecting = Reconnexion vers votre Pad...
|
||||
pad.modals.forcereconnect = Forcer la reconnexion.
|
||||
pad.modals.uderdup = Ouvrir dans une nouvelle fenêtre
|
||||
pad.modals.userdup.explanation = Ce Pad semble avoir été ouvert dans plusieurs fenêtres de votre fureteur sur cet ordinateur.
|
||||
pad.modals.userdup.advice = Se reconnecter en utilisant cette fenêtre.
|
||||
pad.modals.unauth = Not authorized Non authorisé
|
||||
pad.modals.unauth.explanation = Vos permissions ont été changées lors de la visualisation de cette page. Essayer de vous reconnecter.
|
||||
pad.modals.looping = Disconnected. Déconnecté.
|
||||
pad.modals.looping.explanation = Nous éprouvons un problème de communication au serveur de synchronisation.
|
||||
pad.modals.looping.cause = Il est possible que leur connection soit protégée par un pare-feu incompatible ou un serveur proxy incompatible.
|
||||
pad.modals.initsocketfail = Le serveur est introuvable.
|
||||
pad.modals.initsocketfail.explanation = Impossible de se connecter au serveur de synchronisation.
|
||||
pad.modals.initsocketfail.cause = La cause de ce problème peut être liée à votre fureteur web.
|
||||
pad.modals.slowcommit = Disconnected. Déconnecté
|
||||
pad.modals.slowcommit.explanation = Le serveur ne répond pas.
|
||||
pad.modals.slowcommit.cause = La cause de ce problème peut être liée à une erreur de connectivité du réseau.
|
||||
pad.modals.deleted = Supprimé.
|
||||
pad.modals.deleted.explanation = Ce Pad a été supprimé.
|
||||
pad.modals.disconnected = Vous avez été déconnecté.
|
||||
pad.modals.disconnected.explanation = La connexion au serveur a échoué.
|
||||
pad.modals.disconnected.cause = Ce serveur est possiblement hors-ligne. Veuillez nous joindre si le problème persiste.
|
||||
pad.share = Partager ce Pad
|
||||
pad.share.readonly = Lecture seule
|
||||
pad.share.link = Lien
|
||||
pad.share.emebdcode = Lien à intégrer
|
||||
pad.chat = Messagerie
|
||||
pad.chat.title = Ouvrir la messagerie liée au Pad.
|
||||
timeslider.pageTitle = {{appTitle}} Curseur temporel
|
||||
timeslider.toolbar.returnbutton = Retour à ce Pad.
|
||||
timeslider.toolbar.authors = Auteurs:
|
||||
timeslider.toolbar.authorsList = Aucun auteurs
|
||||
timeslider.exportCurrent = Exporter version actuelle vers:
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"index.newPad":"Új notesz","index.createOpenPad":"vagy notesz létrehozása ezen a néven:","pad.toolbar.bold.title":"Félkövér (Ctrl-B)","pad.toolbar.italic.title":"Dőlt (Ctrl-I)","pad.toolbar.underline.title":"Aláhúzás (Ctrl-U)","pad.toolbar.strikethrough.title":"Áthúzás","pad.toolbar.ol.title":"Számozott lista","pad.toolbar.ul.title":"Számozatlan lista","pad.toolbar.indent.title":"Behúzás növelése","pad.toolbar.unindent.title":"Behúzás csökkentése","pad.toolbar.undo.title":"Vissza (Ctrl-Z)","pad.toolbar.redo.title":"Újra (Ctrl-Y)","pad.toolbar.clearAuthorship.title":"Szerzők színezésének kikapcsolása","pad.toolbar.import_export.title":"Importálás/exportálás különböző fájlformátumokból/ba","pad.toolbar.timeslider.title":"Időcsúszka","pad.toolbar.savedRevision.title":"Mentett állapotok","pad.toolbar.settings.title":"Beállítások","pad.toolbar.embed.title":"Notesz beágyazása","pad.toolbar.showusers.title":"Notesz felhasználóinak megmutatása","pad.colorpicker.save":"Mentés","pad.colorpicker.cancel":"Mégsem","pad.loading":"Betöltés…","pad.settings.padSettings":"Notesz beállításai","pad.settings.myView":"Az én nézetem","pad.settings.stickychat":"Mindig mutasd a csevegés-dobozt","pad.settings.colorcheck":"Szerzők színei","pad.settings.linenocheck":"Sorok számozása","pad.settings.fontType":"Betűtípus:","pad.settings.fontType.normal":"Szokásos","pad.settings.fontType.monospaced":"Írógépes","pad.settings.globalView":"Globális nézet","pad.settings.language":"Nyelv:","pad.importExport.import_export":"Import/export","pad.importExport.import":"Tetszőleges szövegfájl vagy dokumentum feltöltése","pad.importExport.export":"Jelenlegi notesz exportálása így:","pad.importExport.exporthtml":"HTML","pad.importExport.exportplain":"Sima szöveg","pad.importExport.exportword":"Microsoft Word","pad.importExport.exportpdf":"PDF","pad.importExport.exportopen":"ODF (Open Document formátum)","pad.importExport.exportdokuwiki":"DokuWiki","pad.modals.connected":"Kapcsolódva.","pad.modals.reconnecting":"Újrakapcsolódás a noteszhez...","pad.modals.forcereconnect":"Újrakapcsolódás kényszerítése","pad.modals.uderdup":"Megnyitva másik ablakban","pad.modals.userdup.explanation":"Úgy tűnik, ez a notesz több különböző böngészőablakban is meg van nyitva a számítógépeden.","pad.modals.userdup.advice":"Kapcsolódj újra, ha ezt az ablakot akarod használni.","pad.modals.unauth":"Nincs rá jogosultságod","pad.modals.unauth.explanation":"A jogosultságaid változtak, miközben nézted ezt az oldalt. Próbálj újrakapcsolódni.","pad.modals.looping":"Kapcsolat bontva.","pad.modals.looping.explanation":"Nem sikerült a kommunikáció a szinkronizációs szerverrel.","pad.modals.looping.cause":"Talán egy túl szigorú tűzfalon vagy proxyn keresztül kapcsolódtál az internetre.","pad.modals.initsocketfail":"A szerver nem érhető el.","pad.modals.initsocketfail.explanation":"Nem sikerült kapcsolódni a szinkronizációs szerverhez.","pad.modals.initsocketfail.cause":"Valószínűleg a böngésződdel vagy az internetkapcsolatoddal van probléma.","pad.modals.slowcommit":"Megszakadt a kapcsolat.","pad.modals.slowcommit.explanation":"A szerver nem válaszol.","pad.modals.slowcommit.cause":"Valószínűleg az internetkapcsolattal van probléma.","pad.modals.deleted":"Törölve.","pad.modals.deleted.explanation":"Ez a notesz el lett távolítva.","pad.modals.disconnected":"Kapcsolat bontva.","pad.modals.disconnected.explanation":"A szerverrel való kapcsolat megszűnt.","pad.modals.disconnected.cause":"Lehet, hogy a szerver nem elérhető. Kérlek, értesíts minket, ha a probléma tartósan fennáll.","pad.share":"Notesz megosztása","pad.share.readonly":"Csak olvasható","pad.share.link":"Hivatkozás","pad.share.emebdcode":"URL beágyazása","pad.chat":"Csevegés","pad.chat.title":"A noteszhez tartozó csevegés megnyitása.","timeslider.pageTitle":"{{appTitle}} időcsúszka","timeslider.toolbar.returnbutton":"Vissza a noteszhez","timeslider.toolbar.authors":"Szerzők:","timeslider.toolbar.authorsList":"Nincsenek szerzők","timeslider.exportCurrent":"Jelenlegi változat exportálása így:","timeslider.month.january":"január","timeslider.month.february":"február","timeslider.month.march":"március","timeslider.month.april":"április","timeslider.month.may":"május","timeslider.month.june":"június","timeslider.month.july":"július","timeslider.month.august":"augusztus","timeslider.month.september":"szeptember","timeslider.month.october":"október","timeslider.month.november":"november","timeslider.month.december":"december"}
|
|
@ -0,0 +1 @@
|
|||
{"index.newPad":"Nove pad","index.createOpenPad":"o crear/aperir un pad con le nomine:","pad.toolbar.bold.title":"Grasse (Ctrl-B)","pad.toolbar.italic.title":"Italic (Ctrl-I)","pad.toolbar.underline.title":"Sublinear (Ctrl-U)","pad.toolbar.strikethrough.title":"Cancellar","pad.toolbar.ol.title":"Lista ordinate","pad.toolbar.ul.title":"Lista non ordinate","pad.toolbar.indent.title":"Indentar","pad.toolbar.unindent.title":"Disindentar","pad.toolbar.undo.title":"Disfacer (Ctrl-Z)","pad.toolbar.redo.title":"Refacer (Ctrl-Y)","pad.toolbar.clearAuthorship.title":"Rader colores de autor","pad.toolbar.import_export.title":"Importar/exportar in differente formatos de file","pad.toolbar.timeslider.title":"Glissa-tempore","pad.toolbar.savedRevision.title":"Versiones salveguardate","pad.toolbar.settings.title":"Configuration","pad.toolbar.embed.title":"Incorporar iste pad","pad.toolbar.showusers.title":"Monstrar le usatores de iste pad","pad.colorpicker.save":"Salveguardar","pad.colorpicker.cancel":"Cancellar","pad.loading":"Cargamento…","pad.settings.padSettings":"Configuration del pad","pad.settings.myView":"Mi vista","pad.settings.stickychat":"Chat sempre visibile","pad.settings.colorcheck":"Colores de autor","pad.settings.linenocheck":"Numeros de linea","pad.settings.fontType":"Typo de litteras:","pad.settings.fontType.normal":"Normal","pad.settings.fontType.monospaced":"Monospatial","pad.settings.globalView":"Vista global","pad.settings.language":"Lingua:","pad.importExport.import_export":"Importar/Exportar","pad.importExport.import":"Incargar qualcunque file de texto o documento","pad.importExport.export":"Exportar le pad actual como:","pad.importExport.exporthtml":"HTML","pad.importExport.exportplain":"Texto simple","pad.importExport.exportword":"Microsoft Word","pad.importExport.exportpdf":"PDF","pad.importExport.exportopen":"ODF (Open Document Format)","pad.importExport.exportdokuwiki":"DokuWiki","pad.modals.connected":"Connectite.","pad.modals.reconnecting":"Reconnecte a tu pad…","pad.modals.forcereconnect":"Fortiar reconnexion","pad.modals.uderdup":"Aperte in un altere fenestra","pad.modals.userdup.explanation":"Iste pad pare esser aperte in plus de un fenestra de navigator in iste computator.","pad.modals.userdup.advice":"Reconnecte pro usar iste fenestra.","pad.modals.unauth":"Non autorisate","pad.modals.unauth.explanation":"Tu permissiones ha cambiate durante que tu legeva iste pagina. Tenta reconnecter.","pad.modals.looping":"Disconnectite.","pad.modals.looping.explanation":"Il ha problemas de communication con le servitor de synchronisation.","pad.modals.looping.cause":"Il es possibile que tu connexion passa per un firewall o proxy incompatibile.","pad.modals.initsocketfail":"Le servitor es inattingibile.","pad.modals.initsocketfail.explanation":"Impossibile connecter al servitor de synchronisation.","pad.modals.initsocketfail.cause":"Isto es probabilemente causate per un problema con tu navigator o connexion a internet.","pad.modals.slowcommit":"Disconnectite.","pad.modals.slowcommit.explanation":"Le servitor non responde.","pad.modals.slowcommit.cause":"Isto pote esser causate per problemas con le connexion al rete.","pad.modals.deleted":"Delite.","pad.modals.deleted.explanation":"Iste pad ha essite removite.","pad.modals.disconnected":"Tu ha essite disconnectite.","pad.modals.disconnected.explanation":"Le connexion al servitor ha essite perdite.","pad.modals.disconnected.cause":"Le servitor pote esser indisponibile. Per favor notifica nos si isto continua a producer se.","pad.share":"Diffunder iste pad","pad.share.readonly":"Lectura solmente","pad.share.link":"Ligamine","pad.share.emebdcode":"Codice de incorporation","pad.chat":"Chat","pad.chat.title":"Aperir le chat pro iste pad.","timeslider.pageTitle":"Glissa-tempore pro {{appTitle}}","timeslider.toolbar.returnbutton":"Retornar al pad","timeslider.toolbar.authors":"Autores:","timeslider.toolbar.authorsList":"Nulle autor","timeslider.exportCurrent":"Exportar le version actual como:","timeslider.month.january":"januario","timeslider.month.february":"februario","timeslider.month.march":"martio","timeslider.month.april":"april","timeslider.month.may":"maio","timeslider.month.june":"junio","timeslider.month.july":"julio","timeslider.month.august":"augusto","timeslider.month.september":"septembre","timeslider.month.october":"octobre","timeslider.month.november":"novembre","timeslider.month.december":"decembre"}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"index.newPad":"Neu Padd","index.createOpenPad":"udder maach e Padd op med däm Naame:","pad.toolbar.bold.title":"Fättschreff (Strg-B)","pad.toolbar.italic.title":"Scheive Schreff (Strg-I)","pad.toolbar.underline.title":"Ongerstresche (Strg-U)","pad.toolbar.strikethrough.title":"Dorschjeschtresche","pad.toolbar.ol.title":"Leß met Nommere","pad.toolbar.ul.title":"Leß met Pongkte","pad.toolbar.indent.title":"Enjerök","pad.toolbar.unindent.title":"Ußjerök","pad.toolbar.undo.title":"Retuur nämme (Strg-Z)","pad.toolbar.redo.title":"Norrens (Strg-Y)","pad.toolbar.clearAuthorship.title":"dä Schriiver ier Färve fottnämme","pad.toolbar.import_export.title":"Vun ongerscheidlijje Dattei_Fommaate empotteere udder äxpotteere","pad.toolbar.timeslider.title":"Verjangeheid afschpelle","pad.toolbar.savedRevision.title":"Faßjehallde Versione","pad.toolbar.settings.title":"Enschtällonge","pad.toolbar.embed.title":"Donn dat Padd enbenge","pad.toolbar.showusers.title":"Verbonge Metschriiver aanzeije","pad.colorpicker.save":"Faßhallde","pad.colorpicker.cancel":"Ophüüre","pad.loading":"Aam Laade …","pad.settings.padSettings":"Dam Pädd sin Enschtällonge","pad.settings.myView":"Anseesch","pad.settings.stickychat":"Donn der Klaaf emmer aanzeije","pad.settings.colorcheck":"Färve för de Schriiver","pad.settings.linenocheck":"Nommere för de Reije","pad.settings.fontType":"Zoot Schreff","pad.settings.fontType.normal":"Nomaal","pad.settings.fontType.monospaced":"einheidlesch brejde Zeische","pad.settings.globalView":"Et Ußsin för Alle","pad.settings.language":"Schprooch:","pad.importExport.import_export":"Empoot/Äxpoot","pad.importExport.import":"Donn jeede Täx udder jeede Zoot Dokemänt huhlaade","pad.importExport.export":"Don dat Pädd äxpoteere alß:","pad.importExport.exporthtml":"HTML","pad.importExport.exportplain":"Eijfach Täx","pad.importExport.exportword":"Microsoft Word","pad.importExport.exportpdf":"PDF (Poteerbaa Dokemänte Fommaat)","pad.importExport.exportopen":"ODF (Offe Dokemänte-Fommaat)","pad.importExport.exportdokuwiki":"DokuWiki","pad.modals.connected":"Verbonge.","pad.modals.reconnecting":"Ben wider aam Verbenge …","pad.modals.forcereconnect":"Wider verbenge","pad.modals.uderdup":"En enem andere Finster en Ärbeid","pad.modals.userdup.explanation":"Heh dat Padd schingk en mieh wi einem Finster vun enem Brauser op heh däm Rääschner op ze sin.","pad.modals.userdup.advice":"En heh däm Finster wider verbenge.","pad.modals.unauth":"Nit berääschtesch","pad.modals.unauth.explanation":"Ding Berääschtejong hät sesch jeändert, derwiehl De di Sigg aam beloore wohrß. Versöhk en neu Verbendong ze maache.","pad.modals.looping":"De Verbendong es fott.","pad.modals.looping.explanation":"Et jitt Probleeme met dä Verbendong mem ẞööver för de Schriiver ier Aandeile zesamme_ze_bränge.","pad.modals.looping.cause":"Künnt sin, Ding Verbendong jeiht dorj_ene onzopaß proxy-ẞööver udder firewall.","pad.modals.initsocketfail":"Dä ẞööver es nit ze äreische.","pad.modals.initsocketfail.explanation":"Kein Verbendong met däm ẞööver ze krijje.","pad.modals.initsocketfail.cause":"Dat künnt aam Brauser udder aan däm singer Verbendong övver et Internet lijje.","pad.modals.slowcommit":"De Verbendong es fott.","pad.modals.slowcommit.explanation":"Dä ẞööver antwoot nit.","pad.modals.slowcommit.cause":"Dat künnt aan Probleeme met Verbendonge em Näzwärrek lijje.","pad.modals.deleted":"Fottjeschmeße.","pad.modals.deleted.explanation":"Dat Pädd es fottjeschmeße woode.","pad.modals.disconnected":"Do bes nit mieh verbonge.","pad.modals.disconnected.explanation":"De Verbendong mem ẞööver es fott.","pad.modals.disconnected.cause":"Dä ẞööver künnt nit loufe.","pad.share":"Maach heh dat Padd öffentlesch","pad.share.readonly":"Nor zom Lässe","pad.share.link":"Lengk","pad.share.emebdcode":"URL enboue","pad.chat":"Klaaf","pad.chat.title":"Maach dä Klaaf för heh dat Pädd op","timeslider.pageTitle":"{{appTitle}} - Verjangeheid affschpelle","timeslider.toolbar.returnbutton":"Jangk retuur nohm Pädd","timeslider.toolbar.authors":"Schriiver:","timeslider.toolbar.authorsList":"Kein Schriivere","timeslider.exportCurrent":"Donn de meußte Väsjohn äxpotteere alß:","timeslider.version":"Väsjon {{version}}","timeslider.saved":"Faßjehallde aam {{day}}. {{month}} {{year}}","timeslider.dateformat":"amm {{day}}. {{month}} {{year}} öm {{hours}}:{{minutes}}:{{seconds}}","timeslider.month.january":"Jannewaa","timeslider.month.february":"Fääbrowaa","timeslider.month.march":"Määz","timeslider.month.april":"Apprell","timeslider.month.may":"Mai","timeslider.month.june":"Juuni","timeslider.month.july":"Juuli","timeslider.month.august":"Oujoß","timeslider.month.september":"Säptämber","timeslider.month.october":"Oktoober","timeslider.month.november":"Novämber","timeslider.month.december":"Dezämber"}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,79 +0,0 @@
|
|||
; Exported from translatewiki.net
|
||||
; Author: Siebrand
|
||||
[nl]
|
||||
index.newPad = Nieuw pad
|
||||
index.createOpenPad = Maak of open pad met de naam:
|
||||
pad.toolbar.bold.title = Vet (Ctrl-B)
|
||||
pad.toolbar.italic.title = Cursief (Ctrl-I)
|
||||
pad.toolbar.underline.title = Onderstrepen (Ctrl-U)
|
||||
pad.toolbar.strikethrough.title = Doorhalen
|
||||
pad.toolbar.ol.title = Geordende lijst
|
||||
pad.toolbar.ul.title = Ongeordende lijst
|
||||
pad.toolbar.indent.title = Inspringen
|
||||
pad.toolbar.unindent.title = Inspringing verkleinen
|
||||
pad.toolbar.undo.title = Ongedaan maken (Ctrl-Z)
|
||||
pad.toolbar.redo.title = Opnieuw uitvoeren (Ctrl-Y)
|
||||
pad.toolbar.clearAuthorship.title = Kleuren auteurs wissen
|
||||
pad.toolbar.import_export.title = Naar/van andere opmaak exporteren/importeren
|
||||
pad.toolbar.timeslider.title = Tijdlijn
|
||||
pad.toolbar.savedRevision.title = Opgeslagen versies
|
||||
pad.toolbar.settings.title = Instellingen
|
||||
pad.toolbar.embed.title = Pad insluiten
|
||||
pad.toolbar.showusers.title = Gebruikers van dit pad weergeven
|
||||
pad.colorpicker.save = Opslaan
|
||||
pad.colorpicker.cancel = Annuleren
|
||||
pad.loading = Bezig met laden…
|
||||
pad.settings.padSettings = Padinstellingen
|
||||
pad.settings.myView = Mijn overzicht
|
||||
pad.settings.stickychat = Chat altijd zichtbaar
|
||||
pad.settings.colorcheck = Kleuren auteurs
|
||||
pad.settings.linenocheck = Regelnummers
|
||||
pad.settings.fontType = Lettertype:
|
||||
pad.settings.fontType.normal = Normaal
|
||||
pad.settings.fontType.monospaced = Monospace
|
||||
pad.settings.globalView = Globaal overzicht
|
||||
pad.settings.language = Taal:
|
||||
pad.importExport.import_export = Importeren/exporteren
|
||||
pad.importExport.import = Upload een tekstbestand of document
|
||||
pad.importExport.successful = Afgerond
|
||||
; Fuzzy
|
||||
pad.importExport.export = Huidige pad exporteren als
|
||||
pad.importExport.exporthtml = HTML
|
||||
pad.importExport.exportplain = Tekst zonder opmaak
|
||||
pad.importExport.exportword = Microsoft Word
|
||||
pad.importExport.exportpdf = PDF
|
||||
pad.importExport.exportopen = ODF (Open Document Format)
|
||||
pad.importExport.exportdokuwiki = DokuWiki
|
||||
pad.modals.connected = Verbonden.
|
||||
pad.modals.reconnecting = Opnieuw verbinding maken met uw pad...
|
||||
pad.modals.forcereconnect = Opnieuw verbinden
|
||||
pad.modals.uderdup = Openen in ander venster
|
||||
pad.modals.userdup.explanation = Dit pad is meer dan één keer geopend in een browservenster op deze computer.
|
||||
pad.modals.userdup.advice = Opnieuw verbinden en dit venster gebruiken.
|
||||
pad.modals.unauth = Niet toegestaan
|
||||
pad.modals.unauth.explanation = Uw rechten zijn gewijzigd terwijl u de pagina aan het bekijken was. Probeer opnieuw te verbinden.
|
||||
pad.modals.looping = Verbinding verbroken.
|
||||
pad.modals.looping.explanation = Er is een probleem opgetreden tijdens de communicatie met de synchronisatieserver.
|
||||
pad.modals.looping.cause = Mogelijk gebruikt de server een niet compatibele firewall of proxy server.
|
||||
pad.modals.initsocketfail = Server is niet bereikbaar.
|
||||
pad.modals.initsocketfail.explanation = Het was niet mogelijk te verbinden met de synchronisatieserver.
|
||||
pad.modals.initsocketfail.cause = Mogelijk komt dit door uw browser of internetverbinding.
|
||||
pad.modals.slowcommit = Verbinding verbroken.
|
||||
pad.modals.slowcommit.explanation = De server reageert niet.
|
||||
pad.modals.slowcommit.cause = Dit komt mogelijk door netwerkproblemen.
|
||||
pad.modals.deleted = Verwijderd.
|
||||
pad.modals.deleted.explanation = Dit pad is verwijderd.
|
||||
pad.modals.disconnected = Uw verbinding is verbroken.
|
||||
pad.modals.disconnected.explanation = De verbinding met de server is verbroken
|
||||
pad.modals.disconnected.cause = De server is mogelijk niet beschikbaar. Stel alstublieft de beheerder op de hoogte.
|
||||
pad.share = Pad delen
|
||||
pad.share.readonly = Alleen-lezen
|
||||
pad.share.link = Verwijzing
|
||||
pad.share.emebdcode = URL insluiten
|
||||
pad.chat = Chatten
|
||||
pad.chat.title = Chat voor dit pad opnenen
|
||||
timeslider.pageTitle = Tijdlijn voor {{appTitle}}
|
||||
timeslider.toolbar.returnbutton = Terug naar pad
|
||||
timeslider.toolbar.authors = Auteurs:
|
||||
timeslider.toolbar.authorsList = Geen auteurs
|
||||
timeslider.exportCurrent = Huidige versie exporteren als:
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
{"pad.toolbar.bold.title":"زغرد (Ctrl-B)","pad.toolbar.italic.title":"رېوند (Ctrl-I)","pad.toolbar.undo.title":"ناکړل (Ctrl-Z)","pad.toolbar.redo.title":"بياکړل (Ctrl-Y)","pad.toolbar.settings.title":"امستنې","pad.colorpicker.save":"خوندي کول","pad.colorpicker.cancel":"ناګارل","pad.loading":"برسېرېدنې کې دی...","pad.settings.myView":"زما کتنه","pad.settings.fontType":"ليکبڼې ډول:","pad.settings.fontType.normal":"نورمال","pad.settings.fontType.monospaced":"مونوسپېس","pad.settings.language":"ژبه:","pad.importExport.exporthtml":"اچ ټي ام اېل","pad.importExport.exportplain":"ساده متن","pad.importExport.exportword":"مايکروسافټ ورډ","pad.importExport.exportpdf":"پي ډي اېف","pad.importExport.exportopen":"ODF (اوپن ډاکومنټ فارمټ)","pad.modals.deleted":"ړنګ شو.","pad.share.readonly":"يوازې لوستنه","pad.share.link":"تړنه","pad.share.emebdcode":"يو آر اېل ټومبل","pad.chat":"بانډار","timeslider.toolbar.authors":"ليکوال:","timeslider.month.january":"جنوري","timeslider.month.february":"فبروري","timeslider.month.march":"مارچ","timeslider.month.april":"اپرېل","timeslider.month.may":"مۍ","timeslider.month.june":"جون","timeslider.month.july":"جولای","timeslider.month.august":"اګسټ","timeslider.month.september":"سېپتمبر","timeslider.month.october":"اکتوبر","timeslider.month.november":"نومبر","timeslider.month.december":"ډيسمبر"}
|
|
@ -0,0 +1 @@
|
|||
{"index.newPad":"Novo Pad","index.createOpenPad":"ou criar/abrir um Pad com o nome:","pad.toolbar.bold.title":"Negrito (Ctrl-B)","pad.toolbar.italic.title":"Itálico (Ctrl-I)","pad.toolbar.underline.title":"Sublinhado (Ctrl-U)","pad.toolbar.ol.title":"Lista numerada","pad.toolbar.ul.title":"Lista","pad.toolbar.undo.title":"Desfazer (Ctrl-Z)","pad.toolbar.redo.title":"Refazer (Ctrl-Y)","pad.toolbar.clearAuthorship.title":"Limpar cores de autoria","pad.toolbar.import_export.title":"Importar/exportar de/para diferentes formatos de ficheiro","pad.toolbar.timeslider.title":"Linha de tempo","pad.toolbar.savedRevision.title":"Versões gravadas","pad.toolbar.settings.title":"Configurações","pad.toolbar.embed.title":"Incorporar este Pad","pad.toolbar.showusers.title":"Mostrar os utilizadores neste Pad","pad.colorpicker.save":"Gravar","pad.colorpicker.cancel":"Cancelar","pad.loading":"A carregar…","pad.settings.padSettings":"Configurações do Pad","pad.settings.myView":"Minha vista","pad.settings.colorcheck":"Cores de autoria","pad.settings.linenocheck":"Números de linha","pad.settings.fontType":"Tipo de letra:","pad.settings.fontType.normal":"Normal","pad.settings.fontType.monospaced":"Monoespaçada","pad.settings.globalView":"Vista global","pad.settings.language":"Língua:","pad.importExport.import_export":"Importar/Exportar","pad.importExport.import":"Carregar qualquer ficheiro de texto ou documento","pad.importExport.export":"Exportar o Pad actual como:","pad.importExport.exporthtml":"HTML","pad.importExport.exportplain":"Texto simples","pad.importExport.exportword":"Microsoft Word","pad.importExport.exportpdf":"PDF","pad.importExport.exportopen":"ODF (Open Document Format)","pad.importExport.exportdokuwiki":"DokuWiki","pad.modals.connected":"Ligado.","pad.modals.reconnecting":"Reconectando-se ao seu bloco…","pad.modals.forcereconnect":"Forçar reconexão","pad.modals.uderdup":"Aberto noutra janela","timeslider.month.january":"Janeiro","timeslider.month.february":"Fevereiro","timeslider.month.march":"Março","timeslider.month.april":"Abril<69><6C>","timeslider.month.may":"Maio","timeslider.month.june":"Junho","timeslider.month.july":"Julho","timeslider.month.august":"Agosto","timeslider.month.september":"Setembro","timeslider.month.october":"Outubro","timeslider.month.november":"Novembro","timeslider.month.december":"Dezembro"}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -548,6 +548,19 @@ exports.sendClientsMessage = function (padID, msg, callback) {
|
|||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
checkToken() returns ok when api token is valid
|
||||
|
||||
Example returns:
|
||||
|
||||
{"code":0,"message":"ok","data":null}
|
||||
{"code":4,"message":"no or wrong API Key","data":null}
|
||||
*/
|
||||
exports.checkToken = function(callback)
|
||||
{
|
||||
callback();
|
||||
}
|
||||
|
||||
|
||||
/******************************/
|
||||
/** INTERNAL HELPER FUNCTIONS */
|
||||
|
|
|
@ -25,7 +25,7 @@ var async = require("async");
|
|||
var authorManager = require("./AuthorManager");
|
||||
var padManager = require("./PadManager");
|
||||
var sessionManager = require("./SessionManager");
|
||||
var settings = require("../utils/Settings")
|
||||
var settings = require("../utils/Settings");
|
||||
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
||||
|
||||
/**
|
||||
|
@ -83,7 +83,7 @@ exports.checkAccess = function (padID, sessionCookie, token, password, callback)
|
|||
// grant access, with author of token
|
||||
callback(null, statusObject);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
//don't continue
|
||||
return;
|
||||
|
@ -133,10 +133,16 @@ exports.checkAccess = function (padID, sessionCookie, token, password, callback)
|
|||
var now = Math.floor(new Date().getTime()/1000);
|
||||
|
||||
//is it for this group?
|
||||
if(sessionInfo.groupID != groupID) return;
|
||||
if(sessionInfo.groupID != groupID) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
//is validUntil still ok?
|
||||
if(sessionInfo.validUntil <= now) return;
|
||||
if(sessionInfo.validUntil <= now){
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
// There is a valid session
|
||||
validSession = true;
|
||||
|
@ -282,4 +288,4 @@ exports.checkAccess = function (padID, sessionCookie, token, password, callback)
|
|||
if(ERR(err, callback)) return;
|
||||
callback(null, statusObject);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -28,18 +28,25 @@ var resolve = require("resolve");
|
|||
exports.info = {
|
||||
buf_stack: [],
|
||||
block_stack: [],
|
||||
blocks: {},
|
||||
file_stack: [],
|
||||
args: []
|
||||
};
|
||||
|
||||
function getCurrentFile() {
|
||||
return exports.info.file_stack[exports.info.file_stack.length-1];
|
||||
}
|
||||
|
||||
function createBlockId(name) {
|
||||
return getCurrentFile().path + '|' + name;
|
||||
}
|
||||
|
||||
exports._init = function (b, recursive) {
|
||||
exports.info.buf_stack.push(exports.info.buf);
|
||||
exports.info.buf = b;
|
||||
}
|
||||
|
||||
exports._exit = function (b, recursive) {
|
||||
exports.info.file_stack[exports.info.file_stack.length-1].inherit.forEach(function (item) {
|
||||
getCurrentFile().inherit.forEach(function (item) {
|
||||
exports._require(item.name, item.args);
|
||||
});
|
||||
exports.info.buf = exports.info.buf_stack.pop();
|
||||
|
@ -59,29 +66,17 @@ exports.end_capture = function () {
|
|||
}
|
||||
|
||||
exports.begin_define_block = function (name) {
|
||||
if (typeof exports.info.blocks[name] == "undefined")
|
||||
exports.info.blocks[name] = {};
|
||||
exports.info.block_stack.push(name);
|
||||
exports.begin_capture();
|
||||
}
|
||||
|
||||
exports.super = function () {
|
||||
exports.info.buf.push('<!eejs!super!>');
|
||||
}
|
||||
|
||||
exports.end_define_block = function () {
|
||||
content = exports.end_capture();
|
||||
var name = exports.info.block_stack.pop();
|
||||
if (typeof exports.info.blocks[name].content == "undefined")
|
||||
exports.info.blocks[name].content = content;
|
||||
else if (typeof exports.info.blocks[name].content.indexOf('<!eejs!super!>'))
|
||||
exports.info.blocks[name].content = exports.info.blocks[name].content.replace('<!eejs!super!>', content);
|
||||
|
||||
return exports.info.blocks[name].content;
|
||||
return content;
|
||||
}
|
||||
|
||||
exports.end_block = function () {
|
||||
var name = exports.info.block_stack[exports.info.block_stack.length-1];
|
||||
var name = exports.info.block_stack.pop();
|
||||
var renderContext = exports.info.args[exports.info.args.length-1];
|
||||
var args = {content: exports.end_define_block(), renderContext: renderContext};
|
||||
hooks.callAll("eejsBlock_" + name, args);
|
||||
|
@ -91,7 +86,7 @@ exports.end_block = function () {
|
|||
exports.begin_block = exports.begin_define_block;
|
||||
|
||||
exports.inherit = function (name, args) {
|
||||
exports.info.file_stack[exports.info.file_stack.length-1].inherit.push({name:name, args:args});
|
||||
getCurrentFile().inherit.push({name:name, args:args});
|
||||
}
|
||||
|
||||
exports.require = function (name, args, mod) {
|
||||
|
@ -101,7 +96,7 @@ exports.require = function (name, args, mod) {
|
|||
var paths = [];
|
||||
|
||||
if (exports.info.file_stack.length) {
|
||||
basedir = path.dirname(exports.info.file_stack[exports.info.file_stack.length-1].path);
|
||||
basedir = path.dirname(getCurrentFile().path);
|
||||
}
|
||||
if (mod) {
|
||||
basedir = path.dirname(mod.filename);
|
||||
|
|
|
@ -103,6 +103,41 @@ var version =
|
|||
, "sendClientsMessage" : ["padID", "msg"]
|
||||
, "listAllGroups" : []
|
||||
}
|
||||
, "1.2":
|
||||
{ "createGroup" : []
|
||||
, "createGroupIfNotExistsFor" : ["groupMapper"]
|
||||
, "deleteGroup" : ["groupID"]
|
||||
, "listPads" : ["groupID"]
|
||||
, "createPad" : ["padID", "text"]
|
||||
, "createGroupPad" : ["groupID", "padName", "text"]
|
||||
, "createAuthor" : ["name"]
|
||||
, "createAuthorIfNotExistsFor": ["authorMapper" , "name"]
|
||||
, "listPadsOfAuthor" : ["authorID"]
|
||||
, "createSession" : ["groupID", "authorID", "validUntil"]
|
||||
, "deleteSession" : ["sessionID"]
|
||||
, "getSessionInfo" : ["sessionID"]
|
||||
, "listSessionsOfGroup" : ["groupID"]
|
||||
, "listSessionsOfAuthor" : ["authorID"]
|
||||
, "getText" : ["padID", "rev"]
|
||||
, "setText" : ["padID", "text"]
|
||||
, "getHTML" : ["padID", "rev"]
|
||||
, "setHTML" : ["padID", "html"]
|
||||
, "getRevisionsCount" : ["padID"]
|
||||
, "getLastEdited" : ["padID"]
|
||||
, "deletePad" : ["padID"]
|
||||
, "getReadOnlyID" : ["padID"]
|
||||
, "setPublicStatus" : ["padID", "publicStatus"]
|
||||
, "getPublicStatus" : ["padID"]
|
||||
, "setPassword" : ["padID", "password"]
|
||||
, "isPasswordProtected" : ["padID"]
|
||||
, "listAuthorsOfPad" : ["padID"]
|
||||
, "padUsersCount" : ["padID"]
|
||||
, "getAuthorName" : ["authorID"]
|
||||
, "padUsers" : ["padID"]
|
||||
, "sendClientsMessage" : ["padID", "msg"]
|
||||
, "listAllGroups" : []
|
||||
, "checkToken" : []
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
/*
|
||||
* 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
|
||||
* 2012 Iván Eixarch
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -18,26 +19,23 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var ERR = require("async-stacktrace");
|
||||
var padManager = require("../db/PadManager");
|
||||
var padMessageHandler = require("./PadMessageHandler");
|
||||
var async = require("async");
|
||||
var fs = require("fs");
|
||||
var settings = require('../utils/Settings');
|
||||
var formidable = require('formidable');
|
||||
var os = require("os");
|
||||
var ERR = require("async-stacktrace")
|
||||
, padManager = require("../db/PadManager")
|
||||
, padMessageHandler = require("./PadMessageHandler")
|
||||
, async = require("async")
|
||||
, fs = require("fs")
|
||||
, path = require("path")
|
||||
, settings = require('../utils/Settings')
|
||||
, formidable = require('formidable')
|
||||
, os = require("os")
|
||||
, importHtml = require("../utils/ImportHtml");
|
||||
|
||||
//load abiword only if its enabled
|
||||
if(settings.abiword != null)
|
||||
var abiword = require("../utils/Abiword");
|
||||
|
||||
var tempDirectory = "/tmp/";
|
||||
|
||||
//tempDirectory changes if the operating system is windows
|
||||
if(os.type().indexOf("Windows") > -1)
|
||||
{
|
||||
tempDirectory = process.env.TEMP;
|
||||
}
|
||||
//for node 0.6 compatibily, os.tmpDir() only works from 0.8
|
||||
var tmpDirectory = process.env.TEMP || process.env.TMPDIR || process.env.TMP || '/tmp';
|
||||
|
||||
/**
|
||||
* do a requested import
|
||||
|
@ -45,32 +43,28 @@ if(os.type().indexOf("Windows") > -1)
|
|||
exports.doImport = function(req, res, padId)
|
||||
{
|
||||
//pipe to a file
|
||||
//convert file to text via abiword
|
||||
//set text in the pad
|
||||
//convert file to html via abiword
|
||||
//set html in the pad
|
||||
|
||||
var srcFile, destFile;
|
||||
var pad;
|
||||
var text;
|
||||
var srcFile, destFile
|
||||
, pad
|
||||
, text;
|
||||
|
||||
async.series([
|
||||
//save the uploaded file to /tmp
|
||||
function(callback)
|
||||
{
|
||||
function(callback) {
|
||||
var form = new formidable.IncomingForm();
|
||||
form.keepExtensions = true;
|
||||
form.uploadDir = tempDirectory;
|
||||
form.uploadDir = tmpDirectory;
|
||||
|
||||
form.parse(req, function(err, fields, files)
|
||||
{
|
||||
form.parse(req, function(err, fields, files) {
|
||||
//the upload failed, stop at this point
|
||||
if(err || files.file === undefined)
|
||||
{
|
||||
if(err || files.file === undefined) {
|
||||
console.warn("Uploading Error: " + err.stack);
|
||||
callback("uploadFailed");
|
||||
}
|
||||
//everything ok, continue
|
||||
else
|
||||
{
|
||||
else {
|
||||
//save the path of the uploaded file
|
||||
srcFile = files.file.path;
|
||||
callback();
|
||||
|
@ -80,57 +74,48 @@ exports.doImport = function(req, res, padId)
|
|||
|
||||
//ensure this is a file ending we know, else we change the file ending to .txt
|
||||
//this allows us to accept source code files like .c or .java
|
||||
function(callback)
|
||||
{
|
||||
var fileEnding = (srcFile.split(".")[1] || "").toLowerCase();
|
||||
var knownFileEndings = ["txt", "doc", "docx", "pdf", "odt", "html", "htm"];
|
||||
|
||||
//find out if this is a known file ending
|
||||
var fileEndingKnown = false;
|
||||
for(var i in knownFileEndings)
|
||||
{
|
||||
if(fileEnding == knownFileEndings[i])
|
||||
{
|
||||
fileEndingKnown = true;
|
||||
}
|
||||
}
|
||||
function(callback) {
|
||||
var fileEnding = path.extname(srcFile).toLowerCase()
|
||||
, knownFileEndings = [".txt", ".doc", ".docx", ".pdf", ".odt", ".html", ".htm"]
|
||||
, fileEndingKnown = (knownFileEndings.indexOf(fileEnding) > -1);
|
||||
|
||||
//if the file ending is known, continue as normal
|
||||
if(fileEndingKnown)
|
||||
{
|
||||
if(fileEndingKnown) {
|
||||
callback();
|
||||
}
|
||||
//we need to rename this file with a .txt ending
|
||||
else
|
||||
{
|
||||
else {
|
||||
var oldSrcFile = srcFile;
|
||||
srcFile = srcFile.split(".")[0] + ".txt";
|
||||
srcFile = path.join(path.dirname(srcFile),path.basename(srcFile, fileEnding)+".txt");
|
||||
|
||||
fs.rename(oldSrcFile, srcFile, callback);
|
||||
}
|
||||
},
|
||||
|
||||
//convert file to text
|
||||
function(callback)
|
||||
{
|
||||
//convert file to html
|
||||
function(callback) {
|
||||
var randNum = Math.floor(Math.random()*0xFFFFFFFF);
|
||||
destFile = tempDirectory + "eplite_import_" + randNum + ".txt";
|
||||
abiword.convertFile(srcFile, destFile, "txt", function(err){
|
||||
//catch convert errors
|
||||
if(err){
|
||||
console.warn("Converting Error:", err);
|
||||
return callback("convertFailed");
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
destFile = path.join(tmpDirectory, "eplite_import_" + randNum + ".htm");
|
||||
|
||||
if (abiword) {
|
||||
abiword.convertFile(srcFile, destFile, "htm", function(err) {
|
||||
//catch convert errors
|
||||
if(err) {
|
||||
console.warn("Converting Error:", err);
|
||||
return callback("convertFailed");
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// if no abiword only rename
|
||||
fs.rename(srcFile, destFile, callback);
|
||||
}
|
||||
},
|
||||
|
||||
//get the pad object
|
||||
function(callback)
|
||||
{
|
||||
padManager.getPad(padId, function(err, _pad)
|
||||
{
|
||||
function(callback) {
|
||||
padManager.getPad(padId, function(err, _pad){
|
||||
if(ERR(err, callback)) return;
|
||||
pad = _pad;
|
||||
callback();
|
||||
|
@ -138,52 +123,47 @@ exports.doImport = function(req, res, padId)
|
|||
},
|
||||
|
||||
//read the text
|
||||
function(callback)
|
||||
{
|
||||
fs.readFile(destFile, "utf8", function(err, _text)
|
||||
{
|
||||
function(callback) {
|
||||
fs.readFile(destFile, "utf8", function(err, _text){
|
||||
if(ERR(err, callback)) return;
|
||||
text = _text;
|
||||
|
||||
//node on windows has a delay on releasing of the file lock.
|
||||
//We add a 100ms delay to work around this
|
||||
if(os.type().indexOf("Windows") > -1)
|
||||
{
|
||||
setTimeout(function()
|
||||
{
|
||||
callback();
|
||||
}, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback();
|
||||
}
|
||||
if(os.type().indexOf("Windows") > -1){
|
||||
setTimeout(function() {callback();}, 100);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//change text of the pad and broadcast the changeset
|
||||
function(callback)
|
||||
{
|
||||
pad.setText(text);
|
||||
function(callback) {
|
||||
var fileEnding = path.extname(srcFile).toLowerCase();
|
||||
if (abiword || fileEnding == ".htm" || fileEnding == ".html") {
|
||||
importHtml.setPadHTML(pad, text);
|
||||
} else {
|
||||
pad.setText(text);
|
||||
}
|
||||
padMessageHandler.updatePadClients(pad, callback);
|
||||
},
|
||||
|
||||
//clean up temporary files
|
||||
function(callback)
|
||||
{
|
||||
function(callback) {
|
||||
//for node < 0.7 compatible
|
||||
var fileExists = fs.exists || path.exists;
|
||||
async.parallel([
|
||||
function(callback)
|
||||
{
|
||||
fs.unlink(srcFile, callback);
|
||||
function(callback){
|
||||
fileExists (srcFile, function(exist) { (exist)? fs.unlink(srcFile, callback): callback(); });
|
||||
},
|
||||
function(callback)
|
||||
{
|
||||
fs.unlink(destFile, callback);
|
||||
function(callback){
|
||||
fileExists (destFile, function(exist) { (exist)? fs.unlink(destFile, callback): callback(); });
|
||||
}
|
||||
], callback);
|
||||
}
|
||||
], function(err)
|
||||
{
|
||||
], function(err) {
|
||||
|
||||
var status = "ok";
|
||||
|
||||
//check for known errors and replace the status
|
||||
|
@ -196,6 +176,7 @@ exports.doImport = function(req, res, padId)
|
|||
ERR(err);
|
||||
|
||||
//close the connection
|
||||
res.send("<script type='text/javascript' src='/static/js/jquery.js'></script><script> if ( (!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf(\"1.8.\") == 0)) ){document.domain = document.domain;}var impexp = window.top.require('/pad_impexp').padimpexp.handleFrameCall('" + status + "');</script>", 200);
|
||||
res.send("<head><script type='text/javascript' src='/static/js/jquery.js'></script></head><script>$(window).load(function(){if ( (!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf(\"1.8.\") == 0)) ){document.domain = document.domain;}var impexp = window.parent.require('/pad_impexp').padimpexp.handleFrameCall('" + status + "');})</script>", 200);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
|
||||
var http = require('http');
|
||||
var express = require('express');
|
||||
var settings = require('../utils/Settings');
|
||||
var fs = require('fs');
|
||||
|
@ -26,9 +25,9 @@ exports.createServer = function () {
|
|||
{
|
||||
console.warn("Can't get git version for server header\n" + e.message)
|
||||
}
|
||||
console.log("Report bugs at https://github.com/Pita/etherpad-lite/issues")
|
||||
console.log("Report bugs at https://github.com/ether/etherpad-lite/issues")
|
||||
|
||||
serverName = "Etherpad-Lite " + version + " (http://j.mp/ep-lite)";
|
||||
serverName = "Etherpad-Lite " + version + " (http://etherpad.org)";
|
||||
|
||||
exports.restartServer();
|
||||
|
||||
|
@ -50,7 +49,26 @@ exports.restartServer = function () {
|
|||
}
|
||||
|
||||
var app = express(); // New syntax for express v3
|
||||
server = http.createServer(app);
|
||||
|
||||
if (settings.ssl) {
|
||||
|
||||
console.log( "SSL -- enabled");
|
||||
console.log( "SSL -- server key file: " + settings.ssl.key );
|
||||
console.log( "SSL -- Certificate Authority's certificate file: " + settings.ssl.cert );
|
||||
|
||||
options = {
|
||||
key: fs.readFileSync( settings.ssl.key ),
|
||||
cert: fs.readFileSync( settings.ssl.cert )
|
||||
};
|
||||
|
||||
var https = require('https');
|
||||
server = https.createServer(options, app);
|
||||
|
||||
} else {
|
||||
|
||||
var http = require('http');
|
||||
server = http.createServer(app);
|
||||
}
|
||||
|
||||
app.use(function (req, res, next) {
|
||||
res.header("Server", serverName);
|
||||
|
|
|
@ -28,12 +28,6 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
|||
|
||||
//handle import requests
|
||||
args.app.post('/p/:pad/import', function(req, res, next) {
|
||||
//if abiword is disabled, skip handling this request
|
||||
if(settings.abiword == null) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
hasPadAccess(req, res, function() {
|
||||
importHandler.doImport(req, res, req.params.pad);
|
||||
});
|
||||
|
|
|
@ -36,13 +36,10 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
|||
});
|
||||
});
|
||||
|
||||
// the following has been successfully tested with the following browsers
|
||||
// works also behind reverse proxy
|
||||
// Firefox 14.0.1
|
||||
// IE8 with Native XMLHTTP support
|
||||
// IE8 without Native XMLHTTP support
|
||||
// Chrome 21.0.1180.79
|
||||
io.set('transports', ['jsonp-polling']);
|
||||
// there shouldn't be a browser that isn't compatible to all
|
||||
// transports in this list at once
|
||||
// e.g. XHR is disabled in IE by default, so in IE it should use jsonp-polling
|
||||
io.set('transports', settings.socketTransportProtocols );
|
||||
|
||||
var socketIOLogger = log4js.getLogger("socket.io");
|
||||
io.set('logger', {
|
||||
|
|
|
@ -15,8 +15,8 @@ exports.basicAuth = function (req, res, next) {
|
|||
}
|
||||
|
||||
var authorize = function (cb) {
|
||||
// Do not require auth for static paths...this could be a bit brittle
|
||||
if (req.path.match(/^\/(static|javascripts|pluginfw)/)) return cb(true);
|
||||
// Do not require auth for static paths and the API...this could be a bit brittle
|
||||
if (req.path.match(/^\/(static|javascripts|pluginfw|api)/)) return cb(true);
|
||||
|
||||
if (req.path.indexOf('/admin') != 0) {
|
||||
if (!settings.requireAuthentication) return cb(true);
|
||||
|
|
|
@ -1,35 +1,103 @@
|
|||
var languages = require('languages')
|
||||
var languages = require('languages4translatewiki')
|
||||
, fs = require('fs')
|
||||
, path = require('path')
|
||||
, express = require('express')
|
||||
, _ = require('underscore')
|
||||
, npm = require('npm')
|
||||
, plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins.js').plugins
|
||||
;
|
||||
|
||||
var localesPath = __dirname+"/../../locales";
|
||||
|
||||
// Serve English strings directly with /locales.ini
|
||||
var localeIndex = fs.readFileSync(localesPath+'/en.ini')+'\r\n';
|
||||
// returns all existing messages merged together and grouped by langcode
|
||||
// {es: {"foo": "string"}, en:...}
|
||||
function getAllLocales() {
|
||||
var locales2paths = {};
|
||||
|
||||
// add language base 'en' to availableLangs
|
||||
exports.availableLangs = {en: languages.getLanguageInfo('en')}
|
||||
// Puts the paths of all locale files contained in a given directory
|
||||
// into `locales2paths` (files from various dirs are grouped by lang code)
|
||||
// (only json files with valid language code as name)
|
||||
function extractLangs(dir) {
|
||||
if(!fs.existsSync(dir)) return;
|
||||
var stat = fs.lstatSync(dir);
|
||||
if (!stat.isDirectory() || stat.isSymbolicLink()) return;
|
||||
|
||||
fs.readdir(localesPath, function(er, files) {
|
||||
files.forEach(function(locale) {
|
||||
locale = locale.split('.')[0]
|
||||
if(locale.toLowerCase() == 'en') return;
|
||||
fs.readdirSync(dir).forEach(function(file) {
|
||||
file = path.resolve(dir, file);
|
||||
stat = fs.lstatSync(file);
|
||||
if (stat.isDirectory() || stat.isSymbolicLink()) return;
|
||||
|
||||
var ext = path.extname(file)
|
||||
, locale = path.basename(file, ext).toLowerCase();
|
||||
|
||||
if ((ext == '.json') && languages.isValid(locale)) {
|
||||
if(!locales2paths[locale]) locales2paths[locale] = [];
|
||||
locales2paths[locale].push(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//add core supported languages first
|
||||
extractLangs(npm.root+"/ep_etherpad-lite/locales");
|
||||
|
||||
//add plugins languages (if any)
|
||||
for(var pluginName in plugins) extractLangs(path.join(npm.root, pluginName, 'locales'));
|
||||
|
||||
// Build a locale index (merge all locale data)
|
||||
var locales = {}
|
||||
_.each (locales2paths, function(files, langcode) {
|
||||
locales[langcode]={};
|
||||
|
||||
files.forEach(function(file) {
|
||||
var fileContents = JSON.parse(fs.readFileSync(file,'utf8'));
|
||||
_.extend(locales[langcode], fileContents);
|
||||
});
|
||||
});
|
||||
|
||||
return locales;
|
||||
}
|
||||
|
||||
// returns a hash of all available languages availables with nativeName and direction
|
||||
// e.g. { es: {nativeName: "español", direction: "ltr"}, ... }
|
||||
function getAvailableLangs(locales) {
|
||||
var result = {};
|
||||
_.each(_.keys(locales), function(langcode) {
|
||||
result[langcode] = languages.getLanguageInfo(langcode);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
// returns locale index that will be served in /locales.json
|
||||
var generateLocaleIndex = function (locales) {
|
||||
var result = _.clone(locales) // keep English strings
|
||||
_.each(_.keys(locales), function(langcode) {
|
||||
if (langcode != 'en') result[langcode]='locales/'+langcode+'.json';
|
||||
});
|
||||
return JSON.stringify(result);
|
||||
}
|
||||
|
||||
// build locale index
|
||||
localeIndex += '['+locale+']\r\n@import url(locales/'+locale+'.ini)\r\n'
|
||||
|
||||
// add info language {name, nativeName, direction} to availableLangs
|
||||
exports.availableLangs[locale]=languages.getLanguageInfo(locale);
|
||||
})
|
||||
})
|
||||
|
||||
exports.expressCreateServer = function(n, args) {
|
||||
|
||||
args.app.use('/locales', express.static(localesPath));
|
||||
//regenerate locales on server restart
|
||||
var locales = getAllLocales();
|
||||
var localeIndex = generateLocaleIndex(locales);
|
||||
exports.availableLangs = getAvailableLangs(locales);
|
||||
|
||||
args.app.get ('/locales/:locale', function(req, res) {
|
||||
//works with /locale/en and /locale/en.json requests
|
||||
var locale = req.params.locale.split('.')[0];
|
||||
if (exports.availableLangs.hasOwnProperty(locale)) {
|
||||
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
res.send('{"'+locale+'":'+JSON.stringify(locales[locale])+'}');
|
||||
} else {
|
||||
res.send(404, 'Language not available');
|
||||
}
|
||||
})
|
||||
|
||||
args.app.get('/locales.ini', function(req, res) {
|
||||
args.app.get('/locales.json', function(req, res) {
|
||||
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
res.send(localeIndex);
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ exports.title = "Etherpad Lite";
|
|||
* The app favicon fully specified url, visible e.g. in the browser window
|
||||
*/
|
||||
exports.favicon = "favicon.ico";
|
||||
exports.faviconPad = "../" + exports.favicon;
|
||||
exports.faviconTimeslider = "../../" + exports.favicon;
|
||||
|
||||
/**
|
||||
* The IP ep-lite should listen to
|
||||
|
@ -48,6 +50,18 @@ exports.ip = "0.0.0.0";
|
|||
* The Port ep-lite should listen to
|
||||
*/
|
||||
exports.port = process.env.PORT || 9001;
|
||||
|
||||
/**
|
||||
* The SSL signed server key and the Certificate Authority's own certificate
|
||||
* default case: ep-lite does *not* use SSL. A signed server key is not required in this case.
|
||||
*/
|
||||
exports.ssl = false;
|
||||
|
||||
/**
|
||||
* socket.io transport methods
|
||||
**/
|
||||
exports.socketTransportProtocols = ['xhr-polling', 'jsonp-polling', 'htmlfile'];
|
||||
|
||||
/*
|
||||
* The Type of the database
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name" : "ep_etherpad-lite",
|
||||
"description" : "A Etherpad based on node.js",
|
||||
"homepage" : "https://github.com/Pita/etherpad-lite",
|
||||
"homepage" : "https://github.com/ether/etherpad-lite",
|
||||
"keywords" : ["etherpad", "realtime", "collaborative", "editor"],
|
||||
"author" : "Peter 'Pita' Martischka <petermartischka@googlemail.com> - Primary Technology Ltd",
|
||||
"contributors" : [
|
||||
|
@ -11,32 +11,32 @@
|
|||
{ "name": "Marcel Klehr" }
|
||||
],
|
||||
"dependencies" : {
|
||||
"yajsml" : "1.1.6",
|
||||
"request" : "2.9.100",
|
||||
"require-kernel" : "1.0.5",
|
||||
"resolve" : "0.2.x",
|
||||
"socket.io" : "0.9.x",
|
||||
"ueberDB" : "0.1.8",
|
||||
"async" : "0.1.x",
|
||||
"express" : "3.x",
|
||||
"connect" : "2.4.x",
|
||||
"clean-css" : "0.3.2",
|
||||
"uglify-js" : "1.2.5",
|
||||
"formidable" : "1.0.9",
|
||||
"log4js" : "0.5.x",
|
||||
"jsdom-nocontextifiy" : "0.2.10",
|
||||
"async-stacktrace" : "0.0.2",
|
||||
"npm" : "1.1.x",
|
||||
"npm-registry-client" : "0.2.10",
|
||||
"ejs" : "0.6.1",
|
||||
"graceful-fs" : "1.1.5",
|
||||
"slide" : "1.1.3",
|
||||
"semver" : "1.0.13",
|
||||
"security" : "1.0.0",
|
||||
"tinycon" : "0.0.1",
|
||||
"underscore" : "1.3.1",
|
||||
"unorm" : "1.0.0",
|
||||
"languages" : "0.1.1"
|
||||
"yajsml" : "1.1.6",
|
||||
"request" : "2.9.100",
|
||||
"require-kernel" : "1.0.5",
|
||||
"resolve" : "0.2.x",
|
||||
"socket.io" : "0.9.x",
|
||||
"ueberDB" : "0.1.8",
|
||||
"async" : "0.1.x",
|
||||
"express" : "3.x",
|
||||
"connect" : "2.4.x",
|
||||
"clean-css" : "0.3.2",
|
||||
"uglify-js" : "1.2.5",
|
||||
"formidable" : "1.0.9",
|
||||
"log4js" : "0.5.x",
|
||||
"jsdom-nocontextifiy" : "0.2.10",
|
||||
"async-stacktrace" : "0.0.2",
|
||||
"npm" : "1.1.x",
|
||||
"npm-registry-client" : "0.2.10",
|
||||
"ejs" : "0.6.1",
|
||||
"graceful-fs" : "1.1.5",
|
||||
"slide" : "1.1.3",
|
||||
"semver" : "1.0.13",
|
||||
"security" : "1.0.0",
|
||||
"tinycon" : "0.0.1",
|
||||
"underscore" : "1.3.1",
|
||||
"unorm" : "1.0.0",
|
||||
"languages4translatewiki" : "0.1.3"
|
||||
},
|
||||
"bin": { "etherpad-lite": "./node/server.js" },
|
||||
"devDependencies": {
|
||||
|
@ -46,5 +46,5 @@
|
|||
"engines" : { "node" : ">=0.6.0",
|
||||
"npm" : ">=1.0"
|
||||
},
|
||||
"version" : "1.2.1"
|
||||
"version" : "1.2.2"
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ iframe {
|
|||
.readonly .acl-write {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#users {
|
||||
background: #f7f7f7;
|
||||
background: -webkit-linear-gradient( #F7F7F7,#EEE);
|
||||
|
@ -190,6 +191,19 @@ a img {
|
|||
height: 30px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#editorloadingbox .passForm{
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
#editorloadingbox input{
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
#editorloadingbox button{
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
#editorcontainerbox {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
|
@ -571,15 +585,20 @@ table#otheruserstable {
|
|||
#exportdokuwiki {
|
||||
background-position: 0px -459px
|
||||
}
|
||||
#importstatusball {
|
||||
display: none
|
||||
|
||||
/* hidden element */
|
||||
#importstatusball,
|
||||
#importarrow,
|
||||
#importmessagesuccess,
|
||||
#importmessageabiword {
|
||||
display: none;
|
||||
}
|
||||
#importarrow {
|
||||
display: none
|
||||
}
|
||||
#importmessagesuccess {
|
||||
display: none
|
||||
|
||||
#importmessageabiword {
|
||||
color: #900;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
#importsubmitinput {
|
||||
height: 25px;
|
||||
width: 85px;
|
||||
|
@ -755,7 +774,7 @@ input[type=checkbox] {
|
|||
border-radius: 3px;
|
||||
border: 1px solid #ccc;
|
||||
outline: none;
|
||||
min-width: 105px;
|
||||
width: 120px;
|
||||
}
|
||||
.column {
|
||||
float: left;
|
||||
|
@ -878,3 +897,15 @@ input[type=checkbox] {
|
|||
line-height: 24px
|
||||
}
|
||||
}
|
||||
|
||||
#passwordRequired{
|
||||
display:none;
|
||||
}
|
||||
|
||||
#permissionDenied{
|
||||
display:none;
|
||||
}
|
||||
|
||||
#wrongPassword{
|
||||
display:none;
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@
|
|||
background-position: -29px -22px;
|
||||
right: 5px;
|
||||
top: 20px;
|
||||
width: 29px;
|
||||
width: 30px;
|
||||
}
|
||||
#timeslider .star {
|
||||
background-image: url(../../static/img/star.png);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* 90% of the code is still like in the original Etherpad
|
||||
* Look at https://github.com/ether/pad/blob/master/infrastructure/ace/www/easysync2.js
|
||||
* You can find a explanation what a attribute pool is here:
|
||||
* https://github.com/Pita/etherpad-lite/blob/master/doc/easysync/easysync-notes.txt
|
||||
* https://github.com/ether/etherpad-lite/blob/master/doc/easysync/easysync-notes.txt
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
@ -166,10 +166,12 @@ function Ace2Inner(){
|
|||
}
|
||||
|
||||
var dynamicCSS = null;
|
||||
var parentDynamicCSS = null;
|
||||
|
||||
function initDynamicCSS()
|
||||
{
|
||||
dynamicCSS = makeCSSManager("dynamicsyntax");
|
||||
parentDynamicCSS = makeCSSManager("dynamicsyntax", true);
|
||||
}
|
||||
|
||||
var changesetTracker = makeChangesetTracker(scheduler, rep.apool, {
|
||||
|
@ -217,6 +219,7 @@ function Ace2Inner(){
|
|||
if (dynamicCSS)
|
||||
{
|
||||
dynamicCSS.removeSelectorStyle(getAuthorColorClassSelector(getAuthorClassName(author)));
|
||||
parentDynamicCSS.removeSelectorStyle(getAuthorColorClassSelector(getAuthorClassName(author)));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -234,18 +237,23 @@ function Ace2Inner(){
|
|||
|
||||
var authorStyle = dynamicCSS.selectorStyle(getAuthorColorClassSelector(
|
||||
getAuthorClassName(author)));
|
||||
var parentAuthorStyle = parentDynamicCSS.selectorStyle(getAuthorColorClassSelector(
|
||||
getAuthorClassName(author)));
|
||||
var anchorStyle = dynamicCSS.selectorStyle(getAuthorColorClassSelector(
|
||||
getAuthorClassName(author))+' > a')
|
||||
|
||||
// author color
|
||||
authorStyle.backgroundColor = bgcolor;
|
||||
parentAuthorStyle.backgroundColor = bgcolor;
|
||||
|
||||
// text contrast
|
||||
if(colorutils.luminosity(colorutils.css2triple(bgcolor)) < 0.5)
|
||||
{
|
||||
authorStyle.color = '#ffffff';
|
||||
parentAuthorStyle.color = '#ffffff';
|
||||
}else{
|
||||
authorStyle.color = null;
|
||||
parentAuthorStyle.color = null;
|
||||
}
|
||||
|
||||
// anchor text contrast
|
||||
|
@ -333,14 +341,6 @@ function Ace2Inner(){
|
|||
return colorutils.triple2css(color);
|
||||
}
|
||||
|
||||
function doAlert(str)
|
||||
{
|
||||
scheduler.setTimeout(function()
|
||||
{
|
||||
alert(str);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
editorInfo.ace_getRep = function()
|
||||
{
|
||||
return rep;
|
||||
|
@ -1624,7 +1624,7 @@ function Ace2Inner(){
|
|||
|
||||
if (linesWrapped > 0)
|
||||
{
|
||||
doAlert("Editor warning: " + linesWrapped + " long line" + (linesWrapped == 1 ? " was" : "s were") + " hard-wrapped into " + ccData.numLinesAfter + " lines.");
|
||||
// console.log("Editor warning: " + linesWrapped + " long line" + (linesWrapped == 1 ? " was" : "s were") + " hard-wrapped into " + ccData.numLinesAfter + " lines.");
|
||||
}
|
||||
|
||||
if (ss[0] >= 0) selStart = [ss[0] + a + netNumLinesChangeSoFar, ss[1]];
|
||||
|
@ -3266,7 +3266,7 @@ function Ace2Inner(){
|
|||
}
|
||||
}
|
||||
//hide the dropdownso
|
||||
if(window.parent.parent.padeditbar){ // required in case its in an iframe should probably use parent.. See Issue 327 https://github.com/Pita/etherpad-lite/issues/327
|
||||
if(window.parent.parent.padeditbar){ // required in case its in an iframe should probably use parent.. See Issue 327 https://github.com/ether/etherpad-lite/issues/327
|
||||
window.parent.parent.padeditbar.toggleDropDown("none");
|
||||
}
|
||||
}
|
||||
|
@ -3569,7 +3569,6 @@ function Ace2Inner(){
|
|||
|
||||
inCallStackIfNecessary("handleKeyEvent", function()
|
||||
{
|
||||
|
||||
if (type == "keypress" || (isTypeForSpecialKey && keyCode == 13 /*return*/ ))
|
||||
{
|
||||
// in IE, special keys don't send keypress, the keydown does the action
|
||||
|
@ -3583,7 +3582,6 @@ function Ace2Inner(){
|
|||
{
|
||||
outsideKeyDown(evt);
|
||||
}
|
||||
|
||||
if (!stopped)
|
||||
{
|
||||
var specialHandledInHook = hooks.callAll('aceKeyEvent', {
|
||||
|
@ -3622,6 +3620,12 @@ function Ace2Inner(){
|
|||
}, 0);
|
||||
specialHandled = true;
|
||||
}
|
||||
if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "s" && (evt.metaKey || evt.ctrlKey)) /* Do a saved revision on ctrl S */
|
||||
{
|
||||
evt.preventDefault();
|
||||
parent.parent.pad.collabClient.sendMessage({"type":"SAVE_REVISION"}); /* The parent.parent part of this is BAD and I feel bad.. It may break something */
|
||||
specialHandled = true;
|
||||
}
|
||||
if ((!specialHandled) && isTypeForSpecialKey && keyCode == 9 && !(evt.metaKey || evt.ctrlKey))
|
||||
{
|
||||
// tab
|
||||
|
|
|
@ -113,10 +113,15 @@ $(document).ready(function () {
|
|||
for (plugin_name in data.results) {
|
||||
var plugin = data.results[plugin_name];
|
||||
var row = widget.find(".template tr").clone();
|
||||
var version = '0.0.0';
|
||||
// hack to access "versions" property of the npm package object
|
||||
for (version in data.results[plugin_name].versions) break;
|
||||
|
||||
for (attr in plugin) {
|
||||
row.find("." + attr).html(plugin[attr]);
|
||||
}
|
||||
row.find(".version").html(version);
|
||||
|
||||
widget.find(".results").append(row);
|
||||
}
|
||||
|
||||
|
|
|
@ -304,7 +304,14 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
|||
var hours = zpad(date.getHours(), 2);
|
||||
var minutes = zpad(date.getMinutes(), 2);
|
||||
var seconds = zpad(date.getSeconds(), 2);
|
||||
return ([month, '/', day, '/', year, ' ', hours, ':', minutes, ':', seconds].join(""));
|
||||
return (html10n.get("timeslider.dateformat", {
|
||||
"day": day,
|
||||
"month": month,
|
||||
"year": year,
|
||||
"hours": hours,
|
||||
"minutes": minutes,
|
||||
"seconds": seconds
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
|
@ -313,7 +320,24 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
|
|||
|
||||
$('#timer').html(dateFormat());
|
||||
|
||||
var revisionDate = ["Saved", ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"][date.getMonth()], date.getDate() + ",", date.getFullYear()].join(" ")
|
||||
var revisionDate = html10n.get("timeslider.saved", {
|
||||
"day": date.getDate(),
|
||||
"month": [
|
||||
html10n.get("timeslider.month.january"),
|
||||
html10n.get("timeslider.month.february"),
|
||||
html10n.get("timeslider.month.march"),
|
||||
html10n.get("timeslider.month.april"),
|
||||
html10n.get("timeslider.month.may"),
|
||||
html10n.get("timeslider.month.june"),
|
||||
html10n.get("timeslider.month.july"),
|
||||
html10n.get("timeslider.month.august"),
|
||||
html10n.get("timeslider.month.september"),
|
||||
html10n.get("timeslider.month.october"),
|
||||
html10n.get("timeslider.month.november"),
|
||||
html10n.get("timeslider.month.december")
|
||||
][date.getMonth()],
|
||||
"year": date.getFullYear()
|
||||
});
|
||||
$('#revision_date').html(revisionDate)
|
||||
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
|||
{
|
||||
$(this).attr('href', $(this).attr('thref').replace("%revision%", newpos));
|
||||
});
|
||||
$("#revision_label").html("Version " + newpos);
|
||||
$("#revision_label").html(html10n.get("timeslider.version", { "version": newpos}));
|
||||
|
||||
if (newpos == 0)
|
||||
{
|
||||
|
@ -215,7 +215,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
|||
}
|
||||
if (authors.length == 0)
|
||||
{
|
||||
authorsList.append("No Authors");
|
||||
authorsList.append(html10n.get("timeslider.toolbar.authorsList"));
|
||||
}
|
||||
|
||||
fixPadHeight();
|
||||
|
@ -346,7 +346,7 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
|||
var newloc = self.currentLoc + (evt2.clientX - self.startLoc);
|
||||
if (newloc < 0) newloc = 0;
|
||||
if (newloc > ($("#ui-slider-bar").width() - 2)) newloc = ($("#ui-slider-bar").width() - 2);
|
||||
$("#revision_label").html("Version " + Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2)));
|
||||
$("#revision_label").html(html10n.get("timeslider.version", { "version": Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2))}));
|
||||
$(self).css('left', newloc);
|
||||
if (getSliderPosition() != Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2))) _callSliderCallbacks(Math.floor(newloc * sliderLength / ($("#ui-slider-bar").width() - 2)))
|
||||
});
|
||||
|
|
|
@ -109,7 +109,7 @@ var chat = (function()
|
|||
}
|
||||
/* End of new action */
|
||||
|
||||
var authorName = msg.userName == null ? "unnamed" : padutils.escapeHtml(msg.userName);
|
||||
var authorName = msg.userName == null ? _('pad.userlist.unnamed') : padutils.escapeHtml(msg.userName);
|
||||
|
||||
var html = "<p class='" + authorClass + "'><b>" + authorName + ":</b><span class='time " + authorClass + "'>" + timeStr + "</span> " + text + "</p>";
|
||||
$("#chattext").append(html);
|
||||
|
|
|
@ -20,12 +20,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
function makeCSSManager(emptyStylesheetTitle)
|
||||
function makeCSSManager(emptyStylesheetTitle, parentCss)
|
||||
{
|
||||
|
||||
function getSheetByTitle(title)
|
||||
{
|
||||
var allSheets = document.styleSheets;
|
||||
if (parentCss) var allSheets = window.parent.parent.document.styleSheets;
|
||||
else var allSheets = document.styleSheets;
|
||||
|
||||
for (var i = 0; i < allSheets.length; i++)
|
||||
{
|
||||
|
@ -38,7 +39,7 @@ function makeCSSManager(emptyStylesheetTitle)
|
|||
return null;
|
||||
}
|
||||
|
||||
var browserSheet = getSheetByTitle(emptyStylesheetTitle);
|
||||
var browserSheet = getSheetByTitle(emptyStylesheetTitle, parentCss);
|
||||
|
||||
function browserRules()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,874 @@
|
|||
/**
|
||||
* Copyright (c) 2012 Marcel Klehr
|
||||
* Copyright (c) 2011-2012 Fabien Cazenave, Mozilla
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
window.html10n = (function(window, document, undefined) {
|
||||
var consoleLog = console? console.log : function() {}
|
||||
, consoleWarn = console? console.warn : function() {}
|
||||
|
||||
/**
|
||||
* MicroEvent - to make any js object an event emitter (server or browser)
|
||||
*/
|
||||
|
||||
var MicroEvent = function(){}
|
||||
MicroEvent.prototype = {
|
||||
bind : function(event, fct){
|
||||
this._events = this._events || {};
|
||||
this._events[event] = this._events[event] || [];
|
||||
this._events[event].push(fct);
|
||||
},
|
||||
unbind : function(event, fct){
|
||||
this._events = this._events || {};
|
||||
if( event in this._events === false ) return;
|
||||
this._events[event].splice(this._events[event].indexOf(fct), 1);
|
||||
},
|
||||
trigger : function(event /* , args... */){
|
||||
this._events = this._events || {};
|
||||
if( event in this._events === false ) return;
|
||||
for(var i = 0; i < this._events[event].length; i++){
|
||||
this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1))
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* mixin will delegate all MicroEvent.js function in the destination object
|
||||
* @param {Object} the object which will support MicroEvent
|
||||
*/
|
||||
MicroEvent.mixin = function(destObject){
|
||||
var props = ['bind', 'unbind', 'trigger'];
|
||||
if(!destObject) return;
|
||||
for(var i = 0; i < props.length; i ++){
|
||||
destObject[props[i]] = MicroEvent.prototype[props[i]];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loader
|
||||
* The loader is responsible for loading
|
||||
* and caching all necessary resources
|
||||
*/
|
||||
function Loader(resources) {
|
||||
this.resources = resources
|
||||
this.cache = {} // file => contents
|
||||
this.langs = {} // lang => strings
|
||||
}
|
||||
|
||||
Loader.prototype.load = function(lang, cb) {
|
||||
if(this.langs[lang]) return cb()
|
||||
|
||||
if (this.resources.length > 0) {
|
||||
var reqs = 0;
|
||||
for (var i=0, n=this.resources.length; i < n; i++) {
|
||||
this.fetch(this.resources[i], lang, function(e) {
|
||||
reqs++;
|
||||
if(e) return setTimeout(function(){ throw e }, 0)
|
||||
|
||||
if (reqs < n) return;// Call back once all reqs are completed
|
||||
cb && cb()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader.prototype.fetch = function(href, lang, cb) {
|
||||
var that = this
|
||||
|
||||
if (this.cache[href]) {
|
||||
this.parse(lang, href, this.cache[href], cb)
|
||||
return;
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest()
|
||||
xhr.open('GET', href, /*async: */true)
|
||||
if (xhr.overrideMimeType) {
|
||||
xhr.overrideMimeType('application/json; charset=utf-8');
|
||||
}
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState == 4) {
|
||||
if (xhr.status == 200 || xhr.status === 0) {
|
||||
var data = JSON.parse(xhr.responseText)
|
||||
that.cache[href] = data
|
||||
// Pass on the contents for parsing
|
||||
that.parse(lang, href, data, cb)
|
||||
} else {
|
||||
cb(new Error('Failed to load '+href))
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
Loader.prototype.parse = function(lang, currHref, data, cb) {
|
||||
if ('object' != typeof data) {
|
||||
cb(new Error('A file couldn\'t be parsed as json.'))
|
||||
return
|
||||
}
|
||||
|
||||
if (!data[lang]) lang = lang.substr(0, lang.indexOf('-') == -1? lang.length : lang.indexOf('-'))
|
||||
if (!data[lang]) {
|
||||
cb(new Error('Couldn\'t find translations for '+lang))
|
||||
return
|
||||
}
|
||||
|
||||
if ('string' == typeof data[lang]) {
|
||||
// Import rule
|
||||
|
||||
// absolute path
|
||||
var importUrl = data[lang]
|
||||
|
||||
// relative path
|
||||
if(data[lang].indexOf("http") != 0 && data[lang].indexOf("/") != 0) {
|
||||
importUrl = currHref+"/../"+data[lang]
|
||||
}
|
||||
|
||||
this.fetch(importUrl, lang, cb)
|
||||
return
|
||||
}
|
||||
|
||||
if ('object' != typeof data[lang]) {
|
||||
cb(new Error('Translations should be specified as JSON objects!'))
|
||||
return
|
||||
}
|
||||
|
||||
this.langs[lang] = data[lang]
|
||||
// TODO: Also store accompanying langs
|
||||
cb()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The html10n object
|
||||
*/
|
||||
var html10n =
|
||||
{ language : null
|
||||
}
|
||||
MicroEvent.mixin(html10n)
|
||||
|
||||
html10n.macros = {}
|
||||
|
||||
html10n.rtl = ["ar","dv","fa","ha","he","ks","ku","ps","ur","yi"]
|
||||
|
||||
/**
|
||||
* Get rules for plural forms (shared with JetPack), see:
|
||||
* http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
|
||||
* https://github.com/mozilla/addon-sdk/blob/master/python-lib/plural-rules-generator.p
|
||||
*
|
||||
* @param {string} lang
|
||||
* locale (language) used.
|
||||
*
|
||||
* @return {Function}
|
||||
* returns a function that gives the plural form name for a given integer:
|
||||
* var fun = getPluralRules('en');
|
||||
* fun(1) -> 'one'
|
||||
* fun(0) -> 'other'
|
||||
* fun(1000) -> 'other'.
|
||||
*/
|
||||
function getPluralRules(lang) {
|
||||
var locales2rules = {
|
||||
'af': 3,
|
||||
'ak': 4,
|
||||
'am': 4,
|
||||
'ar': 1,
|
||||
'asa': 3,
|
||||
'az': 0,
|
||||
'be': 11,
|
||||
'bem': 3,
|
||||
'bez': 3,
|
||||
'bg': 3,
|
||||
'bh': 4,
|
||||
'bm': 0,
|
||||
'bn': 3,
|
||||
'bo': 0,
|
||||
'br': 20,
|
||||
'brx': 3,
|
||||
'bs': 11,
|
||||
'ca': 3,
|
||||
'cgg': 3,
|
||||
'chr': 3,
|
||||
'cs': 12,
|
||||
'cy': 17,
|
||||
'da': 3,
|
||||
'de': 3,
|
||||
'dv': 3,
|
||||
'dz': 0,
|
||||
'ee': 3,
|
||||
'el': 3,
|
||||
'en': 3,
|
||||
'eo': 3,
|
||||
'es': 3,
|
||||
'et': 3,
|
||||
'eu': 3,
|
||||
'fa': 0,
|
||||
'ff': 5,
|
||||
'fi': 3,
|
||||
'fil': 4,
|
||||
'fo': 3,
|
||||
'fr': 5,
|
||||
'fur': 3,
|
||||
'fy': 3,
|
||||
'ga': 8,
|
||||
'gd': 24,
|
||||
'gl': 3,
|
||||
'gsw': 3,
|
||||
'gu': 3,
|
||||
'guw': 4,
|
||||
'gv': 23,
|
||||
'ha': 3,
|
||||
'haw': 3,
|
||||
'he': 2,
|
||||
'hi': 4,
|
||||
'hr': 11,
|
||||
'hu': 0,
|
||||
'id': 0,
|
||||
'ig': 0,
|
||||
'ii': 0,
|
||||
'is': 3,
|
||||
'it': 3,
|
||||
'iu': 7,
|
||||
'ja': 0,
|
||||
'jmc': 3,
|
||||
'jv': 0,
|
||||
'ka': 0,
|
||||
'kab': 5,
|
||||
'kaj': 3,
|
||||
'kcg': 3,
|
||||
'kde': 0,
|
||||
'kea': 0,
|
||||
'kk': 3,
|
||||
'kl': 3,
|
||||
'km': 0,
|
||||
'kn': 0,
|
||||
'ko': 0,
|
||||
'ksb': 3,
|
||||
'ksh': 21,
|
||||
'ku': 3,
|
||||
'kw': 7,
|
||||
'lag': 18,
|
||||
'lb': 3,
|
||||
'lg': 3,
|
||||
'ln': 4,
|
||||
'lo': 0,
|
||||
'lt': 10,
|
||||
'lv': 6,
|
||||
'mas': 3,
|
||||
'mg': 4,
|
||||
'mk': 16,
|
||||
'ml': 3,
|
||||
'mn': 3,
|
||||
'mo': 9,
|
||||
'mr': 3,
|
||||
'ms': 0,
|
||||
'mt': 15,
|
||||
'my': 0,
|
||||
'nah': 3,
|
||||
'naq': 7,
|
||||
'nb': 3,
|
||||
'nd': 3,
|
||||
'ne': 3,
|
||||
'nl': 3,
|
||||
'nn': 3,
|
||||
'no': 3,
|
||||
'nr': 3,
|
||||
'nso': 4,
|
||||
'ny': 3,
|
||||
'nyn': 3,
|
||||
'om': 3,
|
||||
'or': 3,
|
||||
'pa': 3,
|
||||
'pap': 3,
|
||||
'pl': 13,
|
||||
'ps': 3,
|
||||
'pt': 3,
|
||||
'rm': 3,
|
||||
'ro': 9,
|
||||
'rof': 3,
|
||||
'ru': 11,
|
||||
'rwk': 3,
|
||||
'sah': 0,
|
||||
'saq': 3,
|
||||
'se': 7,
|
||||
'seh': 3,
|
||||
'ses': 0,
|
||||
'sg': 0,
|
||||
'sh': 11,
|
||||
'shi': 19,
|
||||
'sk': 12,
|
||||
'sl': 14,
|
||||
'sma': 7,
|
||||
'smi': 7,
|
||||
'smj': 7,
|
||||
'smn': 7,
|
||||
'sms': 7,
|
||||
'sn': 3,
|
||||
'so': 3,
|
||||
'sq': 3,
|
||||
'sr': 11,
|
||||
'ss': 3,
|
||||
'ssy': 3,
|
||||
'st': 3,
|
||||
'sv': 3,
|
||||
'sw': 3,
|
||||
'syr': 3,
|
||||
'ta': 3,
|
||||
'te': 3,
|
||||
'teo': 3,
|
||||
'th': 0,
|
||||
'ti': 4,
|
||||
'tig': 3,
|
||||
'tk': 3,
|
||||
'tl': 4,
|
||||
'tn': 3,
|
||||
'to': 0,
|
||||
'tr': 0,
|
||||
'ts': 3,
|
||||
'tzm': 22,
|
||||
'uk': 11,
|
||||
'ur': 3,
|
||||
've': 3,
|
||||
'vi': 0,
|
||||
'vun': 3,
|
||||
'wa': 4,
|
||||
'wae': 3,
|
||||
'wo': 0,
|
||||
'xh': 3,
|
||||
'xog': 3,
|
||||
'yo': 0,
|
||||
'zh': 0,
|
||||
'zu': 3
|
||||
};
|
||||
|
||||
// utility functions for plural rules methods
|
||||
function isIn(n, list) {
|
||||
return list.indexOf(n) !== -1;
|
||||
}
|
||||
function isBetween(n, start, end) {
|
||||
return start <= n && n <= end;
|
||||
}
|
||||
|
||||
// list of all plural rules methods:
|
||||
// map an integer to the plural form name to use
|
||||
var pluralRules = {
|
||||
'0': function(n) {
|
||||
return 'other';
|
||||
},
|
||||
'1': function(n) {
|
||||
if ((isBetween((n % 100), 3, 10)))
|
||||
return 'few';
|
||||
if (n === 0)
|
||||
return 'zero';
|
||||
if ((isBetween((n % 100), 11, 99)))
|
||||
return 'many';
|
||||
if (n == 2)
|
||||
return 'two';
|
||||
if (n == 1)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'2': function(n) {
|
||||
if (n !== 0 && (n % 10) === 0)
|
||||
return 'many';
|
||||
if (n == 2)
|
||||
return 'two';
|
||||
if (n == 1)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'3': function(n) {
|
||||
if (n == 1)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'4': function(n) {
|
||||
if ((isBetween(n, 0, 1)))
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'5': function(n) {
|
||||
if ((isBetween(n, 0, 2)) && n != 2)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'6': function(n) {
|
||||
if (n === 0)
|
||||
return 'zero';
|
||||
if ((n % 10) == 1 && (n % 100) != 11)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'7': function(n) {
|
||||
if (n == 2)
|
||||
return 'two';
|
||||
if (n == 1)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'8': function(n) {
|
||||
if ((isBetween(n, 3, 6)))
|
||||
return 'few';
|
||||
if ((isBetween(n, 7, 10)))
|
||||
return 'many';
|
||||
if (n == 2)
|
||||
return 'two';
|
||||
if (n == 1)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'9': function(n) {
|
||||
if (n === 0 || n != 1 && (isBetween((n % 100), 1, 19)))
|
||||
return 'few';
|
||||
if (n == 1)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'10': function(n) {
|
||||
if ((isBetween((n % 10), 2, 9)) && !(isBetween((n % 100), 11, 19)))
|
||||
return 'few';
|
||||
if ((n % 10) == 1 && !(isBetween((n % 100), 11, 19)))
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'11': function(n) {
|
||||
if ((isBetween((n % 10), 2, 4)) && !(isBetween((n % 100), 12, 14)))
|
||||
return 'few';
|
||||
if ((n % 10) === 0 ||
|
||||
(isBetween((n % 10), 5, 9)) ||
|
||||
(isBetween((n % 100), 11, 14)))
|
||||
return 'many';
|
||||
if ((n % 10) == 1 && (n % 100) != 11)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'12': function(n) {
|
||||
if ((isBetween(n, 2, 4)))
|
||||
return 'few';
|
||||
if (n == 1)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'13': function(n) {
|
||||
if ((isBetween((n % 10), 2, 4)) && !(isBetween((n % 100), 12, 14)))
|
||||
return 'few';
|
||||
if (n != 1 && (isBetween((n % 10), 0, 1)) ||
|
||||
(isBetween((n % 10), 5, 9)) ||
|
||||
(isBetween((n % 100), 12, 14)))
|
||||
return 'many';
|
||||
if (n == 1)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'14': function(n) {
|
||||
if ((isBetween((n % 100), 3, 4)))
|
||||
return 'few';
|
||||
if ((n % 100) == 2)
|
||||
return 'two';
|
||||
if ((n % 100) == 1)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'15': function(n) {
|
||||
if (n === 0 || (isBetween((n % 100), 2, 10)))
|
||||
return 'few';
|
||||
if ((isBetween((n % 100), 11, 19)))
|
||||
return 'many';
|
||||
if (n == 1)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'16': function(n) {
|
||||
if ((n % 10) == 1 && n != 11)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'17': function(n) {
|
||||
if (n == 3)
|
||||
return 'few';
|
||||
if (n === 0)
|
||||
return 'zero';
|
||||
if (n == 6)
|
||||
return 'many';
|
||||
if (n == 2)
|
||||
return 'two';
|
||||
if (n == 1)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'18': function(n) {
|
||||
if (n === 0)
|
||||
return 'zero';
|
||||
if ((isBetween(n, 0, 2)) && n !== 0 && n != 2)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'19': function(n) {
|
||||
if ((isBetween(n, 2, 10)))
|
||||
return 'few';
|
||||
if ((isBetween(n, 0, 1)))
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'20': function(n) {
|
||||
if ((isBetween((n % 10), 3, 4) || ((n % 10) == 9)) && !(
|
||||
isBetween((n % 100), 10, 19) ||
|
||||
isBetween((n % 100), 70, 79) ||
|
||||
isBetween((n % 100), 90, 99)
|
||||
))
|
||||
return 'few';
|
||||
if ((n % 1000000) === 0 && n !== 0)
|
||||
return 'many';
|
||||
if ((n % 10) == 2 && !isIn((n % 100), [12, 72, 92]))
|
||||
return 'two';
|
||||
if ((n % 10) == 1 && !isIn((n % 100), [11, 71, 91]))
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'21': function(n) {
|
||||
if (n === 0)
|
||||
return 'zero';
|
||||
if (n == 1)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'22': function(n) {
|
||||
if ((isBetween(n, 0, 1)) || (isBetween(n, 11, 99)))
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'23': function(n) {
|
||||
if ((isBetween((n % 10), 1, 2)) || (n % 20) === 0)
|
||||
return 'one';
|
||||
return 'other';
|
||||
},
|
||||
'24': function(n) {
|
||||
if ((isBetween(n, 3, 10) || isBetween(n, 13, 19)))
|
||||
return 'few';
|
||||
if (isIn(n, [2, 12]))
|
||||
return 'two';
|
||||
if (isIn(n, [1, 11]))
|
||||
return 'one';
|
||||
return 'other';
|
||||
}
|
||||
};
|
||||
|
||||
// return a function that gives the plural form name for a given integer
|
||||
var index = locales2rules[lang.replace(/-.*$/, '')];
|
||||
if (!(index in pluralRules)) {
|
||||
consoleWarn('plural form unknown for [' + lang + ']');
|
||||
return function() { return 'other'; };
|
||||
}
|
||||
return pluralRules[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* pre-defined 'plural' macro
|
||||
*/
|
||||
html10n.macros.plural = function(translations, key, str, param) {
|
||||
var n = parseFloat(param);
|
||||
if (isNaN(n))
|
||||
return str;
|
||||
|
||||
// initialize _pluralRules
|
||||
if (!this._pluralRules)
|
||||
this._pluralRules = getPluralRules(html10n.language);
|
||||
var index = '[' + this._pluralRules(n) + ']';
|
||||
|
||||
// try to find a [zero|one|two] key if it's defined
|
||||
if (n === 0 && (key + '[zero]') in translations) {
|
||||
str = translations[key + '[zero]'];
|
||||
} else if (n == 1 && (key + '[one]') in translations) {
|
||||
str = translations[key + '[one]'];
|
||||
} else if (n == 2 && (key + '[two]') in translations) {
|
||||
str = translations[key + '[two]'];
|
||||
} else if ((key + index) in translations) {
|
||||
str = translations[key + index][prop];
|
||||
}
|
||||
|
||||
return str;
|
||||
};
|
||||
|
||||
/**
|
||||
* Localize a document
|
||||
* @param langs An array of lang codes defining fallbacks
|
||||
*/
|
||||
html10n.localize = function(langs) {
|
||||
var that = this
|
||||
// if only one string => create an array
|
||||
if ('string' == typeof langs) langs = [langs]
|
||||
|
||||
this.build(langs, function(er, translations) {
|
||||
html10n.translations = translations
|
||||
html10n.translateElement(translations)
|
||||
that.trigger('localized')
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers the translation process
|
||||
* for an element
|
||||
* @param translations A hash of all translation strings
|
||||
* @param element A DOM element, if omitted, the document element will be used
|
||||
*/
|
||||
html10n.translateElement = function(translations, element) {
|
||||
element = element || document.documentElement
|
||||
|
||||
var children = element? getTranslatableChildren(element) : document.childNodes;
|
||||
for (var i=0, n=children.length; i < n; i++) {
|
||||
this.translateNode(translations, children[i])
|
||||
}
|
||||
|
||||
// translate element itself if necessary
|
||||
this.translateNode(translations, element)
|
||||
}
|
||||
|
||||
function asyncForEach(list, iterator, cb) {
|
||||
var i = 0
|
||||
, n = list.length
|
||||
iterator(list[i], i, function each(err) {
|
||||
if(err) consoleLog(err)
|
||||
i++
|
||||
if (i < n) return iterator(list[i],i, each);
|
||||
cb()
|
||||
})
|
||||
}
|
||||
|
||||
function getTranslatableChildren(element) {
|
||||
if(!document.querySelectorAll) {
|
||||
if (!element) return []
|
||||
var nodes = element.getElementsByTagName('*')
|
||||
, l10nElements = []
|
||||
for (var i=0, n=nodes.length; i < n; i++) {
|
||||
if (nodes[i].getAttribute('data-l10n-id'))
|
||||
l10nElements.push(nodes[i]);
|
||||
}
|
||||
return l10nElements
|
||||
}
|
||||
return element.querySelectorAll('*[data-l10n-id]')
|
||||
}
|
||||
|
||||
html10n.get = function(id, args) {
|
||||
var translations = html10n.translations
|
||||
if(!translations) return consoleWarn('No translations available (yet)')
|
||||
if(!translations[id]) return consoleWarn('Could not find string '+id)
|
||||
|
||||
// apply args
|
||||
var str = substArguments(translations[id], args)
|
||||
|
||||
// apply macros
|
||||
return substMacros(id, str, args)
|
||||
|
||||
// replace {{arguments}} with their values or the
|
||||
// associated translation string (based on its key)
|
||||
function substArguments(str, args) {
|
||||
var reArgs = /\{\{\s*([a-zA-Z\.]+)\s*\}\}/
|
||||
, match
|
||||
|
||||
while (match = reArgs.exec(str)) {
|
||||
if (!match || match.length < 2)
|
||||
return str // argument key not found
|
||||
|
||||
var arg = match[1]
|
||||
, sub = ''
|
||||
if (arg in args) {
|
||||
sub = args[arg]
|
||||
} else if (arg in translations) {
|
||||
sub = translations[arg]
|
||||
} else {
|
||||
consoleWarn('Could not find argument {{' + arg + '}}')
|
||||
return str
|
||||
}
|
||||
|
||||
str = str.substring(0, match.index) + sub + str.substr(match.index + match[0].length)
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
// replace {[macros]} with their values
|
||||
function substMacros(key, str, args) {
|
||||
var regex = /\{\[\s*([a-zA-Z]+):([a-zA-Z]+)\s*\]\}/
|
||||
, match = regex.exec(str);
|
||||
if (!match || !match.length)
|
||||
return str;
|
||||
|
||||
// a macro has been found
|
||||
// Note: at the moment, only one parameter is supported
|
||||
var macroName = reMatch[1]
|
||||
, paramName = reMatch[2]
|
||||
|
||||
if (!(macroName in gMacros)) return str
|
||||
|
||||
var param
|
||||
if (args && paramName in args) {
|
||||
param = args[paramName]
|
||||
} else if (paramName in translations) {
|
||||
param = translations[paramName]
|
||||
}
|
||||
|
||||
// there's no macro parser yet: it has to be defined in gMacros
|
||||
var macro = html10n.macros[macroName]
|
||||
str = macro(translations, key, str, param)
|
||||
return str
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies translations to a DOM node (recursive)
|
||||
*/
|
||||
html10n.translateNode = function(translations, node) {
|
||||
var str = {}
|
||||
|
||||
// get id
|
||||
str.id = node.getAttribute('data-l10n-id')
|
||||
if (!str.id) return
|
||||
|
||||
if(!translations[str.id]) return consoleWarn('Couldn\'t find translation key '+str.id)
|
||||
|
||||
// get args
|
||||
if(window.JSON) {
|
||||
str.args = JSON.parse(node.getAttribute('data-l10n-args'))
|
||||
}else{
|
||||
try{
|
||||
str.args = eval(node.getAttribute('data-l10n-args'))
|
||||
}catch(e) {
|
||||
consoleWarn('Couldn\'t parse args for '+str.id)
|
||||
}
|
||||
}
|
||||
|
||||
str.str = html10n.get(str.id, str.args)
|
||||
|
||||
// get attribute name to apply str to
|
||||
var prop
|
||||
, index = str.id.lastIndexOf('.')
|
||||
, attrList = // allowed attributes
|
||||
{ "title": 1
|
||||
, "innerHTML": 1
|
||||
, "alt": 1
|
||||
, "textContent": 1
|
||||
}
|
||||
if (index > 0 && str.id.substr(index + 1) in attrList) { // an attribute has been specified
|
||||
prop = str.id.substr(index + 1)
|
||||
} else { // no attribute: assuming text content by default
|
||||
prop = document.body.textContent ? 'textContent' : 'innerText'
|
||||
}
|
||||
|
||||
// Apply translation
|
||||
if (node.children.length === 0 || prop != 'textContent') {
|
||||
node[prop] = str.str
|
||||
} else {
|
||||
var children = node.childNodes,
|
||||
found = false
|
||||
for (var i=0, n=children.length; i < n; i++) {
|
||||
if (children[i].nodeType === 3 && /\S/.test(children[i].textContent)) {
|
||||
if (!found) {
|
||||
children[i].nodeValue = str.str
|
||||
found = true
|
||||
} else {
|
||||
children[i].nodeValue = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
consoleWarn('Unexpected error: could not translate element content for key '+str.id, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a translation object from a list of langs (loads the necessary translations)
|
||||
* @param langs Array - a list of langs sorted by priority (default langs should go last)
|
||||
*/
|
||||
html10n.build = function(langs, cb) {
|
||||
var that = this
|
||||
, build = {}
|
||||
|
||||
asyncForEach(langs, function (lang, i, next) {
|
||||
if(!lang) return next();
|
||||
that.loader.load(lang, next)
|
||||
}, function() {
|
||||
var lang
|
||||
langs.reverse()
|
||||
|
||||
// loop through priority array...
|
||||
for (var i=0, n=langs.length; i < n; i++) {
|
||||
lang = langs[i]
|
||||
|
||||
if(!lang || !(lang in that.loader.langs)) continue;
|
||||
|
||||
// ... and apply all strings of the current lang in the list
|
||||
// to our build object
|
||||
for (var string in that.loader.langs[lang]) {
|
||||
build[string] = that.loader.langs[lang][string]
|
||||
}
|
||||
|
||||
// the last applied lang will be exposed as the
|
||||
// lang the page was translated to
|
||||
that.language = lang
|
||||
}
|
||||
cb(null, build)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language that was last applied to the translations hash
|
||||
* thus overriding most of the formerly applied langs
|
||||
*/
|
||||
html10n.getLanguage = function() {
|
||||
return this.language;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the direction of the language returned be html10n#getLanguage
|
||||
*/
|
||||
html10n.getDirection = function() {
|
||||
var langCode = this.language.indexOf('-') == -1? this.language : this.language.substr(0, this.language.indexOf('-'))
|
||||
return html10n.rtl.indexOf(langCode) == -1? 'ltr' : 'rtl'
|
||||
}
|
||||
|
||||
/**
|
||||
* Index all <link>s
|
||||
*/
|
||||
html10n.index = function () {
|
||||
// Find all <link>s
|
||||
var links = document.getElementsByTagName('link')
|
||||
, resources = []
|
||||
for (var i=0, n=links.length; i < n; i++) {
|
||||
if (links[i].type != 'application/l10n+json')
|
||||
continue;
|
||||
resources.push(links[i].href)
|
||||
}
|
||||
this.loader = new Loader(resources)
|
||||
this.trigger('indexed')
|
||||
}
|
||||
|
||||
if (document.addEventListener) // modern browsers and IE9+
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
html10n.index()
|
||||
}, false)
|
||||
else if (window.attachEvent)
|
||||
document.attachEvent('onload', function() {
|
||||
html10n.index()
|
||||
}, false)
|
||||
|
||||
// gettext-like shortcut
|
||||
if (window._ === undefined)
|
||||
window._ = html10n.get;
|
||||
|
||||
return html10n
|
||||
})(window, document)
|
File diff suppressed because it is too large
Load Diff
|
@ -51,18 +51,20 @@ var randomString = require('./pad_utils').randomString;
|
|||
|
||||
var hooks = require('./pluginfw/hooks');
|
||||
|
||||
function createCookie(name, value, days, path)
|
||||
{
|
||||
function createCookie(name, value, days, path){ /* Warning Internet Explorer doesn't use this it uses the one from pad_utils.js */
|
||||
if (days)
|
||||
{
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
var expires = "; expires=" + date.toGMTString();
|
||||
}
|
||||
else var expires = "";
|
||||
else{
|
||||
var expires = "";
|
||||
}
|
||||
|
||||
if(!path)
|
||||
if(!path){ // If the path isn't set then just whack the cookie on the root path
|
||||
path = "/";
|
||||
}
|
||||
|
||||
//Check if the browser is IE and if so make sure the full path is set in the cookie
|
||||
if(navigator.appName=='Microsoft Internet Explorer'){
|
||||
|
@ -178,7 +180,7 @@ function getParams()
|
|||
{
|
||||
if(lang !== "")
|
||||
{
|
||||
document.webL10n.setLanguage(lang);
|
||||
window.html10n.localize([lang, 'en']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -202,6 +204,7 @@ function savePassword()
|
|||
createCookie("password",$("#passwordinput").val(),null,document.location.pathname);
|
||||
//reload
|
||||
document.location=document.location;
|
||||
return false;
|
||||
}
|
||||
|
||||
function handshake()
|
||||
|
@ -298,21 +301,25 @@ function handshake()
|
|||
//the access was not granted, give the user a message
|
||||
if(!receivedClientVars && obj.accessStatus)
|
||||
{
|
||||
$('.passForm').submit(require(module.id).savePassword);
|
||||
|
||||
if(obj.accessStatus == "deny")
|
||||
{
|
||||
$("#editorloadingbox").html("<b>You do not have permission to access this pad</b>");
|
||||
$('#loading').hide();
|
||||
$("#permissionDenied").show();
|
||||
}
|
||||
else if(obj.accessStatus == "needPassword")
|
||||
{
|
||||
$("#editorloadingbox").html("<b>You need a password to access this pad</b><br>" +
|
||||
"<input id='passwordinput' type='password' name='password'>"+
|
||||
"<button type='button' onclick=\"" + padutils.escapeHtml('require('+JSON.stringify(module.id)+").savePassword()") + "\">ok</button>");
|
||||
$('#loading').hide();
|
||||
$('#passwordRequired').show();
|
||||
$("#passwordinput").focus();
|
||||
}
|
||||
else if(obj.accessStatus == "wrongPassword")
|
||||
{
|
||||
$("#editorloadingbox").html("<b>You're password was wrong</b><br>" +
|
||||
"<input id='passwordinput' type='password' name='password'>"+
|
||||
"<button type='button' onclick=\"" + padutils.escapeHtml('require('+JSON.stringify(module.id)+").savePassword()") + "\">ok</button>");
|
||||
$('#loading').hide();
|
||||
$('#wrongPassword').show();
|
||||
$('#passwordRequired').show();
|
||||
$("#passwordinput").focus();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ var padeditbar = (function()
|
|||
{
|
||||
if ((!(ace.ace_getRep().selStart && ace.ace_getRep().selEnd)) || ace.ace_isCaret())
|
||||
{
|
||||
if (window.confirm("Clear authorship colors on entire document?"))
|
||||
if (window.confirm(html10n.get("pad.editbar.clearcolors")))
|
||||
{
|
||||
ace.ace_performDocumentApplyAttributesToCharRange(0, ace.ace_getRep().alltext.length, [
|
||||
['author', '']
|
||||
|
|
|
@ -75,10 +75,14 @@ var padeditor = (function()
|
|||
{
|
||||
pad.changeViewOption('useMonospaceFont', $("#viewfontmenu").val() == 'monospace');
|
||||
});
|
||||
$("#languagemenu").val(document.webL10n.getLanguage());
|
||||
|
||||
html10n.bind('localized', function() {
|
||||
$("#languagemenu").val(html10n.getLanguage());
|
||||
})
|
||||
$("#languagemenu").val(html10n.getLanguage());
|
||||
$("#languagemenu").change(function() {
|
||||
pad.createCookie("language",$("#languagemenu").val(),null,'/');
|
||||
document.webL10n.setLanguage($("#languagemenu").val());
|
||||
window.html10n.localize([$("#languagemenu").val(), 'en']);
|
||||
});
|
||||
},
|
||||
setViewOptions: function(newOptions)
|
||||
|
|
|
@ -69,7 +69,7 @@ var padimpexp = (function()
|
|||
function fileInputSubmit()
|
||||
{
|
||||
$('#importmessagefail').fadeOut("fast");
|
||||
var ret = window.confirm("Importing a file will overwrite the current text of the pad." + " Are you sure you want to proceed?");
|
||||
var ret = window.confirm(html10n.get("pad.impexp.confirmimport"));
|
||||
if (ret)
|
||||
{
|
||||
hidePanelCall = paddocbar.hideLaterIfNoOtherInteraction();
|
||||
|
@ -85,7 +85,8 @@ var padimpexp = (function()
|
|||
$('#importsubmitinput').attr(
|
||||
{
|
||||
disabled: true
|
||||
}).val("Importing...");
|
||||
}).val(html10n.get("pad.impexp.importing"));
|
||||
|
||||
window.setTimeout(function()
|
||||
{
|
||||
$('#importfileinput').attr(
|
||||
|
@ -106,7 +107,7 @@ var padimpexp = (function()
|
|||
|
||||
function importDone()
|
||||
{
|
||||
$('#importsubmitinput').removeAttr('disabled').val("Import Now");
|
||||
$('#importsubmitinput').removeAttr('disabled').val(html10n.get("pad.impexp.importbutton"));
|
||||
window.setTimeout(function()
|
||||
{
|
||||
$('#importfileinput').removeAttr('disabled');
|
||||
|
@ -130,14 +131,14 @@ var padimpexp = (function()
|
|||
var msg="";
|
||||
|
||||
if(status === "convertFailed"){
|
||||
msg = "We were not able to import this file. Please use a different document format or copy paste manually";
|
||||
msg = html10n.get("pad.impexp.convertFailed");
|
||||
} else if(status === "uploadFailed"){
|
||||
msg = "The upload failed, please try again";
|
||||
msg = html10n.get("pad.impexp.uploadFailed");
|
||||
}
|
||||
|
||||
function showError(fade)
|
||||
{
|
||||
$('#importmessagefail').html('<strong style="color: red">Import failed:</strong> ' + (msg || 'Please copy paste'))[(fade ? "fadeIn" : "show")]();
|
||||
$('#importmessagefail').html('<strong style="color: red">'+html10n.get('pad.impexp.importfailed')+':</strong> ' + (msg || html10n.get('pad.impexp.copypaste','')))[(fade ? "fadeIn" : "show")]();
|
||||
}
|
||||
|
||||
if ($('#importexport .importmessage').is(':visible'))
|
||||
|
@ -198,7 +199,7 @@ var padimpexp = (function()
|
|||
{
|
||||
type = "this file";
|
||||
}
|
||||
alert("Exporting as " + type + " format is disabled. Please contact your" + " system administrator for details.");
|
||||
alert(html10n.get("pad.impexp.exportdisabled", {type:type}));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -214,10 +215,19 @@ var padimpexp = (function()
|
|||
//get http://example.com/p/padname
|
||||
var pad_root_url = document.location.href.replace(document.location.pathname, pad_root_path)
|
||||
|
||||
//i10l buttom import
|
||||
$('#importsubmitinput').val(html10n.get("pad.impexp.importbutton"));
|
||||
html10n.bind('localized', function() {
|
||||
$('#importsubmitinput').val(html10n.get("pad.impexp.importbutton"));
|
||||
})
|
||||
|
||||
// build the export links
|
||||
$("#exporthtmla").attr("href", pad_root_path + "/export/html");
|
||||
$("#exportplaina").attr("href", pad_root_path + "/export/txt");
|
||||
$("#exportdokuwikia").attr("href", pad_root_path + "/export/dokuwiki");
|
||||
|
||||
// activate action to import in the form
|
||||
$("#importform").attr('action', pad_root_url + "/import");
|
||||
|
||||
//hide stuff thats not avaible if abiword is disabled
|
||||
if(clientVars.abiwordAvailable == "no")
|
||||
|
@ -225,8 +235,8 @@ var padimpexp = (function()
|
|||
$("#exportworda").remove();
|
||||
$("#exportpdfa").remove();
|
||||
$("#exportopena").remove();
|
||||
$(".importformdiv").remove();
|
||||
$("#import").html("Import is not available. To enable import please install abiword");
|
||||
|
||||
$("#importmessageabiword").show();
|
||||
}
|
||||
else if(clientVars.abiwordAvailable == "withoutPDF")
|
||||
{
|
||||
|
@ -237,16 +247,12 @@ var padimpexp = (function()
|
|||
|
||||
$("#importexport").css({"height":"142px"});
|
||||
$("#importexportline").css({"height":"142px"});
|
||||
|
||||
$("#importform").attr('action', pad_root_url + "/import");
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#exportworda").attr("href", pad_root_path + "/export/doc");
|
||||
$("#exportpdfa").attr("href", pad_root_path + "/export/pdf");
|
||||
$("#exportopena").attr("href", pad_root_path + "/export/odt");
|
||||
|
||||
$("#importform").attr('action', pad_root_path + "/import");
|
||||
}
|
||||
|
||||
$("#impexp-close").click(function()
|
||||
|
|
|
@ -18,7 +18,7 @@ var pad;
|
|||
|
||||
exports.saveNow = function(){
|
||||
pad.collabClient.sendMessage({"type": "SAVE_REVISION"});
|
||||
alert("This revision is now marked as a saved revision");
|
||||
alert(_("pad.savedrevs.marked"));
|
||||
}
|
||||
|
||||
exports.init = function(_pad){
|
||||
|
|
|
@ -113,12 +113,12 @@ var paduserlist = (function()
|
|||
nameHtml = padutils.escapeHtml(data.name);
|
||||
if (isGuest && pad.getIsProPad())
|
||||
{
|
||||
nameHtml += ' (Guest)';
|
||||
nameHtml += ' ('+_(pad.userlist.guest)+')';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nameHtml = '<input type="text" class="editempty newinput" value="unnamed" ' + (isNameEditable(data) ? '' : 'disabled="disabled" ') + '/>';
|
||||
nameHtml = '<input type="text" class="editempty newinput" value="'+_('pad.userlist.unnamed')+'" ' + (isNameEditable(data) ? '' : 'disabled="disabled" ') + '/>';
|
||||
}
|
||||
|
||||
return ['<td style="height:', height, 'px" class="usertdswatch"><div class="swatch" style="background:' + data.color + '"> </div></td>', '<td style="height:', height, 'px" class="usertdname">', nameHtml, '</td>', '<td style="height:', height, 'px" class="activity">', padutils.escapeHtml(data.activity), '</td>'].join('');
|
||||
|
@ -374,7 +374,7 @@ var paduserlist = (function()
|
|||
if (!newName)
|
||||
{
|
||||
jnode.addClass("editempty");
|
||||
jnode.val("unnamed");
|
||||
jnode.val(_('pad.userlist.unnamed'));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -662,13 +662,13 @@ var paduserlist = (function()
|
|||
if (box.length == 0)
|
||||
{
|
||||
// make guest prompt box
|
||||
box = $('<div id="'+padutils.escapeHtml('guestprompt-' + encodedUserId) + '" class="guestprompt"><div class="choices"><a href="' + padutils.escapeHtml('javascript:void(require('+JSON.stringify(module.id)+').paduserlist.answerGuestPrompt(' + JSON.stringify(encodedUserId) + ',false))')+'">Deny</a> <a href="' + padutils.escapeHtml('javascript:void(require('+JSON.stringify(module.id)+').paduserlist.answerGuestPrompt(' + JSON.stringify(encodedUserId) + ',true))') + '">Approve</a></div><div class="guestname"><strong>Guest:</strong> ' + padutils.escapeHtml(displayName) + '</div></div>');
|
||||
box = $('<div id="'+padutils.escapeHtml('guestprompt-' + encodedUserId) + '" class="guestprompt"><div class="choices"><a href="' + padutils.escapeHtml('javascript:void(require('+JSON.stringify(module.id)+').paduserlist.answerGuestPrompt(' + JSON.stringify(encodedUserId) + ',false))')+'">'+_('pad.userlist.deny')+'</a> <a href="' + padutils.escapeHtml('javascript:void(require('+JSON.stringify(module.id)+').paduserlist.answerGuestPrompt(' + JSON.stringify(encodedUserId) + ',true))') + '">'+_('pad.userlist.approve')+'</a></div><div class="guestname"><strong>'+_('pad.userlist.guest')+':</strong> ' + padutils.escapeHtml(displayName) + '</div></div>');
|
||||
$("#guestprompts").append(box);
|
||||
}
|
||||
else
|
||||
{
|
||||
// update display name
|
||||
box.find(".guestname").html('<strong>Guest:</strong> ' + padutils.escapeHtml(displayName));
|
||||
box.find(".guestname").html('<strong>'+_('pad.userlist.guest')+':</strong> ' + padutils.escapeHtml(displayName));
|
||||
}
|
||||
var hideLater = padutils.getCancellableAction(actionName, function()
|
||||
{
|
||||
|
@ -715,7 +715,7 @@ var paduserlist = (function()
|
|||
}
|
||||
else
|
||||
{
|
||||
$("#myusernameedit").addClass("editempty").val("Enter your name");
|
||||
$("#myusernameedit").addClass("editempty").val(_("pad.userlist.entername"));
|
||||
}
|
||||
if (colorPickerOpen)
|
||||
{
|
||||
|
|
|
@ -39,20 +39,29 @@ function randomString(len)
|
|||
return randomstring;
|
||||
}
|
||||
|
||||
function createCookie(name, value, days, path)
|
||||
{
|
||||
function createCookie(name, value, days, path){ /* Used by IE */
|
||||
if (days)
|
||||
{
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
var expires = "; expires=" + date.toGMTString();
|
||||
}
|
||||
else var expires = "";
|
||||
else{
|
||||
var expires = "";
|
||||
}
|
||||
|
||||
if(!path)
|
||||
if(!path){ // IF the Path of the cookie isn't set then just create it on root
|
||||
path = "/";
|
||||
}
|
||||
|
||||
//Check if the browser is IE and if so make sure the full path is set in the cookie
|
||||
if(navigator.appName=='Microsoft Internet Explorer'){
|
||||
document.cookie = name + "=" + value + expires + "; path=/"; /* Note this bodge fix for IE is temporary until auth is rewritten */
|
||||
}
|
||||
else{
|
||||
document.cookie = name + "=" + value + expires + "; path=" + path;
|
||||
}
|
||||
|
||||
document.cookie = name + "=" + value + expires + "; path=" + path;
|
||||
}
|
||||
|
||||
function readCookie(name)
|
||||
|
|
|
@ -91,9 +91,12 @@ exports.search = function(query, cache, cb) {
|
|||
if (er) return cb(er);
|
||||
var res = {};
|
||||
var i = 0;
|
||||
for (key in data) {
|
||||
for (key in data) { // for every plugin in the data from npm
|
||||
if ( key.indexOf(plugins.prefix) == 0
|
||||
&& key.indexOf(query.pattern) != -1) {
|
||||
&& key.indexOf(query.pattern) != -1
|
||||
|| key.indexOf(plugins.prefix) == 0
|
||||
&& data[key].description.indexOf(query.pattern) != -1
|
||||
) { // If the name contains ep_ and the search string is in the name or description
|
||||
i++;
|
||||
if (i > query.offset
|
||||
&& i <= query.offset + query.limit) {
|
||||
|
|
|
@ -14,17 +14,17 @@
|
|||
<div class="separator"></div>
|
||||
|
||||
<h2>Installed plugins</h2>
|
||||
<pre><%= plugins.formatPlugins() %></pre>
|
||||
<pre><%- plugins.formatPlugins().replace(", ","\n") %></pre>
|
||||
|
||||
<h2>Installed parts</h2>
|
||||
<pre><%= plugins.formatParts() %></pre>
|
||||
|
||||
<h2>Installed hooks</h2>
|
||||
<h3>Server side hooks</h3>
|
||||
<div><%= plugins.formatHooks() %></div>
|
||||
<div><%- plugins.formatHooks() %></div>
|
||||
|
||||
<h3>Client side hooks</h3>
|
||||
<div><%= plugins.formatHooks("client_hooks") %></div>
|
||||
<div><%- plugins.formatHooks("client_hooks") %></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Version</th>
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -37,6 +38,7 @@
|
|||
<tr id="installed-plugin-template">
|
||||
<td class="name"></td>
|
||||
<td class="description"></td>
|
||||
<td class="version"></td>
|
||||
<td class="actions">
|
||||
<input type="button" value="Uninstall" class="do-uninstall">
|
||||
</td>
|
||||
|
@ -58,6 +60,7 @@
|
|||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Version</th>
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -65,6 +68,7 @@
|
|||
<tr>
|
||||
<td class="name"></td>
|
||||
<td class="description"></td>
|
||||
<td class="version"></td>
|
||||
<td class="actions">
|
||||
<input type="button" value="Install" class="do-install">
|
||||
</td>
|
||||
|
|
|
@ -31,17 +31,11 @@
|
|||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
|
||||
<link rel="resource" type="application/l10n" href="locales.ini" />
|
||||
<link rel="shortcut icon" href="<%=settings.favicon%>">
|
||||
|
||||
<script type="text/javascript">
|
||||
(function(document) {
|
||||
// Set language for l10n
|
||||
var language = document.cookie.match(/language=(\w{2})/);
|
||||
if(language) document.documentElement.lang = language[1];
|
||||
})(document)
|
||||
</script>
|
||||
<script type="text/javascript" src="static/js/l10n.js" async></script>
|
||||
|
||||
<link rel="localizations" type="application/l10n+json" href="../locales.json" />
|
||||
<script type="text/javascript" src="../static/js/html10n.js"></script>
|
||||
<script type="text/javascript" src="../static/js/l10n.js"></script>
|
||||
|
||||
<style>
|
||||
html, body {
|
||||
|
|
|
@ -32,17 +32,11 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
|
||||
<link rel="shortcut icon" href="<%=settings.favicon%>">
|
||||
<link rel="shortcut icon" href="<%=settings.faviconPad%>">
|
||||
|
||||
<link rel="resource" type="application/l10n" href="../locales.ini" />
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
// Set language for l10n
|
||||
var language = document.cookie.match(/language=(\w{2})/);
|
||||
if(language) document.documentElement.lang = language[1];
|
||||
})();
|
||||
</script>
|
||||
<script type="text/javascript" src="../static/js/l10n.js" async></script>
|
||||
<link rel="localizations" type="application/l10n+json" href="../locales.json" />
|
||||
<script type="text/javascript" src="../static/js/html10n.js"></script>
|
||||
<script type="text/javascript" src="../static/js/l10n.js"></script>
|
||||
|
||||
<% e.begin_block("styles"); %>
|
||||
<link href="../static/css/pad.css" rel="stylesheet">
|
||||
|
@ -60,60 +54,60 @@
|
|||
<ul class="menu_left">
|
||||
<% e.begin_block("editbarMenuLeft"); %>
|
||||
<li class="acl-write" id="bold" data-key="bold">
|
||||
<a class="grouped-left" data-l10n-id="pad.toolbar.bold">
|
||||
<a class="grouped-left" data-l10n-id="pad.toolbar.bold.title">
|
||||
<span class="buttonicon buttonicon-bold"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="acl-write" id="italic" data-key="italic">
|
||||
<a class="grouped-middle" data-l10n-id="pad.toolbar.italic">
|
||||
<a class="grouped-middle" data-l10n-id="pad.toolbar.italic.title">
|
||||
<span class="buttonicon buttonicon-italic"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="acl-write" id="underline" data-key="underline">
|
||||
<a class="grouped-middle" data-l10n-id="pad.toolbar.underline">
|
||||
<a class="grouped-middle" data-l10n-id="pad.toolbar.underline.title">
|
||||
<span class="buttonicon buttonicon-underline"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="acl-write" id="strikethrough" data-key="strikethrough">
|
||||
<a class="grouped-right" data-l10n-id="pad.toolbar.strikethrough">
|
||||
<a class="grouped-right" data-l10n-id="pad.toolbar.strikethrough.title">
|
||||
<span class="buttonicon buttonicon-strikethrough"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="acl-write separator"></li>
|
||||
<li class="acl-write" id="oderedlist" data-key="insertorderedlist">
|
||||
<a class="grouped-left" data-l10n-id="pad.toolbar.ol">
|
||||
<a class="grouped-left" data-l10n-id="pad.toolbar.ol.title">
|
||||
<span class="buttonicon buttonicon-insertorderedlist"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="acl-write" id="unoderedlist" data-key="insertunorderedlist">
|
||||
<a class="grouped-middle" data-l10n-id="pad.toolbar.ul">
|
||||
<a class="grouped-middle" data-l10n-id="pad.toolbar.ul.title">
|
||||
<span class="buttonicon buttonicon-insertunorderedlist"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="acl-write" id="indent" data-key="indent">
|
||||
<a class="grouped-middle" data-l10n-id="pad.toolbar.indent">
|
||||
<a class="grouped-middle" data-l10n-id="pad.toolbar.indent.title">
|
||||
<span class="buttonicon buttonicon-indent"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="acl-write" id="outdent" data-key="outdent">
|
||||
<a class="grouped-right" data-l10n-id="pad.toolbar.unindent">
|
||||
<a class="grouped-right" data-l10n-id="pad.toolbar.unindent.title">
|
||||
<span class="buttonicon buttonicon-outdent"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="acl-write separator"></li>
|
||||
<li class="acl-write" id="undo" data-key="undo">
|
||||
<a class="grouped-left" data-l10n-id="pad.toolbar.undo">
|
||||
<a class="grouped-left" data-l10n-id="pad.toolbar.undo.title">
|
||||
<span class="buttonicon buttonicon-undo"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="acl-write" id="redo" data-key="redo">
|
||||
<a class="grouped-right" data-l10n-id="pad.toolbar.redo">
|
||||
<a class="grouped-right" data-l10n-id="pad.toolbar.redo.title">
|
||||
<span class="buttonicon buttonicon-redo"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="acl-write separator"></li>
|
||||
<li class="acl-write" id="clearAuthorship" data-key="clearauthorship">
|
||||
<a data-l10n-id="pad.toolbar.clearAuthorship">
|
||||
<a data-l10n-id="pad.toolbar.clearAuthorship.title">
|
||||
<span class="buttonicon buttonicon-clearauthorship"></span>
|
||||
</a>
|
||||
</li>
|
||||
|
@ -122,34 +116,34 @@
|
|||
<ul class="menu_right">
|
||||
<% e.begin_block("editbarMenuRight"); %>
|
||||
<li data-key="import_export">
|
||||
<a class="grouped-left" id="importexportlink" data-l10n-id="pad.toolbar.import_export">
|
||||
<a class="grouped-left" id="importexportlink" data-l10n-id="pad.toolbar.import_export.title">
|
||||
<span class="buttonicon buttonicon-import_export"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li onClick="document.location = document.location.pathname+ '/timeslider'">
|
||||
<a id="timesliderlink" class="grouped-middle" data-l10n-id="pad.toolbar.timeslider">
|
||||
<a id="timesliderlink" class="grouped-middle" data-l10n-id="pad.toolbar.timeslider.title">
|
||||
<span class="buttonicon buttonicon-history"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="acl-write" data-key="savedRevision">
|
||||
<a class="grouped-right" id="revisionlink" data-l10n-id="pad.toolbar.savedRevision">
|
||||
<a class="grouped-right" id="revisionlink" data-l10n-id="pad.toolbar.savedRevision.title">
|
||||
<span class="buttonicon buttonicon-savedRevision"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="acl-write separator"></li>
|
||||
<li class="acl-write" data-key="settings">
|
||||
<a class="grouped-left" id="settingslink" data-l10n-id="pad.toolbar.settings">
|
||||
<a class="grouped-left" id="settingslink" data-l10n-id="pad.toolbar.settings.title">
|
||||
<span class="buttonicon buttonicon-settings"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li data-key="embed">
|
||||
<a class="grouped-right" id="embedlink" data-l10n-id="pad.toolbar.embed">
|
||||
<a class="grouped-right" id="embedlink" data-l10n-id="pad.toolbar.embed.title">
|
||||
<span class="grouped-right buttonicon buttonicon-embed"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="separator"></li>
|
||||
<li id="usericon" data-key="showusers">
|
||||
<a data-l10n-id="pad.toolbar.showusers">
|
||||
<a data-l10n-id="pad.toolbar.showusers.title">
|
||||
<span class="buttonicon buttonicon-showusers"></span>
|
||||
<span id="online_count">1</span>
|
||||
</a>
|
||||
|
@ -184,7 +178,19 @@
|
|||
<div id="editorcontainerbox">
|
||||
<div id="editorcontainer"></div>
|
||||
<div id="editorloadingbox">
|
||||
<p data-l10n-id="pad.loading">Loading...</p>
|
||||
<div id="passwordRequired">
|
||||
<p data-l10n-id="pad.passwordRequired">You need a password to access this pad</p>
|
||||
<form class='passForm' method='POST'>
|
||||
<input id='passwordinput' type='password' name='password'><input type='submit' value='Submit'>
|
||||
</form>
|
||||
</div>
|
||||
<div id="permissionDenied">
|
||||
<p data-l10n-id="pad.permissionDenied">You do not have permission to access this pad</p>
|
||||
</div>
|
||||
<div id="wrongPassword">
|
||||
<p data-l10n-id="pad.wrongPassword">Your password was wrong</p>
|
||||
</div>
|
||||
<p data-l10n-id="pad.loading" id="loading">Loading...</p>
|
||||
<noscript><strong>Sorry, you have to enable Javascript in order to use this.</strong></noscript>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -246,14 +252,15 @@
|
|||
<h1 data-l10n-id="pad.importExport.import_export"></h1>
|
||||
<div class="column acl-write">
|
||||
<% e.begin_block("importColumn"); %>
|
||||
<h2 data-l10n-id="pad.importExport.import"></h2><br>
|
||||
<h2 data-l10n-id="pad.importExport.import"></h2>
|
||||
<div class="importmessage" id="importmessageabiword" data-l10n-id="pad.importExport.abiword.innerHTML"></div><br>
|
||||
<form id="importform" method="post" action="" target="importiframe" enctype="multipart/form-data">
|
||||
<div class="importformdiv" id="importformfilediv">
|
||||
<input type="file" name="file" size="15" id="importfileinput">
|
||||
<input type="file" name="file" size="10" id="importfileinput">
|
||||
<div class="importmessage" id="importmessagefail"></div>
|
||||
</div>
|
||||
<div id="import"></div>
|
||||
<div class="importmessage" id="importmessagesuccess" data-l10n-id="pad.importExport.successful"></div>
|
||||
<div class="importmessage" id="importmessagesuccess" data-l10n-id="pad.importExport.importSuccessful"></div>
|
||||
<div class="importformdiv" id="importformsubmitdiv">
|
||||
<input type="hidden" name="padId" value="blpmaXT35R">
|
||||
<span class="nowrap">
|
||||
|
@ -288,9 +295,9 @@
|
|||
<p><img alt="" border="0" src="../static/img/connectingbar.gif" /></p>
|
||||
</div>
|
||||
<div class="userdup">
|
||||
<h1 data-l10n-id="pad.modals.uderdup"></h1>
|
||||
<h1 data-l10n-id="pad.modals.userdup"></h1>
|
||||
<h2 data-l10n-id="pad.modals.userdup.explanation"></h2>
|
||||
<p data-l10n-id="pad.modals.connected.advice"></p>
|
||||
<p data-l10n-id="pad.modals.userdup.advice"></p>
|
||||
<button id="forcereconnect" data-l10n-id="pad.modals.forcereconnect"></button>
|
||||
</div>
|
||||
<div class="unauth">
|
||||
|
@ -353,7 +360,7 @@
|
|||
|
||||
<div id="chatthrob"></div>
|
||||
|
||||
<div id="chaticon" data-l10n-id="pad.chat" onclick="chat.show();return false;">
|
||||
<div id="chaticon" onclick="chat.show();return false;">
|
||||
<span id="chatlabel" data-l10n-id="pad.chat"></span>
|
||||
<span class="buttonicon buttonicon-chat"></span>
|
||||
<span id="chatcounter">0</span>
|
||||
|
|
|
@ -31,17 +31,12 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<link rel="shortcut icon" href="<%=settings.favicon%>">
|
||||
<link rel="resource" type="application/l10n" href="../../locales.ini" />
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
// Set language for l10n
|
||||
var language = document.cookie.match(/language=(\w{2})/);
|
||||
if(language) document.documentElement.lang = language[1];
|
||||
})();
|
||||
</script>
|
||||
<script type="text/javascript" src="../../static/js/l10n.js" async></script>
|
||||
<link rel="shortcut icon" href="<%=settings.faviconTimeslider%>">
|
||||
|
||||
<link rel="localizations" type="application/l10n+json" href="../../locales.json" />
|
||||
<script type="text/javascript" src="../../static/js/html10n.js"></script>
|
||||
<script type="text/javascript" src="../../static/js/l10n.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../../static/css/pad.css">
|
||||
<link rel="stylesheet" href="../../static/css/timeslider.css">
|
||||
<link rel="stylesheet" href="../../static/custom/timeslider.css">
|
||||
|
@ -80,7 +75,7 @@
|
|||
<div class="editbarright toolbar" id="editbar">
|
||||
<ul>
|
||||
<li onClick="window.padeditbar.toolbarClick('import_export');return false;">
|
||||
<a id="exportlink" data-l10n-id="pad.importExport.export">
|
||||
<a id="exportlink" data-l10n-id="timeslider.toolbar.exportlink.title">
|
||||
<div class="buttonicon buttonicon-import_export"></div>
|
||||
</a>
|
||||
</li>
|
||||
|
@ -93,7 +88,8 @@
|
|||
<span id="revision_label"></span>
|
||||
<span id="revision_date"></span>
|
||||
</h1>
|
||||
<p data-l10n-id="timeslider.toolbar.authors">
|
||||
<p>
|
||||
<span data-l10n-id="timeslider.toolbar.authors"></span>
|
||||
<span id="authorsList" data-l10n-id="timeslider.toolbar.authorsList"></span>
|
||||
</span> </p>
|
||||
</div>
|
||||
|
@ -120,9 +116,9 @@
|
|||
<p><img alt="" border="0" src="../../static/img/connectingbar.gif" /></p>
|
||||
</div>
|
||||
<div class="userdup">
|
||||
<h1 data-l10n-id="pad.modals.uderdup"></h1>
|
||||
<h1 data-l10n-id="pad.modals.userdup"></h1>
|
||||
<h2 data-l10n-id="pad.modals.userdup.explanation"></h2>
|
||||
<p data-l10n-id="pad.modals.connected.advice"></p>
|
||||
<p data-l10n-id="pad.modals.userdup.advice"></p>
|
||||
<button id="forcereconnect" data-l10n-id="pad.modals.forcereconnect"></button>
|
||||
</div>
|
||||
<div class="unauth">
|
||||
|
@ -167,7 +163,8 @@
|
|||
<!-- export code -->
|
||||
<div id="importexport">
|
||||
|
||||
<div id="export" class="popup" data-l10n-id="timeslider.exportCurrent">
|
||||
<div id="export" class="popup">
|
||||
<p data-l10n-id="timeslider.exportCurrent"></p>
|
||||
<a id="exporthtmla" target="_blank" class="exportlink"><div class="exporttype" id="exporthtml" data-l10n-id="pad.importExport.exporthtml"></div></a>
|
||||
<a id="exportplaina" target="_blank" class="exportlink"><div class="exporttype" id="exportplain" data-l10n-id="pad.importExport.exportplain"></div></a>
|
||||
<a id="exportworda" target="_blank" class="exportlink"><div class="exporttype" id="exportword" data-l10n-id="pad.importExport.exportword"></div></a>
|
||||
|
|
|
@ -15,12 +15,15 @@ body {
|
|||
#iframe-container {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
float:right;
|
||||
}
|
||||
|
||||
#iframe-container iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position:absolute;
|
||||
min-width:500px;
|
||||
max-width:800px;
|
||||
left:50%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
#mocha {
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
describe("All the alphabet works n stuff", function(){
|
||||
var expectedString = "abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
//create a new pad before each test run
|
||||
beforeEach(function(cb){
|
||||
helper.newPad(cb);
|
||||
this.timeout(60000);
|
||||
});
|
||||
|
||||
it("when you enter any char it appears right", function(done) {
|
||||
var inner$ = helper.padInner$;
|
||||
var chrome$ = helper.padChrome$;
|
||||
|
||||
//get the first text element out of the inner iframe
|
||||
var firstTextElement = inner$("div").first();
|
||||
|
||||
// simulate key presses to delete content
|
||||
firstTextElement.sendkeys('{selectall}'); // select all
|
||||
firstTextElement.sendkeys('{del}'); // clear the first line
|
||||
firstTextElement.sendkeys(expectedString); // insert the string
|
||||
|
||||
helper.waitFor(function(){
|
||||
return inner$("div").first().text() === expectedString;
|
||||
}, 2000).done(done);
|
||||
});
|
||||
|
||||
});
|
|
@ -1,10 +1,19 @@
|
|||
function deletecookie(name) {
|
||||
document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
|
||||
}
|
||||
|
||||
describe("Language select and change", function(){
|
||||
// Destroy language cookies
|
||||
deletecookie("language", null);
|
||||
|
||||
//create a new pad before each test run
|
||||
beforeEach(function(cb){
|
||||
helper.newPad(cb);
|
||||
this.timeout(60000);
|
||||
});
|
||||
|
||||
// Destroy language cookies
|
||||
|
||||
it("makes text german", function(done) {
|
||||
var inner$ = helper.padInner$;
|
||||
var chrome$ = helper.padChrome$;
|
||||
|
@ -21,14 +30,16 @@ describe("Language select and change", function(){
|
|||
$languageoption.attr('selected','selected');
|
||||
$language.change();
|
||||
|
||||
helper.waitFor(function() { return $language.val() == "de"})
|
||||
helper.waitFor(function() {
|
||||
return chrome$(".buttonicon-bold").parent()[0]["title"] == "Fett (Strg-B)";
|
||||
})
|
||||
.done(function(){
|
||||
//get the value of the bold button
|
||||
var $boldButton = chrome$(".buttonicon-bold").parent();
|
||||
|
||||
//get the title of the bold button
|
||||
var boldButtonTitle = $boldButton[0]["title"];
|
||||
|
||||
|
||||
//check if the language is now german
|
||||
expect(boldButtonTitle).to.be("Fett (Strg-B)");
|
||||
done();
|
||||
|
@ -51,7 +62,10 @@ describe("Language select and change", function(){
|
|||
$languageoption.attr('selected','selected');
|
||||
$language.change();
|
||||
|
||||
helper.waitFor(function() { return $language.val() == "en";})
|
||||
//get the value of the bold button
|
||||
var $boldButton = chrome$(".buttonicon-bold").parent();
|
||||
|
||||
helper.waitFor(function() { return $boldButton[0]["title"] != "Fett (Strg-B)";})
|
||||
.done(function(){
|
||||
|
||||
//get the value of the bold button
|
||||
|
@ -66,5 +80,31 @@ describe("Language select and change", function(){
|
|||
|
||||
});
|
||||
});
|
||||
|
||||
it("changes direction when picking an rtl lang", function(done) {
|
||||
var inner$ = helper.padInner$;
|
||||
var chrome$ = helper.padChrome$;
|
||||
|
||||
});
|
||||
//click on the settings button to make settings visible
|
||||
var $settingsButton = chrome$(".buttonicon-settings");
|
||||
$settingsButton.click();
|
||||
|
||||
//click the language button
|
||||
var $language = chrome$("#languagemenu");
|
||||
var $languageoption = $language.find("[value=ar]");
|
||||
|
||||
//select arabic
|
||||
$languageoption.attr('selected','selected');
|
||||
$language.change();
|
||||
|
||||
helper.waitFor(function() {
|
||||
return chrome$("html")[0]["dir"] != 'ltr';
|
||||
})
|
||||
.done(function(){
|
||||
// check if the document's direction was changed
|
||||
expect(chrome$("html")[0]["dir"]).to.be("rtl");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
describe("timeslider", function(){
|
||||
//create a new pad before each test run
|
||||
beforeEach(function(cb){
|
||||
helper.newPad(cb);
|
||||
this.timeout(6000);
|
||||
});
|
||||
|
||||
it("loads adds a hundred revisions", function(done) {
|
||||
var inner$ = helper.padInner$;
|
||||
var chrome$ = helper.padChrome$;
|
||||
|
||||
// make some changes to produce 100 revisions
|
||||
var timePerRev = 900
|
||||
, revs = 100;
|
||||
this.timeout(revs*timePerRev+10000);
|
||||
for(var i=0; i < revs; i++) {
|
||||
setTimeout(function() {
|
||||
// enter 'a' in the first text element
|
||||
inner$("div").first().sendkeys('a');
|
||||
}, timePerRev*i);
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
// go to timeslider
|
||||
$('#iframe-container iframe').attr('src', $('#iframe-container iframe').attr('src')+'/timeslider');
|
||||
|
||||
setTimeout(function() {
|
||||
var timeslider$ = $('#iframe-container iframe')[0].contentWindow.$;
|
||||
var $sliderBar = timeslider$('#ui-slider-bar');
|
||||
|
||||
var latestContents = timeslider$('#padcontent').text();
|
||||
|
||||
// Click somewhere on the timeslider
|
||||
var e = new jQuery.Event('mousedown');
|
||||
e.clientX = e.pageX = 150;
|
||||
e.clientY = e.pageY = 45;
|
||||
$sliderBar.trigger(e);
|
||||
|
||||
e = new jQuery.Event('mousedown');
|
||||
e.clientX = e.pageX = 150;
|
||||
e.clientY = e.pageY = 40;
|
||||
$sliderBar.trigger(e);
|
||||
|
||||
e = new jQuery.Event('mousedown');
|
||||
e.clientX = e.pageX = 150;
|
||||
e.clientY = e.pageY = 50;
|
||||
$sliderBar.trigger(e);
|
||||
|
||||
$sliderBar.trigger('mouseup')
|
||||
|
||||
setTimeout(function() {
|
||||
//make sure the text has changed
|
||||
expect( timeslider$('#padcontent').text() ).not.to.eql( latestContents );
|
||||
done();
|
||||
}, 1000);
|
||||
|
||||
}, 6000);
|
||||
}, revs*timePerRev);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue