summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan <stefan@stefans-entwicklerecke.de>2016-12-23 22:00:34 +0100
committerGitHub <noreply@github.com>2016-12-23 22:00:34 +0100
commit8992dd665a37e471800d449cd06bbd0812365b8d (patch)
treee0e5c29083cc951766f90204db8707ddf62d5040
parentd6da6b3c637c92b7a2d0a8dd9e7bd27f6de4e362 (diff)
parent6dc808ad5483f616afcd64e5058ef0e69bb0c9bd (diff)
downloadetherpad-lite-8992dd665a37e471800d449cd06bbd0812365b8d.zip
Merge new release into master branch!
-rw-r--r--README.md2
-rwxr-xr-xbin/buildForWindows.sh2
-rwxr-xr-xbin/createRelease.sh176
-rw-r--r--bin/migrateDirtyDBtoRealDB.js4
-rwxr-xr-xbin/run.sh2
-rw-r--r--doc/api/editbar.md2
-rw-r--r--doc/api/hooks_client-side.md18
-rw-r--r--doc/api/http_api.md9
-rw-r--r--settings.json.template9
-rw-r--r--src/locales/ar.json23
-rw-r--r--src/locales/az.json2
-rw-r--r--src/locales/azb.json63
-rw-r--r--src/locales/de.json5
-rw-r--r--src/locales/diq.json43
-rw-r--r--src/locales/dty.json69
-rw-r--r--src/locales/eo.json5
-rw-r--r--src/locales/fr.json7
-rw-r--r--src/locales/hsb.json3
-rw-r--r--src/locales/hu.json10
-rw-r--r--src/locales/hy.json58
-rw-r--r--src/locales/ko.json9
-rw-r--r--src/locales/ku-latn.json2
-rw-r--r--src/locales/lb.json26
-rw-r--r--src/locales/lt.json39
-rw-r--r--src/locales/mk.json4
-rw-r--r--src/locales/mn.json15
-rw-r--r--src/locales/ne.json12
-rw-r--r--src/locales/oc.json2
-rw-r--r--src/locales/pa.json5
-rw-r--r--src/locales/pl.json1
-rw-r--r--src/locales/qqq.json122
-rw-r--r--src/locales/sl.json9
-rw-r--r--src/locales/sq.json54
-rw-r--r--src/locales/vi.json2
-rw-r--r--src/locales/zh-hans.json2
-rw-r--r--src/locales/zh-hant.json8
-rw-r--r--src/node/db/API.js4
-rw-r--r--src/node/handler/ExportHandler.js9
-rw-r--r--src/node/handler/PadMessageHandler.js111
-rw-r--r--src/node/hooks/express/adminsettings.js8
-rw-r--r--src/node/hooks/express/padreadonly.js4
-rw-r--r--src/node/hooks/express/specialpages.js7
-rw-r--r--src/node/hooks/express/webaccess.js2
-rw-r--r--src/node/hooks/i18n.js2
-rw-r--r--src/node/utils/ExportHtml.js111
-rw-r--r--src/node/utils/ExportTxt.js12
-rw-r--r--src/node/utils/Minify.js54
-rw-r--r--src/node/utils/Settings.js5
-rw-r--r--src/node/utils/caching_middleware.js3
-rw-r--r--src/node/utils/path_exists.js15
-rw-r--r--src/package.json36
-rw-r--r--src/static/css/admin.css6
-rw-r--r--src/static/css/iframe_editor.css207
-rw-r--r--src/static/css/lists_and_indents.css195
-rw-r--r--src/static/css/timeslider.css88
-rw-r--r--src/static/js/ace.js8
-rw-r--r--src/static/js/ace2_inner.js71
-rw-r--r--src/static/js/admin/plugins.js4
-rw-r--r--src/static/js/admin/settings.js10
-rw-r--r--src/static/js/linestylefilter.js2
-rw-r--r--src/static/js/pad.js77
-rw-r--r--src/static/js/pad_cookie.js7
-rw-r--r--src/static/js/pad_editbar.js4
-rw-r--r--src/static/js/pad_editor.js7
-rw-r--r--src/static/js/pad_utils.js9
-rw-r--r--src/static/js/pluginfw/plugins.js5
-rw-r--r--src/templates/admin/index.html1
-rw-r--r--src/templates/admin/plugins-info.html1
-rw-r--r--src/templates/admin/plugins.html1
-rw-r--r--src/templates/admin/settings.html6
-rw-r--r--src/templates/export_html.html144
-rw-r--r--src/templates/index.html35
-rw-r--r--src/templates/javascript.html73
-rw-r--r--src/templates/pad.html8
-rw-r--r--src/templates/timeslider.html5
-rw-r--r--tests/backend/specs/api/sessionsAndGroups.js2
-rw-r--r--tests/frontend/helper.js77
-rw-r--r--tests/frontend/specs/drag_and_drop.js160
-rw-r--r--tests/frontend/specs/helper.js115
-rw-r--r--tests/frontend/specs/indentation.js45
-rw-r--r--tests/frontend/specs/urls_become_clickable.js23
81 files changed, 1854 insertions, 749 deletions
diff --git a/README.md b/README.md
index cc90800f..afec716e 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ Also, check out the **[FAQ](https://github.com/ether/etherpad-lite/wiki/FAQ)**,
# Installation
-Etherpad works with node v0.10+ and io.js.
+Etherpad works with node v0.10+ (except 6.0 and 6.1).
## Windows
diff --git a/bin/buildForWindows.sh b/bin/buildForWindows.sh
index 8e921d84..fddb96a1 100755
--- a/bin/buildForWindows.sh
+++ b/bin/buildForWindows.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-NODE_VERSION="4.4.3"
+NODE_VERSION="6.9.2"
#Move to the folder where ep-lite is installed
cd `dirname $0`
diff --git a/bin/createRelease.sh b/bin/createRelease.sh
new file mode 100755
index 00000000..435ec346
--- /dev/null
+++ b/bin/createRelease.sh
@@ -0,0 +1,176 @@
+#!/bin/bash
+#
+# This script is used to publish a new release/version of etherpad on github
+#
+# Work that is done by this script:
+# ETHER_REPO:
+# - Add text to CHANGELOG.md
+# - Replace version of etherpad in src/package.json
+# - Create a release branch and push it to github
+# - Merges this release branch into master branch
+# - Creating the windows build and the docs
+# ETHER_WEB_REPO:
+# - Creating a new branch with the docs and the windows build
+# - Replacing the version numbers in the index.html
+# - Push this branch and merge it to master
+# ETHER_REPO:
+# - Create a new release on github
+
+ETHER_REPO="https://github.com/ether/etherpad-lite.git"
+ETHER_WEB_REPO="https://github.com/ether/ether.github.com.git"
+TMP_DIR="/tmp/"
+
+echo "WARNING: You can only run this script if your github api token is allowed to create and merge branches on $ETHER_REPO and $ETHER_WEB_REPO."
+echo "This script automatically changes the version number in package.json and adds a text to CHANGELOG.md."
+echo "When you use this script you should be in the branch that you want to release (develop probably) on latest version. Any changes that are currently not commited will be commited."
+echo "-----"
+
+# get the latest version
+LATEST_GIT_TAG=$(git tag | tail -n 1)
+
+# current environment
+echo "Current environment: "
+echo "- branch: $(git branch | grep '* ')"
+echo "- last commit date: $(git show --quiet --pretty=format:%ad)"
+echo "- current version: $LATEST_GIT_TAG"
+echo "- temp dir: $TMP_DIR"
+
+# get new version number
+# format: x.x.x
+echo -n "Enter new version (x.x.x): "
+read VERSION
+
+# get the message for the changelogs
+read -p "Enter new changelog entries (press enter): "
+tmp=$(mktemp)
+"${EDITOR:-vi}" $tmp
+changelogText=$(<$tmp)
+echo "$changelogText"
+rm $tmp
+
+if [ "$changelogText" != "" ]; then
+ changelogText="# $VERSION\n$changelogText"
+fi
+
+# get the token for the github api
+echo -n "Enter your github api token: "
+read API_TOKEN
+
+function check_api_token {
+ echo "Checking if github api token is valid..."
+ CURL_RESPONSE=$(curl --silent -i https://api.github.com/user?access_token=$API_TOKEN | iconv -f utf8)
+ HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/')
+ [[ $HTTP_STATUS != "200" ]] && echo "Aborting: Invalid github api token" && exit 1
+}
+
+function modify_files {
+ # Add changelog text to first line of CHANGELOG.md
+ sed -i "1s/^/${changelogText}\n/" CHANGELOG.md
+ # Replace version number of etherpad in package.json
+ sed -i -r "s/(\"version\"[ ]*: \").*(\")/\1$VERSION\2/" src/package.json
+}
+
+function create_release_branch {
+ echo "Creating new release branch..."
+ git rev-parse --verify release/$VERSION 2>/dev/null
+ if [ $? == 0 ]; then
+ echo "Aborting: Release branch already present"
+ exit 1
+ fi
+ git checkout -b release/$VERSION
+ [[ $? != 0 ]] && echo "Aborting: Error creating relase branch" && exit 1
+
+ echo "Commiting CHANGELOG.md and package.json"
+ git add CHANGELOG.md
+ git add src/package.json
+ git commit -m "Release version $VERSION"
+
+ echo "Pushing release branch to github..."
+ git push -u $ETHER_REPO release/$VERSION
+ [[ $? != 0 ]] && echo "Aborting: Error pushing release branch to github" && exit 1
+}
+
+function merge_release_branch {
+ echo "Merging release to master branch on github..."
+ API_JSON=$(printf '{"base": "master","head": "release/%s","commit_message": "Merge new release into master branch!"}' $VERSION)
+ CURL_RESPONSE=$(curl --silent -i -N --data "$API_JSON" https://api.github.com/repos/ether/etherpad-lite/merges?access_token=$API_TOKEN | iconv -f utf8)
+ echo $CURL_RESPONSE
+ HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/')
+ [[ $HTTP_STATUS != "200" ]] && echo "Aborting: Error merging release branch on github" && exit 1
+}
+
+function create_builds {
+ echo "Cloning etherpad-lite repo and ether.github.com repo..."
+ cd $TMP_DIR
+ rm -rf etherpad-lite ether.github.com
+ git clone $ETHER_REPO --branch master
+ git clone $ETHER_WEB_REPO
+ echo "Creating windows build..."
+ cd etherpad-lite
+ bin/buildForWindows.sh
+ [[ $? != 0 ]] && echo "Aborting: Error creating build for windows" && exit 1
+ echo "Creating docs..."
+ make docs
+ [[ $? != 0 ]] && echo "Aborting: Error generating docs" && exit 1
+}
+
+function push_builds {
+ cd $TMP_DIR/etherpad-lite/
+ echo "Copying windows build and docs to website repo..."
+ GIT_SHA=$(git rev-parse HEAD | cut -c1-10)
+ mv etherpad-lite-win.zip $TMP_DIR/ether.github.com/downloads/etherpad-lite-win-$VERSION-$GIT_SHA.zip
+
+ mv out/doc $TMP_DIR/ether.github.com/doc/v$VERSION
+
+ cd $TMP_DIR/ether.github.com/
+ sed -i "s/etherpad-lite-win.*\.zip/etherpad-lite-win-$VERSION-$GIT_SHA.zip/" index.html
+ sed -i "s/$LATEST_GIT_TAG/$VERSION/g" index.html
+ git checkout -b release_$VERSION
+ [[ $? != 0 ]] && echo "Aborting: Error creating new release branch" && exit 1
+ git add doc/
+ git add downloads/
+ git commit -a -m "Release version $VERSION"
+ git push -u $ETHER_WEB_REPO release_$VERSION
+ [[ $? != 0 ]] && echo "Aborting: Error pushing release branch to github" && exit 1
+}
+
+function merge_web_branch {
+ echo "Merging release to master branch on github..."
+ API_JSON=$(printf '{"base": "master","head": "release_%s","commit_message": "Release version %s"}' $VERSION $VERSION)
+ CURL_RESPONSE=$(curl --silent -i -N --data "$API_JSON" https://api.github.com/repos/ether/ether.github.com/merges?access_token=$API_TOKEN | iconv -f utf8)
+ echo $CURL_RESPONSE
+ HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/')
+ [[ $HTTP_STATUS != "200" ]] && echo "Aborting: Error merging release branch" && exit 1
+}
+
+function publish_release {
+ echo -n "Do you want to publish a new release on github (y/n)? "
+ read PUBLISH_RELEASE
+ if [ $PUBLISH_RELEASE = "y" ]; then
+ # create a new release on github
+ API_JSON=$(printf '{"tag_name": "%s","target_commitish": "master","name": "Release %s","body": "%s","draft": false,"prerelease": false}' $VERSION $VERSION $changelogText)
+ CURL_RESPONSE=$(curl --silent -i -N --data "$API_JSON" https://api.github.com/repos/ether/etherpad-lite/releases?access_token=$API_TOKEN | iconv -f utf8)
+ HTTP_STATUS=$(echo $CURL_RESPONSE | head -1 | sed -r 's/.* ([0-9]{3}) .*/\1/')
+ [[ $HTTP_STATUS != "201" ]] && echo "Aborting: Error publishing release on github" && exit 1
+ else
+ echo "No release published on github!"
+ fi
+}
+
+function todo_notification {
+ echo "Release procedure was successful, but you have to do some steps manually:"
+ echo "- Update the wiki at https://github.com/ether/etherpad-lite/wiki"
+ echo "- Create a pull request on github to merge the master branch back to develop"
+ echo "- Announce the new release on the mailing list, blog.etherpad.org and Twitter"
+}
+
+# call functions
+check_api_token
+modify_files
+create_release_branch
+merge_release_branch
+create_builds
+push_builds
+merge_web_branch
+publish_release
+todo_notification
diff --git a/bin/migrateDirtyDBtoRealDB.js b/bin/migrateDirtyDBtoRealDB.js
index 393c3081..c616714a 100644
--- a/bin/migrateDirtyDBtoRealDB.js
+++ b/bin/migrateDirtyDBtoRealDB.js
@@ -7,8 +7,8 @@ require("ep_etherpad-lite/node_modules/npm").load({}, function(er,npm) {
// file before using this script, just to be safe.
var settings = require("ep_etherpad-lite/node/utils/Settings");
- var dirty = require("dirty")('var/dirty.db');
- var ueberDB = require("../src/node_modules/ueberDB");
+ var dirty = require("../src/node_modules/dirty")('var/dirty.db');
+ var ueberDB = require("../src/node_modules/ueberdb2");
var log4js = require("../src/node_modules/log4js");
var dbWrapperSettings = {
"cache": "0", // The cache slows things down when you're mostly writing.
diff --git a/bin/run.sh b/bin/run.sh
index 08cd1da7..c50845ec 100755
--- a/bin/run.sh
+++ b/bin/run.sh
@@ -35,5 +35,5 @@ bin/installDeps.sh $* || exit 1
echo "Started Etherpad..."
SCRIPTPATH=`pwd -P`
-exec node $SCRIPTPATH/node_modules/ep_etherpad-lite/node/server.js $*
+exec node "$SCRIPTPATH/node_modules/ep_etherpad-lite/node/server.js" $*
diff --git a/doc/api/editbar.md b/doc/api/editbar.md
index ce89c0b7..d4ad4c64 100644
--- a/doc/api/editbar.md
+++ b/doc/api/editbar.md
@@ -12,7 +12,7 @@ Shows the dropdown `div.popup` whose `id` equals `dropdown`.
Register a handler for a specific command. Commands are fired if the corresponding button is clicked or the corresponding select is changed.
## registerAceCommand(cmd, callback)
-Creates an ace callstack and calls the callback with an ace instance: `callback(cmd, ace)`.
+Creates an ace callstack and calls the callback with an ace instance (and a toolbar item, if applicable): `callback(cmd, ace, item)`.
Example:
```
diff --git a/doc/api/hooks_client-side.md b/doc/api/hooks_client-side.md
index b22db5da..9af03569 100644
--- a/doc/api/hooks_client-side.md
+++ b/doc/api/hooks_client-side.md
@@ -134,6 +134,20 @@ Things in context:
This hook is made available to edit the edit events that might occur when changes are made. Currently you can change the editor information, some of the meanings of the edit, and so on. You can also make internal changes (internal to your plugin) that use the information provided by the edit event.
+## aceRegisterNonScrollableEditEvents
+Called from: src/static/js/ace2_inner.js
+
+Things in context: None
+
+When aceEditEvent (documented above) finishes processing the event, it scrolls the viewport to make caret visible to the user, but if you don't want that behavior to happen you can use this hook to register which edit events should not scroll viewport. The return value of this hook should be a list of event names.
+
+Example:
+```
+exports.aceRegisterNonScrollableEditEvents = function(){
+ return [ 'repaginate', 'updatePageCount' ];
+}
+```
+
## aceRegisterBlockElements
Called from: src/static/js/ace2_inner.js
@@ -166,11 +180,11 @@ Called from: src/static/js/pad_editbar.js
Things in context:
1. ace - the ace object that is applied to this editor.
-2. toolbar - Editbar instance. See below for the Editbar documentation.
+2. toolbar - Editbar instance. See below for the Editbar documentation.
Can be used to register custom actions to the toolbar.
-Usage examples:
+Usage examples:
* [https://github.com/tiblu/ep_authorship_toggle]()
diff --git a/doc/api/http_api.md b/doc/api/http_api.md
index 8d1b64f1..93a9b399 100644
--- a/doc/api/http_api.md
+++ b/doc/api/http_api.md
@@ -363,6 +363,15 @@ returns an object of diffs from 2 points in a pad
* `{"code":0,"message":"ok","data":{"html":"<style>\n.authora_HKIv23mEbachFYfH {background-color: #a979d9}\n.authora_n4gEeMLsv1GivNeh {background-color: #a9b5d9}\n.removed {text-decoration: line-through; -ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)'; filter: alpha(opacity=80); opacity: 0.8; }\n</style>Welcome to Etherpad!<br><br>This pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!<br><br>Get involved with Etherpad at <a href=\"http&#x3a;&#x2F;&#x2F;etherpad&#x2e;org\">http:&#x2F;&#x2F;etherpad.org</a><br><span class=\"authora_HKIv23mEbachFYfH\">aw</span><br><br>","authors":["a.HKIv23mEbachFYfH",""]}}`
* `{"code":4,"message":"no or wrong API Key","data":null}`
+#### restoreRevision(padId, rev)
+ * API >= 1.2.11
+
+Restores revision from past as new changeset
+
+*Example returns:*
+ * {code:0, message:"ok", data:null}
+ * {code: 1, message:"padID does not exist", data: null}
+
### Chat
#### getChatHistory(padID, [start, end])
* API >= 1.2.7
diff --git a/settings.json.template b/settings.json.template
index 9eaec478..6af5f78a 100644
--- a/settings.json.template
+++ b/settings.json.template
@@ -3,7 +3,7 @@
Please edit settings.json, not settings.json.template
- To still commit settings without credentials you can
+ To still commit settings without credentials you can
store any credential settings in credentials.json
*/
{
@@ -18,6 +18,9 @@
"ip": "0.0.0.0",
"port" : 9001,
+ // Option to hide/show the settings.json in admin page, default option is set to true
+ "showSettingsInAdminPage" : true,
+
/*
// Node native SSL support
// this is disabled by default
@@ -192,9 +195,9 @@
, "level": "error" // filters out all log messages that have a lower level than "error"
, "appender":
{ "type": "smtp"
- , "subject": "An error occured in your EPL instance!"
+ , "subject": "An error occurred in your EPL instance!"
, "recipients": "bar@blurdybloop.com, baz@blurdybloop.com"
- , "sendInterval": 60*5 // in secs -- will buffer log messages; set to 0 to send a mail for every message
+ , "sendInterval": 300 // 60 * 5 = 5 minutes -- will buffer log messages; set to 0 to send a mail for every message
, "transport": "SMTP", "SMTP": { // see https://github.com/andris9/Nodemailer#possible-transport-methods
"host": "smtp.example.com", "port": 465,
"secureConnection": true,
diff --git a/src/locales/ar.json b/src/locales/ar.json
index 33c6beb3..1b9271d1 100644
--- a/src/locales/ar.json
+++ b/src/locales/ar.json
@@ -7,11 +7,12 @@
"Meno25",
"Test Create account",
"محمد أحمد عبد الفتاح",
- "Haytham morsy"
+ "Haytham morsy",
+ "ديفيد"
]
},
"index.newPad": "باد جديد",
- "index.createOpenPad": "أو صنع/فتح باد بوضع إسمه:",
+ "index.createOpenPad": "أو صنع/فتح باد بوضع اسمه:",
"pad.toolbar.bold.title": "سميك (Ctrl-B)",
"pad.toolbar.italic.title": "مائل (Ctrl-I)",
"pad.toolbar.underline.title": "تسطير (Ctrl-U)",
@@ -31,7 +32,7 @@
"pad.toolbar.showusers.title": "عرض المستخدمين على هذا الباد",
"pad.colorpicker.save": "تسجيل",
"pad.colorpicker.cancel": "إلغاء",
- "pad.loading": "جاري التحميل...",
+ "pad.loading": "جارٍ التحميل...",
"pad.noCookie": "الكوكيز غير متاحة. الرجاء السماح بتحميل الكوكيز على متصفحك!",
"pad.passwordRequired": "تحتاج إلى كلمة مرور للوصول إلى هذا الباد",
"pad.permissionDenied": "ليس لديك إذن لدخول هذا الباد",
@@ -64,24 +65,24 @@
"pad.modals.forcereconnect": "فرض إعادة الاتصال",
"pad.modals.userdup": "مفتوح في نافذة أخرى",
"pad.modals.userdup.explanation": "يبدو أن هذا الباد تم فتحه في أكثر من نافذة متصفح في هذا الحاسوب.",
- "pad.modals.userdup.advice": "إعادة الاتصال لإستعمال هذه النافذة بدلاً من الاخرى.",
+ "pad.modals.userdup.advice": "إعادة الاتصال لاستعمال هذه النافذة بدلاً من الأخرى.",
"pad.modals.unauth": "غير مخول",
- "pad.modals.unauth.explanation": "لقد تغيرت الأذونات الخاصة بك أثناء عرض هذه الصفحة. حاول إعادة الاتصال.",
+ "pad.modals.unauth.explanation": "لقد تغيرت الأذونات الخاصة بك أثناء عرض هذه الصفحة. أعد محاولة الاتصال.",
"pad.modals.looping.explanation": "هناك مشاكل في الاتصال مع ملقم التزامن.",
"pad.modals.looping.cause": "ربما كنت متصلاً من خلال وكيل أو جدار حماية غير متوافق.",
"pad.modals.initsocketfail": "لا يمكن الوصول إلى الخادم",
"pad.modals.initsocketfail.explanation": "تعذر الاتصال بخادم المزامنة.",
- "pad.modals.initsocketfail.cause": "وهذا على الأرجح بسبب مشكلة في المستعرض الخاص بك أو الاتصال بإنترنت.",
+ "pad.modals.initsocketfail.cause": "هذا على الأرجح بسبب مشكلة في المستعرض الخاص بك أو الاتصال بإنترنت.",
"pad.modals.slowcommit.explanation": "الخادم لا يستجيب.",
"pad.modals.slowcommit.cause": "يمكن أن يكون هذا بسبب مشاكل في الاتصال بالشبكة.",
- "pad.modals.badChangeset.explanation": "لقد صنفت إحدى عمليات التحرير التي قمت بها كعملية غير مسموح بها من قبل ملقم التزامن.",
+ "pad.modals.badChangeset.explanation": "لقد صُنفَت إحدى عمليات التحرير التي قمت بها كعملية غير مسموح بها من قبل ملقم التزامن.",
"pad.modals.badChangeset.cause": "يمكن أن يكون هذا بسبب تكوين ملقم خاطئ أو بسبب سلوك آخر غير متوقع. يرجى الاتصال بمسؤول الخدمة إذا كنت تعتقد بأن هناك خطأ ما. حاول إعادة الاتصال لمتابعة التحرير.",
"pad.modals.corruptPad.explanation": "الباد الذي تحاول الوصول إليه تالف.",
"pad.modals.corruptPad.cause": "قد يكون هذا بسبب تكوين ملقم خاطئ أو بسبب سلوك آخر غير متوقع. يرجى الاتصال بمسؤول الخدمة.",
"pad.modals.deleted": "محذوف.",
"pad.modals.deleted.explanation": "تمت إزالة هذا الباد",
- "pad.modals.disconnected": "لم تعد متّصل.",
- "pad.modals.disconnected.explanation": "تم فقدان الإتصال بالخادم",
+ "pad.modals.disconnected": "لم تعد متصلا.",
+ "pad.modals.disconnected.explanation": "تم فقدان الاتصال بالخادم",
"pad.modals.disconnected.cause": "قد يكون الخادم غير متوفر. يرجى إعلام مسؤول الخدمة إذا كان هذا لا يزال يحدث.",
"pad.share": "شارك هذه الباد",
"pad.share.readonly": "للقراءة فقط",
@@ -98,7 +99,7 @@
"timeslider.exportCurrent": "تصدير النسخة الحالية ك:",
"timeslider.version": "إصدار {{version}}",
"timeslider.saved": "محفوظ {{month}} {{day}}, {{year}}",
- "timeslider.playPause": "تشغيل / إيقاف مؤقت محتويات الباد",
+ "timeslider.playPause": "تشغيل / إيقاف مؤقت لمحتويات الباد",
"timeslider.backRevision": "عد إلى مراجعة في هذه الباد",
"timeslider.forwardRevision": "انطلق إلى مراجعة في هذه الباد",
"timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
@@ -127,7 +128,7 @@
"pad.impexp.importing": "الاستيراد...",
"pad.impexp.confirmimport": "استيراد ملف سيؤدي للكتابة فوق النص الحالي بالباد. هل أنت متأكد من أنك تريد المتابعة؟",
"pad.impexp.convertFailed": "لم نتمكن من استيراد هذا الملف. يرجى استخدام تنسيق مستند مختلف، أو النسخ واللصق يدوياً",
- "pad.impexp.padHasData": "لا يمكننا استيراد هذا الملف لأن هذه اللوحة تم بالفعل تغييره, الرجاء استيراد لوحة جديد",
+ "pad.impexp.padHasData": "لا يمكننا استيراد هذا الملف لأن هذا الباد تم بالفعل تغييره; الرجاء استيراد باد جديد",
"pad.impexp.uploadFailed": "فشل التحميل، الرجاء المحاولة مرة أخرى",
"pad.impexp.importfailed": "فشل الاستيراد",
"pad.impexp.copypaste": "الرجاء نسخ/لصق",
diff --git a/src/locales/az.json b/src/locales/az.json
index e27beaf8..48f0f841 100644
--- a/src/locales/az.json
+++ b/src/locales/az.json
@@ -97,6 +97,8 @@
"timeslider.version": "Versiya {{version}}",
"timeslider.saved": "Saxlanıldı {{day}} {{month}}, {{year}}",
"timeslider.playPause": "Geri oxutma / Lövhə Məzmunlarını Dayandır",
+ "timeslider.backRevision": "Sənədin bundan əvvəlki bir versiyasına qayıtmaq",
+ "timeslider.forwardRevision": "Sənədin bundan sonrakı bir versiyasına qayıtmaq",
"timeslider.dateformat": "{{day}} {{month}}, {{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Yanvar",
"timeslider.month.february": "Fevral",
diff --git a/src/locales/azb.json b/src/locales/azb.json
index 995e8539..f8d8f93b 100644
--- a/src/locales/azb.json
+++ b/src/locales/azb.json
@@ -4,7 +4,8 @@
"Amir a57",
"Mousa",
"Koroğlu",
- "Alp Er Tunqa"
+ "Alp Er Tunqa",
+ "Ilğım"
]
},
"index.newPad": "یئنی یادداشت دفترچه سی",
@@ -15,25 +16,31 @@
"pad.toolbar.strikethrough.title": "خط یئمیش (Ctrl+5)",
"pad.toolbar.ol.title": "جوتدنمیش فهرست (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "جوتدنمه‌میش لیست (Ctrl+Shift+L)",
- "pad.toolbar.indent.title": "ایچری باتدیگی",
+ "pad.toolbar.indent.title": "ایچری باتما (TAB)",
"pad.toolbar.unindent.title": "ائشیگه چیخدیغی (Shift+TAB)",
"pad.toolbar.undo.title": "باطل ائتمک",
"pad.toolbar.redo.title": "یئنی دن",
- "pad.toolbar.clearAuthorship.title": "یازیچی رنگ لری پوزماق (Ctrl+Shift+C)",
+ "pad.toolbar.clearAuthorship.title": "یازیچی بوْیالارینی سیلمک (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "آیری قالیب لردن /ایچری توکمه / ائشیگه توکمه",
"pad.toolbar.timeslider.title": "زمان اسلایدی",
"pad.toolbar.savedRevision.title": "نۆسخه‌نی ذخیره ائت",
"pad.toolbar.settings.title": "تنظیملر",
- "pad.toolbar.embed.title": "بو یادداشت دفترچه سین یئرلتمک",
+ "pad.toolbar.embed.title": "بو یادداشت دفترچه سین یئرلشدیر و پایلاش",
"pad.toolbar.showusers.title": "بو دفترچه یادداشت دا اولان کاربرلری گوستر",
"pad.colorpicker.save": "ذخیره ائت",
- "pad.colorpicker.cancel": "لغو ائت",
+ "pad.colorpicker.cancel": "وازگئچ",
"pad.loading": "یوکلنیر...",
+ "pad.noCookie": "کوکی تاپیلمادی. لوطفن براوزرینیزده کوکیلره ایجازه وئرین!",
+ "pad.passwordRequired": "بو نوت دفترچه سینه ال تاپماق اوچون بیر رمزه احتیاجینیز واردیر.",
+ "pad.permissionDenied": "بو نوت دفترچه سینه ال تاپماق اوچون ایجازه نیز یوخدور.",
+ "pad.wrongPassword": "سیزین رمزینیز دوز دئییل",
"pad.settings.padSettings": "یادداشت دفترچه سینین تنظیملر",
"pad.settings.myView": "منیم گورنتوم",
"pad.settings.stickychat": "نمایش صفحه سینده همیشه چت اولسون",
+ "pad.settings.chatandusers": "چت ایله ایشلدنلری گؤستر",
"pad.settings.colorcheck": "یازیچی رنگ لری",
"pad.settings.linenocheck": "خطوط شماره سی",
+ "pad.settings.rtlcheck": "ایچینده کیلری ساغدان یوخسا سولدان اوخوسون؟",
"pad.settings.fontType": "قلم نوعی",
"pad.settings.fontType.normal": "نورمال",
"pad.settings.fontType.monospaced": "مونو اسپئیس",
@@ -41,41 +48,49 @@
"pad.settings.language": "دیل:",
"pad.importExport.import_export": "ایچری توکمه /ائشیگه توکمه",
"pad.importExport.import": "سند یا دا متنی پرونده یوکله",
+ "pad.importExport.importSuccessful": "باشاریلی اولدو!",
"pad.importExport.export": "بو یادداشت دفترچه سی عنوانا ایچری توکمه",
+ "pad.importExport.exportetherpad": "اترپد",
"pad.importExport.exporthtml": "اچ تی ام ال",
"pad.importExport.exportplain": "ساده متن",
"pad.importExport.exportword": "مایکروسافت وورد",
"pad.importExport.exportpdf": "پی دی اف",
"pad.importExport.exportopen": "او دی اف",
- "pad.modals.connected": "متصل اولدی",
- "pad.modals.reconnecting": "سیزین یادداشت دفترچه سینه یئنی دن متصیل اولدی",
- "pad.modals.forcereconnect": "یئنی اتصال اوچون زورلاما",
+ "pad.modals.connected": "باغلاندی.",
+ "pad.modals.reconnecting": "یادداشت دفترچه‌نیزه یئنی‌دن باغلانمایا چالیشیلیر...",
+ "pad.modals.forcereconnect": "تکرار باغلانماق اوچون زوْرلاما",
+ "pad.modals.userdup": "آیری پنجره ده آچیلدی",
"pad.modals.userdup.advice": "بو پئنجره دن ایستفاده ائتمک اوچون یئنی دن متصیل اول",
- "pad.modals.unauth": "اولماز",
+ "pad.modals.unauth": "اوْلماز",
"pad.modals.unauth.explanation": "سیزین ال چتما مسئله سی بو صفحه نین گورونوش زمانیندا دییشیلیب دیر .\nسعی ائدین یئنی دن متصیل اولاسینیز",
"pad.modals.looping.explanation": "ارتیباطی موشکیل بیر ائتمه سرور ده وار دیر",
"pad.modals.looping.cause": "بلکه سیز دوز دئمیین بیر فایروال یادا پروکسی طریقی ایله متصیل اولوب سینیز",
- "pad.modals.initsocketfail": "دسترسی اولمویان سرور دیر",
+ "pad.modals.initsocketfail": "سرور الده دئییلدیر.",
"pad.modals.initsocketfail.explanation": "بیرلشدیریلمه سرور لرینه متصیل اولا بیلمه دی",
+ "pad.modals.slowcommit.explanation": "سرور جواب وئرمه ییر.",
"pad.modals.deleted": "سیلیندی.",
- "pad.modals.deleted.explanation": "بو یادداشت دفترچه سی سیلینیب دیر.",
- "pad.modals.disconnected": "سیزین اتصالینیز قطع اولوب دور.",
- "pad.modals.disconnected.explanation": "سروره اتصال قطع اولوب دور.",
- "pad.share.readonly": "اوخومالی فقط",
+ "pad.modals.deleted.explanation": "بۇ یادداشت دفترچه‌سی سیلینیبدیر.",
+ "pad.modals.disconnected": "سیزین باغلانتینیز کسیلیبدیر.",
+ "pad.modals.disconnected.explanation": "سروره باغلانتی کسیلیبدیر.",
+ "pad.share": "بو نوت دفترچه سینی پایلاش",
+ "pad.share.readonly": "ساده‌جه اوْخومالی",
"pad.share.link": "باغلانتی",
- "pad.share.emebdcode": "نشانی نی یئرلتمک",
+ "pad.share.emebdcode": "یۇآرالی یئرلشدیرمک",
"pad.chat": "چت",
- "pad.chat.title": "بو یادداشت دفترچه نی چت اوچون آچ",
+ "pad.chat.title": "بو یادداشت دفترچه‌سینه چتی آچ.",
+ "pad.chat.loadmessages": "داها آرتیق پیام یوکله",
"timeslider.pageTitle": "{{appTitle}}زمان اسلایدری",
- "timeslider.toolbar.returnbutton": "یادداشت دفترچه سینه قاییت",
+ "timeslider.toolbar.returnbutton": "یادداشت دفترچه‌سینه قاییت.",
"timeslider.toolbar.authors": "یازیچیلار",
- "timeslider.toolbar.authorsList": "یازیچی سیز",
+ "timeslider.toolbar.authorsList": "یازیچی‌سیز",
"timeslider.toolbar.exportlink.title": "ائشیگه آپارماق",
+ "timeslider.exportCurrent": "موجود نوسخه نی بو عونوانلا ائشیگه چیخارت:",
+ "timeslider.version": "{{version}} ورژنی",
"timeslider.month.january": "ژانویه",
"timeslider.month.february": "فوریه",
"timeslider.month.march": "مارس",
- "timeslider.month.april": "آپریل",
- "timeslider.month.may": "مای",
+ "timeslider.month.april": "آوریل",
+ "timeslider.month.may": "مئی",
"timeslider.month.june": "ژوئن",
"timeslider.month.july": "جولای",
"timeslider.month.august": "آقوست",
@@ -83,8 +98,14 @@
"timeslider.month.october": "اوْکتوبر",
"timeslider.month.november": "نوْوامبر",
"timeslider.month.december": "دسامبر",
+ "pad.userlist.entername": "آدینیزی یازین",
"pad.userlist.unnamed": "آدسیز",
"pad.userlist.guest": "قوْناق",
"pad.userlist.deny": "دانماق",
- "pad.userlist.approve": "اوْنایلا"
+ "pad.userlist.approve": "اوْنایلا",
+ "pad.impexp.importbutton": "ایندی ایچری گتیر",
+ "pad.impexp.importing": "ایچری گتیریلیر...",
+ "pad.impexp.uploadFailed": "آپلود اولونمادی، یئنه چالیشین",
+ "pad.impexp.importfailed": "ایچری گتیرمه اولونمادی",
+ "pad.impexp.copypaste": "لوطفن کوپی ائدیب، یاپیشدیرین"
}
diff --git a/src/locales/de.json b/src/locales/de.json
index 29387fd5..f32b8cf6 100644
--- a/src/locales/de.json
+++ b/src/locales/de.json
@@ -6,11 +6,12 @@
"Nipsky",
"Wikinaut",
"Thargon",
- "Predatorix"
+ "Predatorix",
+ "Sebastian Wallroth"
]
},
"index.newPad": "Neues Pad",
- "index.createOpenPad": "oder Pad mit folgendem Namen öffnen:",
+ "index.createOpenPad": "oder ein Pad mit folgendem Namen erstellen/öffnen:",
"pad.toolbar.bold.title": "Fett (Strg-B)",
"pad.toolbar.italic.title": "Kursiv (Strg-I)",
"pad.toolbar.underline.title": "Unterstrichen (Strg-U)",
diff --git a/src/locales/diq.json b/src/locales/diq.json
index c69d6244..e1546e94 100644
--- a/src/locales/diq.json
+++ b/src/locales/diq.json
@@ -3,10 +3,12 @@
"authors": [
"Erdemaslancan",
"Gorizon",
- "Mirzali"
+ "Mirzali",
+ "Kumkumuk"
]
},
"index.newPad": "Pedo newe",
+ "index.createOpenPad": "Yana eno bamaeya bloknot vıraz/ak:",
"pad.toolbar.bold.title": "Qalın (Ctrl-B)",
"pad.toolbar.italic.title": "Namıte (Ctrl-I)",
"pad.toolbar.underline.title": "Bınxetın (Ctrl-U)",
@@ -18,6 +20,7 @@
"pad.toolbar.undo.title": "Meke (Ctrl-Z)",
"pad.toolbar.redo.title": "Fına bıke (Ctrl-Y)",
"pad.toolbar.clearAuthorship.title": "Rengê Nuştoğiê Arıstey (Ctrl+Shift+C)",
+ "pad.toolbar.import_export.title": "Babaetna tewranê dosyaya azere/ateber ke",
"pad.toolbar.timeslider.title": "Ğızagê zemani",
"pad.toolbar.savedRevision.title": "Çımraviyarnayışi qeyd ke",
"pad.toolbar.settings.title": "Sazkerdışi",
@@ -26,32 +29,57 @@
"pad.colorpicker.save": "Qeyd ke",
"pad.colorpicker.cancel": "Bıtexelne",
"pad.loading": "Bar beno...",
+ "pad.noCookie": "Çerez nêvibeya. Rovıter de çereza aktiv kerê",
+ "pad.passwordRequired": "Ena bloknot resayışi rê parola icab krna",
+ "pad.permissionDenied": "Ena bloknot resayışi rê icazeta şıma çıni ya",
"pad.wrongPassword": "Parola şıma ğeleta",
"pad.settings.padSettings": "Sazkerdışê Pedi",
"pad.settings.myView": "Asayışê mı",
+ "pad.settings.stickychat": "Ekran de tım mıhebet bıkerê",
+ "pad.settings.chatandusers": "Werênayış û Karberan bımocne",
"pad.settings.colorcheck": "Rengê nuştekariye",
"pad.settings.linenocheck": "Nımreyê xeter",
+ "pad.settings.rtlcheck": "Zerrek heto raşt ra be heto çep bıwaniyo?",
"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.import": "Dosya ya zi dokumanê meqaleyê de tesadufi bar ke",
"pad.importExport.importSuccessful": "Mıwafaq biye",
+ "pad.importExport.export": "Mewcud bloknoti ateberd:",
"pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Metno pan",
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)",
+ "pad.importExport.abiword.innerHTML": "Teyna duz metini yana html formati şıma şenê azete dê. Dehana vêşi xısusiyetanê azere kerdışi rê grey <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">AbiWord'i bar kerên</a>.",
"pad.modals.connected": "Gırediya.",
+ "pad.modals.reconnecting": "Bloknot da şıma rê fına irtibat kewê no",
"pad.modals.forcereconnect": "Mecbur anciya gırê de",
"pad.modals.userdup": "Zewbina pençere de bi a",
+ "pad.modals.userdup.explanation": "Ena bloknot ena komputer de yew ra zeder penceran dı akerde asena",
+ "pad.modals.userdup.advice": "Ena pencera ra kar finayışi rê fına irtibat kewê",
"pad.modals.unauth": "Selahiyetdar niyo",
+ "pad.modals.unauth.explanation": "Ena pela asenayış de mısadey şıma vuriyay. Fına irtibat kewtışi bıcerebne",
+ "pad.modals.looping.explanation": "Bahdê takêş kerdışi problemê irtibati esta",
+ "pad.modals.looping.cause": "Belki zi dêsê emeley hewl niyo yana şımayê proksi ya kenê dekewê de",
"pad.modals.initsocketfail": "Nêresneyêno ciyageyroği.",
+ "pad.modals.initsocketfail.explanation": "Rovıterê takêş kerdışi ya irtibato nêbeno.",
+ "pad.modals.initsocketfail.cause": "Ena probleme muhtemelen komputer yana grebıyayışa ibter da şıma ra bıya",
"pad.modals.slowcommit.explanation": "Server cewab nêdano.",
+ "pad.modals.slowcommit.cause": "Ena xeta gındık ta greyan de şıma ameya meydan",
+ "pad.modals.badChangeset.explanation": "Ena vurriyayışa şıma tereftê rovıterê tekêş kerdışi ra bêkaide deyne liste biya",
+ "pad.modals.badChangeset.cause": "Eno, xırab vıraziyena rovıteri yana nezanaye xırab yew faktori ra amrya meydan. Ena şıma çımdı xeta yena se idarekaran de sisteniya irtibat kewê. Dewam kerdışi re fına grebıyayışi bıcerebne",
+ "pad.modals.corruptPad.explanation": "Bloknota ke şımayê kenê cıresê xerpiyayi ya",
+ "pad.modals.corruptPad.cause": "Eno, xırab vıraziyena rovıteri yana nezanaye xırab yew faktori ra amrya meydan. Ena şıma çımdı xeta yena se idarekaran de sisteniya irtibat kewê",
"pad.modals.deleted": "Esteriya.",
"pad.modals.deleted.explanation": "Ena ped wedariye",
+ "pad.modals.disconnected": "İrtibata şıma reyê",
+ "pad.modals.disconnected.explanation": "Rovıteri ya irtibata şıma reyyê",
+ "pad.modals.disconnected.cause": "Qay rovıtero nêkarên o. Ena xerpey deqam kena se idarekaranê sistemiya irtibat kewê",
"pad.share": "Na ped vıla ke",
"pad.share.readonly": "Tenya bıwane",
"pad.share.link": "Gıre",
@@ -67,10 +95,13 @@
"timeslider.exportCurrent": "Versiyonê enewki teber de:",
"timeslider.version": "Versiyonê {{version}}",
"timeslider.saved": "{{day}} {{month}}, {{year}} de biyo qeyd",
+ "timeslider.playPause": "Zerrekê bloknoti kayfi/vındarn",
+ "timeslider.backRevision": "Peyser şo revizyona ena bloknoter",
+ "timeslider.forwardRevision": "Ena bloknot de şo revizyonê bini",
"timeslider.dateformat": "{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Çele",
"timeslider.month.february": "Zemherı",
- "timeslider.month.march": "Mert",
+ "timeslider.month.march": "Adar",
"timeslider.month.april": "Nisane",
"timeslider.month.may": "Gúlan",
"timeslider.month.june": "Heziran",
@@ -81,6 +112,8 @@
"timeslider.month.november": "Tışrino Peyên",
"timeslider.month.december": "Kanun",
"timeslider.unnamedauthors": "{{num}} unnamed {[plural(num) zu: nuştoğ, zewbi: nustoği ]}",
+ "pad.savedrevs.marked": "Eno vurriyayış henda qeyd bıyaye yew vurriyayış deyne nışan bıyo",
+ "pad.savedrevs.timeslider": "Xızberê zemani ziyer kerdış ra şıma şenê revizyonanê qeyd bıyayan bıvinê",
"pad.userlist.entername": "Nameyê xo cıkewe",
"pad.userlist.unnamed": "Name nébıyo",
"pad.userlist.guest": "Meyman",
@@ -89,7 +122,11 @@
"pad.editbar.clearcolors": "Wesiqa de renge nuştoğey bıesterneye?",
"pad.impexp.importbutton": "Nıka miyan ke",
"pad.impexp.importing": "Deyeno azere...",
+ "pad.impexp.confirmimport": "Yu dosya azere kerdış de mewcud bloknoti sero nuşiye no. Şıma qayılê dewam bıkerê?",
+ "pad.impexp.convertFailed": "Ena dosya azere kerdış mıkum niyo. Babetna namey dokumani weçinê yana xo desti kopya kerê u pronê.",
+ "pad.impexp.padHasData": "Ma nêşa dosya azere kem, çıkı ena bloknot xora vurriya ya. Xorê yewna bloknot azere kerê",
"pad.impexp.uploadFailed": "Barkerdış nêbi, kerem ke anciya bıcerebne",
"pad.impexp.importfailed": "Zer kerdış mıwafaq nebı",
- "pad.impexp.copypaste": "Reca keme kopya pronayış bıkeri"
+ "pad.impexp.copypaste": "Reca keme kopya pronayış bıkeri",
+ "pad.impexp.exportdisabled": "Formatta {{type}} ya ateber kerdış dewra vıciya yo. Qandé teferruati idarekarana irtibat kewê"
}
diff --git a/src/locales/dty.json b/src/locales/dty.json
index fde36512..c0d439e6 100644
--- a/src/locales/dty.json
+++ b/src/locales/dty.json
@@ -2,7 +2,8 @@
"@metadata": {
"authors": [
"रमेश सिंह बोहरा",
- "राम प्रसाद जोशी"
+ "राम प्रसाद जोशी",
+ "Nirajan pant"
]
},
"index.newPad": "नयाँ प्याड",
@@ -18,6 +19,7 @@
"pad.toolbar.undo.title": "खारेजी (Ctrl-Z)",
"pad.toolbar.redo.title": "दोसर्या:लागु (Ctrl-Y)",
"pad.toolbar.clearAuthorship.title": "लेखकीय रङ्ग हटाउन्या (Ctrl+Shift+C)",
+ "pad.toolbar.import_export.title": "विविध फाइल फर्म्याटअन बठेइ/मी आयात/निर्यात",
"pad.toolbar.timeslider.title": "टाइमस्लाइडर",
"pad.toolbar.savedRevision.title": "पुनरावलोकन संग्रहा गद्य्य",
"pad.toolbar.settings.title": "सेटिङ्गहरू",
@@ -26,6 +28,7 @@
"pad.colorpicker.save": "सङ्ग्रह गद्या",
"pad.colorpicker.cancel": "खारेजी",
"pad.loading": "लोड हुन्नाछ....",
+ "pad.noCookie": "कुकी पाउन नाइ सकियो। तमरा ब्राउजरमी कुकी राख्दाइ अनुमति दिय!",
"pad.passwordRequired": "यो प्यड खोल्लाकी पासवर्ड चाहिन्छ",
"pad.permissionDenied": "तमलाईँ यै प्याड खोल्लाकी अनुमति नाइथिन",
"pad.wrongPassword": "तमरो पासवर्ड गलत थ्यो",
@@ -49,16 +52,78 @@
"pad.importExport.exportword": "माइक्रोसफ्ट वर्ड",
"pad.importExport.exportpdf": "पिडिएफ",
"pad.importExport.exportopen": "ओडिएफ(खुल्ला कागजात ढाँचा)",
+ "pad.importExport.abiword.innerHTML": "तम सादा पाठ या HTML ढाँचा बठेइ मात्तरी आयात अरीसकन्छऽ। विस्तारित आयात विशेषता खिलाई कृपया <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">abiword स्थापना अरऽ</a>।",
"pad.modals.connected": "जोडीयाको",
"pad.modals.reconnecting": "तमरो प्याडमि आजि: जडान हुन्नाछ",
+ "pad.modals.forcereconnect": "बलात् पुन:जडान",
+ "pad.modals.userdup": "अर्खा विण्डोमी खुलिरैछ",
+ "pad.modals.userdup.explanation": "यो प्याड येइ कम्प्युटरमी एक़ है बर्ता ब्राउजर सञ्झ्यालमी खोल्याऽ धेकीँछ।",
+ "pad.modals.userdup.advice": "बरु यो विण्डो प्रयोग अद्दाइ दोसर्‍याँ जोणिय।",
+ "pad.modals.unauth": "अनुमति नदियीयाऽ",
+ "pad.modals.unauth.explanation": "येइ पन्ना हेरनज्याँ तमरा अधिकार बदेलिया। दोसर्‍याँ जोणिन्या प्रयास अरऽ।",
+ "pad.modals.looping.explanation": "सिक्रोनाइजेसन सर्भर सित सञ्चार समस्या धेकिन्नाछ़।",
+ "pad.modals.looping.cause": "शायद तम यक असंगत फायरवाल या प्रोक्सी का माध्यम बठेइ जोणीरैछऽ।",
"pad.modals.initsocketfail": "सर्भरमा पहुँच पुर्‍याउन नाइसकियो ।",
+ "pad.modals.initsocketfail.explanation": "सिङ्क्रोनाइजेसन सर्भर सित जोणीन नाइ सकियो?",
+ "pad.modals.initsocketfail.cause": "यो शायद तमरा ब्राउजर या इन्टरनेट जडान सित सम्बन्धित समस्याऽ कारणले होइ सकन्छ़।",
+ "pad.modals.slowcommit.explanation": "सर्भर प्रत्युत्तर दिन्नारेन।",
+ "pad.modals.slowcommit.cause": "यो नेटवर्क कनेक्टिविटी सङ्ङ सम्बन्धित समस्याऽ कारण ले होइसकन्छ।",
+ "pad.modals.badChangeset.explanation": "तमले अर्‍याऽ यक सम्पादन समक्रमण सर्भर हताँ अवैध वर्गीकृत अरियाऽ थ्यो।",
+ "pad.modals.badChangeset.cause": "यो यक गलत सर्भर विन्यास या केइ और अप्रत्याशित चालचलनाऽ कारण़ ले होइसकन्छ। यदि तमलाई यो गल्ती हो भण्ण्या लागन्छ भँण्या, कृपया सेवा व्यवस्थापकलाई सम्पर्क अरऽ। सम्पादन चालु राख्दाइ दोसर्‍याँ जोणिन्या प्रयास अरऽ।",
+ "pad.modals.corruptPad.explanation": "तमले उपयोग अद्द़ खोज्याऽ प्याड बिगण्योऽ छ।",
+ "pad.modals.corruptPad.cause": "यो गलत सर्भर विन्यास या केइ और नसोच्याऽ चालचलनले होइसकन्छ। कृपया सेवा व्यवस्थापकलाई सम्पर्क अरऽ।",
"pad.modals.deleted": "मेटियाको",
"pad.modals.deleted.explanation": "यो प्याड हटाइसक्याको छ ।",
"pad.modals.disconnected": "तमरो जडान अवरुद्ध भयो ।",
"pad.modals.disconnected.explanation": "तमरो सर्भरसितको जडान अवरुद्ध भयो",
+ "pad.modals.disconnected.cause": "सर्भर अनुपलब्ध होइसकन्छ। यदि यो हुनोइ रयाबर कृपया सेवा व्यवस्थापकलाई सूचित अरऽ।",
"pad.share": "यस प्यडलाई बाड्न्या",
"pad.share.readonly": "पड्या मात्तरै",
"pad.share.link": "लिङ्क",
"pad.share.emebdcode": "URL थप्प्या",
- "pad.chat": "कुरणिकानी"
+ "pad.chat": "कुरणिकानी",
+ "pad.chat.title": "येइ प्याड खिलाइ गफ खोलऽ",
+ "pad.chat.loadmessages": "जेदा सन्देश लोड अरऽ",
+ "timeslider.pageTitle": "{{appTitle}} समय स्लाइडर",
+ "timeslider.toolbar.returnbutton": "प्याडमी फर्कऽ",
+ "timeslider.toolbar.authors": "लेखकअन:",
+ "timeslider.toolbar.authorsList": "लेखकअन आथीनन",
+ "timeslider.toolbar.exportlink.title": "निर्यात",
+ "timeslider.exportCurrent": "हालआ शंसोधनलाई इस्याँ निर्यात अरऽ:",
+ "timeslider.version": "संस्करण {{version}}",
+ "timeslider.saved": "भँणार अरीयाऽ {{month}} {{day}}, {{year}}",
+ "timeslider.playPause": "प्याडआ सामाग्रीइनलाई प्लेब्याक/पउज अरऽ",
+ "timeslider.backRevision": "येइ प्याडमी यक शंसोधन पछा जाऽ",
+ "timeslider.forwardRevision": "येइ शंसोधनमी यक शंसोधन अघा जाऽ",
+ "timeslider.dateformat": "{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
+ "timeslider.month.january": "जनवरी",
+ "timeslider.month.february": "फेब्रुअरी",
+ "timeslider.month.march": "मार्च",
+ "timeslider.month.april": "अप्रिल",
+ "timeslider.month.may": "मे",
+ "timeslider.month.june": "जुन",
+ "timeslider.month.july": "जुलाई",
+ "timeslider.month.august": "अगस्ट",
+ "timeslider.month.september": "सेप्टेम्बर",
+ "timeslider.month.october": "अक्टोबर",
+ "timeslider.month.november": "नोभेम्बर",
+ "timeslider.month.december": "डिसेम्बर",
+ "timeslider.unnamedauthors": "{{num}} बिननाउँइको {[plural(num) one: author, other: authors ]}",
+ "pad.savedrevs.marked": "आब येइ संशोधनलाई सङ्ग्रहित संशोधनआ रूपमी चिनो लायियो",
+ "pad.savedrevs.timeslider": "समयस्लाइडर भेटिबर तम भँणार अरीयाऽ शंसोधनअनलाई हेरि सकन्छऽ",
+ "pad.userlist.entername": "तमरो नाउँ हाल",
+ "pad.userlist.unnamed": "बिननाउँइको",
+ "pad.userlist.guest": "पाउनो",
+ "pad.userlist.deny": "अस्वीकार",
+ "pad.userlist.approve": "अनुमोदन",
+ "pad.editbar.clearcolors": "सङताइ कागताजमी है लेखक रङ्ङअन साप अद्द्या?",
+ "pad.impexp.importbutton": "ऐलै आयार अरऽ",
+ "pad.impexp.importing": "आयात अद्दाछ़...",
+ "pad.impexp.confirmimport": "फाइल आयात़ ले प्याडओ अइलओ पाठ बदेलिन्या हो। तम ऐतिऱ बड्ड चाहन्छ भणिबर पक्का छऽ?",
+ "pad.impexp.convertFailed": "एइ फाइललाई आयात अद्द नाइसक्यो। कृपया जुदोइ कागजात फर्याट प्रयोग अरऽ या नकल पेस्ट अरऽ",
+ "pad.impexp.padHasData": "हम एइ फाइलाई आयात अद्दाइ असमर्थ छौँ क्याइकि एइ प्याडमी पैली अरीयाऽ फेलबदेल छन्, कृपया नयाँ प्याडमी आयात अरऽ",
+ "pad.impexp.uploadFailed": "अपलोड असफल, कृपया दोसर्‍याँ प्रयास अर:",
+ "pad.impexp.importfailed": "आयात असफल",
+ "pad.impexp.copypaste": "कृपया नकल सार अर:",
+ "pad.impexp.exportdisabled": "{{type}} फर्म्याटमी निर्यात अक्षम अरीरैछ। विवरण खिलाइ कृपया तमरा संयन्त्र प्रशासकलाई सम्पर्क अर:।"
}
diff --git a/src/locales/eo.json b/src/locales/eo.json
index c4526728..786d3bbe 100644
--- a/src/locales/eo.json
+++ b/src/locales/eo.json
@@ -3,7 +3,8 @@
"authors": [
"Eliovir",
"Mschmitt",
- "Objectivesea"
+ "Objectivesea",
+ "Robin van der Vliet"
]
},
"index.newPad": "Nova Teksto",
@@ -120,7 +121,7 @@
"pad.userlist.approve": "Aprobi",
"pad.editbar.clearcolors": "Forigi kolorojn de aŭtoreco en la tuta dokumento?",
"pad.impexp.importbutton": "Enporti Nun",
- "pad.impexp.importing": "Enportanta...",
+ "pad.impexp.importing": "Enportante...",
"pad.impexp.confirmimport": "Enporti dosieron superskribos la nunan tekston en la redaktilo. Ĉu vi certe volas daŭrigi?",
"pad.impexp.convertFailed": "Ni ne kapablis enporti tiun dosieron. Bonvolu uzi alian dokumentformaton aŭ permane kopii kaj alglui.",
"pad.impexp.padHasData": "Ni ne kapablis enporti tiun dosieron ĉar la teksto jam estas ŝanĝita. Bonvolu enporti en novan tekston.",
diff --git a/src/locales/fr.json b/src/locales/fr.json
index 27382354..47f490c1 100644
--- a/src/locales/fr.json
+++ b/src/locales/fr.json
@@ -21,7 +21,8 @@
"Macofe",
"Framafan",
"Fylip22",
- "C13m3n7"
+ "C13m3n7",
+ "Wladek92"
]
},
"index.newPad": "Nouveau pad",
@@ -141,8 +142,8 @@
"pad.impexp.importing": "Import en cours...",
"pad.impexp.confirmimport": "Importer un fichier écrasera le contenu actuel du pad. Êtes-vous sûr de vouloir le faire ?",
"pad.impexp.convertFailed": "Nous ne pouvons pas importer ce fichier. Veuillez utiliser un autre format de document ou faire manuellement un copier/coller du texte brut",
- "pad.impexp.padHasData": "Nous n’avons pas pu importer ce fichier parce que ce pad a déjà eu des modifications ; veuillez donc en créer un nouveau",
- "pad.impexp.uploadFailed": "Le téléchargement a échoué, veuillez réessayer",
+ "pad.impexp.padHasData": "Nous n’avons pas pu importer ce fichier parce que ce pad a déjà eu des modifications ; veuillez donc créer un nouveau pad",
+ "pad.impexp.uploadFailed": "Le téléversement a échoué, veuillez réessayer",
"pad.impexp.importfailed": "Échec de l'importation",
"pad.impexp.copypaste": "Veuillez copier/coller",
"pad.impexp.exportdisabled": "L'option d'export au format {{type}} est désactivée. Veuillez contacter votre administrateur système pour plus de détails."
diff --git a/src/locales/hsb.json b/src/locales/hsb.json
index d4d3ef76..798c596e 100644
--- a/src/locales/hsb.json
+++ b/src/locales/hsb.json
@@ -92,6 +92,9 @@
"timeslider.exportCurrent": "Aktualnu wersiju eksportować jako:",
"timeslider.version": "Wersija {{version}}",
"timeslider.saved": "Składowany {{day}}. {{month}} {{year}}",
+ "timeslider.playPause": "Wobdźěłanje wothrać/pawzować",
+ "timeslider.backRevision": "Wo jednu wersiju w tutym dokumenće wróćo hić",
+ "timeslider.forwardRevision": "Wo jednu wersiju w tutym dokumenće doprědka hić",
"timeslider.dateformat": "{{day}}. {{month}} {{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "januara",
"timeslider.month.february": "februara",
diff --git a/src/locales/hu.json b/src/locales/hu.json
index c4d06c27..f34c76ca 100644
--- a/src/locales/hu.json
+++ b/src/locales/hu.json
@@ -64,7 +64,7 @@
"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 megváltoztak, miközben ezt az oldalt nézted. Próbálj meg újrakapcsolódni.",
+ "pad.modals.unauth.explanation": "A jogosultságaid megváltoztak, miközben ezt az oldalt nézted. Próbálj meg újrakapcsolódni!",
"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.",
@@ -96,6 +96,9 @@
"timeslider.exportCurrent": "Jelenlegi változat exportálása így:",
"timeslider.version": "{{version}} verzió",
"timeslider.saved": "{{year}}. {{month}} {{day}}-n elmentve",
+ "timeslider.playPause": "Notesz tartalom visszajátszása / leállítása",
+ "timeslider.backRevision": "Egy revízióval vissza a noteszben",
+ "timeslider.forwardRevision": "Egy revízióval előre a noteszben",
"timeslider.dateformat": "{{year}}/{{month}}/{{day}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "január",
"timeslider.month.february": "február",
@@ -109,8 +112,9 @@
"timeslider.month.october": "október",
"timeslider.month.november": "november",
"timeslider.month.december": "december",
- "timeslider.unnamedauthors": "{{num}} névtelen {[plural(num), one: szerző, other: szerző]}",
+ "timeslider.unnamedauthors": "{{num}} névtelen {[plural(num), one: szerző, other: szerzők]}",
"pad.savedrevs.marked": "Ez a revízió mostantól mentettként jelölve",
+ "pad.savedrevs.timeslider": "A mentett revíziókat az időcsúszkán tudod megnézni",
"pad.userlist.entername": "Add meg a nevedet",
"pad.userlist.unnamed": "névtelen",
"pad.userlist.guest": "Vendég",
@@ -121,7 +125,7 @@
"pad.impexp.importing": "Importálás…",
"pad.impexp.confirmimport": "Egy fájl importálása felülírja a jelenlegi szöveget a noteszben. Biztos hogy folytatod?",
"pad.impexp.convertFailed": "Nem tudtuk importálni ezt a fájlt. Kérjük, használj másik dokumentum formátumot, vagy kézzel másold és illeszd be a tartalmat",
- "pad.impexp.padHasData": "Nem tudjuk importálni ezt a fájlt, mert ez a Pad már megváltozott, kérjük, importálj egy új padra",
+ "pad.impexp.padHasData": "Nem tudjuk importálni ezt a fájlt, mert ez a notesz már megváltozott, kérjük, importálj egy új noteszba.",
"pad.impexp.uploadFailed": "A feltöltés sikertelen, próbáld meg újra",
"pad.impexp.importfailed": "Az importálás nem sikerült",
"pad.impexp.copypaste": "Kérjük másold be",
diff --git a/src/locales/hy.json b/src/locales/hy.json
new file mode 100644
index 00000000..672905c5
--- /dev/null
+++ b/src/locales/hy.json
@@ -0,0 +1,58 @@
+{
+ "@metadata": {
+ "authors": [
+ "Kareyac"
+ ]
+ },
+ "pad.toolbar.underline.title": "ընդգծելով (Ctrl-U)",
+ "pad.toolbar.undo.title": "Չեղարկել (Ctrl-Z)",
+ "pad.toolbar.redo.title": "Վերադարձնել (Ctrl-Y)",
+ "pad.toolbar.clearAuthorship.title": "Մաքրել փաստաթղթի գույներ (Ctrl+Shift+C)",
+ "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.wrongPassword": "Սխալ գաղտնաբառ",
+ "pad.settings.myView": "Իմ տեսարան",
+ "pad.settings.rtlcheck": "Կարդալ բովանդակությունը աջից ձախ",
+ "pad.settings.fontType": "Տառատեսակի տեսակը",
+ "pad.settings.globalView": "Ընդհանուր տեսքը",
+ "pad.settings.language": "Լեզու",
+ "pad.importExport.import_export": "Ներմուծում/արտահանում",
+ "pad.importExport.import": "Բեռնել ցանկացած տեքստային ֆայլը կամ փաստաթուղթ",
+ "pad.importExport.importSuccessful": "Հաջողություն",
+ "pad.importExport.export": "Արտահանել ընթացիկ փաստաթուղթ է որպես",
+ "pad.importExport.exportplain": "Պարզ տեքստ",
+ "pad.importExport.exportpdf": "PDF",
+ "pad.modals.connected": "Կապված է",
+ "pad.modals.forcereconnect": "Հարկադիր վերամիավորել",
+ "pad.modals.userdup": "Բաց է մյուս պատուհանում",
+ "pad.modals.initsocketfail": "Սերվերը անհասանելի է ։",
+ "pad.modals.slowcommit.explanation": "Սերվերը չի պատասխանում։",
+ "pad.modals.deleted": "Ջնջված է",
+ "pad.share.readonly": "Միայն կարդալու",
+ "pad.share.link": "Հղում",
+ "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": "Դեկտեմբեր",
+ "pad.userlist.entername": "Մուտքագրեք ձեր անունը",
+ "pad.userlist.unnamed": "անանուն",
+ "pad.userlist.guest": "Հյուր",
+ "pad.userlist.deny": "Մերժել",
+ "pad.userlist.approve": "Հաստատել",
+ "pad.impexp.importbutton": "Ներմուծել հիմա",
+ "pad.impexp.copypaste": "Խնդրում ենք պատճենել"
+}
diff --git a/src/locales/ko.json b/src/locales/ko.json
index 87f4eba7..d0ba7bdc 100644
--- a/src/locales/ko.json
+++ b/src/locales/ko.json
@@ -5,12 +5,13 @@
"아라",
"Revi",
"Kurousagi",
- "SeoJeongHo"
+ "SeoJeongHo",
+ "Ykhwong"
]
},
"index.newPad": "새 패드",
"index.createOpenPad": "또는 다음 이름으로 패드 만들기/열기:",
- "pad.toolbar.bold.title": "굵은꼴 (Ctrl+B)",
+ "pad.toolbar.bold.title": "굵게 (Ctrl+B)",
"pad.toolbar.italic.title": "기울임꼴 (Ctrl+I)",
"pad.toolbar.underline.title": "밑줄 (Ctrl+U)",
"pad.toolbar.strikethrough.title": "취소선 (Ctrl+5)",
@@ -37,7 +38,7 @@
"pad.settings.padSettings": "패드 설정",
"pad.settings.myView": "내 보기",
"pad.settings.stickychat": "화면에 항상 대화 보기",
- "pad.settings.chatandusers": "채트와 사용자 보이기",
+ "pad.settings.chatandusers": "채트와 사용자 보기",
"pad.settings.colorcheck": "저자 색",
"pad.settings.linenocheck": "줄 번호",
"pad.settings.rtlcheck": "우횡서(오른쪽에서 왼쪽으로)입니까?",
@@ -125,7 +126,7 @@
"pad.impexp.importing": "가져오는 중...",
"pad.impexp.confirmimport": "파일을 가져오면 패드의 현재 텍스트를 덮어쓰게 됩니다. 진행하시겠습니까?",
"pad.impexp.convertFailed": "이 파일을 가져올 수 없습니다. 다른 문서 형식을 사용하거나 수동으로 복사하여 붙여넣으세요",
- "pad.impexp.padHasData": "우리는 이 파일을 가져올수 없었습니다. 이 패드는 이미 수정되었으니, 새 패드를 가져와 주십시오",
+ "pad.impexp.padHasData": "우리는 이 파일을 가져올 수 없었습니다. 이 패드는 이미 수정되었으니, 새 패드를 가져와 주십시오",
"pad.impexp.uploadFailed": "올리기를 실패했습니다. 다시 시도하세요",
"pad.impexp.importfailed": "가져오기를 실패했습니다",
"pad.impexp.copypaste": "복사하여 붙여넣으세요",
diff --git a/src/locales/ku-latn.json b/src/locales/ku-latn.json
index 2aa4fda7..725a84d7 100644
--- a/src/locales/ku-latn.json
+++ b/src/locales/ku-latn.json
@@ -22,7 +22,7 @@
"pad.toolbar.savedRevision.title": "Sererastkirinê tomar bike",
"pad.toolbar.settings.title": "Eyar",
"pad.colorpicker.save": "Tomar bike",
- "pad.colorpicker.cancel": "Beta bike",
+ "pad.colorpicker.cancel": "Betal bike",
"pad.loading": "Tê barkirin...",
"pad.settings.padSettings": "Eyarên bloknotê",
"pad.settings.myView": "Dîmena min",
diff --git a/src/locales/lb.json b/src/locales/lb.json
index 99bfe0b5..50cebaf2 100644
--- a/src/locales/lb.json
+++ b/src/locales/lb.json
@@ -8,10 +8,14 @@
},
"index.newPad": "Neie Pad",
"index.createOpenPad": "oder maacht ee Pad mat dësem Numm op:",
+ "pad.toolbar.bold.title": "Fett (Strg-B)",
+ "pad.toolbar.italic.title": "Schréi (Ctrl+I)",
"pad.toolbar.underline.title": "Ënnerstrach (Ctrl+U)",
"pad.toolbar.strikethrough.title": "Duerchgestrach (Ctrl+5)",
"pad.toolbar.ol.title": "Numeréiert Lëscht (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Net-numeréiert Lëscht (Ctrl+Shift+L)",
+ "pad.toolbar.indent.title": "Aréckelen (TAB)",
+ "pad.toolbar.unindent.title": "Erausréckelen (Shift+TAB)",
"pad.toolbar.undo.title": "Réckgängeg (Ctrl-Z)",
"pad.toolbar.redo.title": "Widderhuelen (Ctrl-Y)",
"pad.toolbar.savedRevision.title": "Versioun späicheren",
@@ -25,23 +29,38 @@
"pad.permissionDenied": "Dir hutt net déi néideg Rechter fir dëse Pad opzemaachen",
"pad.wrongPassword": "Äert Passwuert ass falsch",
"pad.settings.myView": "Méng Usiicht",
+ "pad.settings.linenocheck": "Zeilennummeren",
+ "pad.settings.rtlcheck": "Inhalt vu riets no lénks liesen?",
+ "pad.settings.fontType": "Schrëftart:",
"pad.settings.fontType.normal": "Normal",
+ "pad.settings.globalView": "Global Vue",
"pad.settings.language": "Sprooch:",
"pad.importExport.import_export": "Import/Export",
+ "pad.importExport.import": "Text-Fichier oder Dokument eroplueden",
"pad.importExport.importSuccessful": "Erfollegräich",
+ "pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
+ "pad.importExport.exportplain": "Kloertext",
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.modals.connected": "Verbonnen.",
+ "pad.modals.userdup": "An enger anerer Fënster opgemaach",
"pad.modals.unauth": "Net autoriséiert",
+ "pad.modals.unauth.explanation": "Är Rechter hu geännert während deem Dir dës säit gekuckt hutt. Probéiert fir Iech nei ze connectéieren.",
+ "pad.modals.looping.explanation": "Et gëtt Kommunikatiounsproblemer mam Synchronisatiouns-Server.",
+ "pad.modals.initsocketfail": "De Server kann net erreecht ginn.",
"pad.modals.slowcommit.explanation": "De Server äntwert net.",
"pad.modals.deleted": "Geläscht.",
+ "pad.modals.disconnected": "Äre Verbindung ass ofgebrach.",
+ "pad.modals.disconnected.explanation": "D'Verbindung mam Server ass verluergaang.",
"pad.share.readonly": "Nëmme liesen",
"pad.share.link": "Link",
+ "pad.chat": "Chat",
"pad.chat.loadmessages": "Méi Message lueden",
"timeslider.toolbar.authors": "Auteuren:",
"timeslider.toolbar.authorsList": "Keng Auteuren",
+ "timeslider.toolbar.exportlink.title": "Exportéieren",
"timeslider.exportCurrent": "Exportéiert déi aktuell Versioun als:",
"timeslider.version": "Versioun {{version}}",
"timeslider.saved": "Gespäichert de(n) {{day}} {{month}} {{year}}",
@@ -58,9 +77,14 @@
"timeslider.month.october": "Oktober",
"timeslider.month.november": "November",
"timeslider.month.december": "Dezember",
+ "pad.savedrevs.marked": "Dës Versioun ass elo als gespäichert Versioun markéiert",
"pad.userlist.entername": "Gitt Ären Numm an",
+ "pad.userlist.unnamed": "anonym",
"pad.userlist.guest": "Gaascht",
+ "pad.userlist.deny": "Refuséieren",
"pad.userlist.approve": "Zoustëmmen",
"pad.impexp.importbutton": "Elo importéieren",
- "pad.impexp.importing": "Importéieren..."
+ "pad.impexp.importing": "Importéieren...",
+ "pad.impexp.uploadFailed": "D'Eroplueden huet net funktionéiert, probéiert w.e.g. nach eng Kéier",
+ "pad.impexp.importfailed": "Den Import huet net funktionéiert"
}
diff --git a/src/locales/lt.json b/src/locales/lt.json
index 524146de..f0f02d1e 100644
--- a/src/locales/lt.json
+++ b/src/locales/lt.json
@@ -3,9 +3,12 @@
"authors": [
"Eitvys200",
"Mantak111",
- "I-svetaines"
+ "I-svetaines",
+ "Zygimantus"
]
},
+ "index.newPad": "Naujas bloknotas",
+ "index.createOpenPad": "arba sukurkite/atidarykite Bloknotą su pavadinimu:",
"pad.toolbar.bold.title": "Paryškintasis (Ctrl-B)",
"pad.toolbar.italic.title": "Pasvirasis (Ctrl-I)",
"pad.toolbar.underline.title": "Pabraukimas (Ctrl-U)",
@@ -13,9 +16,10 @@
"pad.toolbar.ol.title": "Numeruotas sąrašas (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Nenumeruotas Sąrašas (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Įtrauka",
+ "pad.toolbar.unindent.title": "Atvirkštinė įtrauka (Shift+TAB)",
"pad.toolbar.undo.title": "Anuliuoti (Ctrl-Z)",
"pad.toolbar.redo.title": "Perdaryti (Ctrl-Y)",
- "pad.toolbar.clearAuthorship.title": "Tvarkyti autorystės spalvas",
+ "pad.toolbar.clearAuthorship.title": "Valyti Autorystės Spalvas (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Importuoti/Eksportuoti iš/į įvairius failų formatus",
"pad.toolbar.timeslider.title": "Laiko slankiklis",
"pad.toolbar.savedRevision.title": "Išsaugoti peržiūrą",
@@ -50,29 +54,49 @@
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Atvirasis dokumento formatas)",
+ "pad.importExport.abiword.innerHTML": "Galite importuoti tik iš paprasto teksto ar HTML formato. Dėl išplėstinių importavimo funkcijų prašome <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">įdiegti abiword</a>.",
"pad.modals.connected": "Prisijungta.",
"pad.modals.reconnecting": "Iš naujo prisijungiama prie Jūsų bloknoto",
"pad.modals.forcereconnect": "Priversti prisijungti iš naujo",
"pad.modals.userdup": "Atidaryta kitame lange",
"pad.modals.userdup.explanation": "Šis bloknotas, atrodo yra atidarytas daugiau nei viename šio kompiuterio naršyklės lange.",
+ "pad.modals.userdup.advice": "Prisijunkite iš naujo, kad vietoj to naudotumėte šį langą.",
"pad.modals.unauth": "Neleidžiama",
"pad.modals.unauth.explanation": "Jūsų teiisės pasikeitė kol žiūrėjote šį puslapį. Bandykite prisijungti iš naujo.",
"pad.modals.looping.explanation": "Yra komunikacijos problemų su sinchronizacijos serveriu.",
+ "pad.modals.looping.cause": "Galbūt prisijungėte per nesuderinamą ugniasienę ar proxy.",
"pad.modals.initsocketfail": "Serveris yra nepasiekiamas.",
+ "pad.modals.initsocketfail.explanation": "Nepavyko prisijungti prie sinchronizacijos serverio.",
+ "pad.modals.initsocketfail.cause": "Tai tikriausiai nutiko dėl problemų su jūsų naršykle ar jūsų interneto ryšiu.",
"pad.modals.slowcommit.explanation": "Serveris neatsako.",
+ "pad.modals.slowcommit.cause": "Tai gali būti dėl problemų su tinklo ryšiu.",
+ "pad.modals.badChangeset.explanation": "Pakeitimas, kurį atlikote buvo klasifikuotas sinchorizacijos serverio kaip neteisėtas.",
+ "pad.modals.badChangeset.cause": "Tai galėjo nutikti dėl neteisingos serverio konfigūracijos ar kitos netikėtos elgsenos. Prašome susisiekti su paslaugos administratoriumi jei manote, kad tai klaida. Pabandykite prisijungti iš naujo, kad tęstumėte redagavimą.",
+ "pad.modals.corruptPad.explanation": "Bloknotas, kurį bandote pasiekti yra sugadintas.",
+ "pad.modals.corruptPad.cause": "Tai gali nutikti dėl neteisingos serverio konfigūracijos ar kitos netikėtos elgsenos. Prašome susisiekti su paslaugos administratoriumi.",
"pad.modals.deleted": "Ištrintas.",
+ "pad.modals.deleted.explanation": "Bloknotas buvo pašalintas.",
"pad.modals.disconnected": "Jūs atsijungėte.",
+ "pad.modals.disconnected.explanation": "Ryšys su serveriu nutrūko",
+ "pad.modals.disconnected.cause": "Gali būti, kad serveris yra nepasiekiamas. Prašome informuoti paslaugos administratorių jei tai tęsiasi.",
+ "pad.share": "Dalintis šiuo bloknotu",
"pad.share.readonly": "Tik skaityti",
"pad.share.link": "Nuoroda",
"pad.share.emebdcode": "Įterptasis URL",
"pad.chat": "Pokalbiai",
+ "pad.chat.title": "Atverti šio bloknoto pokalbį.",
"pad.chat.loadmessages": "Įkrauti daugiau pranešimų",
+ "timeslider.pageTitle": "{{appTitle}} Laiko slinkiklis",
+ "timeslider.toolbar.returnbutton": "Grįžti į bloknotą",
"timeslider.toolbar.authors": "Autoriai:",
"timeslider.toolbar.authorsList": "Nėra autorių",
"timeslider.toolbar.exportlink.title": "Eksportuoti",
"timeslider.exportCurrent": "Eksportuoti dabartinę versiją kaip:",
"timeslider.version": "Versija {{version}}",
"timeslider.saved": "Išsaugota {{year}},{{month}} {{day}}",
+ "timeslider.playPause": "Atkurti / Pristabdyti Bloknoto Turinį",
+ "timeslider.backRevision": "Grįžti viena Bloknoto peržiūra atgal",
+ "timeslider.forwardRevision": "Eiti viena Bloknoto peržiūra į priekį",
"timeslider.dateformat": "{{year}}-{{month}}-{{day}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Sausis",
"timeslider.month.february": "Vasaris",
@@ -86,15 +110,22 @@
"timeslider.month.october": "Spalis",
"timeslider.month.november": "Lapkritis",
"timeslider.month.december": "Gruodis",
- "timeslider.unnamedauthors": "{{num}} bevardžiai(-ių) autoriai(-ių)",
+ "timeslider.unnamedauthors": "{{num}} {[plural(num) one: bevardis autorius, other: bevardžiai autoriai ]}",
+ "pad.savedrevs.marked": "Peržiūrą dabar pažymėta kaip išsaugota peržiūra",
+ "pad.savedrevs.timeslider": "Galite peržiūrėti išsaugotas peržiūras apsilankydami laiko slinkiklyje",
"pad.userlist.entername": "Įveskite savo vardą",
"pad.userlist.unnamed": "bevardis",
"pad.userlist.guest": "Svečias",
"pad.userlist.deny": "Neigti",
"pad.userlist.approve": "Patvirtinti",
+ "pad.editbar.clearcolors": "Išvalyti autorystės spalvas visame dokumente?",
"pad.impexp.importbutton": "Importuoti dabar",
"pad.impexp.importing": "Importuojama...",
+ "pad.impexp.confirmimport": "Failo importavimas pakeis dabartinį bloknoto tekstą. Ar tikrai norite tęsti?",
+ "pad.impexp.convertFailed": "Mums nepavyko importuoti šio failo. Prašome naudoti kitokį dokumento formatą arba nukopijuoti ir įklijuoti rankiniu būdu",
+ "pad.impexp.padHasData": "Mums nepavyko importuoti šio failo, nes šis Bloknotas jau turėjo pakeitimų, prašome importuoti į naują bloknotą",
"pad.impexp.uploadFailed": "Įkėlimas nepavyko, bandykite dar kartą",
"pad.impexp.importfailed": "Importuoti nepavyko",
- "pad.impexp.copypaste": "Prašome nukopijuoti ir įklijuoti"
+ "pad.impexp.copypaste": "Prašome nukopijuoti ir įklijuoti",
+ "pad.impexp.exportdisabled": "Eksportavimas {{type}} formatu yra išjungtas. Prašome susisiekti su savo sistemos administratoriumi dėl informacijos."
}
diff --git a/src/locales/mk.json b/src/locales/mk.json
index e00d47d8..e292efa6 100644
--- a/src/locales/mk.json
+++ b/src/locales/mk.json
@@ -13,8 +13,8 @@
"pad.toolbar.strikethrough.title": "Прецртано (Ctrl+5)",
"pad.toolbar.ol.title": "Подреден список (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Неподреден список (Ctrl+Shift+L)",
- "pad.toolbar.indent.title": "Вовлекување (TAB)",
- "pad.toolbar.unindent.title": "Отстап (Shift+TAB)",
+ "pad.toolbar.indent.title": "Отстап (TAB)",
+ "pad.toolbar.unindent.title": "Истап (Shift+TAB)",
"pad.toolbar.undo.title": "Врати (Ctrl-Z)",
"pad.toolbar.redo.title": "Повтори (Ctrl-Y)",
"pad.toolbar.clearAuthorship.title": "Тргни ги авторските бои (Ctrl+Shift+C)",
diff --git a/src/locales/mn.json b/src/locales/mn.json
index 4b418bef..6242d591 100644
--- a/src/locales/mn.json
+++ b/src/locales/mn.json
@@ -2,7 +2,8 @@
"@metadata": {
"authors": [
"MongolWiki",
- "Wisdom"
+ "Wisdom",
+ "Munkhzaya.E"
]
},
"pad.toolbar.bold.title": "Болд тескт (Ctrl-B)",
@@ -11,13 +12,20 @@
"pad.toolbar.strikethrough.title": "Дундуураа зураастай",
"pad.toolbar.ol.title": "Эрэмбэлэгдсэн жагсаалт",
"pad.toolbar.ul.title": "Эрэмбэлээгүй жагсаалт",
+ "pad.toolbar.indent.title": "Догол мөр (TAB)",
+ "pad.toolbar.unindent.title": "Догол мөрийг буцаах (Shift+TAB)",
"pad.toolbar.undo.title": "Буцаах (Ctrl-Z)",
- "pad.toolbar.redo.title": "Undo -ын эсрэг (Ctrl-Y)",
+ "pad.toolbar.redo.title": "Давтах (Ctrl-Y)",
+ "pad.toolbar.clearAuthorship.title": "Зохиогчийн өнгийг буцаах (Ctrl+Shift+C)",
+ "pad.toolbar.timeslider.title": "Засварласан түүх",
+ "pad.toolbar.savedRevision.title": "Хувилбарыг хадгалах",
"pad.toolbar.settings.title": "Тохиргоо",
"pad.colorpicker.save": "Хадгалах",
"pad.colorpicker.cancel": "Цуцлах",
"pad.loading": "Уншиж байна...",
+ "pad.wrongPassword": "Таны оруулсан нууц үг буруу байна",
"pad.settings.padSettings": "Падын тохиргоо",
+ "pad.settings.myView": "Өөрийн харагдац",
"pad.settings.linenocheck": "Мөрийн дугаар",
"pad.settings.fontType": "Фонтын төрөл:",
"pad.settings.fontType.normal": "Ердийн",
@@ -26,7 +34,10 @@
"pad.importExport.import_export": "Импорт/Экспорт",
"pad.importExport.import": "Бичвэр, текст файл оруулах",
"pad.importExport.importSuccessful": "Амжилттай!",
+ "pad.importExport.exportetherpad": "Etherpad",
+ "pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Цулгаа бичвэр",
+ "pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF файл",
"pad.importExport.exportopen": "ODF файл",
"pad.modals.connected": "Холбогдсон.",
diff --git a/src/locales/ne.json b/src/locales/ne.json
index 1179c93b..3e23659a 100644
--- a/src/locales/ne.json
+++ b/src/locales/ne.json
@@ -28,8 +28,8 @@
"pad.colorpicker.cancel": "रद्द",
"pad.loading": "लोड हुदैछ...",
"pad.passwordRequired": "यो प्यड खोल्न पासवर्ड चाहिन्छ",
- "pad.permissionDenied": "तपाईँलाई यस प्याड खोल्न अनुमति छैन",
- "pad.wrongPassword": "तपाईँको पासवर्ड गलत थियो",
+ "pad.permissionDenied": "तपाईंलाई यो प्याड खोल्न अनुमति छैन",
+ "pad.wrongPassword": "तपाईंको पासवर्ड गलत थियो",
"pad.settings.padSettings": "प्याड सेटिङ्गहरू",
"pad.settings.myView": "मेरो दृष्य",
"pad.settings.stickychat": "पर्दामा सधै च्याट गर्ने",
@@ -53,7 +53,7 @@
"pad.importExport.exportpdf": "पिडिएफ",
"pad.importExport.exportopen": "ओडिएफ(खुल्ला कागजात ढाँचा)",
"pad.modals.connected": "जोडीएको।",
- "pad.modals.reconnecting": "तपाईँको प्याडमा पुन: जडान गर्दै",
+ "pad.modals.reconnecting": "तपाईंको प्याडमा पुन: जडान गर्दै",
"pad.modals.forcereconnect": "जडानको लागि जोडगर्ने",
"pad.modals.userdup": "अर्को सन्झ्यालमा खोल्ने",
"pad.modals.unauth": "अनुमती नदिइएको",
@@ -61,8 +61,8 @@
"pad.modals.slowcommit.explanation": "सर्भरसँग सम्पर्क हुने सकेन ।",
"pad.modals.deleted": "मेटिएको ।",
"pad.modals.deleted.explanation": "यो प्याड हटाइसकेको छ ।",
- "pad.modals.disconnected": "तपाईँको जडान अवरुद्ध भयो ।",
- "pad.modals.disconnected.explanation": "तपाईँको सर्भरसँगको जडान अवरुद्ध भयो",
+ "pad.modals.disconnected": "तपाईंको जडान अवरुद्ध भयो ।",
+ "pad.modals.disconnected.explanation": "तपाईंको सर्भरसँगको जडान अवरुद्ध भयो",
"pad.share": "यस प्यडलाई बाड्ने",
"pad.share.readonly": "पढ्ने मात्र",
"pad.share.link": "लिङ्क",
@@ -96,7 +96,7 @@
"timeslider.month.december": "डिसेम्बर",
"timeslider.unnamedauthors": "{{num}} unnamed {[plural(num) one: author, other: authors ]}",
"pad.savedrevs.marked": "यस संस्करणलाई संग्रहितको रुपमा चिनो लगाइएको छैन",
- "pad.userlist.entername": "तपाईँको नाम लेख्नुहोस्",
+ "pad.userlist.entername": "तपाईंको नाम लेख्नुहोस्",
"pad.userlist.unnamed": "नाम नखुलाइएको",
"pad.userlist.guest": "पाहुना",
"pad.userlist.deny": "अस्वीकार गर्ने",
diff --git a/src/locales/oc.json b/src/locales/oc.json
index bc3a4459..00944531 100644
--- a/src/locales/oc.json
+++ b/src/locales/oc.json
@@ -36,7 +36,7 @@
"pad.settings.chatandusers": "Afichar la discussion e los utilizaires",
"pad.settings.colorcheck": "Colors d’identificacion",
"pad.settings.linenocheck": "Numèros de linhas",
- "pad.settings.rtlcheck": "Lectura de drecha a esquèrra",
+ "pad.settings.rtlcheck": "Lectura de dreita a esquèrra",
"pad.settings.fontType": "Tipe de poliça :",
"pad.settings.fontType.normal": "Normal",
"pad.settings.fontType.monospaced": "Monospace",
diff --git a/src/locales/pa.json b/src/locales/pa.json
index 531e4ac8..f1e8ffc9 100644
--- a/src/locales/pa.json
+++ b/src/locales/pa.json
@@ -3,7 +3,8 @@
"authors": [
"Aalam",
"Babanwalia",
- "ਪ੍ਰਚਾਰਕ"
+ "ਪ੍ਰਚਾਰਕ",
+ "Tow"
]
},
"index.newPad": "ਨਵਾਂ ਪੈਡ",
@@ -112,6 +113,7 @@
"timeslider.month.december": "ਦਸੰਬਰ",
"timeslider.unnamedauthors": "{{num}} ਬੇਨਾਮ {[plural(num) one: ਲੇਖਕ, other: ਲੇਖਕ ]}",
"pad.savedrevs.marked": "ਇਹ ਰੀਵਿਜ਼ਨ ਨੂੰ ਹੁਣ ਸੰਭਾਲੇ ਹੋਏ ਰੀਵਿਜ਼ਨ ਵਜੋਂ ਮੰਨਿਆ ਗਿਆ ਹੈ",
+ "pad.savedrevs.timeslider": "ਤੁਸੀੰ ਸਾੰਭੀਆੰ ਹੋਈਆੰ ਵਰਜਨਾੰ ਸਮਾੰਸਲਾਈਡਰ ਤੇ ਜਾ ਕੇ ਵੇਖ ਸਕਦੇ ਹੋ",
"pad.userlist.entername": "ਆਪਣਾ ਨਾਂ ਦਿਉ",
"pad.userlist.unnamed": "ਬੇਨਾਮ",
"pad.userlist.guest": "ਮਹਿਮਾਨ",
@@ -122,6 +124,7 @@
"pad.impexp.importing": "...ਇੰਪੋਰਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ",
"pad.impexp.confirmimport": "ਕੋਈ ਫ਼ਾਈਲ ਦਰਾਮਦ ਕਾਰਨ ਨਾਲ਼ ਪੈਡ ਦੀ ਮੌਜੂਦਾ ਲਿਖਤ ਉੱਤੇ ਲਿਖਿਆ ਜਾਵੇਗਾ। ਕੀ ਤੁਸੀਂ ਸੱਚੀਂ ਇਹ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?",
"pad.impexp.convertFailed": "ਅਸੀਂ ਇਸ ਫ਼ਾਈਲ ਦੀ ਦਰਾਮਦ ਨਹੀਂ ਕਰ ਸਕੇ। ਮਿਹਰਬਾਨੀ ਕਰਕੇ ਕੋਈ ਵੱਖਰੀ ਦਸਤਾਵੇਜ਼ੀ ਰੂਪ-ਰੇਖਾ ਵਰਤੋ ਜਾਂ ਹੱਥੀਂ ਨਕਲ-ਚੇਪੀ ਕਰੋ।",
+ "pad.impexp.padHasData": "ਅਸੀ ਇਸ ਫਾਈਲ ਨੂੰ ਆਯਾਤ ਨਹੀੰ ਕਰ ਸਕੇ ਕਿਉੰਕਿ ਇਸ ਪੈਡ ਉੱਤੇ ਪਹਿਲਾੰ ਹੀ ਤਬਦੀਲੀਆੰ ਕੀਤੀਆੰ ਜਾ ਚੁਕੀਆੰ ਹਨ, ਕਿਰਪਾ ਕਰਕੇ ਨਵੇੰ ਪੈਡ ਵਿਚ ਆਯਾਤ ਕਰੋ",
"pad.impexp.uploadFailed": "ਅੱਪਲੋਡ ਲਈ ਫੇਲ੍ਹ ਹੈ, ਫੇਰ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਜੀ।",
"pad.impexp.importfailed": "ਇੰਪੋਰਟ ਫੇਲ੍ਹ ਹੈ",
"pad.impexp.copypaste": "ਕਾਪੀ ਕਰੋ ਚੇਪੋ ਜੀ",
diff --git a/src/locales/pl.json b/src/locales/pl.json
index 3d9170ba..85bbf474 100644
--- a/src/locales/pl.json
+++ b/src/locales/pl.json
@@ -98,6 +98,7 @@
"timeslider.exportCurrent": "Eksportuj bieżącą wersję jako:",
"timeslider.version": "Wersja {{version}}",
"timeslider.saved": "Zapisano {{day}} {{month}} {{year}}",
+ "timeslider.playPause": "Odtwarzaj / pauzuj zawartość dokumentu",
"timeslider.backRevision": "Przejdź do poprzedniej wersji dokumentu",
"timeslider.forwardRevision": "Przejdź do następnej wersji dokumentu",
"timeslider.dateformat": "{{year}}-{{month}}-{{day}} {{hours}}:{{minutes}}:{{seconds}}",
diff --git a/src/locales/qqq.json b/src/locales/qqq.json
new file mode 100644
index 00000000..0beec0cc
--- /dev/null
+++ b/src/locales/qqq.json
@@ -0,0 +1,122 @@
+{
+ "@metadata": {
+ "authors": [
+ "Liuxinyu970226",
+ "Mklehr",
+ "Nemo bis",
+ "Shirayuki",
+ "Siebrand"
+ ]
+ },
+ "index.newPad": "Used as button text.\nA pad, in the context of Etherpad, is a notepad, something to write on.",
+ "index.createOpenPad": "label for an input field that allows the user to choose a custom name for his new pad. In case the pad already exists the user will be redirected to its url.",
+ "pad.toolbar.bold.title": "Used as tooltip of button",
+ "pad.toolbar.italic.title": "Used as tooltip of button",
+ "pad.toolbar.underline.title": "Used as tooltip of button",
+ "pad.toolbar.strikethrough.title": "Used as tooltip of button.\n{{Identical|Strikethrough}}",
+ "pad.toolbar.ol.title": "Used as tooltip for button",
+ "pad.toolbar.ul.title": "Used as tooltip for button",
+ "pad.toolbar.indent.title": "Used as tooltip of button.\n\n\"TAB\" refers to \"Tab key\".\n\nSee also:\n* {{msg-etherpadlite|Pad.toolbar.unindent.title}}\n{{Identical|Indent}}",
+ "pad.toolbar.unindent.title": "Used as tooltip of button.\n\n\"TAB\" refers to \"Tab key\".\n\nSee also:\n* {{msg-etherpadlite|Pad.toolbar.indent.title}}",
+ "pad.toolbar.undo.title": "Used as tooltip of button",
+ "pad.toolbar.redo.title": "Used as tooltip of button\n{{Identical|Redo}}",
+ "pad.toolbar.clearAuthorship.title": "Used as tooltip of button",
+ "pad.toolbar.import_export.title": "Used as tooltip of button",
+ "pad.toolbar.timeslider.title": "The timeslider is a separate \"page\" that allows you to browse through the history of your pad's contents",
+ "pad.toolbar.savedRevision.title": "Used as tooltip for button.",
+ "pad.toolbar.settings.title": "settings that determine how the pad content is displayed\n{{Identical|Settings}}",
+ "pad.toolbar.embed.title": "Used as tooltip for button",
+ "pad.toolbar.showusers.title": "Used as tooltip for button",
+ "pad.colorpicker.save": "Used as button text in the \"Color picker\" window.\n\nSee also:\n* {{msg-etherpadlite|Pad.colorpicker.cancel}}\n{{Identical|Save}}",
+ "pad.colorpicker.cancel": "Used as button text in the \"Color picker\" window.\n\nSee also:\n* {{msg-etherpadlite|Pad.colorpicker.save}}\n{{Identical|Cancel}}",
+ "pad.loading": "Used to indicate the pad is being loaded.\n{{Identical|Loading}}",
+ "pad.passwordRequired": "Followed by the \"Password\" input box.",
+ "pad.permissionDenied": "Used as error message.",
+ "pad.wrongPassword": "Used as error message if the specified password is wrong.",
+ "pad.settings.padSettings": "Used as heading of settings window",
+ "pad.settings.myView": "Section heading for a users personal settings, meaning changes to the settings in this section will only affect the current view (this browser window) of the pad.",
+ "pad.settings.stickychat": "Used as checkbox label",
+ "pad.settings.colorcheck": "Used as checkbox label",
+ "pad.settings.linenocheck": "Used as checkbox label",
+ "pad.settings.rtlcheck": "Used as label for checkbox for RTL (right-to-left) languages",
+ "pad.settings.fontType": "Used as label for the \"Font type\" select box which has the following options:\n* {{msg-etherpadlite|Pad.settings.fontType.normal}}\n* {{msg-etherpadlite|Pad.settings.fontType.monospaced}}",
+ "pad.settings.fontType.normal": "Used as an option in the \"Font type\" select box which is labeled {{msg-etherpadlite|Pad.settings.fontType}}.\n{{Identical|Normal}}",
+ "pad.settings.fontType.monospaced": "Used as an option in the \"Font type\" select box which is labeled {{msg-etherpadlite|Pad.settings.fontType}}.",
+ "pad.settings.globalView": "Section heading for global view settings, meaning the settings in this section will affect everyone viewing the pad.",
+ "pad.settings.language": "This is a label for a select list of languages.\n{{Identical|Language}}",
+ "pad.importExport.import_export": "Used as HTML <code><nowiki><h1></nowiki></code> heading of window.\n\nFollowed by the child heading {{msg-etherpadlite|Pad.importExport.import}}.",
+ "pad.importExport.import": "Used as HTML <code><nowiki><h2></nowiki></code> heading.\n\nPreceded by the parent heading {{msg-etherpadlite|Pad.importExport.import_export}}.",
+ "pad.importExport.importSuccessful": "Used as success message to indicate that the pad has been imported successfully.\n{{Identical|Successful}}",
+ "pad.importExport.export": "Used as HTML <code><nowiki><h2></nowiki></code> heading.\n\nFollowed by the following link texts:\n* {{msg-etherpadlite|Pad.importExport.exporthtml}}\n* {{msg-etherpadlite|Pad.importExport.exportplain}}\n* {{msg-etherpadlite|Pad.importExport.exportword}}\n* {{msg-etherpadlite|Pad.importExport.exportpdf}}\n* {{msg-etherpadlite|Pad.importExport.exportopen}}\n* {{msg-etherpadlite|Pad.importExport.exportdokuwiki}}",
+ "pad.importExport.exportetherpad": "{{Identical|Etherpad}}",
+ "pad.importExport.exporthtml": "Used as link text, preceded by {{msg-etherpadlite|Pad.importExport.export}}.\n{{Related|Pad.importExport.export}}\n{{Identical|HTML}}",
+ "pad.importExport.exportplain": "Used as link text, preceded by {{msg-etherpadlite|Pad.importExport.export}}.\n{{Related|Pad.importExport.export}}\n{{Identical|Plain text}}",
+ "pad.importExport.exportword": "Used as link text, preceded by {{msg-etherpadlite|Pad.importExport.export}}.\n{{Related|Pad.importExport.export}}",
+ "pad.importExport.exportpdf": "Used as link text, preceded by {{msg-etherpadlite|Pad.importExport.export}}.\n{{Related|Pad.importExport.export}}",
+ "pad.importExport.exportopen": "Used as link text, preceded by {{msg-etherpadlite|Pad.importExport.export}}.\n{{Related|Pad.importExport.export}}",
+ "pad.importExport.abiword.innerHTML": "Used as intro text for the \"Import file\" form.\n\nPreceded by the heading {{msg-etherpadlite|pad.importExport.import}}.",
+ "pad.modals.connected": "Used as HTML <code><nowiki><h2></nowiki></code> heading to indicate the status.\n\nSee also:\n* {{msg-etherpadlite|Pad.modals.reconnecting}}\n{{Identical|Connected}}",
+ "pad.modals.reconnecting": "Used as HTML <code><nowiki><h2></nowiki></code> heading to indicate the status.\n\nSee also:\n* {{msg-etherpadlite|Pad.modals.connected}}",
+ "pad.modals.forcereconnect": "Label of a button that will make the browser reconnect to the synchronization server.",
+ "pad.modals.userdup": "Used as HTML <code><nowiki><h1></nowiki></code> heading to indicate that the pad is opened in another window on this computer.\n\nFollowed by the following messages:\n* {{msg-etherpadlite|Pad.modals.userdup.explanation}} - <code><nowiki><h2></nowiki></code> heading\n* {{msg-etherpadlite|Pad.modals.userdup.advice}}",
+ "pad.modals.userdup.explanation": "Used as HTML <code><nowiki><h2></nowiki></code> heading.\n\nPreceded by the parent heading {{msg-etherpadlite|Pad.modals.userdup}}.\n\nFollowed by the message {{msg-etherpadlite|Pad.modals.userdup.advice}}.",
+ "pad.modals.userdup.advice": "Preceded by the following headings:\n* {{msg-etherpadlite|Pad.modals.userdup}}\n* {{msg-etherpadlite|Pad.modals.userdup.explanation}}",
+ "pad.modals.unauth": "Used as HTML <code><nowiki><h1></nowiki></code> heading to indicate that the user is not authorized.\n\nFollowed by the explanation {{msg-etherpadlite|Pad.modals.unauth.explanation}}.\n{{Identical|Not authorized}}",
+ "pad.modals.unauth.explanation": "Used to indicate that the user is not authorized.\n\nPreceded by the heading {{msg-etherpadlite|Pad.modals.unauth}}.",
+ "pad.modals.looping.explanation": "Used as HTML <code><nowiki><h2></nowiki></code> heading.\n\nPreceded by the parent heading {{msg-etherpadlite|Pad.modals.looping}}.\n\nFollowed by the message {{msg-etherpadlite|Pad.modals.looping.cause}}.",
+ "pad.modals.looping.cause": "Preceded by the following messages:\n* {{msg-etherpadlite|Pad.modals.looping}}\n* {{msg-etherpadlite|Pad.modals.looping.explanation}}",
+ "pad.modals.initsocketfail": "Used as HTML <code><nowiki><h1></nowiki></code> heading.",
+ "pad.modals.initsocketfail.explanation": "Used as HTML <code><nowiki><h2></nowiki></code> heading.",
+ "pad.modals.initsocketfail.cause": "Preceded by the following headings:\n* {{msg-etherpadlite|Pad.modals.initsocketfail}}\n* {{msg-etherpadlite|Pad.modals.initsocketfail.explanation}}",
+ "pad.modals.slowcommit.explanation": "Used as HTML <code><nowiki><h2></nowiki></code> heading.",
+ "pad.modals.slowcommit.cause": "Preceded by the following headings:\n* {{msg-etherpadlite|Pad.modals.slowcommit}}\n* {{msg-etherpadlite|Pad.modals.slowcommit.explanation}}\nFollowed by the Submit button which is labeled {{msg-etherpadlite|Pad.modals.forcereconnect}}.",
+ "pad.modals.deleted": "Used as HTML <code><nowiki><h1></nowiki></code> heading.\n{{Identical|Deleted}}",
+ "pad.modals.deleted.explanation": "Preceded by the heading {{msg-etherpadlite|Pad.modals.deleted}}.",
+ "pad.modals.disconnected": "Used as HTML <code><nowiki><h1></nowiki></code> heading.",
+ "pad.modals.disconnected.explanation": "Used as HTML <code><nowiki><h2></nowiki></code> heading.",
+ "pad.modals.disconnected.cause": "Preceded by the following headings:\n* {{msg-etherpadlite|Pad.modals.disconnected}}\n* {{msg-etherpadlite|Pad.modals.disconnected.explanation}}\nFollowed by the Submit button which is labeled {{msg-etherpadlite|Pad.modals.forcereconnect}}.",
+ "pad.share": "Used as heading of window",
+ "pad.share.readonly": "Used as checkbox label",
+ "pad.share.link": "Used as label for a field providing URL of the pad.\n{{Identical|Link}}",
+ "pad.share.emebdcode": "Label for a field providing code that allows you to embed the pad into your website.",
+ "pad.chat": "Used as button text and as title of Chat window.\n{{Identical|Chat}}",
+ "pad.chat.title": "Used as tooltip for the Chat button",
+ "pad.chat.loadmessages": "chat messages",
+ "timeslider.pageTitle": "{{doc-important|Please leave <code><nowiki>{{appTitle}}</nowiki></code> parameter untouched. It will be replaced by app title.}}\nInserted into HTML title tag.",
+ "timeslider.toolbar.returnbutton": "Used as link title",
+ "timeslider.toolbar.authors": "A list of Authors follows after the colon.\n{{Identical|Author}}",
+ "timeslider.toolbar.authorsList": "Displayed when there are no authors of the currently viewed revision.",
+ "timeslider.toolbar.exportlink.title": "Used in Timeslider view.\n\nUsed as tooltip for the \"Export\" button which enables to export the current pad as HTML, plain text, or DokuWiki.\n\nIf the button is clicked, the following messages appear:\n* {{msg-etherpadlite|Timeslider.exportCurrent}}\n* {{msg-etherpadlite|Pad.importExport.exporthtml}}\n* {{msg-etherpadlite|Pad.importExport.exportplain}}\n* {{msg-etherpadlite|Pad.importExport.exportdokuwiki}}\n{{Identical|Export}}",
+ "timeslider.exportCurrent": "Used as label in the Timeslider view.\n\nFollowed by the following link texts (which are used to export the current pad):\n* {{msg-etherpadlite|Pad.importExport.exporthtml}}\n* {{msg-etherpadlite|Pad.importExport.exportplain}}\n* {{msg-etherpadlite|Pad.importExport.exportword}}\n* {{msg-etherpadlite|Pad.importExport.exportpdf}}\n* {{msg-etherpadlite|Pad.importExport.exportopen}}\n* {{msg-etherpadlite|Pad.importExport.exportdokuwiki}}",
+ "timeslider.version": "{{doc-important|Please leave <nowiki>{{version}}</nowiki> parameter untouched. It will be replaced with the version number}}",
+ "timeslider.saved": "{{doc-important|Do not translate <code><nowiki>{{month}}</nowiki></code>, <code><nowiki>{{day}}</nowiki></code> and <code><nowiki>{{year}}</nowiki></code> parameters. These will be replaced.}}\nParameters:\n* <nowiki>{{month}}</nowiki> - month name such as {{msg-etherpadlite|Timeslider.month.january}}, {{msg-etherpadlite|Timeslider.month.february}} and so on\n* <nowiki>{{day}}</nowiki> - day of the month (01-31)\n* <nowiki>{{year}}</nowiki> - year in 4 digit format",
+ "timeslider.dateformat": "{{doc-important|Do not translate <code><nowiki>month</nowiki></code>, <code><nowiki>day</nowiki></code>, <code><nowiki>year</nowiki></code>, <code><nowiki>hours</nowiki></code>, <code><nowiki>minutes</nowiki></code> and <code><nowiki>seconds</nowiki></code> parameters. These will be replaced.}}\n* <nowiki>{{month}}</nowiki> - a month number (01-12), NOT {{msg-etherpadlite|Timeslider.month.january}} etc.\n* <nowiki>{{day}}</nowiki> - day of the month (01-31)\n* <nowiki>{{year}}</nowiki> - year in 4 digit format\n* <nowiki>{{hours}}</nowiki> - hours (00-23)\n* <nowiki>{{minutes}}</nowiki> - minutes (00-59)\n* <nowiki>{{seconds}}</nowiki> - seconds (00-59)",
+ "timeslider.month.january": "Example usage: <samp>Saved on August 26, 2014</samp>. This message is substituted for:\n* {{msg-etherpadlite|Timeslider.saved|notext=1}}\n* {{msg-etherpadlite|Timeslider.dateformat|notext=1}}\n{{Identical|January}}",
+ "timeslider.month.february": "Example usage: <samp>Saved on August 26, 2014</samp>.\n{{Identical|February}}",
+ "timeslider.month.march": "Example usage: <samp>Saved on August 26, 2014</samp>.\n{{Identical|March}}",
+ "timeslider.month.april": "Example usage: <samp>Saved on August 26, 2014</samp>.\n{{Identical|April}}",
+ "timeslider.month.may": "Example usage: <samp>Saved on August 26, 2014</samp>.\n{{Identical|May}}",
+ "timeslider.month.june": "Example usage: <samp>Saved on August 26, 2014</samp>.\n{{Identical|June}}",
+ "timeslider.month.july": "Example usage: <samp>Saved on August 26, 2014</samp>.\n{{Identical|July}}",
+ "timeslider.month.august": "Example usage: <samp>Saved on August 26, 2014</samp>.\n{{Identical|August}}",
+ "timeslider.month.september": "Example usage: <samp>Saved on August 26, 2014</samp>.\n{{Identical|September}}",
+ "timeslider.month.october": "Example usage: <samp>Saved on August 26, 2014</samp>.\n{{Identical|October}}",
+ "timeslider.month.november": "Example usage: <samp>Saved on August 26, 2014</samp>.\n{{Identical|November}}",
+ "timeslider.month.december": "Example usage: <samp>Saved on August 26, 2014</samp>.\n{{Identical|December}}",
+ "timeslider.unnamedauthors": "See also:\n* {{msg-etherpadlite|Timeslider.unnamedauthor}}",
+ "pad.savedrevs.marked": "more like bookmarked, or tagged/starred",
+ "pad.userlist.entername": "Used as placeholder for the \"Name\" input box in the upper right corner of the screen.",
+ "pad.userlist.unnamed": "Displayed, if a user has not set a nick yet",
+ "pad.userlist.guest": "Preceded by the link text which is labeled {{msg-etherpadlite|Pad.userlist.approve}}.\n{{Identical|Guest}}",
+ "pad.userlist.deny": "Used as link text.\n\nFollowed by the link which is labeled {{msg-etherpadlite|Pad.userlist.approve}}.",
+ "pad.userlist.approve": "Used as link text.\n\nPreceded by the link which is labeled {{msg-etherpadlite|Pad.userlist.deny}}.\n\nFollowed by the message {{msg-etherpadlite|Pad.userlist.guest}}.\n{{Identical|Approve}}",
+ "pad.editbar.clearcolors": "Used as confirmation message (JavaScript <code>confirm()</code> function).\n\nThis message means \"Are you sure you want to clear authorship colors on entire document?\".",
+ "pad.impexp.importbutton": "Used as label for the Submit button.",
+ "pad.impexp.importing": "Used to indicate that the file is being imported.\n{{Identical|Importing}}",
+ "pad.impexp.confirmimport": "Used as confirmation message (JavaScript <code>confirm()</code> function).",
+ "pad.impexp.convertFailed": "Used as error message when importing a file.",
+ "pad.impexp.uploadFailed": "Used as error message when uploading a file.\n\nThis message means \"The upload has been failed. Please try again.\".",
+ "pad.impexp.importfailed": "Used as error message.\n\nThis message means \"The import has been failed\".\n\nFollowed by any one of the following messages:\n* {{msg-etherpadlite|Pad.impexp.convertFailed}}\n* {{msg-etherpadlite|Pad.impexp.uploadFailed}}\n* {{msg-etherpadlite|Pad.impexp.copypaste}}",
+ "pad.impexp.copypaste": "Displayed in case the import failed",
+ "pad.impexp.exportdisabled": "{{doc-important|Please leave <nowiki>{{type}}</nowiki> parameter untouched. It will be replaced}}"
+}
diff --git a/src/locales/sl.json b/src/locales/sl.json
index a51cb53d..5d2dd85e 100644
--- a/src/locales/sl.json
+++ b/src/locales/sl.json
@@ -6,7 +6,7 @@
"Skalcaa"
]
},
- "index.newPad": "Nova Ploščica",
+ "index.newPad": "Nov dokument",
"index.createOpenPad": "ali pa odpri dokument z imenom:",
"pad.toolbar.bold.title": "Krepko (Ctrl-B)",
"pad.toolbar.italic.title": "Ležeče (Ctrl-I)",
@@ -72,7 +72,7 @@
"pad.modals.slowcommit.cause": "Najverjetneje je prišlo do napake med vzpostavitvijo povezave.",
"pad.modals.badChangeset.explanation": "Urejanje, ki ste ga naredili, je sinhronizacijski strežnik označil kot nelegalno.",
"pad.modals.badChangeset.cause": "Razlog za to je morda napačna konfiguracija strežnika ali neko drugo nepričakovano vedenje. Prosimo, stopite v stik z upravljavcem storitve, če menite, da gre za napako. Poskusite se ponovno povezati, da nadaljujete z urejanjem.",
- "pad.modals.corruptPad.explanation": "Blok, do katerega želite dostopati, je poškodovan.",
+ "pad.modals.corruptPad.explanation": "Dokument, do katerega želite dostopati, je poškodovan.",
"pad.modals.corruptPad.cause": "Razlog za to je morda napačna konfiguracija strežnika ali neko drugo nepričakovano vedenje. Prosimo, stopite v stik z upravljavcem storitve.",
"pad.modals.deleted": "Izbrisano.",
"pad.modals.deleted.explanation": "Dokument je odstranjen.",
@@ -94,6 +94,9 @@
"timeslider.exportCurrent": "Izvozi trenutno različico kot:",
"timeslider.version": "Različica {{version}}",
"timeslider.saved": "Shranjeno {{day}}.{{month}}.{{year}}",
+ "timeslider.playPause": "Predvajaj/začasno ustavi vsebino dokumenta",
+ "timeslider.backRevision": "Pojdi eno redakcijo nazaj v tem dokumentu",
+ "timeslider.forwardRevision": "Pojdi redakcijo naprej v tem dokumentu",
"timeslider.dateformat": "{{day}}.{{month}}.{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Januar",
"timeslider.month.february": "Februar",
@@ -120,7 +123,7 @@
"pad.impexp.importing": "Poteka uvažanje ...",
"pad.impexp.confirmimport": "Uvoz datoteke prepiše obstoječe besedilo dokumenta. Ali ste prepričani, da želite nadaljevati?",
"pad.impexp.convertFailed": "Datoteke ni mogoče uvoziti. Uporabiti je treba enega izmed podprtih zapisov dokumentov ali pa vsebino prilepiti ročno.",
- "pad.impexp.padHasData": "Nismo mogli uvoziti datoteke, ker ta Ploščica že vsebuje spremembe. Prosimo, uvozite datoteko v novo ploščico",
+ "pad.impexp.padHasData": "Nismo mogli uvoziti datoteke, ker dokument že vsebuje spremembe. Prosimo, uvozite datoteko v nov dokument",
"pad.impexp.uploadFailed": "Nalaganje je spodletelo, poskusite znova.",
"pad.impexp.importfailed": "Uvoz je spodletel.",
"pad.impexp.copypaste": "Vsebino kopirajte in prilepite.",
diff --git a/src/locales/sq.json b/src/locales/sq.json
index 24494f79..d6d959ee 100644
--- a/src/locales/sq.json
+++ b/src/locales/sq.json
@@ -5,44 +5,44 @@
"Kosovastar"
]
},
- "index.newPad": "Bllok i ri",
- "index.createOpenPad": "ose krijoni/hapni një bllok me emrin:",
+ "index.newPad": "Bllok i Ri",
+ "index.createOpenPad": "ose krijoni/hapni një Bllok me emrin:",
"pad.toolbar.bold.title": "Të trasha (Ctrl-B)",
"pad.toolbar.italic.title": "Të pjerrëta (Ctrl-I)",
"pad.toolbar.underline.title": "Të nënvizuara (Ctrl-U)",
- "pad.toolbar.strikethrough.title": "Mbivijëzuar (Ctrl+5)",
+ "pad.toolbar.strikethrough.title": "Hequr vije (Ctrl+5)",
"pad.toolbar.ol.title": "Listë e renditur (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Listë e parenditur (Ctrl+Shift+L)",
- "pad.toolbar.indent.title": "E dhëmbëzuar (TAB)",
+ "pad.toolbar.indent.title": "Brendazi (TAB)",
"pad.toolbar.unindent.title": "Jashtazi (Shift+TAB)",
"pad.toolbar.undo.title": "Zhbëje (Ctrl-Z)",
"pad.toolbar.redo.title": "Ribëje (Ctrl-Y)",
- "pad.toolbar.clearAuthorship.title": "Hiqju Ngjyra Autorësish (Ctrl+Shift+C)",
+ "pad.toolbar.clearAuthorship.title": "Hiqu Ngjyra Autorësish (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Importoni/Eksportoni nga/në formate të tjera kartelash",
"pad.toolbar.timeslider.title": "Rrjedha kohore",
- "pad.toolbar.savedRevision.title": "Ruaje rishikimin",
+ "pad.toolbar.savedRevision.title": "Ruaje Rishikimin",
"pad.toolbar.settings.title": "Rregullime",
- "pad.toolbar.embed.title": "Ndajeni me të tjerët dhe trupëzojeni këtë bllok",
+ "pad.toolbar.embed.title": "Ndajeni me të tjerët dhe Trupëzojeni këtë bllok",
"pad.toolbar.showusers.title": "Shfaq përdoruesit në këtë bllok",
"pad.colorpicker.save": "Ruaje",
"pad.colorpicker.cancel": "Anuloje",
"pad.loading": "Po ngarkohet…",
"pad.noCookie": "S’u gjet dot cookie. Ju lutemi, lejoni cookie-t te shfletuesi juaj!",
"pad.passwordRequired": "Ju duhet një fjalëkalim që të mund të përdorni këtë bllok",
- "pad.permissionDenied": "Ju nuk keni leje t'i qaseni këtij blloku",
+ "pad.permissionDenied": "S’keni leje të hyni në këtë bllok",
"pad.wrongPassword": "Fjalëkalimi juaj qe gabim",
- "pad.settings.padSettings": "Rregullime blloku",
+ "pad.settings.padSettings": "Rregullime Blloku",
"pad.settings.myView": "Pamja ime",
"pad.settings.stickychat": "Fjalosje përherë në ekran",
- "pad.settings.chatandusers": "Shfaq fjalosje dhe përdorues",
+ "pad.settings.chatandusers": "Shfaq Fjalosje dhe Përdorues",
"pad.settings.colorcheck": "Ngjyra autorësish",
"pad.settings.linenocheck": "Numra rreshtash",
"pad.settings.rtlcheck": "Të lexohet lënda nga e djathta në të majtë?",
"pad.settings.fontType": "Lloj shkronjash:",
"pad.settings.fontType.normal": "Normale",
"pad.settings.fontType.monospaced": "Monospace",
- "pad.settings.globalView": "Pamje e përgjithshme",
- "pad.settings.language": "Gjuha:",
+ "pad.settings.globalView": "Pamje e Përgjithshme",
+ "pad.settings.language": "Gjuhë:",
"pad.importExport.import_export": "Import/Eksport",
"pad.importExport.import": "Ngarkoni cilëndo kartelë teksti ose dokument",
"pad.importExport.importSuccessful": "Me sukses!",
@@ -55,7 +55,7 @@
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Mund të importoni vetëm prej formati tekst i thjeshtë ose html. Për veçori më të thelluara importimi, ju lutemi, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">instaloni Abiword-in</a>.",
"pad.modals.connected": "I lidhur.",
- "pad.modals.reconnecting": "Po rilidheni te blloku juaj..",
+ "pad.modals.reconnecting": "Po rilidheni te blloku juaj…",
"pad.modals.forcereconnect": "Rilidhje e detyruar",
"pad.modals.userdup": "Hapur në një tjetër dritare",
"pad.modals.userdup.explanation": "Ky bllok duket se gjendet i hapur në më shumë se një dritare shfletuesi në këtë kompjuter.",
@@ -64,8 +64,8 @@
"pad.modals.unauth.explanation": "Lejet tuaja ndryshuan teksa shihnit këtë dritare. Provoni të rilidheni.",
"pad.modals.looping.explanation": "Ka probleme komunikimi me shërbyesin e njëkohësimit.",
"pad.modals.looping.cause": "Ndoshta jeni lidhur përmes një firewall-i ose ndërmjetësi të papërputhshëm.",
- "pad.modals.initsocketfail": "Shërbyesi (serveri) është i pakapshëm.",
- "pad.modals.initsocketfail.explanation": "Nuk u lidh dot te shërbyesi (serveri) i sinkronizimit.",
+ "pad.modals.initsocketfail": "Shërbyesi është i pakapshëm.",
+ "pad.modals.initsocketfail.explanation": "S’u lidh dot te shërbyesi i njëkohësimit.",
"pad.modals.initsocketfail.cause": "Ka gjasa që kjo vjen për shkak të një problemi me shfletuesin tuaj ose lidhjen tuaj në internet.",
"pad.modals.slowcommit.explanation": "Shërbyesi nuk po përgjigjet.",
"pad.modals.slowcommit.cause": "Kjo mund të vijë për shkak problemesh lidhjeje me rrjetin.",
@@ -88,15 +88,15 @@
"timeslider.pageTitle": "Rrjedhë kohore e {{appTitle}}",
"timeslider.toolbar.returnbutton": "Rikthehuni te blloku",
"timeslider.toolbar.authors": "Autorë:",
- "timeslider.toolbar.authorsList": "Nuk ka autorë",
- "timeslider.toolbar.exportlink.title": "Eksportoni",
+ "timeslider.toolbar.authorsList": "S’ka Autorë",
+ "timeslider.toolbar.exportlink.title": "Eksportoje",
"timeslider.exportCurrent": "Eksportojeni versionin e tanishëm si:",
"timeslider.version": "Versioni {{version}}",
- "timeslider.saved": "Ruajtur më {{month}} {{day}}, {{year}}",
- "timeslider.playPause": "Riluaj / Pusho përmbajtjet e bllokut",
- "timeslider.backRevision": "Kalo një rishikim mbrapsht te ky bllok",
- "timeslider.forwardRevision": "Kalo një rishikim përpara në këtë bllok",
- "timeslider.dateformat": "{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
+ "timeslider.saved": "Ruajtur më {{day}} {{month}}, {{year}}",
+ "timeslider.playPause": "Luaj / Pusho Lëndë Blloku",
+ "timeslider.backRevision": "Kalo një rishikim mbrapsht në këtë Bllok",
+ "timeslider.forwardRevision": "Kalo një rishikim përpara në këtë Bllok",
+ "timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Janar",
"timeslider.month.february": "Shkurt",
"timeslider.month.march": "Mars",
@@ -109,20 +109,20 @@
"timeslider.month.october": "Tetor",
"timeslider.month.november": "Nëntor",
"timeslider.month.december": "Dhjetor",
- "timeslider.unnamedauthors": "{{num}} i paemërt {[plural(num) një: autor, tjetër: autorë ]}",
+ "timeslider.unnamedauthors": "{{num}} i paemër {[plural(num) një: autor, tjetër:{{num}} autorë ]}",
"pad.savedrevs.marked": "Ky rishikim tani është shënuar si rishikim i ruajtur",
- "pad.savedrevs.timeslider": "Rishikimet e ruajtura mund t’i shihni duke vizituar rrjedhjen kohore",
+ "pad.savedrevs.timeslider": "Rishikimet e ruajtura mund t’i shihni duke vizituar rrjedhën kohore",
"pad.userlist.entername": "Jepni emrin tuaj",
"pad.userlist.unnamed": "pa emër",
"pad.userlist.guest": "Vizitor",
- "pad.userlist.deny": "Refuzo",
+ "pad.userlist.deny": "Hidhe poshtë",
"pad.userlist.approve": "Miratoje",
"pad.editbar.clearcolors": "Të hiqen ngjyra autorësish në krejt dokumentin?",
- "pad.impexp.importbutton": "Importoje tani",
+ "pad.impexp.importbutton": "Importoje Tani",
"pad.impexp.importing": "Po importohet…",
"pad.impexp.confirmimport": "Importimi i një kartele do të mbishkruajë tekstin e tanishëm të bllokut. Jeni i sigurt se doni të vazhdohet?",
"pad.impexp.convertFailed": "Nuk qemë në gjendje ta importonim këtë kartelë. Ju lutemi, përdorni një format tjetër dokumentesh ose kopjojeni dhe hidheni dorazi",
- "pad.impexp.padHasData": "Ne nuk ishim në gjendje për të importuar këtë skedë, sepse ky bllok tashmë ka pasur ndryshime, ju lutem importojeni tek një bllok i ri",
+ "pad.impexp.padHasData": "S’qemë në gjendje të importojmë këtë kartelë, ngaqë ky Bllok kish tashmë ndryshime, ju lutemi, importojeni tek një bllok i ri",
"pad.impexp.uploadFailed": "Ngarkimi dështoi, ju lutemi, riprovoni",
"pad.impexp.importfailed": "Importimi dështoi",
"pad.impexp.copypaste": "Ju lutemi, kopjojeni dhe ngjiteni",
diff --git a/src/locales/vi.json b/src/locales/vi.json
index da0baf50..57f58e0c 100644
--- a/src/locales/vi.json
+++ b/src/locales/vi.json
@@ -19,7 +19,7 @@
"pad.toolbar.unindent.title": "Giảm lề (Shift+TAB)",
"pad.toolbar.undo.title": "Hoàn tác (Ctrl-Z)",
"pad.toolbar.redo.title": "Làm lại (Ctrl-Y)",
- "pad.toolbar.clearAuthorship.title": "Xóa Màu chỉ Tác giả",
+ "pad.toolbar.clearAuthorship.title": "Xóa Màu chỉ Tác giả (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Xuất/Nhập từ/đến các định dạng file khác nhau",
"pad.toolbar.timeslider.title": "Thanh thời gian",
"pad.toolbar.savedRevision.title": "Lưu Phiên bản",
diff --git a/src/locales/zh-hans.json b/src/locales/zh-hans.json
index 15f11591..b4ff306f 100644
--- a/src/locales/zh-hans.json
+++ b/src/locales/zh-hans.json
@@ -105,7 +105,7 @@
"timeslider.playPause": "回放 / 暂停Pad内容",
"timeslider.backRevision": "返回此Pad的一次修订",
"timeslider.forwardRevision": "前往此Pad的一次修订",
- "timeslider.dateformat": "{{year}}年{{month}}月{{day}}日 {{hours}}{{minutes}}{{seconds}}",
+ "timeslider.dateformat": "{{year}}年{{month}}月{{day}}日 {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "1月",
"timeslider.month.february": "2月",
"timeslider.month.march": "3月",
diff --git a/src/locales/zh-hant.json b/src/locales/zh-hant.json
index 01aa4215..a66ec416 100644
--- a/src/locales/zh-hant.json
+++ b/src/locales/zh-hant.json
@@ -7,7 +7,8 @@
"Shirayuki",
"Simon Shek",
"LNDDYL",
- "Wehwei"
+ "Wehwei",
+ "Kly"
]
},
"index.newPad": "新Pad",
@@ -98,6 +99,9 @@
"timeslider.exportCurrent": "匯出當前版本為:",
"timeslider.version": "版本{{version}}",
"timeslider.saved": "{{year}}年{{month}}{{day}}日儲存",
+ "timeslider.playPause": "放送 / 暫停Pad內容",
+ "timeslider.backRevision": "返回此Pad的前一次修訂",
+ "timeslider.forwardRevision": "前往此Pad的前一次修訂",
"timeslider.dateformat": "{{year}}年{{month}}月{{day}}日 {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "1月",
"timeslider.month.february": "二月",
@@ -113,6 +117,7 @@
"timeslider.month.december": "12月",
"timeslider.unnamedauthors": "{{num}}匿名{[plural(num) 作者]}",
"pad.savedrevs.marked": "標記此修訂版本為已儲存修訂版本。",
+ "pad.savedrevs.timeslider": "您可使用時段滑標來查看先前保存的版本內容",
"pad.userlist.entername": "輸入您的姓名",
"pad.userlist.unnamed": "未命名",
"pad.userlist.guest": "訪客",
@@ -123,6 +128,7 @@
"pad.impexp.importing": "匯入中...",
"pad.impexp.confirmimport": "匯入的檔案將會覆蓋pad內目前的文字。您確定要繼續嗎?",
"pad.impexp.convertFailed": "未能匯入此檔案。請以其他檔案格式或手動複製貼上匯入。",
+ "pad.impexp.padHasData": "此Pad已異動過所以無法匯入該檔案,請匯入至另一個Pad試試。",
"pad.impexp.uploadFailed": "上載失敗,請重試",
"pad.impexp.importfailed": "匯入失敗",
"pad.impexp.copypaste": "請複製貼上",
diff --git a/src/node/db/API.js b/src/node/db/API.js
index 237bcb0a..be3e7348 100644
--- a/src/node/db/API.js
+++ b/src/node/db/API.js
@@ -28,6 +28,7 @@ var authorManager = require("./AuthorManager");
var sessionManager = require("./SessionManager");
var async = require("async");
var exportHtml = require("../utils/ExportHtml");
+var exportTxt = require("../utils/ExportTxt");
var importHtml = require("../utils/ImportHtml");
var cleanText = require("./Pad").cleanText;
var PadDiff = require("../utils/padDiff");
@@ -271,7 +272,8 @@ exports.getText = function(padID, rev, callback)
//the client wants the latest text, lets return it to him
else
{
- callback(null, {"text": pad.text()});
+ var padText = exportTxt.getTXTFromAtext(pad, pad.atext);
+ callback(null, {"text": padText});
}
});
}
diff --git a/src/node/handler/ExportHandler.js b/src/node/handler/ExportHandler.js
index 8f91ced2..678519fb 100644
--- a/src/node/handler/ExportHandler.js
+++ b/src/node/handler/ExportHandler.js
@@ -76,10 +76,11 @@ exports.doExport = function(req, res, padId, type)
}
else if(type == "txt")
{
- exporttxt.getPadTXTDocument(padId, req.params.rev, false, function(err, txt)
+ exporttxt.getPadTXTDocument(padId, req.params.rev, function(err, txt)
{
- if(ERR(err)) return;
- res.send(txt);
+ if(!err) {
+ res.send(txt);
+ }
});
}
else
@@ -92,7 +93,7 @@ exports.doExport = function(req, res, padId, type)
//render the html document
function(callback)
{
- exporthtml.getPadHTMLDocument(padId, req.params.rev, false, function(err, _html)
+ exporthtml.getPadHTMLDocument(padId, req.params.rev, function(err, _html)
{
if(ERR(err, callback)) return;
html = _html;
diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js
index f48be604..279a44e1 100644
--- a/src/node/handler/PadMessageHandler.js
+++ b/src/node/handler/PadMessageHandler.js
@@ -98,14 +98,7 @@ exports.kickSessionsFromPad = function(padID)
return;
//skip if there is nobody on this pad
- var roomClients = [], room = socketio.sockets.adapter.rooms[padID];
- if (room) {
- for (var id in room) {
- roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
- }
- }
-
- if(roomClients.length == 0)
+ if(_getRoomClients(padID).length == 0)
return;
//disconnect everyone from this pad
@@ -519,21 +512,16 @@ function handleSuggestUserName(client, message)
}
var padId = sessioninfos[client.id].padId;
- var roomClients = [], room = socketio.sockets.adapter.rooms[padId];
- if (room) {
- for (var id in room) {
- roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
- }
- }
+ var roomClients = _getRoomClients(padId);
//search the author and send him this message
- for(var i = 0; i < roomClients.length; i++) {
- var session = sessioninfos[roomClients[i].id];
+ roomClients.forEach(function(client) {
+ var session = sessioninfos[client.id];
if(session && session.author == message.data.payload.unnamedId) {
- roomClients[i].json.send(message);
- break;
+ client.json.send(message);
+ return;
}
- }
+ });
}
/**
@@ -821,12 +809,7 @@ function handleUserChanges(data, cb)
exports.updatePadClients = function(pad, callback)
{
//skip this step if noone is on this pad
- var roomClients = [], room = socketio.sockets.adapter.rooms[pad.id];
- if (room) {
- for (var id in room) {
- roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
- }
- }
+ var roomClients = _getRoomClients(pad.id);
if(roomClients.length==0)
return callback();
@@ -952,21 +935,16 @@ function handleSwitchToPad(client, message)
// clear the session and leave the room
var currentSession = sessioninfos[client.id];
var padId = currentSession.padId;
- var roomClients = [], room = socketio.sockets.adapter.rooms[padId];
- if (room) {
- for (var id in room) {
- roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
- }
- }
-
- for(var i = 0; i < roomClients.length; i++) {
- var sinfo = sessioninfos[roomClients[i].id];
+ var roomClients = _getRoomClients(padId);
+
+ async.forEach(roomClients, function(client, callback) {
+ var sinfo = sessioninfos[client.id];
if(sinfo && sinfo.author == currentSession.author) {
// fix user's counter, works on page refresh or if user closes browser window and then rejoins
- sessioninfos[roomClients[i].id] = {};
- roomClients[i].leave(padId);
+ sessioninfos[client.id] = {};
+ client.leave(padId);
}
- }
+ });
// start up the new pad
createSessionInfo(client, message);
@@ -1136,22 +1114,17 @@ function handleClientReady(client, message)
return callback();
//Check if this author is already on the pad, if yes, kick the other sessions!
- var roomClients = [], room = socketio.sockets.adapter.rooms[pad.id];
- if (room) {
- for (var id in room) {
- roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
- }
- }
-
- for(var i = 0; i < roomClients.length; i++) {
- var sinfo = sessioninfos[roomClients[i].id];
+ var roomClients = _getRoomClients(pad.id);
+
+ async.forEach(roomClients, function(client, callback) {
+ var sinfo = sessioninfos[client.id];
if(sinfo && sinfo.author == author) {
// fix user's counter, works on page refresh or if user closes browser window and then rejoins
- sessioninfos[roomClients[i].id] = {};
- roomClients[i].leave(padIds.padId);
- roomClients[i].json.send({disconnect:"userdup"});
+ sessioninfos[client.id] = {};
+ client.leave(padIds.padId);
+ client.json.send({disconnect:"userdup"});
}
- }
+ });
//Save in sessioninfos that this session belonges to this pad
sessioninfos[client.id].padId = padIds.padId;
@@ -1295,13 +1268,8 @@ function handleClientReady(client, message)
// notify all existing users about new user
client.broadcast.to(padIds.padId).json.send(messageToTheOtherUsers);
- //Run trough all sessions of this pad
- var roomClients = [], room = socketio.sockets.adapter.rooms[pad.id];
- if (room) {
- for (var id in room) {
- roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
- }
- }
+ //Get sessions for this pad
+ var roomClients = _getRoomClients(pad.id);
async.forEach(roomClients, function(roomClient, callback)
{
@@ -1706,20 +1674,24 @@ function composePadChangesets(padId, startNum, endNum, callback)
});
}
-/**
- * Get the number of users in a pad
- */
-exports.padUsersCount = function (padID, callback) {
-
- var roomClients = [], room = socketio.sockets.adapter.rooms[padID];
+function _getRoomClients(padID) {
+ var roomClients = []; var room = socketio.sockets.adapter.rooms[padID];
+
if (room) {
- for (var id in room) {
- roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
+ for (var id in room.sockets) {
+ roomClients.push(socketio.sockets.sockets[id]);
}
}
+
+ return roomClients;
+}
+/**
+ * Get the number of users in a pad
+ */
+exports.padUsersCount = function (padID, callback) {
callback(null, {
- padUsersCount: roomClients.length
+ padUsersCount: _getRoomClients(padID).length
});
}
@@ -1729,12 +1701,7 @@ exports.padUsersCount = function (padID, callback) {
exports.padUsers = function (padID, callback) {
var result = [];
- var roomClients = [], room = socketio.sockets.adapter.rooms[padID];
- if (room) {
- for (var id in room) {
- roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
- }
- }
+ var roomClients = _getRoomClients(padID);
async.forEach(roomClients, function(roomClient, callback) {
var s = sessioninfos[roomClient.id];
diff --git a/src/node/hooks/express/adminsettings.js b/src/node/hooks/express/adminsettings.js
index 4986f093..73691837 100644
--- a/src/node/hooks/express/adminsettings.js
+++ b/src/node/hooks/express/adminsettings.js
@@ -30,7 +30,13 @@ exports.socketio = function (hook_name, args, cb) {
}
else
{
- socket.emit("settings", {results: data});
+ //if showSettingsInAdminPage is set to false, then return NOT_ALLOWED in the result
+ if(settings.showSettingsInAdminPage === false) {
+ socket.emit("settings", {results:'NOT_ALLOWED'});
+ }
+ else {
+ socket.emit("settings", {results: data});
+ }
}
});
});
diff --git a/src/node/hooks/express/padreadonly.js b/src/node/hooks/express/padreadonly.js
index 66be3339..bff8adf7 100644
--- a/src/node/hooks/express/padreadonly.js
+++ b/src/node/hooks/express/padreadonly.js
@@ -7,7 +7,7 @@ var exporthtml = require("../../utils/ExportHtml");
exports.expressCreateServer = function (hook_name, args, cb) {
//serve read only pad
args.app.get('/ro/:id', function(req, res)
- {
+ {
var html;
var padId;
@@ -40,7 +40,7 @@ exports.expressCreateServer = function (hook_name, args, cb) {
hasPadAccess(req, res, function()
{
//render the html document
- exporthtml.getPadHTMLDocument(padId, null, false, function(err, _html)
+ exporthtml.getPadHTMLDocument(padId, null, function(err, _html)
{
if(ERR(err, callback)) return;
html = _html;
diff --git a/src/node/hooks/express/specialpages.js b/src/node/hooks/express/specialpages.js
index e8d7795a..2840f82c 100644
--- a/src/node/hooks/express/specialpages.js
+++ b/src/node/hooks/express/specialpages.js
@@ -16,6 +16,13 @@ exports.expressCreateServer = function (hook_name, args, cb) {
res.send(eejs.require("ep_etherpad-lite/templates/index.html"));
});
+ //serve javascript.html
+ args.app.get('/javascript', function(req, res)
+ {
+ res.send(eejs.require("ep_etherpad-lite/templates/javascript.html"));
+ });
+
+
//serve robots.txt
args.app.get('/robots.txt', function(req, res)
{
diff --git a/src/node/hooks/express/webaccess.js b/src/node/hooks/express/webaccess.js
index 2cafd271..c53eb1d1 100644
--- a/src/node/hooks/express/webaccess.js
+++ b/src/node/hooks/express/webaccess.js
@@ -120,7 +120,7 @@ exports.expressConfigure = function (hook_name, args, cb) {
}
args.app.sessionStore = exports.sessionStore;
- args.app.use(sessionModule({secret: exports.secret, store: args.app.sessionStore, resave: true, saveUninitialized: true, name: 'express_sid' }));
+ args.app.use(sessionModule({secret: exports.secret, store: args.app.sessionStore, resave: true, saveUninitialized: true, name: 'express_sid', proxy: true, cookie: { secure: !!settings.ssl }}));
args.app.use(cookieParser(settings.sessionKey, {}));
diff --git a/src/node/hooks/i18n.js b/src/node/hooks/i18n.js
index 1d28b544..1b5b354d 100644
--- a/src/node/hooks/i18n.js
+++ b/src/node/hooks/i18n.js
@@ -5,7 +5,7 @@ var languages = require('languages4translatewiki')
, npm = require('npm')
, plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins.js').plugins
, semver = require('semver')
- , existsSync = semver.gt(process.version, '0.7.0') ? fs.existsSync : path.existsSync
+ , existsSync = require('../utils/path_exists')
;
diff --git a/src/node/utils/ExportHtml.js b/src/node/utils/ExportHtml.js
index 836165b1..bd177ac4 100644
--- a/src/node/utils/ExportHtml.js
+++ b/src/node/utils/ExportHtml.js
@@ -22,6 +22,7 @@ var ERR = require("async-stacktrace");
var _ = require('underscore');
var Security = require('ep_etherpad-lite/static/js/security');
var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks');
+var eejs = require('ep_etherpad-lite/node/eejs');
var _analyzeLine = require('./ExportHelper')._analyzeLine;
var _encodeWhitespace = require('./ExportHelper')._encodeWhitespace;
@@ -478,7 +479,7 @@ function getHTMLFromAtext(pad, atext, authorColors)
return pieces.join('');
}
-exports.getPadHTMLDocument = function (padId, revNum, noDocType, callback)
+exports.getPadHTMLDocument = function (padId, revNum, callback)
{
padManager.getPad(padId, function (err, pad)
{
@@ -490,112 +491,16 @@ exports.getPadHTMLDocument = function (padId, revNum, noDocType, callback)
stylesForExport.forEach(function(css){
stylesForExportCSS += css;
});
- // Core inclusion of head etc.
- var head =
- (noDocType ? '' : '<!doctype html>\n') +
- '<html lang="en">\n' + (noDocType ? '' : '<head>\n' +
- '<title>' + Security.escapeHTML(padId) + '</title>\n' +
- '<meta name="generator" content="Etherpad">\n' +
- '<meta name="author" content="Etherpad">\n' +
- '<meta name="changedby" content="Etherpad">\n' +
- '<meta charset="utf-8">\n' +
- '<style> * { font-family: arial, sans-serif;\n' +
- 'font-size: 13px;\n' +
- 'line-height: 17px; }' +
- 'ul.indent { list-style-type: none; }' +
-
- 'ol { list-style-type: none; padding-left:0;}' +
- 'body > ol { counter-reset: first second third fourth fifth sixth seventh eigth ninth tenth eleventh twelth thirteenth fourteenth fifteenth sixteenth; }' +
- 'ol > li:before {' +
- 'content: counter(first) ". " ;'+
- 'counter-increment: first;}' +
-
- 'ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) ". " ;'+
- 'counter-increment: second;}' +
-
- 'ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) ". ";'+
- 'counter-increment: third;}' +
-
- 'ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) ". ";'+
- 'counter-increment: fourth;}' +
-
- 'ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) ". ";'+
- 'counter-increment: fifth;}' +
-
- 'ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) ". ";'+
- 'counter-increment: sixth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) ". ";'+
- 'counter-increment: seventh;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) ". ";'+
- 'counter-increment: eigth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) ". ";'+
- 'counter-increment: ninth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) ". ";'+
- 'counter-increment: tenth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) ". ";'+
- 'counter-increment: eleventh;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) ". ";'+
- 'counter-increment: twelth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) ". ";'+
- 'counter-increment: thirteenth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) ". ";'+
- 'counter-increment: fourteenth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) "." counter(fifteenth) ". ";'+
- 'counter-increment: fifteenth;}' +
-
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {' +
- 'content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) "." counter(fifteenth) "." counter(sixthteenth) ". ";'+
- 'counter-increment: sixthteenth;}' +
-
- 'ol{ text-indent: 0px; }' +
- 'ol > ol{ text-indent: 10px; }' +
- 'ol > ol > ol{ text-indent: 20px; }' +
- 'ol > ol > ol > ol{ text-indent: 30px; }' +
- 'ol > ol > ol > ol > ol{ text-indent: 40px; }' +
- 'ol > ol > ol > ol > ol > ol{ text-indent: 50px; }' +
- 'ol > ol > ol > ol > ol > ol > ol{ text-indent: 60px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 70px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 80px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 90px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 100px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 110px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol { text-indent: 120px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 130px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 140px; }' +
- 'ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol{ text-indent: 150px; }' +
-
- stylesForExportCSS +
- '</style>\n' + '</head>\n') +
- '<body>';
- var foot = '</body>\n</html>\n';
getPadHTML(pad, revNum, function (err, html)
{
if(ERR(err, callback)) return;
- callback(null, head + html + foot);
+ var exportedDoc = eejs.require("ep_etherpad-lite/templates/export_html.html", {
+ body: html,
+ padId: Security.escapeHTML(padId),
+ extraCSS: stylesForExportCSS
+ });
+ callback(null, exportedDoc);
});
});
});
diff --git a/src/node/utils/ExportTxt.js b/src/node/utils/ExportTxt.js
index a6bec4a5..e3ce0152 100644
--- a/src/node/utils/ExportTxt.js
+++ b/src/node/utils/ExportTxt.js
@@ -192,7 +192,7 @@ function getTXTFromAtext(pad, atext, authorColors)
tags2close.push(i);
}
}
-
+
for (var i = 0; i < propVals.length; i++)
{
if (propVals[i] === ENTER || propVals[i] === STAY)
@@ -208,10 +208,10 @@ function getTXTFromAtext(pad, atext, authorColors)
{
chars--; // exclude newline at end of line, if present
}
-
+
var s = taker.take(chars);
- // removes the characters with the code 12. Don't know where they come
+ // removes the characters with the code 12. Don't know where they come
// from but they break the abiword parser and are completly useless
// s = s.replace(String.fromCharCode(12), "");
@@ -221,7 +221,7 @@ function getTXTFromAtext(pad, atext, authorColors)
assem.append(s);
} // end iteration over spans in line
-
+
var tags2close = [];
for (var i = propVals.length - 1; i >= 0; i--)
{
@@ -231,7 +231,7 @@ function getTXTFromAtext(pad, atext, authorColors)
propVals[i] = false;
}
}
-
+
} // end processNextChars
processNextChars(text.length - idx);
return(assem.toString());
@@ -271,7 +271,7 @@ function getTXTFromAtext(pad, atext, authorColors)
}
exports.getTXTFromAtext = getTXTFromAtext;
-exports.getPadTXTDocument = function (padId, revNum, noDocType, callback)
+exports.getPadTXTDocument = function (padId, revNum, callback)
{
padManager.getPad(padId, function (err, pad)
{
diff --git a/src/node/utils/Minify.js b/src/node/utils/Minify.js
index ee8f5f45..80652310 100644
--- a/src/node/utils/Minify.js
+++ b/src/node/utils/Minify.js
@@ -1,7 +1,7 @@
/**
- * This Module manages all /minified/* requests. It controls the
- * minification && compression of Javascript and CSS.
- */
+ * This Module manages all /minified/* requests. It controls the
+ * minification && compression of Javascript and CSS.
+ */
/*
* 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
@@ -151,7 +151,7 @@ function minify(req, res, next)
} else {
res.writeHead(404, {});
res.end();
- return;
+ return;
}
/* Handle static files for plugins/libraries:
@@ -371,21 +371,19 @@ function requireDefinition() {
function getFileCompressed(filename, contentType, callback) {
getFile(filename, function (error, content) {
- if (error || !content) {
+ if (error || !content || !settings.minify) {
callback(error, content);
- } else {
- if (settings.minify) {
- if (contentType == 'text/javascript') {
- try {
- content = compressJS([content]);
- } catch (error) {
- // silence
- }
- } else if (contentType == 'text/css') {
- content = compressCSS([content]);
- }
+ } else if (contentType == 'text/javascript') {
+ try {
+ content = compressJS(content);
+ } catch (error) {
+ // silence
}
callback(null, content);
+ } else if (contentType == 'text/css') {
+ compressCSS(filename, content, callback);
+ } else {
+ callback(null, content);
}
});
}
@@ -400,20 +398,30 @@ function getFile(filename, callback) {
}
}
-function compressJS(values)
+function compressJS(content)
{
- var complete = values.join("\n");
- var ast = jsp.parse(complete); // parse code and get the initial AST
+ var ast = jsp.parse(content); // parse code and get the initial AST
ast = pro.ast_mangle(ast); // get a new AST with mangled names
ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
return pro.gen_code(ast); // compressed code here
}
-function compressCSS(values)
+function compressCSS(filename, content, callback)
{
- var complete = values.join("\n");
- var minimized = new CleanCSS().minify(complete).styles;
- return minimized;
+ try {
+ var base = path.join(ROOT_DIR, path.dirname(filename));
+ new CleanCSS({relativeTo: base}).minify(content, function (errors, minified) {
+ if (errors) {
+ // On error, just yield the un-minified original.
+ callback(null, content);
+ } else {
+ callback(null, minified.styles);
+ }
+ });
+ } catch (error) {
+ // On error, just yield the un-minified original.
+ callback(null, content);
+ }
}
exports.minify = minify;
diff --git a/src/node/utils/Settings.js b/src/node/utils/Settings.js
index b765670a..24bc25c3 100644
--- a/src/node/utils/Settings.js
+++ b/src/node/utils/Settings.js
@@ -209,6 +209,11 @@ exports.requireAuthentication = false;
exports.requireAuthorization = false;
exports.users = {};
+/*
+* Show settings in admin page, by default it is true
+*/
+exports.showSettingsInAdminPage = true;
+
//checks if abiword is avaiable
exports.abiwordAvailable = function()
{
diff --git a/src/node/utils/caching_middleware.js b/src/node/utils/caching_middleware.js
index 97134356..65fe5d2f 100644
--- a/src/node/utils/caching_middleware.js
+++ b/src/node/utils/caching_middleware.js
@@ -21,8 +21,7 @@ var path = require('path');
var zlib = require('zlib');
var settings = require('./Settings');
var semver = require('semver');
-
-var existsSync = (semver.satisfies(process.version, '>=0.8.0')) ? fs.existsSync : path.existsSync;
+var existsSync = require('./path_exists');
var CACHE_DIR = path.normalize(path.join(settings.root, 'var/'));
CACHE_DIR = existsSync(CACHE_DIR) ? CACHE_DIR : undefined;
diff --git a/src/node/utils/path_exists.js b/src/node/utils/path_exists.js
new file mode 100644
index 00000000..c2d43f6c
--- /dev/null
+++ b/src/node/utils/path_exists.js
@@ -0,0 +1,15 @@
+var fs = require('fs');
+
+var check = function(path) {
+ var existsSync = fs.statSync || fs.existsSync || path.existsSync;
+
+ var result;
+ try {
+ result = existsSync(path);
+ } catch (e) {
+ result = false;
+ }
+ return result;
+}
+
+module.exports = check;
diff --git a/src/package.json b/src/package.json
index fe98e297..ca86258f 100644
--- a/src/package.json
+++ b/src/package.json
@@ -15,35 +15,35 @@
"etherpad-yajsml" : "0.0.2",
"request" : "2.55.0",
"etherpad-require-kernel" : "1.0.9",
- "resolve" : "1.1.6",
- "socket.io" : "1.3.7",
+ "resolve" : "1.1.7",
+ "socket.io" : "1.6.0",
"ueberdb2" : "0.3.0",
- "express" : "4.12.3",
- "express-session" : "1.11.1",
+ "express" : "4.13.4",
+ "express-session" : "1.13.0",
"cookie-parser" : "1.3.4",
"async" : "0.9.0",
- "clean-css" : "3.1.9",
- "uglify-js" : "2.4.19",
+ "clean-css" : "3.4.19",
+ "uglify-js" : "2.6.2",
"formidable" : "1.0.17",
- "log4js" : "0.6.22",
- "cheerio" : "0.19.0",
+ "log4js" : "0.6.35",
+ "cheerio" : "0.20.0",
"async-stacktrace" : "0.0.2",
- "npm" : "2.7.6",
- "ejs" : "2.3.1",
- "graceful-fs" : "3.0.6",
+ "npm" : "4.0.2",
+ "ejs" : "2.4.1",
+ "graceful-fs" : "4.1.3",
"slide" : "1.1.6",
- "semver" : "4.3.3",
+ "semver" : "5.1.0",
"security" : "1.0.0",
"tinycon" : "0.0.1",
"underscore" : "1.8.3",
- "unorm" : "1.3.3",
+ "unorm" : "1.4.1",
"languages4translatewiki" : "0.1.3",
"swagger-node-express" : "2.1.3",
"channels" : "0.0.4",
- "jsonminify" : "0.2.3",
- "measured" : "1.0.0",
- "mocha" : "2.2.4",
- "supertest" : "0.15.0"
+ "jsonminify" : "0.4.1",
+ "measured" : "1.1.0",
+ "mocha" : "2.4.5",
+ "supertest" : "1.2.0"
},
"bin": { "etherpad-lite": "./node/server.js" },
"devDependencies": {
@@ -55,6 +55,6 @@
"repository" : { "type" : "git",
"url" : "http://github.com/ether/etherpad-lite.git"
},
- "version" : "1.6.0",
+ "version" : "1.6.1",
"license" : "Apache-2.0"
}
diff --git a/src/static/css/admin.css b/src/static/css/admin.css
index 97104de9..e9ba6014 100644
--- a/src/static/css/admin.css
+++ b/src/static/css/admin.css
@@ -38,6 +38,12 @@ div.innerwrapper {
padding-left: 265px;
}
+div.innerwrapper-err {
+ padding: 15px;
+ padding-left: 265px;
+ display: none;
+}
+
#wrapper {
background: none repeat scroll 0px 0px #FFFFFF;
box-shadow: 0px 1px 10px rgba(0, 0, 0, 0.2);
diff --git a/src/static/css/iframe_editor.css b/src/static/css/iframe_editor.css
index 451ce807..9aa003aa 100644
--- a/src/static/css/iframe_editor.css
+++ b/src/static/css/iframe_editor.css
@@ -1,6 +1,9 @@
/* These CSS rules are included in both the outer and inner ACE iframe.
Also see inner.css, included only in the inner one.
*/
+
+@import url('./lists_and_indents.css');
+
html { cursor: text; } /* in Safari, produces text cursor for whole doc (inc. below body) */
span { cursor: auto; }
@@ -11,75 +14,11 @@ span { cursor: auto; }
background: #acf;
}
-a {
- cursor: pointer !important;
+a {
+ cursor: pointer !important;
white-space:pre-wrap;
}
-ul, ol, li {
- padding: 0;
- margin: 0;
-}
-
-ul { margin-left: 1.5em; }
-ul ul { margin-left: 0 !important; }
-ul.list-bullet1 { margin-left: 1.5em; }
-ul.list-bullet2 { margin-left: 3em; }
-ul.list-bullet3 { margin-left: 4.5em; }
-ul.list-bullet4 { margin-left: 6em; }
-ul.list-bullet5 { margin-left: 7.5em; }
-ul.list-bullet6 { margin-left: 9em; }
-ul.list-bullet7 { margin-left: 10.5em; }
-ul.list-bullet8 { margin-left: 12em; }
-ul.list-bullet9 { margin-left: 13.5em; }
-ul.list-bullet10 { margin-left: 15em; }
-ul.list-bullet11 { margin-left: 16.5em; }
-ul.list-bullet12 { margin-left: 18em; }
-ul.list-bullet13 { margin-left: 19.5em; }
-ul.list-bullet14 { margin-left: 21em; }
-ul.list-bullet15 { margin-left: 22.5em; }
-ul.list-bullet16 { margin-left: 24em; }
-
-ul { list-style-type: disc; }
-ul.list-bullet1 { list-style-type: disc; }
-ul.list-bullet2 { list-style-type: circle; }
-ul.list-bullet3 { list-style-type: square; }
-ul.list-bullet4 { list-style-type: disc; }
-ul.list-bullet5 { list-style-type: circle; }
-ul.list-bullet6 { list-style-type: square; }
-ul.list-bullet7 { list-style-type: disc; }
-ul.list-bullet8 { list-style-type: circle; }
-ul.list-bullet9 { list-style-type: disc; }
-ul.list-bullet10 { list-style-type: circle; }
-ul.list-bullet11 { list-style-type: square; }
-ul.list-bullet12 { list-style-type: disc; }
-ul.list-bullet13 { list-style-type: circle; }
-ul.list-bullet14 { list-style-type: square; }
-ul.list-bullet15 { list-style-type: disc; }
-ul.list-bullet16 { list-style-type: circle; }
-
-ul.list-indent1 { margin-left: 1.5em; }
-ul.list-indent2 { margin-left: 3em; }
-ul.list-indent3 { margin-left: 4.5em; }
-ul.list-indent4 { margin-left: 6em; }
-ul.list-indent5 { margin-left: 7.5em; }
-ul.list-indent6 { margin-left: 9em; }
-ul.list-indent7 { margin-left: 10.5em; }
-ul.list-indent8 { margin-left: 12em; }
-ul.list-indent9 { margin-left: 13.5em; }
-ul.list-indent10 { margin-left: 15em; }
-ul.list-indent11 { margin-left: 16.5em; }
-ul.list-indent12 { margin-left: 18em; }
-ul.list-indent13 { margin-left: 19.5em; }
-ul.list-indent14 { margin-left: 21em; }
-ul.list-indent15 { margin-left: 22.5em; }
-ul.list-indent16 { margin-left: 24em; }
-
-ul.list-indent1, ul.list-indent2, ul.list-indent3, ul.list-indent4, ul.list-indent5,
-ul.list-indent6, ul.list-indent7, ul.list-indent8, ul.list-indent9, ul.list-indent10,
-ul.list-indent11, ul.list-indent12, ul.list-indent13,
-ul.list-indent14, ul.list-indent15, ul.list-indent16 { list-style-type: none; }
-
body {
margin: 0;
white-space: nowrap;
@@ -102,11 +41,11 @@ body.grayedout { background-color: #eee !important }
body.doesWrap {
/* white-space: pre-wrap; */
- /*
- Must be pre-wrap to keep trailing spaces. Otherwise you get a zombie caret,
+ /*
+ Must be pre-wrap to keep trailing spaces. Otherwise you get a zombie caret,
walking around your screen (see #1766).
WARNING: Enabling this causes Paste as plain text in Chrome to remove line breaks
- this is probably undesirable
+ this is probably undesirable
WARNING: This causes copy & paste events to lose bold etc. attributes
NOTE: The walking-zombie caret issue seems to have been fixed in FF upstream
so let's try diabling pre-wrap and see how we get on now.
@@ -208,134 +147,6 @@ p {
Commented out because it stops IE from being able to render the document, crazy IE bug is crazy. */
/*
.ace-line{
- overflow:hidden;
+ overflow:hidden;
}
*/
-
-ol {
- list-style-type: decimal;
-}
-
-/* Fixes #2223 and #1836 */
-ol > li {
- display:block;
-}
-
-/* Set the indentation */
-ol.list-number1{ text-indent: 0px; }
-ol.list-number2{ text-indent: 10px; }
-ol.list-number3{ text-indent: 20px; }
-ol.list-number4{ text-indent: 30px; }
-ol.list-number5{ text-indent: 40px; }
-ol.list-number6{ text-indent: 50px; }
-ol.list-number7{ text-indent: 60px; }
-ol.list-number8{ text-indent: 70px; }
-ol.list-number9{ text-indent: 80px; }
-ol.list-number10{ text-indent: 90px; }
-ol.list-number11{ text-indent: 100px; }
-ol.list-number12{ text-indent: 110px; }
-ol.list-number13{ text-indent: 120px; }
-ol.list-number14{ text-indent: 130px; }
-ol.list-number15{ text-indent: 140px; }
-ol.list-number16{ text-indent: 150px; }
-
-/* Add styling to the first item in a list */
-
-.list-start-number1 { counter-reset: first second; }
-.list-start-number2 { counter-reset: second; }
-.list-start-number3 { counter-reset: third; }
-.list-start-number4 { counter-reset: fourth; }
-.list-start-number5 { counter-reset: fifth; }
-.list-start-number6 { counter-reset: sixth; }
-.list-start-number7 { counter-reset: seventh; }
-.list-start-number8 { counter-reset: eighth; }
-.list-start-number9 { counter-reset: ninth; }
-.list-start-number10 { counter-reset: tenth; }
-.list-start-number11 { counter-reset: eleventh; }
-.list-start-number12 { counter-reset: twelth; }
-.list-start-number13 { counter-reset: thirteenth; }
-.list-start-number14 { counter-reset: fourteenth; }
-.list-start-number15 { counter-reset: fifteenth; }
-.list-start-number16 { counter-reset: sixteenth; }
-
-/* The behavior for incrementing and the prefix */
-.list-number1 li:before {
- content: counter(first) ". " ;
- counter-increment: first;
-}
-
-.list-number2 li:before {
- content: counter(first) "." counter(second) ". ";
- counter-increment: second;
-}
-
-.list-number3 li:before {
- content: counter(first) "." counter(second) "." counter(third) ". ";
- counter-increment: third 1;
-}
-
-.list-number4 li:before {
- content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) ". ";
- counter-increment: fourth 1;
-}
-
-.list-number5 li:before {
- content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) ". ";
- counter-increment: fifth 1;
-}
-
-.list-number6 li:before {
- content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) ". ";
- counter-increment: sixth 1;
-}
-
-.list-number7 li:before {
- content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) ". ";
- counter-increment: seventh 1;
-}
-
-.list-number8 li:before {
- content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eighth) ". " ;
- counter-increment: eighth 1;
-}
-
-.list-number9 li:before {
- content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eighth) "." counter(ninth) ". ";
- counter-increment: ninth 1;
-}
-
-.list-number10 li:before {
- content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eighth) "." counter(ninth) "." counter(tenth) ". ";
- counter-increment: tenth 1;
-}
-
-.list-number11 li:before {
- content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eighth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) ". ";
- counter-increment: eleventh 1;
-}
-
-.list-number12 li:before {
- content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eighth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) ". ";
- counter-increment: twelth 1;
-}
-
-.list-number13 li:before {
- content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eighth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) ". ";
- counter-increment: thirteenth 1;
-}
-
-.list-number14 li:before {
- content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(eighth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) ". ";
- counter-increment: fourteenth 1;
-}
-
-.list-number15 li:before {
- content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(eighth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) "." counter(fifteenth) ". ";
- counter-increment: fifteenth 1;
-}
-
-.list-number16 li:before {
- content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(eighth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) "." counter(fifteenth) "." counter(sixteenth) ". ";
- counter-increment: fixteenth 1;
-}
-
diff --git a/src/static/css/lists_and_indents.css b/src/static/css/lists_and_indents.css
new file mode 100644
index 00000000..c6348efa
--- /dev/null
+++ b/src/static/css/lists_and_indents.css
@@ -0,0 +1,195 @@
+/*
+ * These are the common definitions for the styling of bulleted lists, numbered
+ * lists, and plain indented blocks, shared by the editor and timeslider pages.
+ */
+
+ul, ol, li {
+ padding: 0;
+ margin: 0;
+}
+
+ul { margin-left: 1.5em; }
+ul ul { margin-left: 0 !important; }
+ul.list-bullet1 { margin-left: 1.5em; }
+ul.list-bullet2 { margin-left: 3em; }
+ul.list-bullet3 { margin-left: 4.5em; }
+ul.list-bullet4 { margin-left: 6em; }
+ul.list-bullet5 { margin-left: 7.5em; }
+ul.list-bullet6 { margin-left: 9em; }
+ul.list-bullet7 { margin-left: 10.5em; }
+ul.list-bullet8 { margin-left: 12em; }
+ul.list-bullet9 { margin-left: 13.5em; }
+ul.list-bullet10 { margin-left: 15em; }
+ul.list-bullet11 { margin-left: 16.5em; }
+ul.list-bullet12 { margin-left: 18em; }
+ul.list-bullet13 { margin-left: 19.5em; }
+ul.list-bullet14 { margin-left: 21em; }
+ul.list-bullet15 { margin-left: 22.5em; }
+ul.list-bullet16 { margin-left: 24em; }
+
+ul { list-style-type: disc; }
+ul.list-bullet1 { list-style-type: disc; }
+ul.list-bullet2 { list-style-type: circle; }
+ul.list-bullet3 { list-style-type: square; }
+ul.list-bullet4 { list-style-type: disc; }
+ul.list-bullet5 { list-style-type: circle; }
+ul.list-bullet6 { list-style-type: square; }
+ul.list-bullet7 { list-style-type: disc; }
+ul.list-bullet8 { list-style-type: circle; }
+ul.list-bullet9 { list-style-type: disc; }
+ul.list-bullet10 { list-style-type: circle; }
+ul.list-bullet11 { list-style-type: square; }
+ul.list-bullet12 { list-style-type: disc; }
+ul.list-bullet13 { list-style-type: circle; }
+ul.list-bullet14 { list-style-type: square; }
+ul.list-bullet15 { list-style-type: disc; }
+ul.list-bullet16 { list-style-type: circle; }
+
+ul.list-indent1 { margin-left: 1.5em; }
+ul.list-indent2 { margin-left: 3em; }
+ul.list-indent3 { margin-left: 4.5em; }
+ul.list-indent4 { margin-left: 6em; }
+ul.list-indent5 { margin-left: 7.5em; }
+ul.list-indent6 { margin-left: 9em; }
+ul.list-indent7 { margin-left: 10.5em; }
+ul.list-indent8 { margin-left: 12em; }
+ul.list-indent9 { margin-left: 13.5em; }
+ul.list-indent10 { margin-left: 15em; }
+ul.list-indent11 { margin-left: 16.5em; }
+ul.list-indent12 { margin-left: 18em; }
+ul.list-indent13 { margin-left: 19.5em; }
+ul.list-indent14 { margin-left: 21em; }
+ul.list-indent15 { margin-left: 22.5em; }
+ul.list-indent16 { margin-left: 24em; }
+
+ul.list-indent1, ul.list-indent2, ul.list-indent3, ul.list-indent4, ul.list-indent5,
+ul.list-indent6, ul.list-indent7, ul.list-indent8, ul.list-indent9, ul.list-indent10,
+ul.list-indent11, ul.list-indent12, ul.list-indent13,
+ul.list-indent14, ul.list-indent15, ul.list-indent16 { list-style-type: none; }
+
+ol {
+ list-style-type: decimal;
+}
+
+/* Fixes #2223 and #1836 */
+ol > li {
+ display:block;
+}
+
+/* Set the indentation */
+ol.list-number1{ text-indent: 0px; }
+ol.list-number2{ text-indent: 10px; }
+ol.list-number3{ text-indent: 20px; }
+ol.list-number4{ text-indent: 30px; }
+ol.list-number5{ text-indent: 40px; }
+ol.list-number6{ text-indent: 50px; }
+ol.list-number7{ text-indent: 60px; }
+ol.list-number8{ text-indent: 70px; }
+ol.list-number9{ text-indent: 80px; }
+ol.list-number10{ text-indent: 90px; }
+ol.list-number11{ text-indent: 100px; }
+ol.list-number12{ text-indent: 110px; }
+ol.list-number13{ text-indent: 120px; }
+ol.list-number14{ text-indent: 130px; }
+ol.list-number15{ text-indent: 140px; }
+ol.list-number16{ text-indent: 150px; }
+
+/* Add styling to the first item in a list */
+
+.list-start-number1 { counter-reset: first second; }
+.list-start-number2 { counter-reset: second; }
+.list-start-number3 { counter-reset: third; }
+.list-start-number4 { counter-reset: fourth; }
+.list-start-number5 { counter-reset: fifth; }
+.list-start-number6 { counter-reset: sixth; }
+.list-start-number7 { counter-reset: seventh; }
+.list-start-number8 { counter-reset: eighth; }
+.list-start-number9 { counter-reset: ninth; }
+.list-start-number10 { counter-reset: tenth; }
+.list-start-number11 { counter-reset: eleventh; }
+.list-start-number12 { counter-reset: twelfth; }
+.list-start-number13 { counter-reset: thirteenth; }
+.list-start-number14 { counter-reset: fourteenth; }
+.list-start-number15 { counter-reset: fifteenth; }
+.list-start-number16 { counter-reset: sixteenth; }
+
+/* The behavior for incrementing and the prefix */
+.list-number1 li:before {
+ content: counter(first) ". " ;
+ counter-increment: first;
+}
+
+.list-number2 li:before {
+ content: counter(first) "." counter(second) ". ";
+ counter-increment: second;
+}
+
+.list-number3 li:before {
+ content: counter(first) "." counter(second) "." counter(third) ". ";
+ counter-increment: third 1;
+}
+
+.list-number4 li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) ". ";
+ counter-increment: fourth 1;
+}
+
+.list-number5 li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) ". ";
+ counter-increment: fifth 1;
+}
+
+.list-number6 li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) ". ";
+ counter-increment: sixth 1;
+}
+
+.list-number7 li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) ". ";
+ counter-increment: seventh 1;
+}
+
+.list-number8 li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eighth) ". " ;
+ counter-increment: eighth 1;
+}
+
+.list-number9 li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eighth) "." counter(ninth) ". ";
+ counter-increment: ninth 1;
+}
+
+.list-number10 li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eighth) "." counter(ninth) "." counter(tenth) ". ";
+ counter-increment: tenth 1;
+}
+
+.list-number11 li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eighth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) ". ";
+ counter-increment: eleventh 1;
+}
+
+.list-number12 li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eighth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelfth) ". ";
+ counter-increment: twelfth 1;
+}
+
+.list-number13 li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eighth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelfth) "." counter(thirteenth) ". ";
+ counter-increment: thirteenth 1;
+}
+
+.list-number14 li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(eighth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelfth) "." counter(thirteenth) "." counter(fourteenth) ". ";
+ counter-increment: fourteenth 1;
+}
+
+.list-number15 li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(eighth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelfth) "." counter(thirteenth) "." counter(fourteenth) "." counter(fifteenth) ". ";
+ counter-increment: fifteenth 1;
+}
+
+.list-number16 li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(eighth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelfth) "." counter(thirteenth) "." counter(fourteenth) "." counter(fifteenth) "." counter(sixteenth) ". ";
+ counter-increment: sixteenth 1;
+}
diff --git a/src/static/css/timeslider.css b/src/static/css/timeslider.css
index 2756a006..0311b10e 100644
--- a/src/static/css/timeslider.css
+++ b/src/static/css/timeslider.css
@@ -1,3 +1,9 @@
+@import url('./lists_and_indents.css');
+
+p.pblort {
+ height: 100px;
+}
+
#editorcontainerbox {
overflow: auto;
top: 40px;
@@ -90,7 +96,7 @@
cursor:hand;
}
#playpause_button_icon:before {
- line-height:44px;
+ line-height:44px;
padding-left:2px;
font-family: fontawesome-etherpad;
content: "\e82c";
@@ -105,7 +111,7 @@
border: solid 1px #666;
}
.pause:before {
- line-height:44px;
+ line-height:44px;
padding-left:2px;
font-family: fontawesome-etherpad;
content: "\e82e" !important;
@@ -256,83 +262,6 @@ stepper:active{
#padeditor {
position: static
}
-/* lists */
-.list-bullet2,
-.list-indent2,
-.list-number2 {
- margin-left: 3em
-}
-.list-bullet3,
-.list-indent3,
-.list-number3 {
- margin-left: 4.5em
-}
-.list-bullet4,
-.list-indent4,
-.list-number4 {
- margin-left: 6em
-}
-.list-bullet5,
-.list-indent5,
-.list-number5 {
- margin-left: 7.5em
-}
-.list-bullet6,
-.list-indent6,
-.list-number6 {
- margin-left: 9em
-}
-.list-bullet7,
-.list-indent7,
-.list-number7 {
- margin-left: 10.5em
-}
-.list-bullet8,
-.list-indent8,
-.list-number8 {
- margin-left: 12em
-}
-/* unordered lists */
-UL {
- list-style-type: disc;
- margin-left: 1.5em;
-}
-UL UL {
- margin-left: 0 !important
-}
-.list-bullet2,
-.list-bullet5,
-.list-bullet8 {
- list-style-type: circle
-}
-.list-bullet3,
-.list-bullet6 {
- list-style-type: square
-}
-.list-indent1,
-.list-indent2,
-.list-indent3,
-.list-indent5,
-.list-indent5,
-.list-indent6,
-.list-indent7,
-.list-indent8 {
- list-style-type: none
-}
-/* ordered lists */
-OL {
- list-style-type: decimal;
- margin-left: 1.5em;
-}
-.list-number2,
-.list-number5,
-.list-number8 {
- list-style-type: lower-latin
-}
-.list-number3,
-.list-number6 {
- list-style-type: lower-roman
-}
button{
margin:0;
@@ -348,4 +277,3 @@ button::-moz-focus-inner {
button:focus{
border: 1px solid #666;
}
-
diff --git a/src/static/js/ace.js b/src/static/js/ace.js
index a5e365ce..9f219e6c 100644
--- a/src/static/js/ace.js
+++ b/src/static/js/ace.js
@@ -226,8 +226,12 @@ function Ace2Editor()
var includedCSS = [];
var $$INCLUDE_CSS = function(filename) {includedCSS.push(filename)};
$$INCLUDE_CSS("../static/css/iframe_editor.css");
- $$INCLUDE_CSS("../static/css/pad.css");
- $$INCLUDE_CSS("../static/custom/pad.css");
+
+ // disableCustomScriptsAndStyles can be used to disable loading of custom scripts
+ if(!clientVars.disableCustomScriptsAndStyles){
+ $$INCLUDE_CSS("../static/css/pad.css");
+ $$INCLUDE_CSS("../static/custom/pad.css");
+ }
var additionalCSS = _(hooks.callAll("aceEditorCSS")).map(function(path){
if (path.match(/\/\//)) { // Allow urls to external CSS - http(s):// and //some/path.css
diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js
index f2c45f6a..0970666e 100644
--- a/src/static/js/ace2_inner.js
+++ b/src/static/js/ace2_inner.js
@@ -369,6 +369,19 @@ function Ace2Inner(){
return thisAuthor;
}
+ var _nonScrollableEditEvents = {
+ "applyChangesToBase": 1
+ };
+
+ _.each(hooks.callAll('aceRegisterNonScrollableEditEvents'), function(eventType) {
+ _nonScrollableEditEvents[eventType] = 1;
+ });
+
+ function isScrollableEditEvent(eventType)
+ {
+ return !_nonScrollableEditEvents[eventType];
+ }
+
var currentCallStack = null;
function inCallStack(type, action)
@@ -506,7 +519,7 @@ function Ace2Inner(){
{
updateBrowserSelectionFromRep();
}
- if ((cs.docTextChanged || cs.userChangedSelection) && cs.type != "applyChangesToBase")
+ if ((cs.docTextChanged || cs.userChangedSelection) && isScrollableEditEvent(cs.type))
{
scrollSelectionIntoView();
}
@@ -1442,16 +1455,6 @@ function Ace2Inner(){
var selection = getSelection();
p.end();
- function topLevel(n)
- {
- if ((!n) || n == root) return null;
- while (n.parentNode != root)
- {
- n = n.parentNode;
- }
- return n;
- }
-
if (selection)
{
var node1 = topLevel(selection.startPoint.node);
@@ -1473,12 +1476,8 @@ function Ace2Inner(){
var nds = root.getElementsByTagName("style");
for (var i = 0; i < nds.length; i++)
{
- var n = nds[i];
- while (n.parentNode && n.parentNode != root)
- {
- n = n.parentNode;
- }
- if (n.parentNode == root)
+ var n = topLevel(nds[i]);
+ if (n && n.parentNode == root)
{
observeChangesAroundNode(n);
}
@@ -5021,6 +5020,23 @@ function Ace2Inner(){
if(e.target.a || e.target.localName === "a"){
e.preventDefault();
}
+
+ // Bug fix: when user drags some content and drop it far from its origin, we
+ // need to merge the changes into a single changeset. So mark origin with <style>,
+ // in order to make content be observed by incorporateUserChanges() (see
+ // observeSuspiciousNodes() for more info)
+ var selection = getSelection();
+ if (selection){
+ var firstLineSelected = topLevel(selection.startPoint.node);
+ var lastLineSelected = topLevel(selection.endPoint.node);
+
+ var lineBeforeSelection = firstLineSelected.previousSibling;
+ var lineAfterSelection = lastLineSelected.nextSibling;
+
+ var neighbor = lineBeforeSelection || lineAfterSelection;
+ neighbor.appendChild(document.createElement('style'));
+ }
+
// Call drop hook
hooks.callAll('aceDrop', {
editorInfo: editorInfo,
@@ -5038,6 +5054,16 @@ function Ace2Inner(){
}
}
+ function topLevel(n)
+ {
+ if ((!n) || n == root) return null;
+ while (n.parentNode != root)
+ {
+ n = n.parentNode;
+ }
+ return n;
+ }
+
function handleIEOuterClick(evt)
{
if ((evt.target.tagName || '').toLowerCase() != "html")
@@ -5433,7 +5459,16 @@ function Ace2Inner(){
// and the line-numbers don't line up unless we pay
// attention to where the divs are actually placed...
// (also: padding on TTs/SPANs in IE...)
- h = b.nextSibling.offsetTop - b.offsetTop;
+ if (b === doc.body.firstChild) {
+ // It's the first line. For line number alignment purposes, its
+ // height is taken to be the top offset of the next line. If we
+ // didn't do this special case, we would miss out on any top margin
+ // included on the first line. The default stylesheet doesn't add
+ // extra margins, but plugins might.
+ h = b.nextSibling.offsetTop;
+ } else {
+ h = b.nextSibling.offsetTop - b.offsetTop;
+ }
}
if (h)
{
diff --git a/src/static/js/admin/plugins.js b/src/static/js/admin/plugins.js
index 48d1ab70..3f88d9b1 100644
--- a/src/static/js/admin/plugins.js
+++ b/src/static/js/admin/plugins.js
@@ -228,7 +228,7 @@ $(document).ready(function () {
if(data.code === "EPEERINVALID"){
alert("This plugin requires that you update Etherpad so it can operate in it's true glory");
}
- alert('An error occured while installing '+data.plugin+' \n'+data.error)
+ alert('An error occurred while installing '+data.plugin+' \n'+data.error)
$('#installed-plugins .'+data.plugin).remove()
}
@@ -241,7 +241,7 @@ $(document).ready(function () {
})
socket.on('finished:uninstall', function(data) {
- if(data.error) alert('An error occured while uninstalling the '+data.plugin+' \n'+data.error)
+ if(data.error) alert('An error occurred while uninstalling the '+data.plugin+' \n'+data.error)
// remove plugin from installed list
$('#installed-plugins .'+data.plugin).remove()
diff --git a/src/static/js/admin/settings.js b/src/static/js/admin/settings.js
index 42b038d5..6c1f5e23 100644
--- a/src/static/js/admin/settings.js
+++ b/src/static/js/admin/settings.js
@@ -14,12 +14,20 @@ $(document).ready(function () {
socket.on('settings', function (settings) {
+ /* Check whether the settings.json is authorized to be viewed */
+ if(settings.results === 'NOT_ALLOWED') {
+ $('.innerwrapper').hide();
+ $('.innerwrapper-err').show();
+ $('.err-message').html("Settings json is not authorized to be viewed in Admin page!!");
+ return;
+ }
+
/* Check to make sure the JSON is clean before proceeding */
if(isJSONClean(settings.results))
{
$('.settings').append(settings.results);
$('.settings').focus();
- $('.settings').autosize();
+ $('.settings').autosize();
}
else{
alert("YOUR JSON IS BAD AND YOU SHOULD FEEL BAD");
diff --git a/src/static/js/linestylefilter.js b/src/static/js/linestylefilter.js
index 93680515..3cf7a510 100644
--- a/src/static/js/linestylefilter.js
+++ b/src/static/js/linestylefilter.js
@@ -265,7 +265,7 @@ linestylefilter.getRegexpFilter = function(regExp, tag)
linestylefilter.REGEX_WORDCHAR = /[\u0030-\u0039\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u1FFF\u3040-\u9FFF\uF900-\uFDFF\uFE70-\uFEFE\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]/;
-linestylefilter.REGEX_URLCHAR = new RegExp('(' + /[-:@a-zA-Z0-9_.,~%+\/\\?=&#!;()\[\]$]/.source + '|' + linestylefilter.REGEX_WORDCHAR.source + ')');
+linestylefilter.REGEX_URLCHAR = new RegExp('(' + /[-:@a-zA-Z0-9_.,~%+\/\\?=&#!;()$]/.source + '|' + linestylefilter.REGEX_WORDCHAR.source + ')');
linestylefilter.REGEX_URL = new RegExp(/(?:(?:https?|s?ftp|ftps|file|nfs):\/\/|(about|geo|mailto|tel):|www\.)/.source + linestylefilter.REGEX_URLCHAR.source + '*(?![:.,;])' + linestylefilter.REGEX_URLCHAR.source, 'g');
linestylefilter.getURLFilter = linestylefilter.getRegexpFilter(
linestylefilter.REGEX_URL, 'url');
diff --git a/src/static/js/pad.js b/src/static/js/pad.js
index 25b1a24d..c967e461 100644
--- a/src/static/js/pad.js
+++ b/src/static/js/pad.js
@@ -52,43 +52,6 @@ var hooks = require('./pluginfw/hooks');
var receivedClientVars = false;
-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 = "";
- }
-
- 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') || ((navigator.appName == 'Netscape') && (new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) != null))){
- document.cookie = name + "=" + value + expires + "; path="+document.location;
- }
- else{
- document.cookie = name + "=" + value + expires + "; path=" + path;
- }
-}
-
-function readCookie(name)
-{
- var nameEQ = name + "=";
- var ca = document.cookie.split(';');
- for (var i = 0; i < ca.length; i++)
- {
- var c = ca[i];
- while (c.charAt(0) == ' ') c = c.substring(1, c.length);
- if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
- }
- return null;
-}
-
function randomString()
{
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -231,40 +194,27 @@ function handshake()
// Allow deployers to host Etherpad on a non-root path
'path': exports.baseURL + "socket.io",
'resource': resource,
- 'max reconnection attempts': 3,
- 'sync disconnect on unload' : false
+ 'reconnectionAttempts': 5,
+ 'reconnection' : true,
+ 'reconnectionDelay' : 1000,
+ 'reconnectionDelayMax' : 5000
});
- var disconnectTimeout;
-
socket.once('connect', function () {
sendClientReady(false);
});
socket.on('reconnect', function () {
- //reconnect is before the timeout, lets stop the timeout
- if(disconnectTimeout)
- {
- clearTimeout(disconnectTimeout);
- }
-
pad.collabClient.setChannelState("CONNECTED");
pad.sendClientReady(true);
});
- socket.on('disconnect', function (reason) {
- if(reason == "booted"){
- pad.collabClient.setChannelState("DISCONNECTED");
- } else {
- function disconnectEvent()
- {
- pad.collabClient.setChannelState("DISCONNECTED", "reconnect_timeout");
- }
-
- pad.collabClient.setChannelState("RECONNECTING");
-
- disconnectTimeout = setTimeout(disconnectEvent, 20000);
- }
+ socket.on('reconnecting', function() {
+ pad.collabClient.setChannelState("RECONNECTING");
+ });
+
+ socket.on('reconnect_failed', function(error) {
+ pad.collabClient.setChannelState("DISCONNECTED", "reconnect_timeout");
});
var initalized = false;
@@ -500,10 +450,10 @@ var pad = {
handshake();
// To use etherpad you have to allow cookies.
- // This will check if the creation of a test-cookie has success.
+ // This will check if the prefs-cookie is set.
// Otherwise it shows up a message to the user.
- createCookie("test", "test");
- if (!readCookie("test"))
+ padcookie.init();
+ if (!readCookie("prefs"))
{
$('#loading').hide();
$('#noCookie').show();
@@ -769,6 +719,7 @@ var pad = {
var wasConnecting = (padconnectionstatus.getStatus().what == 'connecting');
if (newState == "CONNECTED")
{
+ padeditor.enable();
padconnectionstatus.connected();
}
else if (newState == "RECONNECTING")
diff --git a/src/static/js/pad_cookie.js b/src/static/js/pad_cookie.js
index 9866dbfd..b563a7e6 100644
--- a/src/static/js/pad_cookie.js
+++ b/src/static/js/pad_cookie.js
@@ -43,7 +43,8 @@ var padcookie = (function()
{
var expiresDate = new Date();
expiresDate.setFullYear(3000);
- document.cookie = ('prefs=' + safeText + ';expires=' + expiresDate.toGMTString());
+ var secure = isHttpsScheme() ? ";secure" : "";
+ document.cookie = ('prefs=' + safeText + ';expires=' + expiresDate.toGMTString() + secure);
}
function parseCookie(text)
@@ -79,6 +80,10 @@ var padcookie = (function()
alreadyWarnedAboutNoCookies = true;
}
}
+
+ function isHttpsScheme() {
+ return window.location.protocol == "https:";
+ }
var wasNoCookie = true;
var cookieData = {};
diff --git a/src/static/js/pad_editbar.js b/src/static/js/pad_editbar.js
index d44e5d66..dd1c377a 100644
--- a/src/static/js/pad_editbar.js
+++ b/src/static/js/pad_editbar.js
@@ -242,9 +242,9 @@ var padeditbar = (function()
});
},
registerAceCommand: function (cmd, callback) {
- this.registerCommand(cmd, function (cmd, ace) {
+ this.registerCommand(cmd, function (cmd, ace, item) {
ace.callWithAce(function (ace) {
- callback(cmd, ace);
+ callback(cmd, ace, item);
}, cmd, true);
});
},
diff --git a/src/static/js/pad_editor.js b/src/static/js/pad_editor.js
index 6616ebe8..3e6b49d3 100644
--- a/src/static/js/pad_editor.js
+++ b/src/static/js/pad_editor.js
@@ -198,6 +198,13 @@ var padeditor = (function()
self.ace = null;
}
},
+ enable: function()
+ {
+ if (self.ace)
+ {
+ self.ace.setEditable(true);
+ }
+ },
disable: function()
{
if (self.ace)
diff --git a/src/static/js/pad_utils.js b/src/static/js/pad_utils.js
index 5a7700c9..b83f21cf 100644
--- a/src/static/js/pad_utils.js
+++ b/src/static/js/pad_utils.js
@@ -53,13 +53,16 @@ function createCookie(name, value, days, path){ /* Used by IE */
if(!path){ // IF the Path of the cookie isn't set then just create it on root
path = "/";
}
+
+ //Check if we accessed the pad over https
+ var secure = window.location.protocol == "https:" ? ";secure" : "";
//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') || ((navigator.appName == 'Netscape') && (new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) != null))){
- document.cookie = name + "=" + value + expires + "; path=/"; /* Note this bodge fix for IE is temporary until auth is rewritten */
+ document.cookie = name + "=" + value + expires + "; path=/" + secure; /* 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 + secure;
}
}
@@ -520,7 +523,7 @@ function setupGlobalExceptionHandler() {
//show javascript errors to the user
$("#editorloadingbox").css("padding", "10px");
$("#editorloadingbox").css("padding-top", "45px");
- $("#editorloadingbox").html("<div style='text-align:left;color:red;font-size:16px;'><b>An error occured</b><br>The error was reported with the following id: '" + errorId + "'<br><br><span style='color:black;font-weight:bold;font-size:16px'>Please press and hold Ctrl and press F5 to reload this page, if the problem persists please send this error message to your webmaster: </span><div style='color:black;font-size:14px'>'"
+ $("#editorloadingbox").html("<div style='text-align:left;color:red;font-size:16px;'><b>An error occurred</b><br>The error was reported with the following id: '" + errorId + "'<br><br><span style='color:black;font-weight:bold;font-size:16px'>Please press and hold Ctrl and press F5 to reload this page, if the problem persists please send this error message to your webmaster: </span><div style='color:black;font-size:14px'>'"
+ "ErrorId: " + errorId + "<br>URL: " + window.location.href + "<br>UserAgent: " + userAgent + "<br>" + msg + " in " + url + " at line " + linenumber + "'</div></div>");
}
diff --git a/src/static/js/pluginfw/plugins.js b/src/static/js/pluginfw/plugins.js
index dfdf941e..0d0fa1ed 100644
--- a/src/static/js/pluginfw/plugins.js
+++ b/src/static/js/pluginfw/plugins.js
@@ -117,13 +117,14 @@ exports.getPackages = function (cb) {
delete packages[name].parent;
}
- if (deps[name].dependencies !== undefined) flatten(deps[name].dependencies);
+ // I don't think we need recursion
+ //if (deps[name].dependencies !== undefined) flatten(deps[name].dependencies);
});
}
var tmp = {};
tmp[data.name] = data;
- flatten(tmp);
+ flatten(tmp[undefined].dependencies);
cb(null, packages);
});
};
diff --git a/src/templates/admin/index.html b/src/templates/admin/index.html
index f6e9e29e..45755a49 100644
--- a/src/templates/admin/index.html
+++ b/src/templates/admin/index.html
@@ -20,5 +20,6 @@
</ul>
</div>
</div>
+ <div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
</body>
</html>
diff --git a/src/templates/admin/plugins-info.html b/src/templates/admin/plugins-info.html
index 5d39c388..8dd0bf88 100644
--- a/src/templates/admin/plugins-info.html
+++ b/src/templates/admin/plugins-info.html
@@ -41,5 +41,6 @@
</div>
</div>
+ <div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
</body>
</html>
diff --git a/src/templates/admin/plugins.html b/src/templates/admin/plugins.html
index 71c4dbcc..0fff7843 100644
--- a/src/templates/admin/plugins.html
+++ b/src/templates/admin/plugins.html
@@ -112,5 +112,6 @@
</div>
</div>
+ <div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
</body>
</html>
diff --git a/src/templates/admin/settings.html b/src/templates/admin/settings.html
index 3b8615fc..74f35521 100644
--- a/src/templates/admin/settings.html
+++ b/src/templates/admin/settings.html
@@ -44,6 +44,12 @@
<a href='https://github.com/ether/etherpad-lite/wiki/Example-Production-Settings.JSON'>Example production settings template</a>
<a href='https://github.com/ether/etherpad-lite/wiki/Example-Development-Settings.JSON'>Example development settings template</a>
</div>
+
+ <div class="innerwrapper-err" >
+ <h2 class="err-message"></h2>
+ </div>
+
</div>
+ <div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
</body>
</html>
diff --git a/src/templates/export_html.html b/src/templates/export_html.html
new file mode 100644
index 00000000..b29941c9
--- /dev/null
+++ b/src/templates/export_html.html
@@ -0,0 +1,144 @@
+<!doctype html>
+<html lang="en">
+<head>
+<title><%- padId %></title>
+<meta name="generator" content="Etherpad">
+<meta name="author" content="Etherpad">
+<meta name="changedby" content="Etherpad">
+<meta charset="utf-8">
+<style>
+* {
+ font-family: arial, sans-serif;
+ font-size: 13px;
+ line-height: 17px;
+}
+ul.indent {
+ list-style-type: none;
+}
+ol {
+ list-style-type: none;
+ padding-left: 0;
+}
+body > ol {
+ counter-reset: first second third fourth fifth sixth seventh eigth ninth tenth eleventh twelth thirteenth fourteenth fifteenth sixteenth;
+}
+ol > li:before {
+ content: counter(first) ". ";
+ counter-increment: first;
+}
+ol > ol > li:before {
+ content: counter(first) "." counter(second) ". ";
+ counter-increment: second;
+}
+ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) ". ";
+ counter-increment: third;
+}
+ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) ". ";
+ counter-increment: fourth;
+}
+ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) ". ";
+ counter-increment: fifth;
+}
+ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) ". ";
+ counter-increment: sixth;
+}
+ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) ". ";
+ counter-increment: seventh;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) ". ";
+ counter-increment: eigth;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) ". ";
+ counter-increment: ninth;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) ". ";
+ counter-increment: tenth;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) ". ";
+ counter-increment: eleventh;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) ". ";
+ counter-increment: twelth;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) ". ";
+ counter-increment: thirteenth;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) ". ";
+ counter-increment: fourteenth;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) "." counter(fifteenth) ". ";
+ counter-increment: fifteenth;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > li:before {
+ content: counter(first) "." counter(second) "." counter(third) "." counter(fourth) "." counter(fifth) "." counter(sixth) "." counter(seventh) "." counter(eigth) "." counter(ninth) "." counter(tenth) "." counter(eleventh) "." counter(twelth) "." counter(thirteenth) "." counter(fourteenth) "." counter(fifteenth) "." counter(sixthteenth) ". ";
+ counter-increment: sixthteenth;
+}
+ol {
+ text-indent: 0px;
+}
+ol > ol {
+ text-indent: 10px;
+}
+ol > ol > ol {
+ text-indent: 20px;
+}
+ol > ol > ol > ol {
+ text-indent: 30px;
+}
+ol > ol > ol > ol > ol {
+ text-indent: 40px;
+}
+ol > ol > ol > ol > ol > ol {
+ text-indent: 50px;
+}
+ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 60px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 70px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 80px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 90px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 100px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 110px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 120px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 130px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 140px;
+}
+ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol > ol {
+ text-indent: 150px;
+}
+<%- extraCSS %>
+</style>
+</head>
+<body>
+<%- body %>
+<div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
+</body>
+</html>
diff --git a/src/templates/index.html b/src/templates/index.html
index 0b0be79b..e1f59c1e 100644
--- a/src/templates/index.html
+++ b/src/templates/index.html
@@ -29,7 +29,8 @@
*/
</script>
- <meta charset="utf-8">
+ <meta charset="utf-8">
+ <meta name="referrer" content="no-referrer">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<link rel="shortcut icon" href="<%=settings.favicon%>">
@@ -121,7 +122,7 @@
input[type="text"] {
border-radius: 3px;
box-sizing: border-box;
- -moz-box-sizing: border-box;
+ -moz-box-sizing: border-box;
line-height:36px; /* IE8 hack */
padding: 0px 45px 0 10px;
*padding: 0; /* IE7 hack */
@@ -148,22 +149,22 @@
margin-top: 0;
}
#inner {
- width: 95%;
+ width: 95%;
}
#label {
text-align: center;
}
}
</style>
- <link href="static/custom/index.css" rel="stylesheet">
+ <link href="static/custom/index.css" rel="stylesheet">
<div id="wrapper">
<% e.begin_block("indexWrapper"); %>
<div id="inner">
<buttOn id="button" onclick="go2Random()" data-l10n-id="index.newPad"></button>
- <label id="label" for="padname" data-l10n-id="index.createOpenPad"></label>
- <form action="#" onsubmit="go2Name();return false;">
- <input type="text" id="padname" maxlength="50" autofocus x-webkit-speech>
+ <label id="label" for="padname" data-l10n-id="index.createOpenPad"></label>
+ <form action="#" onsubmit="go2Name();return false;">
+ <input type="text" id="padname" maxlength="50" autofocus x-webkit-speech>
<button type="submit">OK</button>
</form>
</div>
@@ -171,33 +172,35 @@
</div>
<script src="static/custom/index.js"></script>
- <script>
-
- function go2Name()
+ <script>
+ // @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7&dn=apache-2.0.txt
+ function go2Name()
{
var padname = document.getElementById("padname").value;
padname.length > 0 ? window.location = "p/" + padname : alert("Please enter a name")
}
-
- function go2Random()
+
+ function go2Random()
{
window.location = "p/" + randomPadName();
}
-
- function randomPadName()
+
+ function randomPadName()
{
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var string_length = 10;
var randomstring = '';
- for (var i = 0; i < string_length; i++)
+ for (var i = 0; i < string_length; i++)
{
var rnum = Math.floor(Math.random() * chars.length);
randomstring += chars.substring(rnum, rnum + 1);
}
return randomstring;
}
-
+
// start the custom js
if (typeof customStart == "function") customStart();
+ // @license-end
</script>
+ <div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
</html>
diff --git a/src/templates/javascript.html b/src/templates/javascript.html
new file mode 100644
index 00000000..29031c4b
--- /dev/null
+++ b/src/templates/javascript.html
@@ -0,0 +1,73 @@
+<!doctype html>
+<html>
+ <head>
+ <title>JavaScript license information</title>
+ <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">
+ </head>
+ <body>
+ <table id="jslicense-labels1">
+ <tr>
+ <td><a href="/static/js/jquery-2.1.1.min.js">jquery-2.1.1.min.js</a></td>
+ <td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
+ <td><a href="/static/js/jquery.js">jquery.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/html10n.js">html10n.js</a></td>
+ <td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
+ <td><a href="/static/js/html10n.js">html10n.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/l10n.js">l10n.js</a></td>
+ <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache-2.0-only</a></td>
+ <td><a href="/static/js/l10n.js">l10n.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/socket.io.js">socket.io.js</a></td>
+ <td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
+ <td><a href="/static/js/socket.io.js">socket.io.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/require-kernel.js">require-kernel.js</a></td>
+ <td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
+ <td><a href="/static/js/require-kernel.js">require-kernel.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/custom/index.js">index.js</a></td>
+ <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache-2.0-only</a></td>
+ <td><a href="/static/custom/index.js">index.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/custom/timeslider.js">timeslider.js</a></td>
+ <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache-2.0-only</a></td>
+ <td><a href="/static/custom/timeslider.js">timeslider.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/custom/pad.js">pad.js</a></td>
+ <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache-2.0-only</a></td>
+ <td><a href="/static/custom/pad.js">pad.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/admin/plugins.js">plugins.js</a></td>
+ <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache-2.0-only</a></td>
+ <td><a href="/static/js/admin/plugins.js">plugins.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/admin/minify.json.js">minify.json.js</a></td>
+ <td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
+ <td><a href="/static/js/admin/minify.json.js">minify.json.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/admin/settings.js">settings.js</a></td>
+ <td><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache-2.0-only</a></td>
+ <td><a href="/static/js/admin/settings.js">settings.js</a></td>
+ </tr>
+ <tr>
+ <td><a href="/static/js/admin/jquery.autosize.js">jquery.autosize.js</a></td>
+ <td><a href="http://www.jclark.com/xml/copying.txt">Expat</a></td>
+ <td><a href="/static/js/admin/jquery.autosize.js">jquery.autosize.js</a></td>
+ </tr>
+ </table>
+ </body>
+</html>
diff --git a/src/templates/pad.html b/src/templates/pad.html
index 767c1ec9..3d89f9d0 100644
--- a/src/templates/pad.html
+++ b/src/templates/pad.html
@@ -36,6 +36,7 @@
<meta charset="utf-8">
<meta name="robots" content="noindex, nofollow">
+ <meta name="referrer" content="no-referrer">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<link rel="shortcut icon" href="<%=settings.faviconPad%>">
@@ -350,19 +351,21 @@
<% e.begin_block("scripts"); %>
<script type="text/javascript">
+ // @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7&dn=apache-2.0.txt
(function() {
// Display errors on page load to the user
// (Gets overridden by padutils.setupGlobalExceptionHandler)
var originalHandler = window.onerror;
window.onerror = function(msg, url, line) {
var box = document.getElementById('editorloadingbox');
- box.innerHTML = '<p><b>An error occured while loading the pad</b></p>'
+ box.innerHTML = '<p><b>An error occurred while loading the pad</b></p>'
+ '<p><b>'+msg+'</b> '
+ '<small>in '+ url +' (line '+ line +')</small></p>';
// call original error handler
if(typeof(originalHandler) == 'function') originalHandler.call(null, arguments);
};
})();
+ // @license-end
</script>
<script type="text/javascript" src="../static/js/require-kernel.js"></script>
@@ -378,6 +381,7 @@
<!-- Bootstrap page -->
<script type="text/javascript">
+ // @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7&dn=apache-2.0.txt
var clientVars = {};
(function () {
var pathComponents = location.pathname.split('/');
@@ -415,6 +419,8 @@
padeditbar = require('ep_etherpad-lite/static/js/pad_editbar').padeditbar;
padimpexp = require('ep_etherpad-lite/static/js/pad_impexp').padimpexp;
}());
+ // @license-end
</script>
+ <div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
<% e.end_block(); %>
</html>
diff --git a/src/templates/timeslider.html b/src/templates/timeslider.html
index f52c0c50..395d0c47 100644
--- a/src/templates/timeslider.html
+++ b/src/templates/timeslider.html
@@ -31,6 +31,7 @@
<head>
<meta charset="utf-8">
<meta name="robots" content="noindex, nofollow">
+ <meta name="referrer" content="no-referrer">
<link rel="shortcut icon" href="<%=settings.faviconTimeslider%>">
<% e.begin_block("timesliderStyles"); %>
<link rel="stylesheet" href="../../static/css/pad.css">
@@ -230,6 +231,7 @@
<!-- Bootstrap -->
<script type="text/javascript" >
+ // @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7&dn=apache-2.0.txt
var clientVars = {};
var BroadcastSlider;
(function () {
@@ -266,8 +268,9 @@
padeditbar.init()
});
})();
+ // @license-end
</script>
<% e.end_block(); %>
+<div style="display:none"><a href="/javascript" data-jslicense="1">JavaScript license information</a></div>
</body>
</html>
-
diff --git a/tests/backend/specs/api/sessionsAndGroups.js b/tests/backend/specs/api/sessionsAndGroups.js
index 4089656a..961cb2df 100644
--- a/tests/backend/specs/api/sessionsAndGroups.js
+++ b/tests/backend/specs/api/sessionsAndGroups.js
@@ -156,7 +156,7 @@ describe('getAuthorName', function(){
it('Gets the author name', function(done) {
api.get(endPoint('getAuthorName')+"&authorID="+authorID)
.expect(function(res){
- if(res.body.code !== 0 || !res.body.data === "john") throw new Error("Unable to get Author Name from Author ID");
+ if(res.body.code !== 0 || res.body.data !== "john") throw new Error("Unable to get Author Name from Author ID");
})
.expect('Content-Type', /json/)
.expect(200, done)
diff --git a/tests/frontend/helper.js b/tests/frontend/helper.js
index 7131119a..7a8d19b6 100644
--- a/tests/frontend/helper.js
+++ b/tests/frontend/helper.js
@@ -6,11 +6,11 @@ var helper = {};
helper.init = function(cb){
$iframeContainer = $("#iframe-container");
- $.get('/static/js/jquery.js').done(function(code){
+ $.get('/static/js/jquery.js').done(function(code){
// make sure we don't override existing jquery
jsLibraries["jquery"] = "if(typeof $ === 'undefined') {\n" + code + "\n}";
- $.get('/tests/frontend/lib/sendkeys.js').done(function(code){
+ $.get('/tests/frontend/lib/sendkeys.js').done(function(code){
jsLibraries["sendkeys"] = code;
cb();
@@ -32,7 +32,7 @@ var helper = {};
var getFrameJQuery = function($iframe){
/*
- I tried over 9000 ways to inject javascript into iframes.
+ I tried over 9000 ways to inject javascript into iframes.
This is the only way I found that worked in IE 7+8+9, FF and Chrome
*/
@@ -45,7 +45,7 @@ var helper = {};
win.eval(jsLibraries["jquery"]);
win.eval(jsLibraries["sendkeys"]);
-
+
win.$.window = win;
win.$.document = doc;
@@ -73,14 +73,14 @@ var helper = {};
if(!padName)
padName = "FRONTEND_TEST_" + helper.randomString(20);
$iframe = $("<iframe src='/p/" + padName + "'></iframe>");
-
+
//clean up inner iframe references
helper.padChrome$ = helper.padOuter$ = helper.padInner$ = null;
//clean up iframes properly to prevent IE from memoryleaking
$iframeContainer.find("iframe").purgeFrame().done(function(){
$iframeContainer.append($iframe);
- $iframe.one('load', function(){
+ $iframe.one('load', function(){
helper.waitFor(function(){
return !$iframe.contents().find("#editorloadingbox").is(":visible");
}, 50000).done(function(){
@@ -92,13 +92,13 @@ var helper = {};
helper.padChrome$.fx.off = true;
helper.padOuter$.fx.off = true;
helper.padInner$.fx.off = true;
-
+
opts.cb();
}).fail(function(){
throw new Error("Pad never loaded");
});
});
- });
+ });
return padName;
}
@@ -108,7 +108,7 @@ var helper = {};
var intervalTime = _intervalTime || 10;
var deferred = $.Deferred();
-
+
var _fail = deferred.fail;
var listenForFail = false;
deferred.fail = function(){
@@ -142,6 +142,65 @@ var helper = {};
return deferred;
}
+ helper.selectLines = function($startLine, $endLine, startOffset, endOffset){
+ // if no offset is provided, use beginning of start line and end of end line
+ startOffset = startOffset || 0;
+ endOffset = endOffset === undefined ? $endLine.text().length : endOffset;
+
+ var inner$ = helper.padInner$;
+ var selection = inner$.document.getSelection();
+ var range = selection.getRangeAt(0);
+
+ var start = getTextNodeAndOffsetOf($startLine, startOffset);
+ var end = getTextNodeAndOffsetOf($endLine, endOffset);
+
+ range.setStart(start.node, start.offset);
+ range.setEnd(end.node, end.offset);
+
+ selection.removeAllRanges();
+ selection.addRange(range);
+ }
+
+ var getTextNodeAndOffsetOf = function($targetLine, targetOffsetAtLine){
+ var $textNodes = $targetLine.find('*').contents().filter(function(){
+ return this.nodeType === Node.TEXT_NODE;
+ });
+
+ // search node where targetOffsetAtLine is reached, and its 'inner offset'
+ var textNodeWhereOffsetIs = null;
+ var offsetBeforeTextNode = 0;
+ var offsetInsideTextNode = 0;
+ $textNodes.each(function(index, element){
+ var elementTotalOffset = element.textContent.length;
+ textNodeWhereOffsetIs = element;
+ offsetInsideTextNode = targetOffsetAtLine - offsetBeforeTextNode;
+
+ var foundTextNode = offsetBeforeTextNode + elementTotalOffset >= targetOffsetAtLine;
+ if (foundTextNode){
+ return false; //stop .each by returning false
+ }
+
+ offsetBeforeTextNode += elementTotalOffset;
+ });
+
+ // edge cases
+ if (textNodeWhereOffsetIs === null){
+ // there was no text node inside $targetLine, so it is an empty line (<br>).
+ // Use beginning of line
+ textNodeWhereOffsetIs = $targetLine.get(0);
+ offsetInsideTextNode = 0;
+ }
+ // avoid errors if provided targetOffsetAtLine is higher than line offset (maxOffset).
+ // Use max allowed instead
+ var maxOffset = textNodeWhereOffsetIs.textContent.length;
+ offsetInsideTextNode = Math.min(offsetInsideTextNode, maxOffset);
+
+ return {
+ node: textNodeWhereOffsetIs,
+ offset: offsetInsideTextNode,
+ };
+ }
+
/* Ensure console.log doesn't blow up in IE, ugly but ok for a test framework imho*/
window.console = window.console || {};
window.console.log = window.console.log || function(){}
diff --git a/tests/frontend/specs/drag_and_drop.js b/tests/frontend/specs/drag_and_drop.js
new file mode 100644
index 00000000..bcec0bd2
--- /dev/null
+++ b/tests/frontend/specs/drag_and_drop.js
@@ -0,0 +1,160 @@
+// WARNING: drag and drop is only simulated on these tests, so manual testing might also be necessary
+describe('drag and drop', function() {
+ before(function(done) {
+ helper.newPad(function() {
+ createScriptWithSeveralLines(done);
+ });
+ this.timeout(60000);
+ });
+
+ context('when user drags part of one line and drops it far form its original place', function() {
+ before(function(done) {
+ selectPartOfSourceLine();
+ dragSelectedTextAndDropItIntoMiddleOfLine(TARGET_LINE);
+
+ // make sure DnD was correctly simulated
+ helper.waitFor(function() {
+ var $targetLine = getLine(TARGET_LINE);
+ var sourceWasMovedToTarget = $targetLine.text() === 'Target line [line 1]';
+ return sourceWasMovedToTarget;
+ }).done(done);
+ });
+
+ context('and user triggers UNDO', function() {
+ before(function() {
+ var $undoButton = helper.padChrome$(".buttonicon-undo");
+ $undoButton.click();
+ });
+
+ it('moves text back to its original place', function(done) {
+ // test text was removed from drop target
+ var $targetLine = getLine(TARGET_LINE);
+ expect($targetLine.text()).to.be('Target line []');
+
+ // test text was added back to original place
+ var $firstSourceLine = getLine(FIRST_SOURCE_LINE);
+ var $lastSourceLine = getLine(FIRST_SOURCE_LINE + 1);
+ expect($firstSourceLine.text()).to.be('Source line 1.');
+ expect($lastSourceLine.text()).to.be('Source line 2.');
+
+ done();
+ });
+ });
+ });
+
+ context('when user drags some lines far form its original place', function() {
+ before(function(done) {
+ selectMultipleSourceLines();
+ dragSelectedTextAndDropItIntoMiddleOfLine(TARGET_LINE);
+
+ // make sure DnD was correctly simulated
+ helper.waitFor(function() {
+ var $lineAfterTarget = getLine(TARGET_LINE + 1);
+ var sourceWasMovedToTarget = $lineAfterTarget.text() !== '...';
+ return sourceWasMovedToTarget;
+ }).done(done);
+ });
+
+ context('and user triggers UNDO', function() {
+ before(function() {
+ var $undoButton = helper.padChrome$(".buttonicon-undo");
+ $undoButton.click();
+ });
+
+ it('moves text back to its original place', function(done) {
+ // test text was removed from drop target
+ var $targetLine = getLine(TARGET_LINE);
+ expect($targetLine.text()).to.be('Target line []');
+
+ // test text was added back to original place
+ var $firstSourceLine = getLine(FIRST_SOURCE_LINE);
+ var $lastSourceLine = getLine(FIRST_SOURCE_LINE + 1);
+ expect($firstSourceLine.text()).to.be('Source line 1.');
+ expect($lastSourceLine.text()).to.be('Source line 2.');
+
+ done();
+ });
+ });
+ });
+
+ /* ********************* Helper functions/constants ********************* */
+ var TARGET_LINE = 2;
+ var FIRST_SOURCE_LINE = 5;
+
+ var getLine = function(lineNumber) {
+ var $lines = helper.padInner$('div');
+ return $lines.slice(lineNumber, lineNumber + 1);
+ }
+
+ var createScriptWithSeveralLines = function(done) {
+ // create some lines to be used on the tests
+ var $firstLine = helper.padInner$('div').first();
+ $firstLine.html('...<br>...<br>Target line []<br>...<br>...<br>Source line 1.<br>Source line 2.<br>');
+
+ // wait for lines to be split
+ helper.waitFor(function(){
+ var $lastSourceLine = getLine(FIRST_SOURCE_LINE + 1);
+ return $lastSourceLine.text() === 'Source line 2.';
+ }).done(done);
+ }
+
+ var selectPartOfSourceLine = function() {
+ var $sourceLine = getLine(FIRST_SOURCE_LINE);
+
+ // select 'line 1' from 'Source line 1.'
+ var start = 'Source '.length;
+ var end = start + 'line 1'.length;
+ helper.selectLines($sourceLine, $sourceLine, start, end);
+ }
+ var selectMultipleSourceLines = function() {
+ var $firstSourceLine = getLine(FIRST_SOURCE_LINE);
+ var $lastSourceLine = getLine(FIRST_SOURCE_LINE + 1);
+
+ helper.selectLines($firstSourceLine, $lastSourceLine);
+ }
+
+ var dragSelectedTextAndDropItIntoMiddleOfLine = function(targetLineNumber) {
+ // dragstart: start dragging content
+ triggerEvent('dragstart');
+
+ // drop: get HTML data from selected text
+ var draggedHtml = getHtmlFromSelectedText();
+ triggerEvent('drop');
+
+ // dragend: remove original content + insert HTML data into target
+ moveSelectionIntoTarget(draggedHtml, targetLineNumber);
+ triggerEvent('dragend');
+ }
+
+ var getHtmlFromSelectedText = function() {
+ var innerDocument = helper.padInner$.document;
+
+ var range = innerDocument.getSelection().getRangeAt(0);
+ var clonedSelection = range.cloneContents();
+ var span = innerDocument.createElement('span');
+ span.id = 'buffer';
+ span.appendChild(clonedSelection);
+ var draggedHtml = span.outerHTML;
+
+ return draggedHtml;
+ }
+
+ var triggerEvent = function(eventName) {
+ var event = helper.padInner$.Event(eventName);
+ helper.padInner$('#innerdocbody').trigger(event);
+ }
+
+ var moveSelectionIntoTarget = function(draggedHtml, targetLineNumber) {
+ var innerDocument = helper.padInner$.document;
+
+ // delete original content
+ innerDocument.execCommand('delete');
+
+ // set position to insert content on target line
+ var $target = getLine(targetLineNumber);
+ $target.sendkeys('{selectall}{rightarrow}{leftarrow}');
+
+ // insert content
+ innerDocument.execCommand('insertHTML', false, draggedHtml);
+ }
+});
diff --git a/tests/frontend/specs/helper.js b/tests/frontend/specs/helper.js
index d5bff629..bb47f4dc 100644
--- a/tests/frontend/specs/helper.js
+++ b/tests/frontend/specs/helper.js
@@ -55,7 +55,7 @@ describe("the test helper", function(){
it("takes an interval and checks on every interval", function(done){
this.timeout(4000);
var checks = 0;
-
+
helper.waitFor(function(){
checks++;
return false;
@@ -96,4 +96,117 @@ describe("the test helper", function(){
});
});
});
+
+ describe("the selectLines method", function(){
+ // function to support tests, use a single way to represent whitespaces
+ var cleanText = function(text){
+ return text
+ .replace(/\n/gi, "\\\\n") // avoid \n to be replaced by \s on next line
+ .replace(/\s/gi, " ")
+ .replace(/\\\\n/gi, "\n"); // move back \n to its original state
+ }
+
+ before(function(done){
+ helper.newPad(function() {
+ // create some lines to be used on the tests
+ var $firstLine = helper.padInner$("div").first();
+ $firstLine.sendkeys("{selectall}some{enter}short{enter}lines{enter}to test{enter}");
+
+ // wait for lines to be split
+ helper.waitFor(function(){
+ var $fourthLine = helper.padInner$("div").slice(3,4);
+ return $fourthLine.text() === "to test";
+ }).done(done);
+ });
+
+ this.timeout(60000);
+ });
+
+ it("changes editor selection to be between startOffset of $startLine and endOffset of $endLine", function(done){
+ var inner$ = helper.padInner$;
+
+ var startOffset = 2;
+ var endOffset = 4;
+
+ var $lines = inner$("div");
+ var $startLine = $lines.slice(1,2);
+ var $endLine = $lines.slice(3,4);
+
+ helper.selectLines($startLine, $endLine, startOffset, endOffset);
+
+ var selection = inner$.document.getSelection();
+ expect(cleanText(selection.toString())).to.be("ort \nlines \nto t");
+
+ done();
+ });
+
+ it("ends selection at beginning of $endLine when it is an empty line", function(done){
+ var inner$ = helper.padInner$;
+
+ var startOffset = 2;
+ var endOffset = 1;
+
+ var $lines = inner$("div");
+ var $startLine = $lines.slice(1,2);
+ var $endLine = $lines.slice(4,5);
+
+ helper.selectLines($startLine, $endLine, startOffset, endOffset);
+
+ var selection = inner$.document.getSelection();
+ expect(cleanText(selection.toString())).to.be("ort \nlines \nto test\n");
+
+ done();
+ });
+
+ it("ends selection at beginning of $endLine when its offset is zero", function(done){
+ var inner$ = helper.padInner$;
+
+ var startOffset = 2;
+ var endOffset = 0;
+
+ var $lines = inner$("div");
+ var $startLine = $lines.slice(1,2);
+ var $endLine = $lines.slice(3,4);
+
+ helper.selectLines($startLine, $endLine, startOffset, endOffset);
+
+ var selection = inner$.document.getSelection();
+ expect(cleanText(selection.toString())).to.be("ort \nlines \n");
+
+ done();
+ });
+
+ it("selects full line when offset is longer than line content", function(done){
+ var inner$ = helper.padInner$;
+
+ var startOffset = 2;
+ var endOffset = 50;
+
+ var $lines = inner$("div");
+ var $startLine = $lines.slice(1,2);
+ var $endLine = $lines.slice(3,4);
+
+ helper.selectLines($startLine, $endLine, startOffset, endOffset);
+
+ var selection = inner$.document.getSelection();
+ expect(cleanText(selection.toString())).to.be("ort \nlines \nto test");
+
+ done();
+ });
+
+ it("selects all text between beginning of $startLine and end of $endLine when no offset is provided", function(done){
+ var inner$ = helper.padInner$;
+
+ var $lines = inner$("div");
+ var $startLine = $lines.slice(1,2);
+ var $endLine = $lines.slice(3,4);
+
+ helper.selectLines($startLine, $endLine);
+
+ var selection = inner$.document.getSelection();
+ expect(cleanText(selection.toString())).to.be("short \nlines \nto test");
+
+ done();
+ });
+ });
});
diff --git a/tests/frontend/specs/indentation.js b/tests/frontend/specs/indentation.js
index de92cc8f..9294cefb 100644
--- a/tests/frontend/specs/indentation.js
+++ b/tests/frontend/specs/indentation.js
@@ -142,6 +142,51 @@ describe("indentation button", function(){
});
});
+ it("issue #2772 shows '*' when multiple indented lines receive a style and are outdented", function(done){
+ var inner$ = helper.padInner$;
+ var chrome$ = helper.padChrome$;
+
+ // make sure pad has more than one line
+ inner$("div").first().sendkeys("First{enter}Second{enter}");
+ helper.waitFor(function(){
+ return inner$("div").first().text().trim() === "First";
+ }).done(function(){
+ // indent first 2 lines
+ var $lines = inner$("div");
+ var $firstLine = $lines.first();
+ var $secondLine = $lines.slice(1,2);
+ helper.selectLines($firstLine, $secondLine);
+
+ var $indentButton = chrome$(".buttonicon-indent");
+ $indentButton.click();
+
+ helper.waitFor(function(){
+ return inner$("div").first().find("ul li").length === 1;
+ }).done(function(){
+ // apply bold
+ var $boldButton = chrome$(".buttonicon-bold");
+ $boldButton.click();
+
+ helper.waitFor(function(){
+ return inner$("div").first().find("b").length === 1;
+ }).done(function(){
+ // outdent first 2 lines
+ var $outdentButton = chrome$(".buttonicon-outdent");
+ $outdentButton.click();
+ helper.waitFor(function(){
+ return inner$("div").first().find("ul li").length === 0;
+ }).done(function(){
+ // check if '*' is displayed
+ var $secondLine = inner$("div").slice(1,2);
+ expect($secondLine.text().trim()).to.be("Second");
+
+ done();
+ });
+ });
+ });
+ });
+ });
+
/*
it("makes text indented and outdented", function() {
diff --git a/tests/frontend/specs/urls_become_clickable.js b/tests/frontend/specs/urls_become_clickable.js
index 2de60bf9..b989717e 100644
--- a/tests/frontend/specs/urls_become_clickable.js
+++ b/tests/frontend/specs/urls_become_clickable.js
@@ -44,4 +44,27 @@ describe("urls", function(){
}, 2000).done(done);
});
+ it("when you enter a url followed by a ], the ] is not included in the URL", 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();
+ var url = "http://etherpad.org/";
+
+ // simulate key presses to delete content
+ firstTextElement.sendkeys('{selectall}'); // select all
+ firstTextElement.sendkeys('{del}'); // clear the first line
+ firstTextElement.sendkeys(url); // insert a URL
+ firstTextElement.sendkeys(']'); // put a ] after it
+
+ helper.waitFor(function(){
+ if(inner$("div").first().find("a").length === 1){ // if it contains an A link
+ if(inner$("div").first().find("a")[0].href === url){
+ return true;
+ }
+ };
+ }, 2000).done(done);
+ });
+
});