Merge pull request #1304 from ether/release/releases-1.2.2

Version 1.2.2 release
This commit is contained in:
Marcel Klehr 2012-12-27 13:16:28 -08:00
commit 6a65a47444
94 changed files with 1749 additions and 1846 deletions

3
.gitignore vendored
View file

@ -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

View file

@ -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

View file

@ -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**

View file

@ -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

View file

@ -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}`

View file

@ -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"
}
```

View file

@ -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).)

View file

@ -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']
}

1
src/locales/af.json Normal file
View file

@ -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"}

1
src/locales/ar.json Normal file
View file

@ -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":"ديسمبر"}

1
src/locales/ast.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/az.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/azb.json Normal file
View file

@ -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":"یازیچی سیز"}

View file

@ -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 = বর্তমান সংস্করণটি এক্সপোর্ট করুন:

1
src/locales/bn.json Normal file
View file

@ -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":"ডিসেম্বর"}

1
src/locales/ca.json Normal file
View file

@ -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"}

1
src/locales/cs.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/da.json Normal file

File diff suppressed because one or more lines are too long

View file

@ -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:

1
src/locales/de.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/diq.json Normal file
View file

@ -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"}

1
src/locales/el.json Normal file

File diff suppressed because one or more lines are too long

View file

@ -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:

1
src/locales/en.json Normal file

File diff suppressed because one or more lines are too long

View file

@ -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:

1
src/locales/es.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/fa.json Normal file

File diff suppressed because one or more lines are too long

View file

@ -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

1
src/locales/fi.json Normal file
View file

@ -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"}

View file

@ -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:

1
src/locales/fr.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/gl.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/he.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/hu.json Normal file
View file

@ -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"}

1
src/locales/ia.json Normal file
View file

@ -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"}

1
src/locales/it.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/ja.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/ko.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/ksh.json Normal file
View file

@ -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&nbsp;&hellip;","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&nbsp;&hellip;","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"}

1
src/locales/mk.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/ml.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/ms.json Normal file

File diff suppressed because one or more lines are too long

View file

@ -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:

1
src/locales/nl.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/nn.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/pl.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/ps.json Normal file
View file

@ -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":"ډيسمبر"}

1
src/locales/pt.json Normal file
View file

@ -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"}

1
src/locales/ru.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/sq.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/sv.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/te.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/uk.json Normal file

File diff suppressed because one or more lines are too long

1
src/locales/zh-hant.json Normal file

File diff suppressed because one or more lines are too long

View file

@ -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 */

View file

@ -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);
});
}
};

View file

@ -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);

View file

@ -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" : []
}
};
/**

View file

@ -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);
});
}

View file

@ -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);

View file

@ -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);
});

View file

@ -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', {

View file

@ -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);

View file

@ -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);
})
}

View file

@ -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
*/

View file

@ -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"
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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
*/
/*

View file

@ -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

View file

@ -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);
}

View file

@ -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)
}

View file

@ -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)))
});

View file

@ -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);

View file

@ -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()
{

874
src/static/js/html10n.js Normal file
View file

@ -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

View file

@ -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();
}
}

View file

@ -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', '']

View file

@ -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)

View file

@ -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()

View file

@ -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){

View file

@ -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 + '">&nbsp;</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)
{

View file

@ -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)

View file

@ -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) {

View file

@ -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>

View file

@ -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>

View file

@ -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 {

View file

@ -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>

View file

@ -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>

View file

@ -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 {

View file

@ -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);
});
});

View file

@ -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();
});
});
});

View file

@ -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);
});
});