Typos and minor fixes in bin, doc, and root
parent
457fdaa360
commit
c7548450c0
|
@ -18,3 +18,4 @@ npm-debug.log
|
|||
*.key
|
||||
bin/etherpad-1.deb
|
||||
credentials.json
|
||||
out/
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Please be polite, we all are humans and problems can occur.
|
||||
* Please add as much information as possible, for example
|
||||
* client os(s) and version(s)
|
||||
* browser(s) and version(s), is the problem reproduceable on different clients
|
||||
* browser(s) and version(s), is the problem reproducible on different clients
|
||||
* special environments like firewalls or antivirus
|
||||
* host os and version
|
||||
* npm and nodejs version
|
||||
|
@ -49,7 +49,7 @@ Also, keep it maintainable. We don't wanna end up as the monster Etherpad was!
|
|||
* Make small pull requests that are easy to review but make sure they do add value by themselves / individually
|
||||
|
||||
## Coding style
|
||||
* Do write comments. (You don't have to comment every line, but if you come up with something thats a bit complex/weird, just leave a comment. Bear in mind that you will probably leave the project at some point and that other people will read your code. Undocumented huge amounts of code are worthless!)
|
||||
* Do write comments. (You don't have to comment every line, but if you come up with something that's a bit complex/weird, just leave a comment. Bear in mind that you will probably leave the project at some point and that other people will read your code. Undocumented huge amounts of code are worthless!)
|
||||
* Never ever use tabs
|
||||
* Indentation: JS/CSS: 2 spaces; HTML: 4 spaces
|
||||
* Don't overengineer. Don't try to solve any possible problem in one step, but try to solve problems as easy as possible and improve the solution over time!
|
||||
|
@ -79,7 +79,7 @@ see git flow http://nvie.com/posts/a-successful-git-branching-model/
|
|||
|
||||
### feature branches (in your own repos)
|
||||
* these are the branches where you develop your features in
|
||||
* If its ready to go out, it will be merged into develop
|
||||
* If it's ready to go out, it will be merged into develop
|
||||
|
||||
Over the time we pull features from feature branches into the develop branch. Every month we pull from develop into master. Bugs in master get fixed in hotfix branches. These branches will get merged into master AND develop. There should never be commits in master that aren't in develop
|
||||
|
||||
|
|
2
Makefile
2
Makefile
|
@ -3,7 +3,7 @@ outdoc_files = $(addprefix out/,$(doc_sources:.md=.html))
|
|||
|
||||
docassets = $(addprefix out/,$(wildcard doc/assets/*))
|
||||
|
||||
VERSION = $(shell node -e "console.log( require('./src/package.json').version )")
|
||||
VERSION = $(shell node -e "console.log( require('./src/package.json').version )")
|
||||
UNAME := $(shell uname -s)
|
||||
|
||||
docs: $(outdoc_files) $(docassets)
|
||||
|
|
14
README.md
14
README.md
|
@ -11,7 +11,7 @@ that allows your web application to manage pads, users and groups. It is recomme
|
|||
|
||||
There is also a [jQuery plugin](https://github.com/ether/etherpad-lite-jquery-plugin) that helps you to embed Pads into your website.
|
||||
|
||||
There's also a full-featured plugin framework, allowing you to easily add your own features. By default your Etherpad is rather sparse and because Etherpad takes a lot of it's inspiration from Wordpress plugins are really easy to install and update. Once you have Etherpad installed you should visit the plugin page and take control.
|
||||
There's also a full-featured plugin framework, allowing you to easily add your own features. By default your Etherpad is rather sparse and because Etherpad takes a lot of its inspiration from WordPress, plugins are really easy to install and update. Once you have Etherpad installed you should visit the plugin page and take control.
|
||||
|
||||
Finally, Etherpad comes with translations into most languages! Users are automatically delivered the correct language for their local settings.
|
||||
|
||||
|
@ -35,7 +35,7 @@ This package works out of the box on any windows machine, but it's not very usef
|
|||
Now, run `start.bat` and open <http://localhost:9001> in your browser. You like it? [Next steps](#next-steps).
|
||||
|
||||
### Fancy install
|
||||
You'll need [node.js](http://nodejs.org) and (optionally, though recommended) git.
|
||||
You'll need [node.js](https://nodejs.org) and (optionally, though recommended) git.
|
||||
|
||||
1. Grab the source, either
|
||||
- download <https://github.com/ether/etherpad-lite/zipball/master>
|
||||
|
@ -60,7 +60,7 @@ You'll need gzip, git, curl, libssl develop libraries, python and gcc.
|
|||
- *For Fedora/CentOS*: `yum install gzip git curl python openssl-devel && yum groupinstall "Development Tools"`
|
||||
- *For FreeBSD*: `portinstall node, npm, curl, git (optional)`
|
||||
|
||||
Additionally, you'll need [node.js](http://nodejs.org) installed, Ideally the latest stable version, we recommend installing/compiling nodejs from source (avoiding apt).
|
||||
Additionally, you'll need [node.js](https://nodejs.org) installed, Ideally the latest stable version, we recommend installing/compiling nodejs from source (avoiding apt).
|
||||
|
||||
**As any user (we recommend creating a separate user called etherpad):**
|
||||
|
||||
|
@ -92,9 +92,9 @@ Documentation can be found in `docs/`.
|
|||
# Development
|
||||
|
||||
## Things you should know
|
||||
Understand [git](https://training.github.com/) and watch this [video on getting started with Etherpad Development](http://youtu.be/67-Q26YH97E).
|
||||
Understand [git](https://training.github.com/) and watch this [video on getting started with Etherpad Development](https://youtu.be/67-Q26YH97E).
|
||||
|
||||
If you're new to node.js, start with Ryan Dahl's [Introduction to Node.js](http://youtu.be/jo_B4LTHi3I).
|
||||
If you're new to node.js, start with Ryan Dahl's [Introduction to Node.js](https://youtu.be/jo_B4LTHi3I).
|
||||
|
||||
You can debug Etherpad using `bin/debugRun.sh`.
|
||||
|
||||
|
@ -108,7 +108,7 @@ Look at the [TODO list](https://github.com/ether/etherpad-lite/wiki/TODO) and ou
|
|||
Also, and most importantly, read our [**Developer Guidelines**](https://github.com/ether/etherpad-lite/blob/master/CONTRIBUTING.md), really!
|
||||
|
||||
# Get in touch
|
||||
Join the [mailinglist](http://groups.google.com/group/etherpad-lite-dev) and make some noise on our busy freenode irc channel [#etherpad-lite-dev](http://webchat.freenode.net?channels=#etherpad-lite-dev)!
|
||||
Join the [mailinglist](https://groups.google.com/group/etherpad-lite-dev) and make some noise on our busy freenode irc channel [#etherpad-lite-dev](https://webchat.freenode.net?channels=#etherpad-lite-dev)!
|
||||
|
||||
# Modules created for this project
|
||||
|
||||
|
@ -117,7 +117,7 @@ Join the [mailinglist](http://groups.google.com/group/etherpad-lite-dev) and mak
|
|||
* [async-stacktrace](https://github.com/Pita/async-stacktrace) "Improves node.js stacktraces and makes it easier to handle errors"
|
||||
|
||||
# Donate!
|
||||
* [Flattr](http://flattr.com/thing/71378/Etherpad-Foundation)
|
||||
* [Flattr](https://flattr.com/thing/71378/Etherpad-Foundation)
|
||||
* Paypal - Press the donate button on [etherpad.org](http://etherpad.org)
|
||||
* [Bitcoin](https://coinbase.com/checkouts/1e572bf8a82e4663499f7f1f66c2d15a)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# IMPORTANT
|
||||
# Protect agaisnt mispelling a var and rm -rf /
|
||||
# Protect against misspelling a var and rm -rf /
|
||||
set -u
|
||||
set -e
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ if(process.argv.length != 3)
|
|||
//get the padID
|
||||
var padId = process.argv[2];
|
||||
|
||||
//initalize the variables
|
||||
//initialize the variables
|
||||
var db, settings, padManager;
|
||||
var npm = require("../src/node_modules/npm");
|
||||
var async = require("../src/node_modules/async");
|
||||
|
@ -29,7 +29,7 @@ async.series([
|
|||
settings = require('../src/node/utils/Settings');
|
||||
db = require('../src/node/db/DB');
|
||||
|
||||
//intallize the database
|
||||
//initialize the database
|
||||
db.init(callback);
|
||||
},
|
||||
//get the pad
|
||||
|
@ -54,7 +54,7 @@ async.series([
|
|||
},
|
||||
function (callback)
|
||||
{
|
||||
//create an array with key kevisions
|
||||
//create an array with key revisions
|
||||
//key revisions always save the full pad atext
|
||||
var head = pad.getHeadRevisionNumber();
|
||||
var keyRevisions = [];
|
||||
|
@ -99,7 +99,7 @@ async.series([
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
//check if there is a atext in the keyRevisions
|
||||
//check if there is an atext in the keyRevisions
|
||||
if(revisions[keyRev] === undefined || revisions[keyRev].meta === undefined || revisions[keyRev].meta.atext === undefined)
|
||||
{
|
||||
console.error("No atext in key revision " + keyRev);
|
||||
|
|
|
@ -16,7 +16,7 @@ do
|
|||
fi
|
||||
done
|
||||
|
||||
#Stop the script if its started as root
|
||||
#Stop the script if it's started as root
|
||||
if [ "$(id -u)" -eq 0 ] && [ $ignoreRoot -eq 0 ]; then
|
||||
echo "You shouldn't start Etherpad as root!"
|
||||
echo "Please type 'Etherpad rocks my socks' or supply the '--root' argument if you still want to start it as root"
|
||||
|
@ -31,7 +31,7 @@ fi
|
|||
#Clean the current environment
|
||||
rm -rf src/node_modules
|
||||
|
||||
#Prepare the enviroment
|
||||
#Prepare the environment
|
||||
bin/installDeps.sh $* || exit 1
|
||||
|
||||
#Move to the node folder and start
|
||||
|
|
|
@ -22,25 +22,25 @@ 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 "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 committed will be committed."
|
||||
echo "-----"
|
||||
|
||||
# get the latest version
|
||||
# Get the latest version
|
||||
LATEST_GIT_TAG=$(git tag | tail -n 1)
|
||||
|
||||
# current environment
|
||||
# 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
|
||||
# Get new version number
|
||||
# format: x.x.x
|
||||
echo -n "Enter new version (x.x.x): "
|
||||
read VERSION
|
||||
|
||||
# get the message for the changelogs
|
||||
# Get the message for the changelogs
|
||||
read -p "Enter new changelog entries (press enter): "
|
||||
tmp=$(mktemp)
|
||||
"${EDITOR:-vi}" $tmp
|
||||
|
@ -49,7 +49,7 @@ echo "$changelogText"
|
|||
rm $tmp
|
||||
|
||||
if [ "$changelogText" != "" ]; then
|
||||
changelogText="# $VERSION\n$changelogText"
|
||||
changelogText="# $VERSION\n$changelogText"
|
||||
fi
|
||||
|
||||
# get the token for the github api
|
||||
|
@ -57,114 +57,114 @@ 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
|
||||
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
|
||||
# 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 "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 release 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 "Committing 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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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"
|
||||
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
|
||||
# Call functions
|
||||
check_api_token
|
||||
modify_files
|
||||
create_release_branch
|
||||
|
|
|
@ -8,7 +8,7 @@ if [ -d "../bin" ]; then
|
|||
cd "../"
|
||||
fi
|
||||
|
||||
#prepare the enviroment
|
||||
#Prepare the environment
|
||||
bin/installDeps.sh || exit 1
|
||||
|
||||
hash node-inspector > /dev/null 2>&1 || {
|
||||
|
@ -20,9 +20,9 @@ hash node-inspector > /dev/null 2>&1 || {
|
|||
|
||||
node-inspector &
|
||||
|
||||
echo "If you are new to node-inspector, take a look at this video: http://youtu.be/AOnK3NVnxL8"
|
||||
echo "If you are new to node-inspector, take a look at this video: https://youtu.be/AOnK3NVnxL8"
|
||||
|
||||
node --debug node_modules/ep_etherpad-lite/node/server.js $*
|
||||
|
||||
#kill node-inspector before ending
|
||||
#Kill node-inspector before ending
|
||||
kill $!
|
||||
|
|
|
@ -37,12 +37,12 @@ async.series([
|
|||
db = require('../src/node/db/DB');
|
||||
callback();
|
||||
},
|
||||
// intallize the database
|
||||
// initialize the database
|
||||
function (callback)
|
||||
{
|
||||
db.init(callback);
|
||||
},
|
||||
// delete the pad and it's links
|
||||
// delete the pad and its links
|
||||
function (callback)
|
||||
{
|
||||
padManager = require('../src/node/db/PadManager');
|
||||
|
|
|
@ -96,7 +96,7 @@ function doJSON(input, filename, cb) {
|
|||
// a list: starting with list_start, ending with list_end,
|
||||
// maybe containing other nested lists in each item.
|
||||
//
|
||||
// If one of these isnt' found, then anything that comes between
|
||||
// If one of these isn't found, then anything that comes between
|
||||
// here and the next heading should be parsed as the desc.
|
||||
var stability
|
||||
if (state === 'AFTERHEADING') {
|
||||
|
@ -198,7 +198,7 @@ function processList(section) {
|
|||
var current;
|
||||
var stack = [];
|
||||
|
||||
// for now, *just* build the heirarchical list
|
||||
// for now, *just* build the hierarchical list
|
||||
list.forEach(function(tok) {
|
||||
var type = tok.type;
|
||||
if (type === 'space') return;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
This is a debug tool. It helps to extract all datas of a pad and move it from an productive enviroment and to a develop enviroment to reproduce bugs there. It outputs a dirtydb file
|
||||
This is a debug tool. It helps to extract all datas of a pad and move it from an productive environment and to a develop environment to reproduce bugs there. It outputs a dirtydb file
|
||||
*/
|
||||
|
||||
if(process.argv.length != 3)
|
||||
|
@ -38,7 +38,7 @@ async.series([
|
|||
dirty = require("../node_modules/ep_etherpad-lite/node_modules/ueberDB/node_modules/dirty")(padId + ".db");
|
||||
callback();
|
||||
},
|
||||
//intallize the database
|
||||
//initialize the database
|
||||
function (callback)
|
||||
{
|
||||
db.init(callback);
|
||||
|
@ -85,7 +85,7 @@ async.series([
|
|||
if(err) { callback(err); return}
|
||||
|
||||
if(dbvalue && typeof dbvalue != 'object'){
|
||||
dbvalue=JSON.parse(dbvalue); // if its not json then parse it as json
|
||||
dbvalue=JSON.parse(dbvalue); // if it's not json then parse it as json
|
||||
}
|
||||
|
||||
dirty.set(dbkey, dbvalue, callback);
|
||||
|
@ -105,5 +105,5 @@ async.series([
|
|||
//get the pad object
|
||||
//get all revisions of this pad
|
||||
//get all authors related to this pad
|
||||
//get the readonly link releated to this pad
|
||||
//get the chat entrys releated to this pad
|
||||
//get the readonly link related to this pad
|
||||
//get the chat entries related to this pad
|
||||
|
|
|
@ -30,7 +30,7 @@ require("ep_etherpad-lite/node_modules/npm").load({}, function(er,npm) {
|
|||
//there was an error while initializing the database, output it and stop
|
||||
if(err)
|
||||
{
|
||||
console.error("ERROR: Problem while initalizing the database");
|
||||
console.error("ERROR: Problem while initializing the database");
|
||||
console.error(err.stack ? err.stack : err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
|
|
@ -23,19 +23,19 @@ hash curl > /dev/null 2>&1 || {
|
|||
}
|
||||
|
||||
#Is node installed?
|
||||
#not checking io.js, default installation creates a symbolic link to node
|
||||
#Not checking io.js, default installation creates a symbolic link to node
|
||||
hash node > /dev/null 2>&1 || {
|
||||
echo "Please install node.js ( http://nodejs.org )" >&2
|
||||
echo "Please install node.js ( https://nodejs.org )" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
#Is npm installed?
|
||||
hash npm > /dev/null 2>&1 || {
|
||||
echo "Please install npm ( http://npmjs.org )" >&2
|
||||
echo "Please install npm ( https://npmjs.org )" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
#check npm version
|
||||
#Check npm version
|
||||
NPM_VERSION=$(npm --version)
|
||||
NPM_MAIN_VERSION=$(echo $NPM_VERSION | cut -d "." -f 1)
|
||||
if [ $(echo $NPM_MAIN_VERSION) = "0" ]; then
|
||||
|
@ -43,7 +43,7 @@ if [ $(echo $NPM_MAIN_VERSION) = "0" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
#check node version
|
||||
#Check node version
|
||||
NODE_VERSION=$(node --version)
|
||||
NODE_V_MINOR=$(echo $NODE_VERSION | cut -d "." -f 1-2)
|
||||
NODE_V_MAIN=$(echo $NODE_VERSION | cut -d "." -f 1)
|
||||
|
@ -61,7 +61,7 @@ for arg in $*; do
|
|||
a=$arg
|
||||
done
|
||||
|
||||
#Does a $settings exist? if no copy the template
|
||||
#Does a $settings exist? if not copy the template
|
||||
if [ ! -f $settings ]; then
|
||||
echo "Copy the settings template to $settings..."
|
||||
cp settings.json.template $settings || exit 1
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
@echo off
|
||||
|
||||
:: change directory to etherpad-lite root
|
||||
:: Change directory to etherpad-lite root
|
||||
cd /D "%~dp0\.."
|
||||
|
||||
:: Is node installed?
|
||||
cmd /C node -e "" || ( echo "Please install node.js ( http://nodejs.org )" && exit /B 1 )
|
||||
cmd /C node -e "" || ( echo "Please install node.js ( https://nodejs.org )" && exit /B 1 )
|
||||
|
||||
echo _
|
||||
echo Ensure that all dependencies are up to date... If this is the first time you have run Etherpad please be patient.
|
||||
|
|
|
@ -39,7 +39,7 @@ async.series([
|
|||
db = require('../src/node/db/DB');
|
||||
callback();
|
||||
},
|
||||
//intallize the database
|
||||
//initialize the database
|
||||
function (callback)
|
||||
{
|
||||
db.init(callback);
|
||||
|
@ -101,6 +101,6 @@ async.series([
|
|||
//get the pad object
|
||||
//get all revisions of this pad
|
||||
//get all authors related to this pad
|
||||
//get the readonly link releated to this pad
|
||||
//get the chat entrys releated to this pad
|
||||
//get the readonly link related to this pad
|
||||
//get the chat entries related to this pad
|
||||
//remove all keys from database and insert them again
|
||||
|
|
20
bin/run.sh
20
bin/run.sh
|
@ -16,19 +16,19 @@ do
|
|||
fi
|
||||
done
|
||||
|
||||
#Stop the script if its started as root
|
||||
#Stop the script if it's started as root
|
||||
if [ "$(id -u)" -eq 0 ] && [ $ignoreRoot -eq 0 ]; then
|
||||
echo "You shouldn't start Etherpad as root!"
|
||||
echo "Please type 'Etherpad rocks my socks' or supply the '--root' argument if you still want to start it as root"
|
||||
read rocks
|
||||
if [ ! "$rocks" == "Etherpad rocks my socks" ]
|
||||
then
|
||||
echo "Your input was incorrect"
|
||||
exit 1
|
||||
fi
|
||||
echo "You shouldn't start Etherpad as root!"
|
||||
echo "Please type 'Etherpad rocks my socks' or supply the '--root' argument if you still want to start it as root"
|
||||
read rocks
|
||||
if [ ! "$rocks" == "Etherpad rocks my socks" ]
|
||||
then
|
||||
echo "Your input was incorrect"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
#prepare the enviroment
|
||||
#Prepare the environment
|
||||
bin/installDeps.sh $* || exit 1
|
||||
|
||||
#Move to the node folder and start
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
# 0 silent
|
||||
# 1 email
|
||||
ERROR_HANDLING=0
|
||||
# Your email address which should recieve the error messages
|
||||
# Your email address which should receive the error messages
|
||||
EMAIL_ADDRESS="no-reply@example.com"
|
||||
# Sets the minimun amount of time betweens the sending of error emails.
|
||||
# This ensures you not get spamed while a endless reboot loop
|
||||
# Sets the minimum amount of time between the sending of error emails.
|
||||
# This ensures you do not get spammed during an endless reboot loop
|
||||
# It's the time in seconds
|
||||
TIME_BETWEEN_EMAILS=600 # 10 minutes
|
||||
|
||||
|
@ -26,7 +26,7 @@ if [ -d "../bin" ]; then
|
|||
cd "../"
|
||||
fi
|
||||
|
||||
#check if a logfile parameter is set
|
||||
#Check if a logfile parameter is set
|
||||
if [ -z "${LOG}" ]; then
|
||||
echo "Set a logfile as the first parameter"
|
||||
exit 1
|
||||
|
@ -35,18 +35,18 @@ fi
|
|||
shift
|
||||
while [ 1 ]
|
||||
do
|
||||
#try to touch the file if it doesn't exist
|
||||
#Try to touch the file if it doesn't exist
|
||||
if [ ! -f ${LOG} ]; then
|
||||
touch ${LOG} || ( echo "Logfile '${LOG}' is not writeable" && exit 1 )
|
||||
fi
|
||||
|
||||
#check if the file is writeable
|
||||
#Check if the file is writeable
|
||||
if [ ! -w ${LOG} ]; then
|
||||
echo "Logfile '${LOG}' is not writeable"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#start the application
|
||||
#Start the application
|
||||
bin/run.sh $@ >>${LOG} 2>>${LOG}
|
||||
|
||||
#Send email
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
"Z:z>1|2=m=b*0|1+1$\n"
|
||||
```
|
||||
|
||||
This is a Changeset. Its just a string and its very difficult to read in this form. But the Changeset Library gives us some tools to read it.
|
||||
This is a Changeset. It's just a string and it's very difficult to read in this form. But the Changeset Library gives us some tools to read it.
|
||||
|
||||
A changeset describes the diff between two revisions of the document. The Browser sends changesets to the server and the server sends them to the clients to update them. This Changesets gets also saved into the history of a pad. Which allows us to go back to every revision from the past.
|
||||
A changeset describes the diff between two revisions of the document. The Browser sends changesets to the server and the server sends them to the clients to update them. These Changesets also get saved into the history of a pad. This allows us to go back to every revision from the past.
|
||||
|
||||
## Changeset.unpack(changeset)
|
||||
|
||||
* `changeset` {String}
|
||||
|
||||
This functions returns an object representaion of the changeset, similar to this:
|
||||
This function returns an object representation of the changeset, similar to this:
|
||||
|
||||
```
|
||||
{ oldLen: 35, newLen: 36, ops: '|2=m=b*0|1+1', charBank: '\n' }
|
||||
|
@ -65,7 +65,7 @@ There are 3 types of operators: `+`,`-` and `=`. These operators describe differ
|
|||
fromJsonable: [Function] }
|
||||
```
|
||||
|
||||
This creates an empty apool. A apool saves which attributes were used during the history of a pad. There is one apool for each pad. It only saves the attributes that were really used, it doesn't save unused attributes. Lets fill this apool with some values
|
||||
This creates an empty apool. An apool saves which attributes were used during the history of a pad. There is one apool for each pad. It only saves the attributes that were really used, it doesn't save unused attributes. Let's fill this apool with some values
|
||||
|
||||
```
|
||||
> apool.fromJsonable({"numToAttrib":{"0":["author","a.kVnWeomPADAT2pn9"],"1":["bold","true"],"2":["italic","true"]},"nextNum":3});
|
||||
|
@ -88,7 +88,7 @@ This creates an empty apool. A apool saves which attributes were used during the
|
|||
fromJsonable: [Function] }
|
||||
```
|
||||
|
||||
We used the fromJsonable function to fill the empty apool with values. the fromJsonable and toJsonable functions are used to serialize and deserialize an apool. You can see that it stores the relation between numbers and attributes. So for example the attribute 1 is the attribute bold and vise versa. A attribute is always a key value pair. For stuff like bold and italic its just 'italic':'true'. For authors its author:$AUTHORID. So a character can be bold and italic. But it can't belong to multiple authors
|
||||
We used the fromJsonable function to fill the empty apool with values. the fromJsonable and toJsonable functions are used to serialize and deserialize an apool. You can see that it stores the relation between numbers and attributes. So for example the attribute 1 is the attribute bold and vise versa. An attribute is always a key value pair. For stuff like bold and italic it's just 'italic':'true'. For authors it's author:$AUTHORID. So a character can be bold and italic. But it can't belong to multiple authors
|
||||
|
||||
```
|
||||
> apool.getAttrib(1)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Embed parameters
|
||||
You can easily embed your etherpad-lite into any webpage by using iframes. You can configure the embedded pad using embed paramters.
|
||||
You can easily embed your etherpad-lite into any webpage by using iframes. You can configure the embedded pad using embed parameters.
|
||||
|
||||
Example:
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ Things in context:
|
|||
|
||||
1. pad - the pad instance
|
||||
|
||||
This hook gets called when an pad was loaded. If a new pad was created and loaded this event will be emitted too.
|
||||
This hook gets called when a pad was loaded. If a new pad was created and loaded this event will be emitted too.
|
||||
|
||||
## padUpdate
|
||||
Called from: src/node/db/Pad.js
|
||||
|
@ -219,7 +219,7 @@ Things in context:
|
|||
1. message - the message being handled
|
||||
2. client - the client object from socket.io
|
||||
|
||||
This hook will be called once a message arrive. If a plugin calls `callback(null)` the message will be dropped. However it is not possible to modify the message.
|
||||
This hook will be called once a message arrive. If a plugin calls `callback(null)` the message will be dropped. However, it is not possible to modify the message.
|
||||
|
||||
Plugins may also decide to implement custom behavior once a message arrives.
|
||||
|
||||
|
@ -272,7 +272,7 @@ Things in context:
|
|||
1. clientVars - the basic `clientVars` built by the core
|
||||
2. pad - the pad this session is about
|
||||
|
||||
This hook will be called once a client connects and the `clientVars` are being sent. Plugins can use this hook to give the client a initial configuriation, like the tracking-id of an external analytics-tool that is used on the client-side. You can also overwrite values from the original `clientVars`.
|
||||
This hook will be called once a client connects and the `clientVars` are being sent. Plugins can use this hook to give the client an initial configuration, like the tracking-id of an external analytics-tool that is used on the client-side. You can also overwrite values from the original `clientVars`.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -397,7 +397,7 @@ Things in context:
|
|||
|
||||
1. Pad object
|
||||
|
||||
Identical to `exportHtmlAdditionalTags`, but for tags that are stored with an specific value (not simply `true`) on the attribute pool. For example `['color', 'red']`, instead of `['bold', true]`. This hook will allow a plug-in developer to include more properties and attributes to support during HTML Export. An Array of arrays should be returned. The exported HTML will contain tags like `<span data-color="red">` for the content where attributes are `['color', 'red']`.
|
||||
Identical to `exportHtmlAdditionalTags`, but for tags that are stored with a specific value (not simply `true`) on the attribute pool. For example `['color', 'red']`, instead of `['bold', true]`. This hook will allow a plug-in developer to include more properties and attributes to support during HTML Export. An Array of arrays should be returned. The exported HTML will contain tags like `<span data-color="red">` for the content where attributes are `['color', 'red']`.
|
||||
|
||||
Example:
|
||||
```
|
||||
|
|
|
@ -86,19 +86,19 @@ Responses are valid JSON in the following format:
|
|||
* **2** internal error
|
||||
* **3** no such function
|
||||
* **4** no or wrong API Key
|
||||
* **message** a status message. Its ok if everything is fine, else it contains an error message
|
||||
* **message** a status message. It's ok if everything is fine, else it contains an error message
|
||||
* **data** the payload
|
||||
|
||||
### Overview
|
||||
|
||||
![API Overview](http://i.imgur.com/d0nWp.png)
|
||||
![API Overview](https://i.imgur.com/d0nWp.png)
|
||||
|
||||
## Data Types
|
||||
|
||||
* **groupID** a string, the unique id of a group. Format is g.16RANDOMCHARS, for example g.s8oes9dhwrvt0zif
|
||||
* **sessionID** a string, the unique id of a session. Format is s.16RANDOMCHARS, for example s.s8oes9dhwrvt0zif
|
||||
* **authorID** a string, the unique id of an author. Format is a.16RANDOMCHARS, for example a.s8oes9dhwrvt0zif
|
||||
* **readOnlyID** a string, the unique id of an readonly relation to a pad. Format is r.16RANDOMCHARS, for example r.s8oes9dhwrvt0zif
|
||||
* **readOnlyID** a string, the unique id of a readonly relation to a pad. Format is r.16RANDOMCHARS, for example r.s8oes9dhwrvt0zif
|
||||
* **padID** a string, format is GROUPID$PADNAME, for example the pad test of group g.s8oes9dhwrvt0zif has padID g.s8oes9dhwrvt0zif$test
|
||||
|
||||
### Authentication
|
||||
|
@ -107,14 +107,14 @@ Authentication works via a token that is sent with each request as a post parame
|
|||
|
||||
### Node Interoperability
|
||||
|
||||
All functions will also be available through a node module accessable from other node.js applications.
|
||||
All functions will also be available through a node module accessible from other node.js applications.
|
||||
|
||||
### JSONP
|
||||
|
||||
The API provides _JSONP_ support to allow requests from a server in a different domain.
|
||||
Simply add `&jsonp=?` to the API call.
|
||||
|
||||
Example usage: http://api.jquery.com/jQuery.getJSON/
|
||||
Example usage: https://api.jquery.com/jQuery.getJSON/
|
||||
|
||||
## API Methods
|
||||
|
||||
|
@ -213,7 +213,7 @@ Returns the Author Name of the author
|
|||
-> can't be deleted cause this would involve scanning all the pads where this author was
|
||||
|
||||
### Session
|
||||
Sessions can be created between a group and an author. This allows an author to access more than one group. The sessionID will be set as a cookie to the client and is valid until a certain date. The session cookie can also contain multiple comma-seperated sessionIDs, allowing a user to edit pads in different groups at the same time. Only users with a valid session for this group, can access group pads. You can create a session after you authenticated the user at your web application, to give them access to the pads. You should save the sessionID of this session and delete it after the user logged out.
|
||||
Sessions can be created between a group and an author. This allows an author to access more than one group. The sessionID will be set as a cookie to the client and is valid until a certain date. The session cookie can also contain multiple comma-separated sessionIDs, allowing a user to edit pads in different groups at the same time. Only users with a valid session for this group, can access group pads. You can create a session after you authenticated the user at your web application, to give them access to the pads. You should save the sessionID of this session and delete it after the user logged out.
|
||||
|
||||
#### createSession(groupID, authorID, validUntil)
|
||||
* API >= 1
|
||||
|
@ -307,7 +307,7 @@ returns the text of a pad formatted as HTML
|
|||
#### setHTML(padID, html)
|
||||
* API >= 1
|
||||
|
||||
sets the text of a pad based on HTML, HTML must be well formed. Malformed HTML will send a warning to the API log.
|
||||
sets the text of a pad based on HTML, HTML must be well-formed. Malformed HTML will send a warning to the API log.
|
||||
|
||||
*Example returns:*
|
||||
* `{code: 0, message:"ok", data: null}`
|
||||
|
@ -411,7 +411,7 @@ creates a chat message, saves it to the database and sends it to all connected c
|
|||
* `{code: 1, message:"text is no string", data: null}`
|
||||
|
||||
### Pad
|
||||
Group pads are normal pads, but with the name schema GROUPID$PADNAME. A security manager controls access of them and its forbidden for normal pads to include a $ in the name.
|
||||
Group pads are normal pads, but with the name schema GROUPID$PADNAME. A security manager controls access of them and it's forbidden for normal pads to include a $ in the name.
|
||||
|
||||
#### createPad(padID [, text])
|
||||
* API >= 1
|
||||
|
@ -543,7 +543,7 @@ return true of false
|
|||
#### setPassword(padID, password)
|
||||
* API >= 1
|
||||
|
||||
returns ok or a error message
|
||||
returns ok or an error message
|
||||
|
||||
*Example returns:*
|
||||
* `{code: 0, message:"ok", data: null}`
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
## plugins.update
|
||||
`require("ep_etherpad-lite/static/js/plugingfw/plugins").update()` will use npm to list all installed modules and read their ep.json files, registering the contained hooks.
|
||||
A hook registration is a pairs of a hook name and a function reference (filename for require() plus function name)
|
||||
A hook registration is a pair of a hook name and a function reference (filename for require() plus function name)
|
||||
|
||||
## hooks.callAll
|
||||
`require("ep_etherpad-lite/static/js/plugingfw/hooks").callAll("hook_name", {argname:value})` will call all hook functions registered for `hook_name` with `{argname:value}`.
|
||||
|
|
|
@ -10,6 +10,6 @@ provided to event handlers are detailed in a list underneath the topic
|
|||
heading.
|
||||
|
||||
Every `.html` file is generated based on the corresponding
|
||||
`.markdown` file in the `doc/api/` folder in the source tree. The
|
||||
`.md` file in the `doc/api/` folder in the source tree. The
|
||||
documentation is generated using the `bin/doc/generate.js` program.
|
||||
The HTML template is located at `doc/template.html`.
|
||||
|
|
|
@ -85,7 +85,7 @@ For any two changesets $A$, $B$ such that
|
|||
\item[] $A=(n_1\rightarrow n_2)[\cdots]$
|
||||
\item[] $B=(n_2\rightarrow n_3)[\cdots]$
|
||||
\end{itemize}
|
||||
it is clear that there is a third changeset $C=(n_1\rightarrow n_3)[\cdots]$ such that applying $C$ to a document $X$ yeilds the same resulting document as does applying $A$ and then $B$. In this case, we write $AB=C$.
|
||||
it is clear that there is a third changeset $C=(n_1\rightarrow n_3)[\cdots]$ such that applying $C$ to a document $X$ yields the same resulting document as does applying $A$ and then $B$. In this case, we write $AB=C$.
|
||||
|
||||
Given the representation from Section \ref{representation}, it is straightforward to compute the composition of two changesets.
|
||||
|
||||
|
@ -93,9 +93,9 @@ Given the representation from Section \ref{representation}, it is straightforwar
|
|||
|
||||
Now we come to realtime document editing. Suppose two different users make two different changes to the same document at the same time. It is impossible to compose these changes. For example, if we have the document $X$ of length $n$, we may have $A=(n\rightarrow n_a)[\ldots n_a \mathrm{characters}]$, $B=(n\rightarrow n_b)[\ldots n_b \mathrm{characters}]$ where $n\neq n_a\neq n_b$.
|
||||
|
||||
It is impossible to compute $(XA)B$ because $B$ can only be applied to a document of length $n$, and $(XA)$ has length $n_a$. Similarly, $A$ cannot be appliet to $(XB)$ because $(XB)$ has length $n_b$.
|
||||
It is impossible to compute $(XA)B$ because $B$ can only be applied to a document of length $n$, and $(XA)$ has length $n_a$. Similarly, $A$ cannot be applied to $(XB)$ because $(XB)$ has length $n_b$.
|
||||
|
||||
This is where \emph{merging} comes in. Merging takes two changesets that apply to the same initial document (and that cannot be composed), and computes a single new changeset that presevers the intent of both changes. The merge of $A$ and $B$ is written as $m(A,B)$. For the Etherpad system to work, we require that $m(A,B)=m(B,A)$.
|
||||
This is where \emph{merging} comes in. Merging takes two changesets that apply to the same initial document (and that cannot be composed), and computes a single new changeset that preserves the intent of both changes. The merge of $A$ and $B$ is written as $m(A,B)$. For the Etherpad system to work, we require that $m(A,B)=m(B,A)$.
|
||||
|
||||
Aside from what we have said so far about merging, there are many different implementations that will lead to a workable system. We have created one implementation for text that has the following constraints.
|
||||
|
||||
|
@ -156,7 +156,7 @@ server always. (This may distinguish from prior art?)
|
|||
The other critical design feature of the system is that
|
||||
\emph{A client must always be able to edit their local
|
||||
copy of the document, so the user is never blocked from
|
||||
typing because of waiting to to send or receive data.}
|
||||
typing because of waiting to send or receive data.}
|
||||
|
||||
\section{Client State}
|
||||
|
||||
|
@ -329,7 +329,7 @@ with:
|
|||
\end{enumerate}
|
||||
|
||||
\subsection{Respond to client connect}
|
||||
When a server recieves a connection request from a client,
|
||||
When a server receives a connection request from a client,
|
||||
it receives the client's unique ID and stores that in the
|
||||
server's set of connected clients. It then sends the
|
||||
client the contents of HEADTEXT, and the corresponding
|
||||
|
|
|
@ -3,9 +3,9 @@ Etherpad provides a multi-language user interface, that's apart from your users'
|
|||
|
||||
|
||||
## Translating
|
||||
We rely on http://translatewiki.net to handle the translation process for us, so if you'd like to help...
|
||||
We rely on https://translatewiki.net to handle the translation process for us, so if you'd like to help...
|
||||
|
||||
1. sign up at http://translatewiki.net
|
||||
1. Sign up at https://translatewiki.net
|
||||
2. Visit our [TWN project page](https://translatewiki.net/wiki/Translating:Etherpad_lite)
|
||||
3. Click on `Translate Etherpad lite interface`
|
||||
4. Choose a target language, you'd like to translate our interface to, and hit `Fetch`
|
||||
|
@ -62,7 +62,7 @@ alert(window._('pad.chat'));
|
|||
```
|
||||
### 2. Create translate files in the locales directory of your plugin
|
||||
|
||||
* The name of the file must be the language code of the language it contains translations for (see [supported lang codes](http://joker-x.github.com/languages4translatewiki/test/); e.g. en ? English, es ? Spanish...)
|
||||
* The name of the file must be the language code of the language it contains translations for (see [supported lang codes](https://joker-x.github.com/languages4translatewiki/test/); e.g. en ? English, es ? Spanish...)
|
||||
* The extension of the file must be `.json`
|
||||
* The default language is English, so your plugin should always provide `en.json`
|
||||
* In order to avoid naming conflicts, your message keys should start with the name of your plugin followed by a dot (see below)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Plugins
|
||||
Etherpad allows you to extend its functionality with plugins. A plugin registers hooks (functions) for certain events (thus certain features) in Etherpad-lite to execute its own functionality based on these events.
|
||||
|
||||
Publicly available plugins can be found in the npm registry (see <http://npmjs.org>). Etherpad-lite's naming convention for plugins is to prefix your plugins with `ep_`. So, e.g. it's `ep_flubberworms`. Thus you can install plugins from npm, using `npm install ep_flubberworm` in etherpad-lite's root directory.
|
||||
Publicly available plugins can be found in the npm registry (see <https://npmjs.org>). Etherpad-lite's naming convention for plugins is to prefix your plugins with `ep_`. So, e.g. it's `ep_flubberworms`. Thus you can install plugins from npm, using `npm install ep_flubberworm` in etherpad-lite's root directory.
|
||||
|
||||
You can also browse to `http://yourEtherpadInstan.ce/admin/plugins`, which will list all installed plugins and those available on npm. It even provides functionality to search through all available plugins.
|
||||
|
||||
|
@ -17,7 +17,7 @@ ep_<plugin>/
|
|||
```
|
||||
If your plugin includes client-side hooks, put them in `static/js/`. If you're adding in CSS or image files, you should put those files in `static/css/ `and `static/image/`, respectively, and templates go into `templates/`. Translations go into `locales/`
|
||||
|
||||
A Standard directory structure like this makes it easier to navigate through your code. That said, do note, that this is not actually *required* to make your plugin run. If you want to make use of our i18n system, you need to put your translations into `locales/`, though, in order to have them intergated. (See "Localization" for more info on how to localize your plugin)
|
||||
A Standard directory structure like this makes it easier to navigate through your code. That said, do note, that this is not actually *required* to make your plugin run. If you want to make use of our i18n system, you need to put your translations into `locales/`, though, in order to have them integrated. (See "Localization" for more info on how to localize your plugin)
|
||||
|
||||
## Plugin definition
|
||||
Your plugin definition goes into `ep.json`. In this file you register your hooks, indicate the parts of your plugin and the order of execution. (A documentation of all available events to hook into can be found in chapter [hooks](#all_hooks).)
|
||||
|
@ -41,7 +41,7 @@ A hook registration is a pairs of a hook name and a function reference (filename
|
|||
}
|
||||
```
|
||||
|
||||
Etherpad-lite will expect the part of the hook definition before the colon to be a javascript file and will try to require it. The part after the colon is expected to be a valid function identifier of that module. So, you have to export your hooks, using [`module.exports`](http://nodejs.org/docs/latest/api/modules.html#modules_modules) and register it in `ep.json` as `ep_<plugin>/path/to/<file>:FUNCTIONNAME`.
|
||||
Etherpad-lite will expect the part of the hook definition before the colon to be a javascript file and will try to require it. The part after the colon is expected to be a valid function identifier of that module. So, you have to export your hooks, using [`module.exports`](https://nodejs.org/docs/latest/api/modules.html#modules_modules) and register it in `ep.json` as `ep_<plugin>/path/to/<file>:FUNCTIONNAME`.
|
||||
You can omit the `FUNCTIONNAME` part, if the exported function has got the same name as the hook. So `"authorize" : "ep_flubberworm/foo"` will call the function `exports.authorize` in `ep_flubberworm/foo.js`
|
||||
|
||||
### Client hooks and server hooks
|
||||
|
@ -89,7 +89,7 @@ Note that it would be far more sane to use `"pre"` in almost any case, but if yo
|
|||
Also, note that dependencies should *also* be listed in your package.json, so they can be `npm install`'d automagically when your plugin gets installed.
|
||||
|
||||
## Package definition
|
||||
Your plugin must also contain a [package definition file](http://npmjs.org/doc/json.html), called package.json, in the project root - this file contains various metadata relevant to your plugin, such as the name and version number, author, project hompage, contributors, a short description, etc. If you publish your plugin on npm, these metadata are used for package search etc., but it's necessary for Etherpad-lite plugins, even if you don't publish your plugin.
|
||||
Your plugin must also contain a [package definition file](https://docs.npmjs.com/files/package.json), called package.json, in the project root - this file contains various metadata relevant to your plugin, such as the name and version number, author, project hompage, contributors, a short description, etc. If you publish your plugin on npm, these metadata are used for package search etc., but it's necessary for Etherpad-lite plugins, even if you don't publish your plugin.
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue