Merge branch 'develop' of https://github.com/Pita/etherpad-lite into pita-plugin
|
@ -10,4 +10,7 @@ var/dirty.db
|
||||||
bin/convertSettings.json
|
bin/convertSettings.json
|
||||||
*~
|
*~
|
||||||
*.patch
|
*.patch
|
||||||
*.DS_Store
|
src/static/js/jquery.js
|
||||||
|
src/static/js/prefixfree.js
|
||||||
|
npm-debug.log
|
||||||
|
*.DS_Store
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
.git*
|
||||||
|
docs/
|
||||||
|
examples/
|
||||||
|
support/
|
||||||
|
test/
|
||||||
|
testing.js
|
||||||
|
.DS_Store
|
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"parts": [
|
||||||
|
{
|
||||||
|
"name": "somepart",
|
||||||
|
"pre": [],
|
||||||
|
"post": ["ep_onemoreplugin/partone"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "partlast",
|
||||||
|
"pre": ["ep_fintest/otherpart"],
|
||||||
|
"post": [],
|
||||||
|
"hooks": {
|
||||||
|
"somehookname": "ep_fintest/partlast:somehook"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "partfirst",
|
||||||
|
"pre": [],
|
||||||
|
"post": ["ep_onemoreplugin/somepart"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "otherpart",
|
||||||
|
"pre": ["ep_fintest/somepart", "ep_otherplugin/main"],
|
||||||
|
"post": [],
|
||||||
|
"hooks": {
|
||||||
|
"somehookname": "ep_fintest/otherpart:somehook",
|
||||||
|
"morehook": "ep_fintest/otherpart:morehook",
|
||||||
|
"expressCreateServer": "ep_fintest/otherpart:expressServer"
|
||||||
|
},
|
||||||
|
"client_hooks": {
|
||||||
|
"somehookname": "ep_fintest/static/js/test:bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
test = require("ep_fintest/static/js/test.js");
|
||||||
|
console.log("FOOO:", test.foo);
|
||||||
|
|
||||||
|
exports.somehook = function (hook_name, args, cb) {
|
||||||
|
return cb(["otherpart:somehook was here"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.morehook = function (hook_name, args, cb) {
|
||||||
|
return cb(["otherpart:morehook was here"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.expressServer = function (hook_name, args, cb) {
|
||||||
|
args.app.get('/otherpart', function(req, res) {
|
||||||
|
res.send("<em>Abra cadabra</em>");
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"name": "ep_fintest",
|
||||||
|
"description": "A test plugin",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"author": "RedHog (Egil Moeller) <egil.moller@freecode.no>",
|
||||||
|
"contributors": [],
|
||||||
|
"dependencies": {},
|
||||||
|
"engines": { "node": ">= 0.4.1 < 0.7.0" }
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
exports.somehook = function (hook_name, args, cb) {
|
||||||
|
return cb(["partlast:somehook was here"]);
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
exports.foo = 42;
|
||||||
|
|
||||||
|
exports.bar = function (hook_name, args, cb) {
|
||||||
|
return cb(["FOOOO"]);
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
<em>Test bla bla</em>
|
|
@ -15,8 +15,8 @@ var log4js = require("log4js");
|
||||||
log4js.setGlobalLogLevel("INFO");
|
log4js.setGlobalLogLevel("INFO");
|
||||||
var async = require("async");
|
var async = require("async");
|
||||||
var db = require('../node/db/DB');
|
var db = require('../node/db/DB');
|
||||||
var CommonCode = require('../node/utils/common_code');
|
|
||||||
var Changeset = CommonCode.require("/Changeset");
|
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
|
||||||
var padManager;
|
var padManager;
|
||||||
|
|
||||||
async.series([
|
async.series([
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
var CommonCode = require('../node/utils/common_code');
|
|
||||||
var startTime = new Date().getTime();
|
var startTime = new Date().getTime();
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var ueberDB = require("ueberDB");
|
var ueberDB = require("ueberDB");
|
||||||
var mysql = require("mysql");
|
var mysql = require("mysql");
|
||||||
var async = require("async");
|
var async = require("async");
|
||||||
var Changeset = CommonCode.require("/Changeset");
|
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
|
||||||
var randomString = CommonCode.require('/pad_utils').randomString;
|
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
||||||
var AttributePoolFactory = CommonCode.require("/AttributePoolFactory");
|
var AttributePoolFactory = require("ep_etherpad-lite/static/js/AttributePoolFactory");
|
||||||
|
|
||||||
var settingsFile = process.argv[2];
|
var settingsFile = process.argv[2];
|
||||||
var sqlOutputFile = process.argv[3];
|
var sqlOutputFile = process.argv[3];
|
||||||
|
|
|
@ -22,8 +22,7 @@ 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: http://youtu.be/AOnK3NVnxL8"
|
||||||
|
|
||||||
cd "node"
|
node --debug node_modules/ep_etherpad-lite/node/server.js $*
|
||||||
node --debug server.js
|
|
||||||
|
|
||||||
#kill node-inspector before ending
|
#kill node-inspector before ending
|
||||||
kill $!
|
kill $!
|
||||||
|
|
|
@ -55,7 +55,13 @@ if [ ! -f $settings ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Ensure that all dependencies are up to date..."
|
echo "Ensure that all dependencies are up to date..."
|
||||||
npm install || {
|
(
|
||||||
|
mkdir -p node_modules
|
||||||
|
cd node_modules
|
||||||
|
[ -e ep_etherpad-lite ] || ln -s ../src ep_etherpad-lite
|
||||||
|
cd ep_etherpad-lite
|
||||||
|
npm install
|
||||||
|
) || {
|
||||||
rm -rf node_modules
|
rm -rf node_modules
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
@ -63,8 +69,8 @@ npm install || {
|
||||||
echo "Ensure jQuery is downloaded and up to date..."
|
echo "Ensure jQuery is downloaded and up to date..."
|
||||||
DOWNLOAD_JQUERY="true"
|
DOWNLOAD_JQUERY="true"
|
||||||
NEEDED_VERSION="1.7.1"
|
NEEDED_VERSION="1.7.1"
|
||||||
if [ -f "static/js/jquery.js" ]; then
|
if [ -f "src/static/js/jquery.js" ]; then
|
||||||
VERSION=$(cat static/js/jquery.js | head -n 3 | grep -o "v[0-9]\.[0-9]\(\.[0-9]\)\?");
|
VERSION=$(cat src/static/js/jquery.js | head -n 3 | grep -o "v[0-9]\.[0-9]\(\.[0-9]\)\?");
|
||||||
|
|
||||||
if [ ${VERSION#v} = $NEEDED_VERSION ]; then
|
if [ ${VERSION#v} = $NEEDED_VERSION ]; then
|
||||||
DOWNLOAD_JQUERY="false"
|
DOWNLOAD_JQUERY="false"
|
||||||
|
@ -72,14 +78,14 @@ if [ -f "static/js/jquery.js" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $DOWNLOAD_JQUERY = "true" ]; then
|
if [ $DOWNLOAD_JQUERY = "true" ]; then
|
||||||
curl -lo static/js/jquery.js http://code.jquery.com/jquery-$NEEDED_VERSION.js || exit 1
|
curl -lo src/static/js/jquery.js http://code.jquery.com/jquery-$NEEDED_VERSION.js || exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Ensure prefixfree is downloaded and up to date..."
|
echo "Ensure prefixfree is downloaded and up to date..."
|
||||||
DOWNLOAD_PREFIXFREE="true"
|
DOWNLOAD_PREFIXFREE="true"
|
||||||
NEEDED_VERSION="1.0.4"
|
NEEDED_VERSION="1.0.4"
|
||||||
if [ -f "static/js/prefixfree.js" ]; then
|
if [ -f "src/static/js/prefixfree.js" ]; then
|
||||||
VERSION=$(cat static/js/prefixfree.js | grep "PrefixFree" | grep -o "[0-9].[0-9].[0-9]");
|
VERSION=$(cat src/static/js/prefixfree.js | grep "PrefixFree" | grep -o "[0-9].[0-9].[0-9]");
|
||||||
|
|
||||||
if [ $VERSION = $NEEDED_VERSION ]; then
|
if [ $VERSION = $NEEDED_VERSION ]; then
|
||||||
DOWNLOAD_PREFIXFREE="false"
|
DOWNLOAD_PREFIXFREE="false"
|
||||||
|
@ -87,7 +93,7 @@ if [ -f "static/js/prefixfree.js" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $DOWNLOAD_PREFIXFREE = "true" ]; then
|
if [ $DOWNLOAD_PREFIXFREE = "true" ]; then
|
||||||
curl -lo static/js/prefixfree.js -k https://raw.github.com/LeaVerou/prefixfree/master/prefixfree.js || exit 1
|
curl -lo src/static/js/prefixfree.js -k https://raw.github.com/LeaVerou/prefixfree/master/prefixfree.js || exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#Remove all minified data to force node creating it new
|
#Remove all minified data to force node creating it new
|
||||||
|
@ -98,12 +104,12 @@ echo "ensure custom css/js files are created..."
|
||||||
|
|
||||||
for f in "index" "pad" "timeslider"
|
for f in "index" "pad" "timeslider"
|
||||||
do
|
do
|
||||||
if [ ! -f "static/custom/$f.js" ]; then
|
if [ ! -f "src/static/custom/$f.js" ]; then
|
||||||
cp -v "static/custom/js.template" "static/custom/$f.js" || exit 1
|
cp -v "src/static/custom/js.template" "src/static/custom/$f.js" || exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f "static/custom/$f.css" ]; then
|
if [ ! -f "src/static/custom/$f.css" ]; then
|
||||||
cp -v "static/custom/css.template" "static/custom/$f.css" || exit 1
|
cp -v "src/static/custom/css.template" "src/static/custom/$f.css" || exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
@ -25,5 +25,4 @@ bin/installDeps.sh $* || exit 1
|
||||||
|
|
||||||
#Move to the node folder and start
|
#Move to the node folder and start
|
||||||
echo "start..."
|
echo "start..."
|
||||||
cd "node"
|
node node_modules/ep_etherpad-lite/node/server.js $*
|
||||||
node server.js $*
|
|
||||||
|
|
500
node/server.js
|
@ -1,500 +0,0 @@
|
||||||
/**
|
|
||||||
* This module is started with bin/run.sh. It sets up a Express HTTP and a Socket.IO Server.
|
|
||||||
* Static file Requests are answered directly from this module, Socket.IO messages are passed
|
|
||||||
* to MessageHandler and minfied requests are passed to minified.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS-IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var ERR = require("async-stacktrace");
|
|
||||||
var log4js = require('log4js');
|
|
||||||
var os = require("os");
|
|
||||||
var socketio = require('socket.io');
|
|
||||||
var fs = require('fs');
|
|
||||||
var settings = require('./utils/Settings');
|
|
||||||
var db = require('./db/DB');
|
|
||||||
var async = require('async');
|
|
||||||
var express = require('express');
|
|
||||||
var path = require('path');
|
|
||||||
var minify = require('./utils/Minify');
|
|
||||||
var CachingMiddleware = require('./utils/caching_middleware');
|
|
||||||
var Yajsml = require('yajsml');
|
|
||||||
var formidable = require('formidable');
|
|
||||||
var apiHandler;
|
|
||||||
var exportHandler;
|
|
||||||
var importHandler;
|
|
||||||
var exporthtml;
|
|
||||||
var readOnlyManager;
|
|
||||||
var padManager;
|
|
||||||
var securityManager;
|
|
||||||
var socketIORouter;
|
|
||||||
|
|
||||||
//try to get the git version
|
|
||||||
var version = "";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var rootPath = path.normalize(__dirname + "/../")
|
|
||||||
var ref = fs.readFileSync(rootPath + ".git/HEAD", "utf-8");
|
|
||||||
var refPath = rootPath + ".git/" + ref.substring(5, ref.indexOf("\n"));
|
|
||||||
version = fs.readFileSync(refPath, "utf-8");
|
|
||||||
version = version.substring(0, 7);
|
|
||||||
console.log("Your Etherpad Lite git version is " + version);
|
|
||||||
}
|
|
||||||
catch(e)
|
|
||||||
{
|
|
||||||
console.warn("Can't get git version for server header\n" + e.message)
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Report bugs at https://github.com/Pita/etherpad-lite/issues")
|
|
||||||
|
|
||||||
var serverName = "Etherpad-Lite " + version + " (http://j.mp/ep-lite)";
|
|
||||||
|
|
||||||
exports.maxAge = settings.maxAge;
|
|
||||||
|
|
||||||
//set loglevel
|
|
||||||
log4js.setGlobalLogLevel(settings.loglevel);
|
|
||||||
|
|
||||||
async.waterfall([
|
|
||||||
//initalize the database
|
|
||||||
function (callback)
|
|
||||||
{
|
|
||||||
db.init(callback);
|
|
||||||
},
|
|
||||||
//initalize the http server
|
|
||||||
function (callback)
|
|
||||||
{
|
|
||||||
//create server
|
|
||||||
var app = express.createServer();
|
|
||||||
|
|
||||||
app.use(function (req, res, next) {
|
|
||||||
res.header("Server", serverName);
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
//redirects browser to the pad's sanitized url if needed. otherwise, renders the html
|
|
||||||
app.param('pad', function (req, res, next, padId) {
|
|
||||||
//ensure the padname is valid and the url doesn't end with a /
|
|
||||||
if(!padManager.isValidPadId(padId) || /\/$/.test(req.url))
|
|
||||||
{
|
|
||||||
res.send('Such a padname is forbidden', 404);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
padManager.sanitizePadId(padId, function(sanitizedPadId) {
|
|
||||||
//the pad id was sanitized, so we redirect to the sanitized version
|
|
||||||
if(sanitizedPadId != padId)
|
|
||||||
{
|
|
||||||
var real_path = req.path.replace(/^\/p\/[^\/]+/, './' + sanitizedPadId);
|
|
||||||
res.header('Location', real_path);
|
|
||||||
res.send('You should be redirected to <a href="' + real_path + '">' + real_path + '</a>', 302);
|
|
||||||
}
|
|
||||||
//the pad id was fine, so just render it
|
|
||||||
else
|
|
||||||
{
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//load modules that needs a initalized db
|
|
||||||
readOnlyManager = require("./db/ReadOnlyManager");
|
|
||||||
exporthtml = require("./utils/ExportHtml");
|
|
||||||
exportHandler = require('./handler/ExportHandler');
|
|
||||||
importHandler = require('./handler/ImportHandler');
|
|
||||||
apiHandler = require('./handler/APIHandler');
|
|
||||||
padManager = require('./db/PadManager');
|
|
||||||
securityManager = require('./db/SecurityManager');
|
|
||||||
socketIORouter = require("./handler/SocketIORouter");
|
|
||||||
|
|
||||||
//install logging
|
|
||||||
var httpLogger = log4js.getLogger("http");
|
|
||||||
app.configure(function()
|
|
||||||
{
|
|
||||||
// Activate http basic auth if it has been defined in settings.json
|
|
||||||
if(settings.httpAuth != null) app.use(basic_auth);
|
|
||||||
|
|
||||||
// If the log level specified in the config file is WARN or ERROR the application server never starts listening to requests as reported in issue #158.
|
|
||||||
// Not installing the log4js connect logger when the log level has a higher severity than INFO since it would not log at that level anyway.
|
|
||||||
if (!(settings.loglevel === "WARN" || settings.loglevel == "ERROR"))
|
|
||||||
app.use(log4js.connectLogger(httpLogger, { level: log4js.levels.INFO, format: ':status, :method :url'}));
|
|
||||||
app.use(express.cookieParser());
|
|
||||||
});
|
|
||||||
|
|
||||||
app.error(function(err, req, res, next){
|
|
||||||
res.send(500);
|
|
||||||
console.error(err.stack ? err.stack : err.toString());
|
|
||||||
gracefulShutdown();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Cache both minified and static.
|
|
||||||
var assetCache = new CachingMiddleware;
|
|
||||||
app.all('/(minified|static)/*', assetCache.handle);
|
|
||||||
|
|
||||||
// Minify will serve static files compressed (minify enabled). It also has
|
|
||||||
// file-specific hacks for ace/require-kernel/etc.
|
|
||||||
app.all('/static/:filename(*)', minify.minify);
|
|
||||||
|
|
||||||
// Setup middleware that will package JavaScript files served by minify for
|
|
||||||
// CommonJS loader on the client-side.
|
|
||||||
var jsServer = new (Yajsml.Server)({
|
|
||||||
rootPath: 'minified/'
|
|
||||||
, rootURI: 'http://localhost:' + settings.port + '/static/js/'
|
|
||||||
});
|
|
||||||
var StaticAssociator = Yajsml.associators.StaticAssociator;
|
|
||||||
var associations =
|
|
||||||
Yajsml.associators.associationsForSimpleMapping(minify.tar);
|
|
||||||
var associator = new StaticAssociator(associations);
|
|
||||||
jsServer.setAssociator(associator);
|
|
||||||
app.use(jsServer);
|
|
||||||
|
|
||||||
//checks for padAccess
|
|
||||||
function hasPadAccess(req, res, callback)
|
|
||||||
{
|
|
||||||
securityManager.checkAccess(req.params.pad, req.cookies.sessionid, req.cookies.token, req.cookies.password, function(err, accessObj)
|
|
||||||
{
|
|
||||||
if(ERR(err, callback)) return;
|
|
||||||
|
|
||||||
//there is access, continue
|
|
||||||
if(accessObj.accessStatus == "grant")
|
|
||||||
{
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
//no access
|
|
||||||
else
|
|
||||||
{
|
|
||||||
res.send("403 - Can't touch this", 403);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//checks for basic http auth
|
|
||||||
function basic_auth (req, res, next) {
|
|
||||||
if (req.headers.authorization && req.headers.authorization.search('Basic ') === 0) {
|
|
||||||
// fetch login and password
|
|
||||||
if (new Buffer(req.headers.authorization.split(' ')[1], 'base64').toString() == settings.httpAuth) {
|
|
||||||
next();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res.header('WWW-Authenticate', 'Basic realm="Protected Area"');
|
|
||||||
if (req.headers.authorization) {
|
|
||||||
setTimeout(function () {
|
|
||||||
res.send('Authentication required', 401);
|
|
||||||
}, 1000);
|
|
||||||
} else {
|
|
||||||
res.send('Authentication required', 401);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//serve read only pad
|
|
||||||
app.get('/ro/:id', function(req, res)
|
|
||||||
{
|
|
||||||
var html;
|
|
||||||
var padId;
|
|
||||||
var pad;
|
|
||||||
|
|
||||||
async.series([
|
|
||||||
//translate the read only pad to a padId
|
|
||||||
function(callback)
|
|
||||||
{
|
|
||||||
readOnlyManager.getPadId(req.params.id, function(err, _padId)
|
|
||||||
{
|
|
||||||
if(ERR(err, callback)) return;
|
|
||||||
|
|
||||||
padId = _padId;
|
|
||||||
|
|
||||||
//we need that to tell hasPadAcess about the pad
|
|
||||||
req.params.pad = padId;
|
|
||||||
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
//render the html document
|
|
||||||
function(callback)
|
|
||||||
{
|
|
||||||
//return if the there is no padId
|
|
||||||
if(padId == null)
|
|
||||||
{
|
|
||||||
callback("notfound");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasPadAccess(req, res, function()
|
|
||||||
{
|
|
||||||
//render the html document
|
|
||||||
exporthtml.getPadHTMLDocument(padId, null, false, function(err, _html)
|
|
||||||
{
|
|
||||||
if(ERR(err, callback)) return;
|
|
||||||
html = _html;
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
], function(err)
|
|
||||||
{
|
|
||||||
//throw any unexpected error
|
|
||||||
if(err && err != "notfound")
|
|
||||||
ERR(err);
|
|
||||||
|
|
||||||
if(err == "notfound")
|
|
||||||
res.send('404 - Not Found', 404);
|
|
||||||
else
|
|
||||||
res.send(html);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//serve pad.html under /p
|
|
||||||
app.get('/p/:pad', function(req, res, next)
|
|
||||||
{
|
|
||||||
var filePath = path.normalize(__dirname + "/../static/pad.html");
|
|
||||||
res.sendfile(filePath, { maxAge: exports.maxAge });
|
|
||||||
});
|
|
||||||
|
|
||||||
//serve timeslider.html under /p/$padname/timeslider
|
|
||||||
app.get('/p/:pad/timeslider', function(req, res, next)
|
|
||||||
{
|
|
||||||
var filePath = path.normalize(__dirname + "/../static/timeslider.html");
|
|
||||||
res.sendfile(filePath, { maxAge: exports.maxAge });
|
|
||||||
});
|
|
||||||
|
|
||||||
//serve timeslider.html under /p/$padname/timeslider
|
|
||||||
app.get('/p/:pad/:rev?/export/:type', function(req, res, next)
|
|
||||||
{
|
|
||||||
var types = ["pdf", "doc", "txt", "html", "odt", "dokuwiki"];
|
|
||||||
//send a 404 if we don't support this filetype
|
|
||||||
if(types.indexOf(req.params.type) == -1)
|
|
||||||
{
|
|
||||||
next();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if abiword is disabled, and this is a format we only support with abiword, output a message
|
|
||||||
if(settings.abiword == null &&
|
|
||||||
["odt", "pdf", "doc"].indexOf(req.params.type) !== -1)
|
|
||||||
{
|
|
||||||
res.send("Abiword is not enabled at this Etherpad Lite instance. Set the path to Abiword in settings.json to enable this feature");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.header("Access-Control-Allow-Origin", "*");
|
|
||||||
|
|
||||||
hasPadAccess(req, res, function()
|
|
||||||
{
|
|
||||||
exportHandler.doExport(req, res, req.params.pad, req.params.type);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//handle import requests
|
|
||||||
app.post('/p/:pad/import', function(req, res, next)
|
|
||||||
{
|
|
||||||
//if abiword is disabled, skip handling this request
|
|
||||||
if(settings.abiword == null)
|
|
||||||
{
|
|
||||||
next();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasPadAccess(req, res, function()
|
|
||||||
{
|
|
||||||
importHandler.doImport(req, res, req.params.pad);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var apiLogger = log4js.getLogger("API");
|
|
||||||
|
|
||||||
//This is for making an api call, collecting all post information and passing it to the apiHandler
|
|
||||||
var apiCaller = function(req, res, fields)
|
|
||||||
{
|
|
||||||
res.header("Content-Type", "application/json; charset=utf-8");
|
|
||||||
|
|
||||||
apiLogger.info("REQUEST, " + req.params.func + ", " + JSON.stringify(fields));
|
|
||||||
|
|
||||||
//wrap the send function so we can log the response
|
|
||||||
res._send = res.send;
|
|
||||||
res.send = function(response)
|
|
||||||
{
|
|
||||||
response = JSON.stringify(response);
|
|
||||||
apiLogger.info("RESPONSE, " + req.params.func + ", " + response);
|
|
||||||
|
|
||||||
//is this a jsonp call, if yes, add the function call
|
|
||||||
if(req.query.jsonp)
|
|
||||||
response = req.query.jsonp + "(" + response + ")";
|
|
||||||
|
|
||||||
res._send(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
//call the api handler
|
|
||||||
apiHandler.handle(req.params.func, fields, req, res);
|
|
||||||
}
|
|
||||||
|
|
||||||
//This is a api GET call, collect all post informations and pass it to the apiHandler
|
|
||||||
app.get('/api/1/:func', function(req, res)
|
|
||||||
{
|
|
||||||
apiCaller(req, res, req.query)
|
|
||||||
});
|
|
||||||
|
|
||||||
//This is a api POST call, collect all post informations and pass it to the apiHandler
|
|
||||||
app.post('/api/1/:func', function(req, res)
|
|
||||||
{
|
|
||||||
new formidable.IncomingForm().parse(req, function(err, fields, files)
|
|
||||||
{
|
|
||||||
apiCaller(req, res, fields)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//The Etherpad client side sends information about how a disconnect happen
|
|
||||||
app.post('/ep/pad/connection-diagnostic-info', function(req, res)
|
|
||||||
{
|
|
||||||
new formidable.IncomingForm().parse(req, function(err, fields, files)
|
|
||||||
{
|
|
||||||
console.log("DIAGNOSTIC-INFO: " + fields.diagnosticInfo);
|
|
||||||
res.end("OK");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//The Etherpad client side sends information about client side javscript errors
|
|
||||||
app.post('/jserror', function(req, res)
|
|
||||||
{
|
|
||||||
new formidable.IncomingForm().parse(req, function(err, fields, files)
|
|
||||||
{
|
|
||||||
console.error("CLIENT SIDE JAVASCRIPT ERROR: " + fields.errorInfo);
|
|
||||||
res.end("OK");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//serve index.html under /
|
|
||||||
app.get('/', function(req, res)
|
|
||||||
{
|
|
||||||
var filePath = path.normalize(__dirname + "/../static/index.html");
|
|
||||||
res.sendfile(filePath, { maxAge: exports.maxAge });
|
|
||||||
});
|
|
||||||
|
|
||||||
//serve robots.txt
|
|
||||||
app.get('/robots.txt', function(req, res)
|
|
||||||
{
|
|
||||||
var filePath = path.normalize(__dirname + "/../static/robots.txt");
|
|
||||||
res.sendfile(filePath, { maxAge: exports.maxAge });
|
|
||||||
});
|
|
||||||
|
|
||||||
//serve favicon.ico
|
|
||||||
app.get('/favicon.ico', function(req, res)
|
|
||||||
{
|
|
||||||
var filePath = path.normalize(__dirname + "/../static/custom/favicon.ico");
|
|
||||||
res.sendfile(filePath, { maxAge: exports.maxAge }, function(err)
|
|
||||||
{
|
|
||||||
//there is no custom favicon, send the default favicon
|
|
||||||
if(err)
|
|
||||||
{
|
|
||||||
filePath = path.normalize(__dirname + "/../static/favicon.ico");
|
|
||||||
res.sendfile(filePath, { maxAge: exports.maxAge });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//let the server listen
|
|
||||||
app.listen(settings.port, settings.ip);
|
|
||||||
console.log("Server is listening at " + settings.ip + ":" + settings.port);
|
|
||||||
|
|
||||||
var onShutdown = false;
|
|
||||||
var gracefulShutdown = function(err)
|
|
||||||
{
|
|
||||||
if(err && err.stack)
|
|
||||||
{
|
|
||||||
console.error(err.stack);
|
|
||||||
}
|
|
||||||
else if(err)
|
|
||||||
{
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
//ensure there is only one graceful shutdown running
|
|
||||||
if(onShutdown) return;
|
|
||||||
onShutdown = true;
|
|
||||||
|
|
||||||
console.log("graceful shutdown...");
|
|
||||||
|
|
||||||
//stop the http server
|
|
||||||
app.close();
|
|
||||||
|
|
||||||
//do the db shutdown
|
|
||||||
db.db.doShutdown(function()
|
|
||||||
{
|
|
||||||
console.log("db sucessfully closed.");
|
|
||||||
|
|
||||||
process.exit(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(function(){
|
|
||||||
process.exit(1);
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
|
|
||||||
//connect graceful shutdown with sigint and uncaughtexception
|
|
||||||
if(os.type().indexOf("Windows") == -1)
|
|
||||||
{
|
|
||||||
//sigint is so far not working on windows
|
|
||||||
//https://github.com/joyent/node/issues/1553
|
|
||||||
process.on('SIGINT', gracefulShutdown);
|
|
||||||
}
|
|
||||||
|
|
||||||
process.on('uncaughtException', gracefulShutdown);
|
|
||||||
|
|
||||||
//init socket.io and redirect all requests to the MessageHandler
|
|
||||||
var io = socketio.listen(app);
|
|
||||||
|
|
||||||
//this is only a workaround to ensure it works with all browers behind a proxy
|
|
||||||
//we should remove this when the new socket.io version is more stable
|
|
||||||
io.set('transports', ['xhr-polling']);
|
|
||||||
|
|
||||||
var socketIOLogger = log4js.getLogger("socket.io");
|
|
||||||
io.set('logger', {
|
|
||||||
debug: function (str)
|
|
||||||
{
|
|
||||||
socketIOLogger.debug.apply(socketIOLogger, arguments);
|
|
||||||
},
|
|
||||||
info: function (str)
|
|
||||||
{
|
|
||||||
socketIOLogger.info.apply(socketIOLogger, arguments);
|
|
||||||
},
|
|
||||||
warn: function (str)
|
|
||||||
{
|
|
||||||
socketIOLogger.warn.apply(socketIOLogger, arguments);
|
|
||||||
},
|
|
||||||
error: function (str)
|
|
||||||
{
|
|
||||||
socketIOLogger.error.apply(socketIOLogger, arguments);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
//minify socket.io javascript
|
|
||||||
if(settings.minify)
|
|
||||||
io.enable('browser client minification');
|
|
||||||
|
|
||||||
var padMessageHandler = require("./handler/PadMessageHandler");
|
|
||||||
var timesliderMessageHandler = require("./handler/TimesliderMessageHandler");
|
|
||||||
|
|
||||||
//Initalize the Socket.IO Router
|
|
||||||
socketIORouter.setSocketIO(io);
|
|
||||||
socketIORouter.addComponent("pad", padMessageHandler);
|
|
||||||
socketIORouter.addComponent("timeslider", timesliderMessageHandler);
|
|
||||||
|
|
||||||
callback(null);
|
|
||||||
}
|
|
||||||
]);
|
|
|
@ -1,24 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright 2009 Google Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS-IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var RequireKernel = require('require-kernel/');
|
|
||||||
var path = require('path');
|
|
||||||
|
|
||||||
var CLIENT_JS_SRC = path.normalize(__dirname + '/../../static/js/');
|
|
||||||
var client_require = RequireKernel.requireForPaths(
|
|
||||||
'file://' + (CLIENT_JS_SRC.charAt(0) == '/' ? '' : '/') + encodeURI(CLIENT_JS_SRC));
|
|
||||||
|
|
||||||
exports.require = client_require;
|
|
|
@ -13,7 +13,7 @@
|
||||||
"dbType" : "dirty",
|
"dbType" : "dirty",
|
||||||
//the database specific settings
|
//the database specific settings
|
||||||
"dbSettings" : {
|
"dbSettings" : {
|
||||||
"filename" : "../var/dirty.db"
|
"filename" : "var/dirty.db"
|
||||||
},
|
},
|
||||||
|
|
||||||
/* An Example of MySQL Configuration
|
/* An Example of MySQL Configuration
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
"dbType" : "dirty",
|
"dbType" : "dirty",
|
||||||
//the database specific settings
|
//the database specific settings
|
||||||
"dbSettings" : {
|
"dbSettings" : {
|
||||||
"filename" : "../var/dirty.db"
|
"filename" : "var/dirty.db"
|
||||||
},
|
},
|
||||||
|
|
||||||
/* An Example of MySQL Configuration
|
/* An Example of MySQL Configuration
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"parts": [
|
||||||
|
{ "name": "static", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/static:expressCreateServer" } },
|
||||||
|
{ "name": "specialpages", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/specialpages:expressCreateServer" } },
|
||||||
|
{ "name": "padurlsanitize", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/padurlsanitize:expressCreateServer" } },
|
||||||
|
{ "name": "padreadonly", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/padreadonly:expressCreateServer" } },
|
||||||
|
{ "name": "webaccess", "hooks": { "expressConfigure": "ep_etherpad-lite/node/hooks/express/webaccess:expressConfigure" } },
|
||||||
|
{ "name": "apicalls", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/apicalls:expressCreateServer" } },
|
||||||
|
{ "name": "importexport", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/importexport:expressCreateServer" } },
|
||||||
|
{ "name": "errorhandling", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/errorhandling:expressCreateServer" } },
|
||||||
|
{ "name": "socketio", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/socketio:expressCreateServer" } }
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
|
@ -18,11 +18,11 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var CommonCode = require('../utils/common_code');
|
|
||||||
var ERR = require("async-stacktrace");
|
var ERR = require("async-stacktrace");
|
||||||
var db = require("./DB").db;
|
var db = require("./DB").db;
|
||||||
var async = require("async");
|
var async = require("async");
|
||||||
var randomString = CommonCode.require('/pad_utils').randomString;
|
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the author exists
|
* Checks if the author exists
|
|
@ -18,10 +18,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var CommonCode = require('../utils/common_code');
|
|
||||||
var ERR = require("async-stacktrace");
|
var ERR = require("async-stacktrace");
|
||||||
var customError = require("../utils/customError");
|
var customError = require("../utils/customError");
|
||||||
var randomString = CommonCode.require('/pad_utils').randomString;
|
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
||||||
var db = require("./DB").db;
|
var db = require("./DB").db;
|
||||||
var async = require("async");
|
var async = require("async");
|
||||||
var padManager = require("./PadManager");
|
var padManager = require("./PadManager");
|
|
@ -2,11 +2,11 @@
|
||||||
* The pad object, defined with joose
|
* The pad object, defined with joose
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var CommonCode = require('../utils/common_code');
|
|
||||||
var ERR = require("async-stacktrace");
|
var ERR = require("async-stacktrace");
|
||||||
var Changeset = CommonCode.require("/Changeset");
|
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
|
||||||
var AttributePoolFactory = CommonCode.require("/AttributePoolFactory");
|
var AttributePoolFactory = require("ep_etherpad-lite/static/js/AttributePoolFactory");
|
||||||
var randomString = CommonCode.require('/pad_utils').randomString;
|
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
||||||
var db = require("./DB").db;
|
var db = require("./DB").db;
|
||||||
var async = require("async");
|
var async = require("async");
|
||||||
var settings = require('../utils/Settings');
|
var settings = require('../utils/Settings');
|
|
@ -18,11 +18,11 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var CommonCode = require('../utils/common_code');
|
|
||||||
var ERR = require("async-stacktrace");
|
var ERR = require("async-stacktrace");
|
||||||
var db = require("./DB").db;
|
var db = require("./DB").db;
|
||||||
var async = require("async");
|
var async = require("async");
|
||||||
var randomString = CommonCode.require('/pad_utils').randomString;
|
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns a read only id for a pad
|
* returns a read only id for a pad
|
|
@ -18,7 +18,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var CommonCode = require('../utils/common_code');
|
|
||||||
var ERR = require("async-stacktrace");
|
var ERR = require("async-stacktrace");
|
||||||
var db = require("./DB").db;
|
var db = require("./DB").db;
|
||||||
var async = require("async");
|
var async = require("async");
|
||||||
|
@ -26,7 +26,7 @@ var authorManager = require("./AuthorManager");
|
||||||
var padManager = require("./PadManager");
|
var padManager = require("./PadManager");
|
||||||
var sessionManager = require("./SessionManager");
|
var sessionManager = require("./SessionManager");
|
||||||
var settings = require("../utils/Settings")
|
var settings = require("../utils/Settings")
|
||||||
var randomString = CommonCode.require('/pad_utils').randomString;
|
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function controlls the access to a pad, it checks if the user can access a pad.
|
* This function controlls the access to a pad, it checks if the user can access a pad.
|
|
@ -18,10 +18,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var CommonCode = require('../utils/common_code');
|
|
||||||
var ERR = require("async-stacktrace");
|
var ERR = require("async-stacktrace");
|
||||||
var customError = require("../utils/customError");
|
var customError = require("../utils/customError");
|
||||||
var randomString = CommonCode.require('/pad_utils').randomString;
|
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
||||||
var db = require("./DB").db;
|
var db = require("./DB").db;
|
||||||
var async = require("async");
|
var async = require("async");
|
||||||
var groupMangager = require("./GroupManager");
|
var groupMangager = require("./GroupManager");
|
|
@ -20,9 +20,9 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var CommonCode = require('./utils/common_code');
|
|
||||||
var Changeset = CommonCode.require("/Changeset");
|
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
|
||||||
var AttributePoolFactory = CommonCode.require("/AttributePoolFactory");
|
var AttributePoolFactory = require("ep_etherpad-lite/static/js/AttributePoolFactory");
|
||||||
|
|
||||||
function random() {
|
function random() {
|
||||||
this.nextInt = function (maxValue) {
|
this.nextInt = function (maxValue) {
|
|
@ -18,12 +18,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var CommonCode = require('../utils/common_code');
|
|
||||||
var ERR = require("async-stacktrace");
|
var ERR = require("async-stacktrace");
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var api = require("../db/API");
|
var api = require("../db/API");
|
||||||
var padManager = require("../db/PadManager");
|
var padManager = require("../db/PadManager");
|
||||||
var randomString = CommonCode.require('/pad_utils').randomString;
|
var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString;
|
||||||
|
|
||||||
//ensure we have an apikey
|
//ensure we have an apikey
|
||||||
var apikey = null;
|
var apikey = null;
|
|
@ -18,16 +18,17 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var CommonCode = require('../utils/common_code');
|
|
||||||
var ERR = require("async-stacktrace");
|
var ERR = require("async-stacktrace");
|
||||||
var async = require("async");
|
var async = require("async");
|
||||||
var padManager = require("../db/PadManager");
|
var padManager = require("../db/PadManager");
|
||||||
var Changeset = CommonCode.require("/Changeset");
|
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
|
||||||
var AttributePoolFactory = CommonCode.require("/AttributePoolFactory");
|
var AttributePoolFactory = require("ep_etherpad-lite/static/js/AttributePoolFactory");
|
||||||
var authorManager = require("../db/AuthorManager");
|
var authorManager = require("../db/AuthorManager");
|
||||||
var readOnlyManager = require("../db/ReadOnlyManager");
|
var readOnlyManager = require("../db/ReadOnlyManager");
|
||||||
var settings = require('../utils/Settings');
|
var settings = require('../utils/Settings');
|
||||||
var securityManager = require("../db/SecurityManager");
|
var securityManager = require("../db/SecurityManager");
|
||||||
|
var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins.js");
|
||||||
var log4js = require('log4js');
|
var log4js = require('log4js');
|
||||||
var messageLogger = log4js.getLogger("message");
|
var messageLogger = log4js.getLogger("message");
|
||||||
|
|
||||||
|
@ -800,9 +801,12 @@ function handleClientReady(client, message)
|
||||||
"hideSidebar": false
|
"hideSidebar": false
|
||||||
},
|
},
|
||||||
"abiwordAvailable": settings.abiwordAvailable(),
|
"abiwordAvailable": settings.abiwordAvailable(),
|
||||||
"hooks": {}
|
"plugins": {
|
||||||
|
"plugins": plugins.plugins,
|
||||||
|
"parts": plugins.parts,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add a username to the clientVars if one avaiable
|
//Add a username to the clientVars if one avaiable
|
||||||
if(authorName != null)
|
if(authorName != null)
|
||||||
{
|
{
|
|
@ -18,12 +18,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var CommonCode = require('../utils/common_code');
|
|
||||||
var ERR = require("async-stacktrace");
|
var ERR = require("async-stacktrace");
|
||||||
var async = require("async");
|
var async = require("async");
|
||||||
var padManager = require("../db/PadManager");
|
var padManager = require("../db/PadManager");
|
||||||
var Changeset = CommonCode.require("/Changeset");
|
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
|
||||||
var AttributePoolFactory = CommonCode.require("/AttributePoolFactory");
|
var AttributePoolFactory = require("ep_etherpad-lite/static/js/AttributePoolFactory");
|
||||||
var settings = require('../utils/Settings');
|
var settings = require('../utils/Settings');
|
||||||
var authorManager = require("../db/AuthorManager");
|
var authorManager = require("../db/AuthorManager");
|
||||||
var log4js = require('log4js');
|
var log4js = require('log4js');
|
|
@ -0,0 +1,58 @@
|
||||||
|
var log4js = require('log4js');
|
||||||
|
var apiLogger = log4js.getLogger("API");
|
||||||
|
var formidable = require('formidable');
|
||||||
|
var apiHandler = require('../../handler/APIHandler');
|
||||||
|
|
||||||
|
//This is for making an api call, collecting all post information and passing it to the apiHandler
|
||||||
|
exports.apiCaller = function(req, res, fields) {
|
||||||
|
res.header("Content-Type", "application/json; charset=utf-8");
|
||||||
|
|
||||||
|
apiLogger.info("REQUEST, " + req.params.func + ", " + JSON.stringify(fields));
|
||||||
|
|
||||||
|
//wrap the send function so we can log the response
|
||||||
|
res._send = res.send;
|
||||||
|
res.send = function (response) {
|
||||||
|
response = JSON.stringify(response);
|
||||||
|
apiLogger.info("RESPONSE, " + req.params.func + ", " + response);
|
||||||
|
|
||||||
|
//is this a jsonp call, if yes, add the function call
|
||||||
|
if(req.query.jsonp)
|
||||||
|
response = req.query.jsonp + "(" + response + ")";
|
||||||
|
|
||||||
|
res._send(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
//call the api handler
|
||||||
|
apiHandler.handle(req.params.func, fields, req, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
|
//This is a api GET call, collect all post informations and pass it to the apiHandler
|
||||||
|
args.app.get('/api/1/:func', function (req, res) {
|
||||||
|
apiCaller(req, res, req.query)
|
||||||
|
});
|
||||||
|
|
||||||
|
//This is a api POST call, collect all post informations and pass it to the apiHandler
|
||||||
|
args.app.post('/api/1/:func', function(req, res) {
|
||||||
|
new formidable.IncomingForm().parse(req, function (err, fields, files) {
|
||||||
|
apiCaller(req, res, fields)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//The Etherpad client side sends information about how a disconnect happen
|
||||||
|
args.app.post('/ep/pad/connection-diagnostic-info', function(req, res) {
|
||||||
|
new formidable.IncomingForm().parse(req, function(err, fields, files) {
|
||||||
|
console.log("DIAGNOSTIC-INFO: " + fields.diagnosticInfo);
|
||||||
|
res.end("OK");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//The Etherpad client side sends information about client side javscript errors
|
||||||
|
args.app.post('/jserror', function(req, res) {
|
||||||
|
new formidable.IncomingForm().parse(req, function(err, fields, files) {
|
||||||
|
console.error("CLIENT SIDE JAVASCRIPT ERROR: " + fields.errorInfo);
|
||||||
|
res.end("OK");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
var os = require("os");
|
||||||
|
var db = require('../../db/DB');
|
||||||
|
|
||||||
|
|
||||||
|
exports.onShutdown = false;
|
||||||
|
exports.gracefulShutdown = function(err) {
|
||||||
|
if(err && err.stack) {
|
||||||
|
console.error(err.stack);
|
||||||
|
} else if(err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
//ensure there is only one graceful shutdown running
|
||||||
|
if(exports.onShutdown) return;
|
||||||
|
exports.onShutdown = true;
|
||||||
|
|
||||||
|
console.log("graceful shutdown...");
|
||||||
|
|
||||||
|
//stop the http server
|
||||||
|
exports.app.close();
|
||||||
|
|
||||||
|
//do the db shutdown
|
||||||
|
db.db.doShutdown(function() {
|
||||||
|
console.log("db sucessfully closed.");
|
||||||
|
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(function(){
|
||||||
|
process.exit(1);
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
|
exports.app = args.app;
|
||||||
|
|
||||||
|
args.app.error(function(err, req, res, next){
|
||||||
|
res.send(500);
|
||||||
|
console.error(err.stack ? err.stack : err.toString());
|
||||||
|
exports.gracefulShutdown();
|
||||||
|
});
|
||||||
|
|
||||||
|
//connect graceful shutdown with sigint and uncaughtexception
|
||||||
|
if(os.type().indexOf("Windows") == -1) {
|
||||||
|
//sigint is so far not working on windows
|
||||||
|
//https://github.com/joyent/node/issues/1553
|
||||||
|
process.on('SIGINT', exports.gracefulShutdown);
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('uncaughtException', exports.gracefulShutdown);
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
var hasPadAccess = require("../../padaccess");
|
||||||
|
var settings = require('../../utils/Settings');
|
||||||
|
var exportHandler = require('../../handler/ExportHandler');
|
||||||
|
var importHandler = require('../../handler/ImportHandler');
|
||||||
|
|
||||||
|
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
|
args.app.get('/p/:pad/:rev?/export/:type', function(req, res, next) {
|
||||||
|
var types = ["pdf", "doc", "txt", "html", "odt", "dokuwiki"];
|
||||||
|
//send a 404 if we don't support this filetype
|
||||||
|
if (types.indexOf(req.params.type) == -1) {
|
||||||
|
next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if abiword is disabled, and this is a format we only support with abiword, output a message
|
||||||
|
if (settings.abiword == null &&
|
||||||
|
["odt", "pdf", "doc"].indexOf(req.params.type) !== -1) {
|
||||||
|
res.send("Abiword is not enabled at this Etherpad Lite instance. Set the path to Abiword in settings.json to enable this feature");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.header("Access-Control-Allow-Origin", "*");
|
||||||
|
|
||||||
|
hasPadAccess(req, res, function() {
|
||||||
|
exportHandler.doExport(req, res, req.params.pad, req.params.type);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//handle import requests
|
||||||
|
args.app.post('/p/:pad/import', function(req, res, next) {
|
||||||
|
//if abiword is disabled, skip handling this request
|
||||||
|
if(settings.abiword == null) {
|
||||||
|
next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasPadAccess(req, res, function() {
|
||||||
|
importHandler.doImport(req, res, req.params.pad);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
var async = require('async');
|
||||||
|
var ERR = require("async-stacktrace");
|
||||||
|
var readOnlyManager = require("../../db/ReadOnlyManager");
|
||||||
|
var hasPadAccess = require("../../padaccess");
|
||||||
|
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;
|
||||||
|
var pad;
|
||||||
|
|
||||||
|
async.series([
|
||||||
|
//translate the read only pad to a padId
|
||||||
|
function(callback)
|
||||||
|
{
|
||||||
|
readOnlyManager.getPadId(req.params.id, function(err, _padId)
|
||||||
|
{
|
||||||
|
if(ERR(err, callback)) return;
|
||||||
|
|
||||||
|
padId = _padId;
|
||||||
|
|
||||||
|
//we need that to tell hasPadAcess about the pad
|
||||||
|
req.params.pad = padId;
|
||||||
|
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//render the html document
|
||||||
|
function(callback)
|
||||||
|
{
|
||||||
|
//return if the there is no padId
|
||||||
|
if(padId == null)
|
||||||
|
{
|
||||||
|
callback("notfound");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasPadAccess(req, res, function()
|
||||||
|
{
|
||||||
|
//render the html document
|
||||||
|
exporthtml.getPadHTMLDocument(padId, null, false, function(err, _html)
|
||||||
|
{
|
||||||
|
if(ERR(err, callback)) return;
|
||||||
|
html = _html;
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
], function(err)
|
||||||
|
{
|
||||||
|
//throw any unexpected error
|
||||||
|
if(err && err != "notfound")
|
||||||
|
ERR(err);
|
||||||
|
|
||||||
|
if(err == "notfound")
|
||||||
|
res.send('404 - Not Found', 404);
|
||||||
|
else
|
||||||
|
res.send(html);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
var padManager = require('../../db/PadManager');
|
||||||
|
|
||||||
|
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
|
//redirects browser to the pad's sanitized url if needed. otherwise, renders the html
|
||||||
|
args.app.param('pad', function (req, res, next, padId) {
|
||||||
|
//ensure the padname is valid and the url doesn't end with a /
|
||||||
|
if(!padManager.isValidPadId(padId) || /\/$/.test(req.url))
|
||||||
|
{
|
||||||
|
res.send('Such a padname is forbidden', 404);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
padManager.sanitizePadId(padId, function(sanitizedPadId) {
|
||||||
|
//the pad id was sanitized, so we redirect to the sanitized version
|
||||||
|
if(sanitizedPadId != padId)
|
||||||
|
{
|
||||||
|
var real_path = req.path.replace(/^\/p\/[^\/]+/, '/p/' + sanitizedPadId);
|
||||||
|
res.header('Location', real_path);
|
||||||
|
res.send('You should be redirected to <a href="' + real_path + '">' + real_path + '</a>', 302);
|
||||||
|
}
|
||||||
|
//the pad id was fine, so just render it
|
||||||
|
else
|
||||||
|
{
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
var log4js = require('log4js');
|
||||||
|
var socketio = require('socket.io');
|
||||||
|
var settings = require('../../utils/Settings');
|
||||||
|
var socketIORouter = require("../../handler/SocketIORouter");
|
||||||
|
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
|
||||||
|
|
||||||
|
var padMessageHandler = require("../../handler/PadMessageHandler");
|
||||||
|
var timesliderMessageHandler = require("../../handler/TimesliderMessageHandler");
|
||||||
|
|
||||||
|
|
||||||
|
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
|
//init socket.io and redirect all requests to the MessageHandler
|
||||||
|
var io = socketio.listen(args.app);
|
||||||
|
|
||||||
|
//this is only a workaround to ensure it works with all browers behind a proxy
|
||||||
|
//we should remove this when the new socket.io version is more stable
|
||||||
|
io.set('transports', ['xhr-polling']);
|
||||||
|
|
||||||
|
var socketIOLogger = log4js.getLogger("socket.io");
|
||||||
|
io.set('logger', {
|
||||||
|
debug: function (str)
|
||||||
|
{
|
||||||
|
socketIOLogger.debug.apply(socketIOLogger, arguments);
|
||||||
|
},
|
||||||
|
info: function (str)
|
||||||
|
{
|
||||||
|
socketIOLogger.info.apply(socketIOLogger, arguments);
|
||||||
|
},
|
||||||
|
warn: function (str)
|
||||||
|
{
|
||||||
|
socketIOLogger.warn.apply(socketIOLogger, arguments);
|
||||||
|
},
|
||||||
|
error: function (str)
|
||||||
|
{
|
||||||
|
socketIOLogger.error.apply(socketIOLogger, arguments);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//minify socket.io javascript
|
||||||
|
if(settings.minify)
|
||||||
|
io.enable('browser client minification');
|
||||||
|
|
||||||
|
//Initalize the Socket.IO Router
|
||||||
|
socketIORouter.setSocketIO(io);
|
||||||
|
socketIORouter.addComponent("pad", padMessageHandler);
|
||||||
|
socketIORouter.addComponent("timeslider", timesliderMessageHandler);
|
||||||
|
|
||||||
|
hooks.callAll("socketio", {"app": args.app, "io": io});
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
|
|
||||||
|
//serve index.html under /
|
||||||
|
args.app.get('/', function(req, res)
|
||||||
|
{
|
||||||
|
var filePath = path.normalize(__dirname + "/../../../static/index.html");
|
||||||
|
res.sendfile(filePath, { maxAge: exports.maxAge });
|
||||||
|
});
|
||||||
|
|
||||||
|
//serve robots.txt
|
||||||
|
args.app.get('/robots.txt', function(req, res)
|
||||||
|
{
|
||||||
|
var filePath = path.normalize(__dirname + "/../../../static/robots.txt");
|
||||||
|
res.sendfile(filePath, { maxAge: exports.maxAge });
|
||||||
|
});
|
||||||
|
|
||||||
|
//serve favicon.ico
|
||||||
|
args.app.get('/favicon.ico', function(req, res)
|
||||||
|
{
|
||||||
|
var filePath = path.normalize(__dirname + "/../../../static/custom/favicon.ico");
|
||||||
|
res.sendfile(filePath, { maxAge: exports.maxAge }, function(err)
|
||||||
|
{
|
||||||
|
//there is no custom favicon, send the default favicon
|
||||||
|
if(err)
|
||||||
|
{
|
||||||
|
filePath = path.normalize(__dirname + "/../../../static/favicon.ico");
|
||||||
|
res.sendfile(filePath, { maxAge: exports.maxAge });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//serve pad.html under /p
|
||||||
|
args.app.get('/p/:pad', function(req, res, next)
|
||||||
|
{
|
||||||
|
var filePath = path.normalize(__dirname + "/../../../static/pad.html");
|
||||||
|
res.sendfile(filePath, { maxAge: exports.maxAge });
|
||||||
|
});
|
||||||
|
|
||||||
|
//serve timeslider.html under /p/$padname/timeslider
|
||||||
|
args.app.get('/p/:pad/timeslider', function(req, res, next)
|
||||||
|
{
|
||||||
|
var filePath = path.normalize(__dirname + "/../../../static/timeslider.html");
|
||||||
|
res.sendfile(filePath, { maxAge: exports.maxAge });
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
var path = require('path');
|
||||||
|
var minify = require('../../utils/Minify');
|
||||||
|
var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins");
|
||||||
|
var CachingMiddleware = require('../../utils/caching_middleware');
|
||||||
|
var settings = require("../../utils/Settings");
|
||||||
|
var Yajsml = require('yajsml');
|
||||||
|
var fs = require("fs");
|
||||||
|
var ERR = require("async-stacktrace");
|
||||||
|
|
||||||
|
exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
|
// Cache both minified and static.
|
||||||
|
var assetCache = new CachingMiddleware;
|
||||||
|
args.app.all('/(javascripts|static)/*', assetCache.handle);
|
||||||
|
|
||||||
|
// Minify will serve static files compressed (minify enabled). It also has
|
||||||
|
// file-specific hacks for ace/require-kernel/etc.
|
||||||
|
args.app.all('/static/:filename(*)', minify.minify);
|
||||||
|
|
||||||
|
// Setup middleware that will package JavaScript files served by minify for
|
||||||
|
// CommonJS loader on the client-side.
|
||||||
|
var jsServer = new (Yajsml.Server)({
|
||||||
|
rootPath: 'javascripts/src/'
|
||||||
|
, rootURI: 'http://localhost:' + settings.port + '/static/js/'
|
||||||
|
, libraryPath: 'javascripts/lib/'
|
||||||
|
, libraryURI: 'http://localhost:' + settings.port + '/static/plugins/'
|
||||||
|
});
|
||||||
|
|
||||||
|
var StaticAssociator = Yajsml.associators.StaticAssociator;
|
||||||
|
var associations =
|
||||||
|
Yajsml.associators.associationsForSimpleMapping(minify.tar);
|
||||||
|
var associator = new StaticAssociator(associations);
|
||||||
|
jsServer.setAssociator(associator);
|
||||||
|
args.app.use(jsServer);
|
||||||
|
|
||||||
|
// serve plugin definitions
|
||||||
|
// not very static, but served here so that client can do require("pluginfw/static/js/plugin-definitions.js");
|
||||||
|
args.app.get('/pluginfw/plugin-definitions.json', function (req, res, next) {
|
||||||
|
res.header("Content-Type","application/json; charset: utf-8");
|
||||||
|
res.write(JSON.stringify({"plugins": plugins.plugins, "parts": plugins.parts}));
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
var express = require('express');
|
||||||
|
var log4js = require('log4js');
|
||||||
|
var httpLogger = log4js.getLogger("http");
|
||||||
|
var settings = require('../../utils/Settings');
|
||||||
|
|
||||||
|
|
||||||
|
//checks for basic http auth
|
||||||
|
exports.basicAuth = function (req, res, next) {
|
||||||
|
if (req.headers.authorization && req.headers.authorization.search('Basic ') === 0) {
|
||||||
|
// fetch login and password
|
||||||
|
if (new Buffer(req.headers.authorization.split(' ')[1], 'base64').toString() == settings.httpAuth) {
|
||||||
|
next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res.header('WWW-Authenticate', 'Basic realm="Protected Area"');
|
||||||
|
if (req.headers.authorization) {
|
||||||
|
setTimeout(function () {
|
||||||
|
res.send('Authentication required', 401);
|
||||||
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
res.send('Authentication required', 401);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.expressConfigure = function (hook_name, args, cb) {
|
||||||
|
// Activate http basic auth if it has been defined in settings.json
|
||||||
|
if(settings.httpAuth != null) args.app.use(exports.basicAuth);
|
||||||
|
|
||||||
|
// If the log level specified in the config file is WARN or ERROR the application server never starts listening to requests as reported in issue #158.
|
||||||
|
// Not installing the log4js connect logger when the log level has a higher severity than INFO since it would not log at that level anyway.
|
||||||
|
if (!(settings.loglevel === "WARN" || settings.loglevel == "ERROR"))
|
||||||
|
args.app.use(log4js.connectLogger(httpLogger, { level: log4js.levels.INFO, format: ':status, :method :url'}));
|
||||||
|
args.app.use(express.cookieParser());
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
var ERR = require("async-stacktrace");
|
||||||
|
var securityManager = require('./db/SecurityManager');
|
||||||
|
|
||||||
|
//checks for padAccess
|
||||||
|
module.exports = function (req, res, callback) {
|
||||||
|
|
||||||
|
// FIXME: Why is this ever undefined??
|
||||||
|
if (req.cookies === undefined) req.cookies = {};
|
||||||
|
|
||||||
|
securityManager.checkAccess(req.params.pad, req.cookies.sessionid, req.cookies.token, req.cookies.password, function(err, accessObj) {
|
||||||
|
if(ERR(err, callback)) return;
|
||||||
|
|
||||||
|
//there is access, continue
|
||||||
|
if(accessObj.accessStatus == "grant") {
|
||||||
|
callback();
|
||||||
|
//no access
|
||||||
|
} else {
|
||||||
|
res.send("403 - Can't touch this", 403);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
/**
|
||||||
|
* This module is started with bin/run.sh. It sets up a Express HTTP and a Socket.IO Server.
|
||||||
|
* Static file Requests are answered directly from this module, Socket.IO messages are passed
|
||||||
|
* to MessageHandler and minfied requests are passed to minified.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS-IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var log4js = require('log4js');
|
||||||
|
var fs = require('fs');
|
||||||
|
var settings = require('./utils/Settings');
|
||||||
|
var db = require('./db/DB');
|
||||||
|
var async = require('async');
|
||||||
|
var express = require('express');
|
||||||
|
var path = require('path');
|
||||||
|
var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins");
|
||||||
|
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
|
||||||
|
var npm = require("npm/lib/npm.js");
|
||||||
|
|
||||||
|
//try to get the git version
|
||||||
|
var version = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var rootPath = path.resolve(npm.dir, '..');
|
||||||
|
var ref = fs.readFileSync(rootPath + "/.git/HEAD", "utf-8");
|
||||||
|
var refPath = rootPath + "/.git/" + ref.substring(5, ref.indexOf("\n"));
|
||||||
|
version = fs.readFileSync(refPath, "utf-8");
|
||||||
|
version = version.substring(0, 7);
|
||||||
|
console.log("Your Etherpad Lite git version is " + version);
|
||||||
|
}
|
||||||
|
catch(e)
|
||||||
|
{
|
||||||
|
console.warn("Can't get git version for server header\n" + e.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Report bugs at https://github.com/Pita/etherpad-lite/issues")
|
||||||
|
|
||||||
|
var serverName = "Etherpad-Lite " + version + " (http://j.mp/ep-lite)";
|
||||||
|
|
||||||
|
//cache 6 hours
|
||||||
|
exports.maxAge = 1000*60*60*6;
|
||||||
|
|
||||||
|
//set loglevel
|
||||||
|
log4js.setGlobalLogLevel(settings.loglevel);
|
||||||
|
|
||||||
|
async.waterfall([
|
||||||
|
//initalize the database
|
||||||
|
function (callback)
|
||||||
|
{
|
||||||
|
db.init(callback);
|
||||||
|
},
|
||||||
|
|
||||||
|
plugins.update,
|
||||||
|
|
||||||
|
function (callback) {
|
||||||
|
console.log("Installed plugins: " + plugins.formatPlugins());
|
||||||
|
console.log("Installed parts:\n" + plugins.formatParts());
|
||||||
|
console.log("Installed hooks:\n" + plugins.formatHooks());
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
|
||||||
|
//initalize the http server
|
||||||
|
function (callback)
|
||||||
|
{
|
||||||
|
//create server
|
||||||
|
var app = express.createServer();
|
||||||
|
|
||||||
|
app.use(function (req, res, next) {
|
||||||
|
res.header("Server", serverName);
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
app.configure(function() { hooks.callAll("expressConfigure", {"app": app}); });
|
||||||
|
|
||||||
|
hooks.callAll("expressCreateServer", {"app": app});
|
||||||
|
|
||||||
|
//let the server listen
|
||||||
|
app.listen(settings.port, settings.ip);
|
||||||
|
console.log("Server is listening at " + settings.ip + ":" + settings.port);
|
||||||
|
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
]);
|
|
@ -15,8 +15,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var async = require("async");
|
var async = require("async");
|
||||||
var CommonCode = require('./common_code');
|
|
||||||
var Changeset = CommonCode.require("/Changeset");
|
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
|
||||||
var padManager = require("../db/PadManager");
|
var padManager = require("../db/PadManager");
|
||||||
|
|
||||||
function getPadDokuWiki(pad, revNum, callback)
|
function getPadDokuWiki(pad, revNum, callback)
|
|
@ -14,12 +14,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var CommonCode = require('./common_code');
|
|
||||||
var async = require("async");
|
var async = require("async");
|
||||||
var Changeset = CommonCode.require("/Changeset");
|
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
|
||||||
var padManager = require("../db/PadManager");
|
var padManager = require("../db/PadManager");
|
||||||
var ERR = require("async-stacktrace");
|
var ERR = require("async-stacktrace");
|
||||||
var Security = CommonCode.require('/security');
|
var Security = require('ep_etherpad-lite/static/js/security');
|
||||||
|
|
||||||
function getPadPlainText(pad, revNum)
|
function getPadPlainText(pad, revNum)
|
||||||
{
|
{
|
|
@ -17,10 +17,10 @@
|
||||||
var jsdom = require('jsdom-nocontextifiy').jsdom;
|
var jsdom = require('jsdom-nocontextifiy').jsdom;
|
||||||
var log4js = require('log4js');
|
var log4js = require('log4js');
|
||||||
|
|
||||||
var CommonCode = require('../utils/common_code');
|
|
||||||
var Changeset = CommonCode.require("/Changeset");
|
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
|
||||||
var contentcollector = CommonCode.require("/contentcollector");
|
var contentcollector = require("ep_etherpad-lite/static/js/contentcollector");
|
||||||
var map = CommonCode.require("/ace2_common").map;
|
var map = require("ep_etherpad-lite/static/js/ace2_common").map;
|
||||||
|
|
||||||
function setPadHTML(pad, html, callback)
|
function setPadHTML(pad, html, callback)
|
||||||
{
|
{
|
|
@ -27,6 +27,7 @@ var cleanCSS = require('clean-css');
|
||||||
var jsp = require("uglify-js").parser;
|
var jsp = require("uglify-js").parser;
|
||||||
var pro = require("uglify-js").uglify;
|
var pro = require("uglify-js").uglify;
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
var plugins = require("ep_etherpad-lite/static/js/pluginfw/plugins");
|
||||||
var RequireKernel = require('require-kernel');
|
var RequireKernel = require('require-kernel');
|
||||||
var server = require('../server');
|
var server = require('../server');
|
||||||
|
|
||||||
|
@ -35,11 +36,14 @@ var TAR_PATH = path.join(__dirname, 'tar.json');
|
||||||
var tar = JSON.parse(fs.readFileSync(TAR_PATH, 'utf8'));
|
var tar = JSON.parse(fs.readFileSync(TAR_PATH, 'utf8'));
|
||||||
|
|
||||||
// Rewrite tar to include modules with no extensions and proper rooted paths.
|
// Rewrite tar to include modules with no extensions and proper rooted paths.
|
||||||
|
var LIBRARY_PREFIX = 'ep_etherpad-lite/static/js';
|
||||||
exports.tar = {};
|
exports.tar = {};
|
||||||
for (var key in tar) {
|
for (var key in tar) {
|
||||||
exports.tar['/' + key] =
|
exports.tar[LIBRARY_PREFIX + '/' + key] =
|
||||||
tar[key].map(function (p) {return '/' + p}).concat(
|
tar[key].map(function (p) {return LIBRARY_PREFIX + '/' + p}).concat(
|
||||||
tar[key].map(function (p) {return '/' + p.replace(/\.js$/, '')})
|
tar[key].map(function (p) {
|
||||||
|
return LIBRARY_PREFIX + '/' + p.replace(/\.js$/, '')
|
||||||
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +67,22 @@ exports.minify = function(req, res, next)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle static files for plugins:
|
||||||
|
paths like "plugins/ep_myplugin/static/js/test.js"
|
||||||
|
are rewritten into ROOT_PATH_OF_MYPLUGIN/static/js/test.js,
|
||||||
|
commonly ETHERPAD_ROOT/node_modules/ep_myplugin/static/js/test.js
|
||||||
|
*/
|
||||||
|
var match = filename.match(/^plugins\/([^\/]+)\/static\/(.*)/);
|
||||||
|
if (match) {
|
||||||
|
var pluginName = match[1];
|
||||||
|
var resourcePath = match[2];
|
||||||
|
var plugin = plugins.plugins[pluginName];
|
||||||
|
if (plugin) {
|
||||||
|
var pluginPath = plugin.package.realPath;
|
||||||
|
filename = path.relative(ROOT_DIR, pluginPath + '/static/' + resourcePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// What content type should this be?
|
// What content type should this be?
|
||||||
// TODO: This should use a MIME module.
|
// TODO: This should use a MIME module.
|
||||||
var contentType;
|
var contentType;
|
|
@ -0,0 +1,513 @@
|
||||||
|
/**
|
||||||
|
* This Module manages all /minified/* requests. It controls the
|
||||||
|
* minification && compression of Javascript and CSS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS-IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var ERR = require("async-stacktrace");
|
||||||
|
var settings = require('./Settings');
|
||||||
|
var async = require('async');
|
||||||
|
var fs = require('fs');
|
||||||
|
var cleanCSS = require('clean-css');
|
||||||
|
var jsp = require("uglify-js").parser;
|
||||||
|
var pro = require("uglify-js").uglify;
|
||||||
|
var path = require('path');
|
||||||
|
var RequireKernel = require('require-kernel');
|
||||||
|
var server = require('../server');
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
var ROOT_DIR = path.normalize(__dirname + "/../" );
|
||||||
|
var JS_DIR = ROOT_DIR + '../static/js/';
|
||||||
|
var CSS_DIR = ROOT_DIR + '../static/css/';
|
||||||
|
var CACHE_DIR = path.join(settings.root, 'var');
|
||||||
|
=======
|
||||||
|
var ROOT_DIR = path.normalize(__dirname + "/../../static/");
|
||||||
|
>>>>>>> pita
|
||||||
|
var TAR_PATH = path.join(__dirname, 'tar.json');
|
||||||
|
var tar = JSON.parse(fs.readFileSync(TAR_PATH, 'utf8'));
|
||||||
|
|
||||||
|
// Rewrite tar to include modules with no extensions and proper rooted paths.
|
||||||
|
exports.tar = {};
|
||||||
|
for (var key in tar) {
|
||||||
|
exports.tar['/' + key] =
|
||||||
|
tar[key].map(function (p) {return '/' + p}).concat(
|
||||||
|
tar[key].map(function (p) {return '/' + p.replace(/\.js$/, '')})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates the minifed javascript for the given minified name
|
||||||
|
* @param req the Express request
|
||||||
|
* @param res the Express response
|
||||||
|
*/
|
||||||
|
exports.minify = function(req, res, next)
|
||||||
|
{
|
||||||
|
<<<<<<< HEAD
|
||||||
|
var jsFilename = req.params[0];
|
||||||
|
|
||||||
|
//choose the js files we need
|
||||||
|
var jsFiles = undefined;
|
||||||
|
if (Object.prototype.hasOwnProperty.call(tar, jsFilename)) {
|
||||||
|
jsFiles = tar[jsFilename];
|
||||||
|
} else {
|
||||||
|
/* Not in tar list, but try anyways, if it fails, pass to `next`.
|
||||||
|
Actually try, not check in filesystem here because
|
||||||
|
we don't want to duplicate the require.resolve() handling
|
||||||
|
*/
|
||||||
|
jsFiles = [jsFilename];
|
||||||
|
}
|
||||||
|
_handle(req, res, jsFilename, jsFiles, function (err) {
|
||||||
|
console.log("Unable to load minified file " + jsFilename + ": " + err.toString());
|
||||||
|
/* Throw away error and generate a 404, not 500 */
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function _handle(req, res, jsFilename, jsFiles, next) {
|
||||||
|
res.header("Content-Type","text/javascript");
|
||||||
|
|
||||||
|
var cacheName = CACHE_DIR + "/minified_" + jsFilename.replace(/\//g, "_");
|
||||||
|
|
||||||
|
//minifying is enabled
|
||||||
|
if(settings.minify)
|
||||||
|
{
|
||||||
|
var result = undefined;
|
||||||
|
var latestModification = 0;
|
||||||
|
|
||||||
|
async.series([
|
||||||
|
//find out the highest modification date
|
||||||
|
function(callback)
|
||||||
|
{
|
||||||
|
var folders2check = [CSS_DIR, JS_DIR];
|
||||||
|
|
||||||
|
//go trough this two folders
|
||||||
|
async.forEach(folders2check, function(path, callback)
|
||||||
|
{
|
||||||
|
//read the files in the folder
|
||||||
|
fs.readdir(path, function(err, files)
|
||||||
|
{
|
||||||
|
if(ERR(err, callback)) return;
|
||||||
|
|
||||||
|
//we wanna check the directory itself for changes too
|
||||||
|
files.push(".");
|
||||||
|
|
||||||
|
//go trough all files in this folder
|
||||||
|
async.forEach(files, function(filename, callback)
|
||||||
|
{
|
||||||
|
//get the stat data of this file
|
||||||
|
fs.stat(path + "/" + filename, function(err, stats)
|
||||||
|
{
|
||||||
|
if(ERR(err, callback)) return;
|
||||||
|
|
||||||
|
//get the modification time
|
||||||
|
var modificationTime = stats.mtime.getTime();
|
||||||
|
|
||||||
|
//compare the modification time to the highest found
|
||||||
|
if(modificationTime > latestModification)
|
||||||
|
{
|
||||||
|
latestModification = modificationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}, callback);
|
||||||
|
});
|
||||||
|
}, callback);
|
||||||
|
},
|
||||||
|
function(callback)
|
||||||
|
{
|
||||||
|
//check the modification time of the minified js
|
||||||
|
fs.stat(cacheName, function(err, stats)
|
||||||
|
{
|
||||||
|
if(err && err.code != "ENOENT")
|
||||||
|
{
|
||||||
|
ERR(err, callback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//there is no minfied file or there new changes since this file was generated, so continue generating this file
|
||||||
|
if((err && err.code == "ENOENT") || stats.mtime.getTime() < latestModification)
|
||||||
|
{
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
//the minified file is still up to date, stop minifying
|
||||||
|
else
|
||||||
|
{
|
||||||
|
callback("stop");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//load all js files
|
||||||
|
function (callback)
|
||||||
|
{
|
||||||
|
var values = [];
|
||||||
|
tarCode(
|
||||||
|
jsFiles
|
||||||
|
, function (content) {values.push(content)}
|
||||||
|
, function (err) {
|
||||||
|
if(ERR(err, next)) return;
|
||||||
|
|
||||||
|
result = values.join('');
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//put all together and write it into a file
|
||||||
|
function(callback)
|
||||||
|
{
|
||||||
|
async.parallel([
|
||||||
|
//write the results plain in a file
|
||||||
|
function(callback)
|
||||||
|
{
|
||||||
|
fs.writeFile(cacheName, result, "utf8", callback);
|
||||||
|
},
|
||||||
|
//write the results compressed in a file
|
||||||
|
function(callback)
|
||||||
|
{
|
||||||
|
zlib.gzip(result, function(err, compressedResult){
|
||||||
|
//weird gzip bug that returns 0 instead of null if everything is ok
|
||||||
|
err = err === 0 ? null : err;
|
||||||
|
|
||||||
|
if(ERR(err, callback)) return;
|
||||||
|
|
||||||
|
fs.writeFile(cacheName + ".gz", compressedResult, callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
],callback);
|
||||||
|
}
|
||||||
|
], function(err)
|
||||||
|
{
|
||||||
|
if(err && err != "stop")
|
||||||
|
{
|
||||||
|
if(ERR(err)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check if gzip is supported by this browser
|
||||||
|
var gzipSupport = req.header('Accept-Encoding', '').indexOf('gzip') != -1;
|
||||||
|
|
||||||
|
var pathStr;
|
||||||
|
if(gzipSupport && os.type().indexOf("Windows") == -1)
|
||||||
|
{
|
||||||
|
pathStr = path.normalize(cacheName + ".gz");
|
||||||
|
res.header('Content-Encoding', 'gzip');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pathStr = path.normalize(cacheName);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.sendfile(pathStr, { maxAge: server.maxAge });
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//minifying is disabled, so put the files together in one file
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tarCode(
|
||||||
|
jsFiles
|
||||||
|
, function (content) {res.write(content)}
|
||||||
|
, function (err) {
|
||||||
|
if(ERR(err, next)) return;
|
||||||
|
=======
|
||||||
|
var filename = req.params['filename'];
|
||||||
|
|
||||||
|
// No relative paths, especially if they may go up the file hierarchy.
|
||||||
|
filename = path.normalize(path.join(ROOT_DIR, filename));
|
||||||
|
if (filename.indexOf(ROOT_DIR) == 0) {
|
||||||
|
filename = filename.slice(ROOT_DIR.length);
|
||||||
|
filename = filename.replace(/\\/g, '/'); // Windows (safe generally?)
|
||||||
|
} else {
|
||||||
|
res.writeHead(404, {});
|
||||||
|
res.end();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// What content type should this be?
|
||||||
|
// TODO: This should use a MIME module.
|
||||||
|
var contentType;
|
||||||
|
if (filename.match(/\.js$/)) {
|
||||||
|
contentType = "text/javascript";
|
||||||
|
} else if (filename.match(/\.css$/)) {
|
||||||
|
contentType = "text/css";
|
||||||
|
} else if (filename.match(/\.html$/)) {
|
||||||
|
contentType = "text/html";
|
||||||
|
} else if (filename.match(/\.txt$/)) {
|
||||||
|
contentType = "text/plain";
|
||||||
|
} else if (filename.match(/\.png$/)) {
|
||||||
|
contentType = "image/png";
|
||||||
|
} else if (filename.match(/\.gif$/)) {
|
||||||
|
contentType = "image/gif";
|
||||||
|
} else if (filename.match(/\.ico$/)) {
|
||||||
|
contentType = "image/x-icon";
|
||||||
|
} else {
|
||||||
|
contentType = "application/octet-stream";
|
||||||
|
}
|
||||||
|
|
||||||
|
statFile(filename, function (error, date, exists) {
|
||||||
|
if (date) {
|
||||||
|
date = new Date(date);
|
||||||
|
res.setHeader('last-modified', date.toUTCString());
|
||||||
|
res.setHeader('date', (new Date()).toUTCString());
|
||||||
|
if (server.maxAge) {
|
||||||
|
var expiresDate = new Date((new Date()).getTime()+server.maxAge*1000);
|
||||||
|
res.setHeader('expires', expiresDate.toUTCString());
|
||||||
|
res.setHeader('cache-control', 'max-age=' + server.maxAge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
res.writeHead(500, {});
|
||||||
|
>>>>>>> pita
|
||||||
|
res.end();
|
||||||
|
} else if (!exists) {
|
||||||
|
res.writeHead(404, {});
|
||||||
|
res.end();
|
||||||
|
} else if (new Date(req.headers['if-modified-since']) >= date) {
|
||||||
|
res.writeHead(304, {});
|
||||||
|
res.end();
|
||||||
|
} else {
|
||||||
|
if (req.method == 'HEAD') {
|
||||||
|
res.header("Content-Type", contentType);
|
||||||
|
res.writeHead(200, {});
|
||||||
|
res.end();
|
||||||
|
} else if (req.method == 'GET') {
|
||||||
|
getFileCompressed(filename, contentType, function (error, content) {
|
||||||
|
if(ERR(error)) return;
|
||||||
|
res.header("Content-Type", contentType);
|
||||||
|
res.writeHead(200, {});
|
||||||
|
res.write(content);
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.writeHead(405, {'allow': 'HEAD, GET'});
|
||||||
|
res.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// find all includes in ace.js and embed them.
|
||||||
|
function getAceFile(callback) {
|
||||||
|
fs.readFile(ROOT_DIR + 'js/ace.js', "utf8", function(err, data) {
|
||||||
|
if(ERR(err, callback)) return;
|
||||||
|
|
||||||
|
// Find all includes in ace.js and embed them
|
||||||
|
var founds = data.match(/\$\$INCLUDE_[a-zA-Z_]+\("[^"]*"\)/gi);
|
||||||
|
if (!settings.minify) {
|
||||||
|
founds = [];
|
||||||
|
}
|
||||||
|
// Always include the require kernel.
|
||||||
|
founds.push('$$INCLUDE_JS("../static/js/require-kernel.js")');
|
||||||
|
|
||||||
|
data += ';\n';
|
||||||
|
data += 'Ace2Editor.EMBEDED = Ace2Editor.EMBEDED || {};\n';
|
||||||
|
|
||||||
|
// Request the contents of the included file on the server-side and write
|
||||||
|
// them into the file.
|
||||||
|
async.forEach(founds, function (item, callback) {
|
||||||
|
var filename = item.match(/"([^"]*)"/)[1];
|
||||||
|
var request = require('request');
|
||||||
|
|
||||||
|
var baseURI = 'http://localhost:' + settings.port
|
||||||
|
|
||||||
|
request(baseURI + path.normalize(path.join('/static/', filename)), function (error, response, body) {
|
||||||
|
if (!error && response.statusCode == 200) {
|
||||||
|
data += 'Ace2Editor.EMBEDED[' + JSON.stringify(filename) + '] = '
|
||||||
|
+ JSON.stringify(body || '') + ';\n';
|
||||||
|
} else {
|
||||||
|
// Silence?
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}, function(error) {
|
||||||
|
callback(error, data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for the existance of the file and get the last modification date.
|
||||||
|
function statFile(filename, callback) {
|
||||||
|
if (filename == 'js/ace.js') {
|
||||||
|
// Sometimes static assets are inlined into this file, so we have to stat
|
||||||
|
// everything.
|
||||||
|
lastModifiedDateOfEverything(function (error, date) {
|
||||||
|
callback(error, date, !error);
|
||||||
|
});
|
||||||
|
} else if (filename == 'js/require-kernel.js') {
|
||||||
|
callback(null, requireLastModified(), true);
|
||||||
|
} else {
|
||||||
|
fs.stat(ROOT_DIR + filename, function (error, stats) {
|
||||||
|
if (error) {
|
||||||
|
if (error.code == "ENOENT") {
|
||||||
|
// Stat the directory instead.
|
||||||
|
fs.stat(path.dirname(ROOT_DIR + filename), function (error, stats) {
|
||||||
|
if (error) {
|
||||||
|
if (error.code == "ENOENT") {
|
||||||
|
callback(null, null, false);
|
||||||
|
} else {
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(null, stats.mtime.getTime(), false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(null, stats.mtime.getTime(), true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function lastModifiedDateOfEverything(callback) {
|
||||||
|
var folders2check = [ROOT_DIR + 'js/', ROOT_DIR + 'css/'];
|
||||||
|
var latestModification = 0;
|
||||||
|
//go trough this two folders
|
||||||
|
async.forEach(folders2check, function(path, callback)
|
||||||
|
{
|
||||||
|
//read the files in the folder
|
||||||
|
fs.readdir(path, function(err, files)
|
||||||
|
{
|
||||||
|
if(ERR(err, callback)) return;
|
||||||
|
|
||||||
|
//we wanna check the directory itself for changes too
|
||||||
|
files.push(".");
|
||||||
|
|
||||||
|
//go trough all files in this folder
|
||||||
|
async.forEach(files, function(filename, callback)
|
||||||
|
{
|
||||||
|
//get the stat data of this file
|
||||||
|
fs.stat(path + "/" + filename, function(err, stats)
|
||||||
|
{
|
||||||
|
if(ERR(err, callback)) return;
|
||||||
|
|
||||||
|
//get the modification time
|
||||||
|
var modificationTime = stats.mtime.getTime();
|
||||||
|
|
||||||
|
//compare the modification time to the highest found
|
||||||
|
if(modificationTime > latestModification)
|
||||||
|
{
|
||||||
|
latestModification = modificationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}, callback);
|
||||||
|
});
|
||||||
|
}, function () {
|
||||||
|
callback(null, latestModification);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should be provided by the module, but until then, just use startup
|
||||||
|
// time.
|
||||||
|
var _requireLastModified = new Date();
|
||||||
|
function requireLastModified() {
|
||||||
|
return _requireLastModified.toUTCString();
|
||||||
|
}
|
||||||
|
function requireDefinition() {
|
||||||
|
return 'var require = ' + RequireKernel.kernelSource + ';\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
function tarCode(jsFiles, write, callback) {
|
||||||
|
write('require.define({');
|
||||||
|
var initialEntry = true;
|
||||||
|
async.forEach(jsFiles, function (filename, callback){
|
||||||
|
var path;
|
||||||
|
var srcPath;
|
||||||
|
if (filename.indexOf('plugins/') == 0) {
|
||||||
|
srcPath = filename.substring('plugins/'.length);
|
||||||
|
path = require.resolve(srcPath);
|
||||||
|
} else {
|
||||||
|
srcPath = '/' + filename;
|
||||||
|
path = JS_DIR + filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
srcPath = JSON.stringify(srcPath);
|
||||||
|
var srcPathAbbv = JSON.stringify(srcPath.replace(/\.js$/, ''));
|
||||||
|
|
||||||
|
if (filename == 'ace.js') {
|
||||||
|
getAceFile(handleFile);
|
||||||
|
} else {
|
||||||
|
fs.readFile(path, "utf8", handleFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleFile(err, data) {
|
||||||
|
if(ERR(err, callback)) return;
|
||||||
|
|
||||||
|
if (!initialEntry) {
|
||||||
|
write('\n,');
|
||||||
|
} else {
|
||||||
|
initialEntry = false;
|
||||||
|
}
|
||||||
|
write(srcPath + ': ')
|
||||||
|
data = '(function (require, exports, module) {' + data + '})';
|
||||||
|
=======
|
||||||
|
function getFileCompressed(filename, contentType, callback) {
|
||||||
|
getFile(filename, function (error, content) {
|
||||||
|
if (error || !content) {
|
||||||
|
callback(error, content);
|
||||||
|
} else {
|
||||||
|
>>>>>>> pita
|
||||||
|
if (settings.minify) {
|
||||||
|
if (contentType == 'text/javascript') {
|
||||||
|
try {
|
||||||
|
content = compressJS([content]);
|
||||||
|
} catch (error) {
|
||||||
|
// silence
|
||||||
|
}
|
||||||
|
} else if (contentType == 'text/css') {
|
||||||
|
content = compressCSS([content]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback(null, content);
|
||||||
|
}
|
||||||
|
<<<<<<< HEAD
|
||||||
|
}, function (err) {
|
||||||
|
if(ERR(err, callback)) return;
|
||||||
|
write('});\n');
|
||||||
|
callback();
|
||||||
|
=======
|
||||||
|
>>>>>>> pita
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFile(filename, callback) {
|
||||||
|
if (filename == 'js/ace.js') {
|
||||||
|
getAceFile(callback);
|
||||||
|
} else if (filename == 'js/require-kernel.js') {
|
||||||
|
callback(undefined, requireDefinition());
|
||||||
|
} else {
|
||||||
|
fs.readFile(ROOT_DIR + filename, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function compressJS(values)
|
||||||
|
{
|
||||||
|
var complete = values.join("\n");
|
||||||
|
var ast = jsp.parse(complete); // 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)
|
||||||
|
{
|
||||||
|
var complete = values.join("\n");
|
||||||
|
return cleanCSS.process(complete);
|
||||||
|
}
|
|
@ -23,6 +23,10 @@ var fs = require("fs");
|
||||||
var os = require("os");
|
var os = require("os");
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var argv = require('./Cli').argv;
|
var argv = require('./Cli').argv;
|
||||||
|
var npm = require("npm/lib/npm.js");
|
||||||
|
|
||||||
|
/* Root path of the installation */
|
||||||
|
exports.root = path.normalize(path.join(npm.dir, ".."));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The IP ep-lite should listen to
|
* The IP ep-lite should listen to
|
||||||
|
@ -40,7 +44,7 @@ exports.dbType = "dirty";
|
||||||
/**
|
/**
|
||||||
* This setting is passed with dbType to ueberDB to set up the database
|
* This setting is passed with dbType to ueberDB to set up the database
|
||||||
*/
|
*/
|
||||||
exports.dbSettings = { "filename" : "../var/dirty.db" };
|
exports.dbSettings = { "filename" : path.join(exports.root, "var/dirty.db") };
|
||||||
/**
|
/**
|
||||||
* The default Text of a new pad
|
* The default Text of a new pad
|
||||||
*/
|
*/
|
||||||
|
@ -96,10 +100,12 @@ exports.abiwordAvailable = function()
|
||||||
|
|
||||||
// Discover where the settings file lives
|
// Discover where the settings file lives
|
||||||
var settingsFilename = argv.settings || "settings.json";
|
var settingsFilename = argv.settings || "settings.json";
|
||||||
var settingsPath = settingsFilename.charAt(0) == '/' ? '' : path.normalize(__dirname + "/../../");
|
if (settingsFilename.charAt(0) != '/') {
|
||||||
|
settingsFilename = path.normalize(path.join(root, settingsFilename));
|
||||||
|
}
|
||||||
|
|
||||||
//read the settings sync
|
//read the settings sync
|
||||||
var settingsStr = fs.readFileSync(settingsPath + settingsFilename).toString();
|
var settingsStr = fs.readFileSync(settingsFilename).toString();
|
||||||
|
|
||||||
//remove all comments
|
//remove all comments
|
||||||
settingsStr = settingsStr.replace(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/gm,"").replace(/#.*/g,"").replace(/\/\/.*/g,"");
|
settingsStr = settingsStr.replace(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/gm,"").replace(/#.*/g,"").replace(/\/\/.*/g,"");
|
|
@ -23,7 +23,9 @@ var zlib = require('zlib');
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
|
|
||||||
var ROOT_DIR = path.normalize(__dirname + "/../");
|
var ROOT_DIR = path.normalize(__dirname + "/../");
|
||||||
var CACHE_DIR = ROOT_DIR + '../var/';
|
var CACHE_DIR = path.normalize(ROOT_DIR + '../../var/');
|
||||||
|
console.log(CACHE_DIR)
|
||||||
|
CACHE_DIR = path.existsSync(CACHE_DIR) ? CACHE_DIR : undefined;
|
||||||
|
|
||||||
var responseCache = {};
|
var responseCache = {};
|
||||||
|
|
||||||
|
@ -37,7 +39,7 @@ function CachingMiddleware() {
|
||||||
}
|
}
|
||||||
CachingMiddleware.prototype = new function () {
|
CachingMiddleware.prototype = new function () {
|
||||||
function handle(req, res, next) {
|
function handle(req, res, next) {
|
||||||
if (!(req.method == "GET" || req.method == "HEAD")) {
|
if (!(req.method == "GET" || req.method == "HEAD") || !CACHE_DIR) {
|
||||||
return next(undefined, req, res);
|
return next(undefined, req, res);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
, "pad.js"
|
, "pad.js"
|
||||||
, "ace2_common.js"
|
, "ace2_common.js"
|
||||||
, "pad_utils.js"
|
, "pad_utils.js"
|
||||||
, "plugins.js"
|
|
||||||
, "undo-xpopup.js"
|
, "undo-xpopup.js"
|
||||||
, "json2.js"
|
, "json2.js"
|
||||||
, "pad_cookie.js"
|
, "pad_cookie.js"
|
||||||
|
@ -27,7 +26,6 @@
|
||||||
, "timeslider.js": [
|
, "timeslider.js": [
|
||||||
"jquery.js"
|
"jquery.js"
|
||||||
, "security.js"
|
, "security.js"
|
||||||
, "plugins.js"
|
|
||||||
, "undo-xpopup.js"
|
, "undo-xpopup.js"
|
||||||
, "json2.js"
|
, "json2.js"
|
||||||
, "colorutils.js"
|
, "colorutils.js"
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name" : "etherpad-lite",
|
"name" : "ep_etherpad-lite",
|
||||||
"description" : "A Etherpad based on node.js",
|
"description" : "A Etherpad based on node.js",
|
||||||
"homepage" : "https://github.com/Pita/etherpad-lite",
|
"homepage" : "https://github.com/Pita/etherpad-lite",
|
||||||
"keywords" : ["etherpad", "realtime", "collaborative", "editor"],
|
"keywords" : ["etherpad", "realtime", "collaborative", "editor"],
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
"dependencies" : {
|
"dependencies" : {
|
||||||
"yajsml" : "1.1.2",
|
"yajsml" : "1.1.2",
|
||||||
"request" : "2.9.100",
|
"request" : "2.9.100",
|
||||||
"require-kernel" : "1.0.3",
|
"require-kernel" : "1.0.5",
|
||||||
"socket.io" : "0.8.7",
|
"socket.io" : "0.8.7",
|
||||||
"ueberDB" : "0.1.7",
|
"ueberDB" : "0.1.7",
|
||||||
"async" : "0.1.18",
|
"async" : "0.1.18",
|
||||||
|
@ -22,7 +22,8 @@
|
||||||
"formidable" : "1.0.9",
|
"formidable" : "1.0.9",
|
||||||
"log4js" : "0.4.1",
|
"log4js" : "0.4.1",
|
||||||
"jsdom-nocontextifiy" : "0.2.10",
|
"jsdom-nocontextifiy" : "0.2.10",
|
||||||
"async-stacktrace" : "0.0.2"
|
"async-stacktrace" : "0.0.2",
|
||||||
|
"npm" : "1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"jshint" : "*"
|
"jshint" : "*"
|
|
@ -0,0 +1,3 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
||||||
|
!*.template
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 697 B After Width: | Height: | Size: 697 B |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 1009 B After Width: | Height: | Size: 1009 B |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 494 B After Width: | Height: | Size: 494 B |
Before Width: | Height: | Size: 658 B After Width: | Height: | Size: 658 B |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 123 B After Width: | Height: | Size: 123 B |
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 131 B |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 182 B After Width: | Height: | Size: 182 B |
Before Width: | Height: | Size: 686 B After Width: | Height: | Size: 686 B |
Before Width: | Height: | Size: 517 B After Width: | Height: | Size: 517 B |
|
@ -25,7 +25,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var AttributePoolFactory = require("/AttributePoolFactory");
|
var AttributePoolFactory = require("./AttributePoolFactory");
|
||||||
|
|
||||||
var _opt = null;
|
var _opt = null;
|
||||||
|
|
|
@ -28,7 +28,7 @@ Ace2Editor.registry = {
|
||||||
nextId: 1
|
nextId: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
var plugins = require('/plugins').plugins;
|
var hooks = require('./pluginfw/hooks');
|
||||||
|
|
||||||
function Ace2Editor()
|
function Ace2Editor()
|
||||||
{
|
{
|
||||||
|
@ -156,7 +156,11 @@ function Ace2Editor()
|
||||||
}
|
}
|
||||||
function pushRequireScriptTo(buffer) {
|
function pushRequireScriptTo(buffer) {
|
||||||
var KERNEL_SOURCE = '../static/js/require-kernel.js';
|
var KERNEL_SOURCE = '../static/js/require-kernel.js';
|
||||||
var KERNEL_BOOT = 'require.setRootURI("../minified/");\nrequire.setGlobalKeyPath("require");'
|
var KERNEL_BOOT = '\
|
||||||
|
require.setRootURI("../javascripts/src");\n\
|
||||||
|
require.setLibraryURI("../javascripts/lib");\n\
|
||||||
|
require.setGlobalKeyPath("require");\n\
|
||||||
|
';
|
||||||
if (Ace2Editor.EMBEDED && Ace2Editor.EMBEDED[KERNEL_SOURCE]) {
|
if (Ace2Editor.EMBEDED && Ace2Editor.EMBEDED[KERNEL_SOURCE]) {
|
||||||
buffer.push('<script type="text/javascript">');
|
buffer.push('<script type="text/javascript">');
|
||||||
buffer.push(Ace2Editor.EMBEDED[KERNEL_SOURCE]);
|
buffer.push(Ace2Editor.EMBEDED[KERNEL_SOURCE]);
|
||||||
|
@ -166,17 +170,18 @@ function Ace2Editor()
|
||||||
}
|
}
|
||||||
function pushScriptsTo(buffer) {
|
function pushScriptsTo(buffer) {
|
||||||
/* Folling is for packaging regular expression. */
|
/* Folling is for packaging regular expression. */
|
||||||
/* $$INCLUDE_JS("../minified/ace2_inner.js?callback=require.define"); */
|
/* $$INCLUDE_JS("../javascripts/src/ace2_inner.js?callback=require.define"); */
|
||||||
var ACE_SOURCE = '../minified/ace2_inner.js?callback=require.define';
|
var ACE_SOURCE = '../javascripts/src/ace2_inner.js?callback=require.define';
|
||||||
if (Ace2Editor.EMBEDED && Ace2Editor.EMBEDED[ACE_SOURCE]) {
|
if (Ace2Editor.EMBEDED && Ace2Editor.EMBEDED[ACE_SOURCE]) {
|
||||||
buffer.push('<script type="text/javascript">');
|
buffer.push('<script type="text/javascript">');
|
||||||
buffer.push(Ace2Editor.EMBEDED[ACE_SOURCE]);
|
buffer.push(Ace2Editor.EMBEDED[ACE_SOURCE]);
|
||||||
buffer.push('require("/ace2_inner");');
|
buffer.push('require("ep_etherpad-lite/static/js/ace2_inner");');
|
||||||
buffer.push('<\/script>');
|
buffer.push('<\/script>');
|
||||||
} else {
|
} else {
|
||||||
|
file = ACE_SOURCE;
|
||||||
buffer.push('<script type="application/javascript" src="' + ACE_SOURCE + '"><\/script>');
|
buffer.push('<script type="application/javascript" src="' + ACE_SOURCE + '"><\/script>');
|
||||||
buffer.push('<script type="text/javascript">');
|
buffer.push('<script type="text/javascript">');
|
||||||
buffer.push('require("/ace2_inner");');
|
buffer.push('require("ep_etherpad-lite/static/js/ace2_inner");');
|
||||||
buffer.push('<\/script>');
|
buffer.push('<\/script>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +237,7 @@ function Ace2Editor()
|
||||||
for (var i = 0, ii = iframeHTML.length; i < ii; i++) {
|
for (var i = 0, ii = iframeHTML.length; i < ii; i++) {
|
||||||
iframeHTML[i] = JSON.stringify(iframeHTML[i]);
|
iframeHTML[i] = JSON.stringify(iframeHTML[i]);
|
||||||
}
|
}
|
||||||
plugins.callHook("aceInitInnerdocbodyHead", {
|
hooks.callAll("aceInitInnerdocbodyHead", {
|
||||||
iframeHTML: iframeHTML
|
iframeHTML: iframeHTML
|
||||||
});
|
});
|
||||||
for (var i = 0, ii = iframeHTML.length; i < ii; i++) {
|
for (var i = 0, ii = iframeHTML.length; i < ii; i++) {
|
||||||
|
@ -258,7 +263,7 @@ function Ace2Editor()
|
||||||
<script type="text/javascript">\
|
<script type="text/javascript">\
|
||||||
require.define("/plugins", null);\n\
|
require.define("/plugins", null);\n\
|
||||||
require.define("/plugins.js", function (require, exports, module) {\
|
require.define("/plugins.js", function (require, exports, module) {\
|
||||||
module.exports = parent.parent.require("/plugins");\
|
module.exports = require("ep_etherpad-lite/static/js/plugins");\
|
||||||
});\
|
});\
|
||||||
</script>\
|
</script>\
|
||||||
');
|
');
|
||||||
|
@ -271,7 +276,7 @@ function Ace2Editor()
|
||||||
var thisFunctionsName = "ChildAccessibleAce2Editor";
|
var thisFunctionsName = "ChildAccessibleAce2Editor";
|
||||||
(function () {return this}())[thisFunctionsName] = Ace2Editor;
|
(function () {return this}())[thisFunctionsName] = Ace2Editor;
|
||||||
|
|
||||||
var outerScript = 'editorId = "' + info.id + '"; editorInfo = parent.' + thisFunctionsName + '.registry[editorId]; ' + 'window.onload = function() ' + '{ window.onload = null; setTimeout' + '(function() ' + '{ var iframe = document.createElement("IFRAME"); ' + 'iframe.scrolling = "no"; var outerdocbody = document.getElementById("outerdocbody"); ' + 'iframe.frameBorder = 0; iframe.allowTransparency = true; ' + // for IE
|
var outerScript = 'editorId = "' + info.id + '"; editorInfo = parent.' + thisFunctionsName + '.registry[editorId]; ' + 'window.onload = function() ' + '{ window.onload = null; setTimeout' + '(function() ' + '{ var iframe = document.createElement("IFRAME"); iframe.name = "ace_inner";' + 'iframe.scrolling = "no"; var outerdocbody = document.getElementById("outerdocbody"); ' + 'iframe.frameBorder = 0; iframe.allowTransparency = true; ' + // for IE
|
||||||
'outerdocbody.insertBefore(iframe, outerdocbody.firstChild); ' + 'iframe.ace_outerWin = window; ' + 'readyFunc = function() { editorInfo.onEditorReady(); readyFunc = null; editorInfo = null; }; ' + 'var doc = iframe.contentWindow.document; doc.open(); var text = (' + JSON.stringify(iframeHTML.join('\n')) + ');doc.write(text); doc.close(); ' + '}, 0); }';
|
'outerdocbody.insertBefore(iframe, outerdocbody.firstChild); ' + 'iframe.ace_outerWin = window; ' + 'readyFunc = function() { editorInfo.onEditorReady(); readyFunc = null; editorInfo = null; }; ' + 'var doc = iframe.contentWindow.document; doc.open(); var text = (' + JSON.stringify(iframeHTML.join('\n')) + ');doc.write(text); doc.close(); ' + '}, 0); }';
|
||||||
|
|
||||||
var outerHTML = [doctype, '<html><head>']
|
var outerHTML = [doctype, '<html><head>']
|
||||||
|
@ -288,6 +293,7 @@ function Ace2Editor()
|
||||||
outerHTML.push('<link rel="stylesheet" type="text/css" href="data:text/css,"/>', '\x3cscript>\n', outerScript.replace(/<\//g, '<\\/'), '\n\x3c/script>', '</head><body id="outerdocbody"><div id="sidediv"><!-- --></div><div id="linemetricsdiv">x</div><div id="overlaysdiv"><!-- --></div></body></html>');
|
outerHTML.push('<link rel="stylesheet" type="text/css" href="data:text/css,"/>', '\x3cscript>\n', outerScript.replace(/<\//g, '<\\/'), '\n\x3c/script>', '</head><body id="outerdocbody"><div id="sidediv"><!-- --></div><div id="linemetricsdiv">x</div><div id="overlaysdiv"><!-- --></div></body></html>');
|
||||||
|
|
||||||
var outerFrame = document.createElement("IFRAME");
|
var outerFrame = document.createElement("IFRAME");
|
||||||
|
outerFrame.name = "ace_outer";
|
||||||
outerFrame.frameBorder = 0; // for IE
|
outerFrame.frameBorder = 0; // for IE
|
||||||
info.frame = outerFrame;
|
info.frame = outerFrame;
|
||||||
document.getElementById(containerId).appendChild(outerFrame);
|
document.getElementById(containerId).appendChild(outerFrame);
|
|
@ -20,7 +20,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var Security = require('/security');
|
var Security = require('./security');
|
||||||
|
|
||||||
function isNodeText(node)
|
function isNodeText(node)
|
||||||
{
|
{
|
|
@ -20,7 +20,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var Ace2Common = require('/ace2_common');
|
var Ace2Common = require('./ace2_common');
|
||||||
|
|
||||||
// Extract useful method defined in the other module.
|
// Extract useful method defined in the other module.
|
||||||
var isNodeText = Ace2Common.isNodeText;
|
var isNodeText = Ace2Common.isNodeText;
|
||||||
|
@ -38,18 +38,17 @@ var htmlPrettyEscape = Ace2Common.htmlPrettyEscape;
|
||||||
var map = Ace2Common.map;
|
var map = Ace2Common.map;
|
||||||
var noop = Ace2Common.noop;
|
var noop = Ace2Common.noop;
|
||||||
|
|
||||||
var makeChangesetTracker = require('/changesettracker').makeChangesetTracker;
|
var makeChangesetTracker = require('./changesettracker').makeChangesetTracker;
|
||||||
var colorutils = require('/colorutils').colorutils;
|
var colorutils = require('./colorutils').colorutils;
|
||||||
var makeContentCollector = require('/contentcollector').makeContentCollector;
|
var makeContentCollector = require('./contentcollector').makeContentCollector;
|
||||||
var makeCSSManager = require('/cssmanager').makeCSSManager;
|
var makeCSSManager = require('./cssmanager').makeCSSManager;
|
||||||
var domline = require('/domline').domline;
|
var domline = require('./domline').domline;
|
||||||
var AttribPool = require('/AttributePoolFactory').createAttributePool;
|
var AttribPool = require('./AttributePoolFactory').createAttributePool;
|
||||||
var Changeset = require('/Changeset');
|
var Changeset = require('./Changeset');
|
||||||
var linestylefilter = require('/linestylefilter').linestylefilter;
|
var linestylefilter = require('./linestylefilter').linestylefilter;
|
||||||
var newSkipList = require('/skiplist').newSkipList;
|
var newSkipList = require('./skiplist').newSkipList;
|
||||||
var undoModule = require('/undomodule').undoModule;
|
var undoModule = require('./undomodule').undoModule;
|
||||||
var makeVirtualLineView = require('/virtual_lines').makeVirtualLineView;
|
var makeVirtualLineView = require('./virtual_lines').makeVirtualLineView;
|
||||||
|
|
||||||
|
|
||||||
function Ace2Inner(){
|
function Ace2Inner(){
|
||||||
var DEBUG = false; //$$ build script replaces the string "var DEBUG=true;//$$" with "var DEBUG=false;"
|
var DEBUG = false; //$$ build script replaces the string "var DEBUG=true;//$$" with "var DEBUG=false;"
|
|
@ -20,12 +20,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var makeCSSManager = require('/cssmanager').makeCSSManager;
|
var makeCSSManager = require('./cssmanager').makeCSSManager;
|
||||||
var domline = require('/domline').domline;
|
var domline = require('./domline').domline;
|
||||||
var AttribPool = require('/AttributePoolFactory').createAttributePool;
|
var AttribPool = require('./AttributePoolFactory').createAttributePool;
|
||||||
var Changeset = require('/Changeset');
|
var Changeset = require('./Changeset');
|
||||||
var linestylefilter = require('/linestylefilter').linestylefilter;
|
var linestylefilter = require('./linestylefilter').linestylefilter;
|
||||||
var colorutils = require('/colorutils').colorutils;
|
var colorutils = require('./colorutils').colorutils;
|
||||||
var Ace2Common = require('./ace2_common');
|
var Ace2Common = require('./ace2_common');
|
||||||
|
|
||||||
var map = Ace2Common.map;
|
var map = Ace2Common.map;
|
|
@ -20,8 +20,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var AttribPool = require('/AttributePoolFactory').createAttributePool;
|
var AttribPool = require('./AttributePoolFactory').createAttributePool;
|
||||||
var Changeset = require('/Changeset');
|
var Changeset = require('./Changeset');
|
||||||
|
|
||||||
function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
|
function makeChangesetTracker(scheduler, apool, aceCallbacksProvider)
|
||||||
{
|
{
|
|
@ -20,8 +20,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var padutils = require('/pad_utils').padutils;
|
var padutils = require('./pad_utils').padutils;
|
||||||
var padcookie = require('/pad_cookie').padcookie;
|
var padcookie = require('./pad_cookie').padcookie;
|
||||||
|
|
||||||
var chat = (function()
|
var chat = (function()
|
||||||
{
|
{
|
|
@ -20,7 +20,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var chat = require('/chat').chat;
|
var chat = require('./chat').chat;
|
||||||
|
|
||||||
// Dependency fill on init. This exists for `pad.socket` only.
|
// Dependency fill on init. This exists for `pad.socket` only.
|
||||||
// TODO: bind directly to the socket.
|
// TODO: bind directly to the socket.
|
|
@ -25,8 +25,8 @@
|
||||||
|
|
||||||
var _MAX_LIST_LEVEL = 8;
|
var _MAX_LIST_LEVEL = 8;
|
||||||
|
|
||||||
var Changeset = require('/Changeset');
|
var Changeset = require('./Changeset');
|
||||||
var plugins = require('/plugins').plugins;
|
var hooks = require('./pluginfw/hooks');
|
||||||
|
|
||||||
function sanitizeUnicode(s)
|
function sanitizeUnicode(s)
|
||||||
{
|
{
|
||||||
|
@ -37,8 +37,6 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class
|
||||||
{
|
{
|
||||||
browser = browser || {};
|
browser = browser || {};
|
||||||
|
|
||||||
var plugins_ = plugins;
|
|
||||||
|
|
||||||
var dom = domInterface || {
|
var dom = domInterface || {
|
||||||
isNodeText: function(n)
|
isNodeText: function(n)
|
||||||
{
|
{
|
||||||
|
@ -448,7 +446,7 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class
|
||||||
var oldAuthorOrNull = null;
|
var oldAuthorOrNull = null;
|
||||||
if (collectStyles)
|
if (collectStyles)
|
||||||
{
|
{
|
||||||
plugins_.callHook('collectContentPre', {
|
hooks.callAll('collectContentPre', {
|
||||||
cc: cc,
|
cc: cc,
|
||||||
state: state,
|
state: state,
|
||||||
tname: tname,
|
tname: tname,
|
||||||
|
@ -510,7 +508,7 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class
|
||||||
|
|
||||||
if (collectStyles)
|
if (collectStyles)
|
||||||
{
|
{
|
||||||
plugins_.callHook('collectContentPost', {
|
hooks.callAll('collectContentPost', {
|
||||||
cc: cc,
|
cc: cc,
|
||||||
state: state,
|
state: state,
|
||||||
tname: tname,
|
tname: tname,
|
|
@ -26,9 +26,9 @@
|
||||||
// requires: plugins
|
// requires: plugins
|
||||||
// requires: undefined
|
// requires: undefined
|
||||||
|
|
||||||
var Security = require('/security');
|
var Security = require('./security');
|
||||||
var Ace2Common = require('/ace2_common');
|
var hooks = require('./pluginfw/hooks');
|
||||||
var plugins = require('/plugins').plugins;
|
var Ace2Common = require('./ace2_common');
|
||||||
var map = Ace2Common.map;
|
var map = Ace2Common.map;
|
||||||
var noop = Ace2Common.noop;
|
var noop = Ace2Common.noop;
|
||||||
var identity = Ace2Common.identity;
|
var identity = Ace2Common.identity;
|
||||||
|
@ -142,9 +142,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument)
|
||||||
var extraOpenTags = "";
|
var extraOpenTags = "";
|
||||||
var extraCloseTags = "";
|
var extraCloseTags = "";
|
||||||
|
|
||||||
var plugins_ = plugins;
|
map(hooks.callAll("aceCreateDomLine", {
|
||||||
|
|
||||||
map(plugins_.callHook("aceCreateDomLine", {
|
|
||||||
domline: domline,
|
domline: domline,
|
||||||
cls: cls
|
cls: cls
|
||||||
}), function(modifier)
|
}), function(modifier)
|