diff options
author | Egil Moeller <egil.moller@freecode.no> | 2012-04-05 20:14:48 +0200 |
---|---|---|
committer | Egil Moeller <egil.moller@freecode.no> | 2012-04-05 20:14:48 +0200 |
commit | a3c9407ed6843fae334aebb29aadbac7a88a71ea (patch) | |
tree | 76eea2110cab5232ac32b7a36a45c32fcd529886 /src | |
parent | 65d32461e0efff4c92cacf89d554340b9e4b6764 (diff) | |
parent | 66fdacf9cf31343721dd8fb38a4584e11ea76e6e (diff) | |
download | etherpad-lite-a3c9407ed6843fae334aebb29aadbac7a88a71ea.zip |
Merge branch 'develop' of git://github.com/Pita/etherpad-lite
Diffstat (limited to 'src')
-rw-r--r-- | src/node/db/Pad.js | 4 | ||||
-rw-r--r-- | src/node/db/PadManager.js | 8 | ||||
-rw-r--r-- | src/node/easysync_tests.js | 20 | ||||
-rw-r--r-- | src/node/handler/PadMessageHandler.js | 4 | ||||
-rw-r--r-- | src/node/handler/TimesliderMessageHandler.js | 4 | ||||
-rw-r--r-- | src/node/hooks/express/specialpages.js | 12 | ||||
-rw-r--r-- | src/node/hooks/express/static.js | 17 | ||||
-rw-r--r-- | src/node/hooks/express/webaccess.js | 22 | ||||
-rw-r--r-- | src/node/server.js | 11 | ||||
-rw-r--r-- | src/node/utils/Minify.js | 7 | ||||
-rw-r--r-- | src/node/utils/tar.json | 4 | ||||
-rw-r--r-- | src/package.json | 5 | ||||
-rw-r--r-- | src/static/css/admin.css | 49 | ||||
-rw-r--r-- | src/static/js/AttributePool.js | 90 | ||||
-rw-r--r-- | src/static/js/AttributePoolFactory.js | 90 | ||||
-rw-r--r-- | src/static/js/Changeset.js | 4 | ||||
-rw-r--r-- | src/static/js/ace2_inner.js | 7 | ||||
-rw-r--r-- | src/static/js/broadcast.js | 2 | ||||
-rw-r--r-- | src/static/js/changesettracker.js | 6 | ||||
-rw-r--r-- | src/static/js/pad_editor.js | 4 | ||||
-rw-r--r-- | src/static/js/pluginfw/plugins.js | 72 | ||||
-rw-r--r-- | src/static/js/skiplist.js | 38 | ||||
-rw-r--r-- | src/templates/admin/plugins.html | 57 |
23 files changed, 277 insertions, 260 deletions
diff --git a/src/node/db/Pad.js b/src/node/db/Pad.js index 73d61458..b4a39c17 100644 --- a/src/node/db/Pad.js +++ b/src/node/db/Pad.js @@ -5,7 +5,7 @@ var ERR = require("async-stacktrace"); var Changeset = require("ep_etherpad-lite/static/js/Changeset"); -var AttributePoolFactory = require("ep_etherpad-lite/static/js/AttributePoolFactory"); +var AttributePool = require("ep_etherpad-lite/static/js/AttributePool"); var randomString = require('ep_etherpad-lite/static/js/pad_utils').randomString; var db = require("./DB").db; var async = require("async"); @@ -33,7 +33,7 @@ exports.cleanText = function (txt) { var Pad = function Pad(id) { this.atext = Changeset.makeAText("\n"); - this.pool = AttributePoolFactory.createAttributePool(); + this.pool = new AttributePool(); this.head = -1; this.chatHead = -1; this.publicStatus = false; diff --git a/src/node/db/PadManager.js b/src/node/db/PadManager.js index 4e3a3199..5f08b1b1 100644 --- a/src/node/db/PadManager.js +++ b/src/node/db/PadManager.js @@ -115,7 +115,13 @@ exports.doesPadExists = function(padId, callback) db.get("pad:"+padId, function(err, value) { if(ERR(err, callback)) return; - callback(null, value != null && value.atext); + if(value != null && value.atext){ + callback(null, true); + } + else + { + callback(null, false); + } }); } diff --git a/src/node/easysync_tests.js b/src/node/easysync_tests.js index 7a148289..374e949f 100644 --- a/src/node/easysync_tests.js +++ b/src/node/easysync_tests.js @@ -22,7 +22,7 @@ var Changeset = require("ep_etherpad-lite/static/js/Changeset"); -var AttributePoolFactory = require("ep_etherpad-lite/static/js/AttributePoolFactory"); +var AttributePool = require("ep_etherpad-lite/static/js/AttributePool"); function random() { this.nextInt = function (maxValue) { @@ -227,7 +227,7 @@ function runTests() { return attribs; // it's already an attrib pool } else { // assume it's an array of attrib strings to be split and added - var p = AttributePoolFactory.createAttributePool(); + var p = new AttributePool(); attribs.forEach(function (kv) { p.putAttrib(kv.split(',')); }); @@ -325,7 +325,7 @@ function runTests() { runMutateAttributionTest(4, ['foo,bar', 'line,1', 'line,2', 'line,3', 'line,4', 'line,5'], "Z:5>1|2=2+1$x", ["?*1|1+1", "?*2|1+1", "*3|1+1", "?*4|1+1", "?*5|1+1"], ["?*1|1+1", "?*2|1+1", "+1*3|1+1", "?*4|1+1", "?*5|1+1"]); var testPoolWithChars = (function () { - var p = AttributePoolFactory.createAttributePool(); + var p = new AttributePool(); p.putAttrib(['char', 'newline']); for (var i = 1; i < 36; i++) { p.putAttrib(['char', Changeset.numToString(i)]); @@ -560,7 +560,7 @@ function runTests() { var rand = new random(); print("> testCompose#" + randomSeed); - var p = AttributePoolFactory.createAttributePool(); + var p = new AttributePool(); var startText = randomMultiline(10, 20, rand) + '\n'; @@ -594,7 +594,7 @@ function runTests() { (function simpleComposeAttributesTest() { print("> simpleComposeAttributesTest"); - var p = AttributePoolFactory.createAttributePool(); + var p = new AttributePool(); p.putAttrib(['bold', '']); p.putAttrib(['bold', 'true']); var cs1 = Changeset.checkRep("Z:2>1*1+1*1=1$x"); @@ -604,7 +604,7 @@ function runTests() { })(); (function followAttributesTest() { - var p = AttributePoolFactory.createAttributePool(); + var p = new AttributePool(); p.putAttrib(['x', '']); p.putAttrib(['x', 'abc']); p.putAttrib(['x', 'def']); @@ -633,7 +633,7 @@ function runTests() { var rand = new random(); print("> testFollow#" + randomSeed); - var p = AttributePoolFactory.createAttributePool(); + var p = new AttributePool(); var startText = randomMultiline(10, 20, rand) + '\n'; @@ -682,8 +682,8 @@ function runTests() { (function testMoveOpsToNewPool() { print("> testMoveOpsToNewPool"); - var pool1 = AttributePoolFactory.createAttributePool(); - var pool2 = AttributePoolFactory.createAttributePool(); + var pool1 = new AttributePool(); + var pool2 = new AttributePool(); pool1.putAttrib(['baz', 'qux']); pool1.putAttrib(['foo', 'bar']); @@ -738,7 +738,7 @@ function runTests() { (function testOpAttributeValue() { print("> testOpAttributeValue"); - var p = AttributePoolFactory.createAttributePool(); + var p = new AttributePool(); p.putAttrib(['name', 'david']); p.putAttrib(['color', 'green']); diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index e1786b2a..866edeb0 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -23,7 +23,7 @@ var ERR = require("async-stacktrace"); var async = require("async"); var padManager = require("../db/PadManager"); var Changeset = require("ep_etherpad-lite/static/js/Changeset"); -var AttributePoolFactory = require("ep_etherpad-lite/static/js/AttributePoolFactory"); +var AttributePool = require("ep_etherpad-lite/static/js/AttributePool"); var authorManager = require("../db/AuthorManager"); var readOnlyManager = require("../db/ReadOnlyManager"); var settings = require('../utils/Settings'); @@ -394,7 +394,7 @@ function handleUserChanges(client, message) //get all Vars we need var baseRev = message.data.baseRev; - var wireApool = (AttributePoolFactory.createAttributePool()).fromJsonable(message.data.apool); + var wireApool = (new AttributePool()).fromJsonable(message.data.apool); var changeset = message.data.changeset; var r, apool, pad; diff --git a/src/node/handler/TimesliderMessageHandler.js b/src/node/handler/TimesliderMessageHandler.js index 9c063acd..a6cf8f4d 100644 --- a/src/node/handler/TimesliderMessageHandler.js +++ b/src/node/handler/TimesliderMessageHandler.js @@ -23,7 +23,7 @@ var ERR = require("async-stacktrace"); var async = require("async"); var padManager = require("../db/PadManager"); var Changeset = require("ep_etherpad-lite/static/js/Changeset"); -var AttributePoolFactory = require("ep_etherpad-lite/static/js/AttributePoolFactory"); +var AttributePool = require("ep_etherpad-lite/static/js/AttributePool"); var settings = require('../utils/Settings'); var authorManager = require("../db/AuthorManager"); var log4js = require('log4js'); @@ -272,7 +272,7 @@ function getChangesetInfo(padId, startNum, endNum, granularity, callback) var forwardsChangesets = []; var backwardsChangesets = []; var timeDeltas = []; - var apool = AttributePoolFactory.createAttributePool(); + var apool = new AttributePool(); var pad; var composedChangesets = {}; var revisionDate = []; diff --git a/src/node/hooks/express/specialpages.js b/src/node/hooks/express/specialpages.js index 585a7eab..474f475e 100644 --- a/src/node/hooks/express/specialpages.js +++ b/src/node/hooks/express/specialpages.js @@ -6,27 +6,27 @@ exports.expressCreateServer = function (hook_name, args, cb) { //serve index.html under / args.app.get('/', function(req, res) { - res.send(eejs.require("ep_etherpad-lite/templates/index.html"), { maxAge: exports.maxAge }); + res.send(eejs.require("ep_etherpad-lite/templates/index.html")); }); //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 }); + res.sendfile(filePath); }); //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) + res.sendfile(filePath, 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 }); + res.sendfile(filePath); } }); }); @@ -34,13 +34,13 @@ exports.expressCreateServer = function (hook_name, args, cb) { //serve pad.html under /p args.app.get('/p/:pad', function(req, res, next) { - res.send(eejs.require("ep_etherpad-lite/templates/pad.html"), { maxAge: exports.maxAge }); + res.send(eejs.require("ep_etherpad-lite/templates/pad.html")); }); //serve timeslider.html under /p/$padname/timeslider args.app.get('/p/:pad/timeslider', function(req, res, next) { - res.send(eejs.require("ep_etherpad-lite/templates/timeslider.html"), { maxAge: exports.maxAge }); + res.send(eejs.require("ep_etherpad-lite/templates/timeslider.html")); }); }
\ No newline at end of file diff --git a/src/node/hooks/express/static.js b/src/node/hooks/express/static.js index 9209967c..f284e478 100644 --- a/src/node/hooks/express/static.js +++ b/src/node/hooks/express/static.js @@ -6,6 +6,7 @@ var settings = require("../../utils/Settings"); var Yajsml = require('yajsml'); var fs = require("fs"); var ERR = require("async-stacktrace"); +var _ = require("underscore"); exports.expressCreateServer = function (hook_name, args, cb) { // Cache both minified and static. @@ -35,8 +36,22 @@ exports.expressCreateServer = function (hook_name, args, cb) { // 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) { + + var clientParts = _(plugins.parts) + .filter(function(part){ return _(part).has('client_hooks') }); + + var clientPlugins = {}; + + _(clientParts).chain() + .map(function(part){ return part.plugin }) + .uniq() + .each(function(name){ + clientPlugins[name] = _(plugins.plugins[name]).clone(); + delete clientPlugins[name]['package']; + }); + res.header("Content-Type","application/json; charset=utf-8"); - res.write(JSON.stringify({"plugins": plugins.plugins, "parts": plugins.parts})); + res.write(JSON.stringify({"plugins": clientPlugins, "parts": clientParts})); res.end(); }); } diff --git a/src/node/hooks/express/webaccess.js b/src/node/hooks/express/webaccess.js index e77e133c..d0e28737 100644 --- a/src/node/hooks/express/webaccess.js +++ b/src/node/hooks/express/webaccess.js @@ -6,22 +6,30 @@ var settings = require('../../utils/Settings'); //checks for basic http auth exports.basicAuth = function (req, res, next) { - var pass = settings.httpAuth; + + // When handling HTTP-Auth, an undefined password will lead to no authorization at all + var pass = settings.httpAuth || ''; + if (req.path.indexOf('/admin') == 0) { var pass = settings.adminHttpAuth; + } - // Just pass if not activated in Activate http basic auth if it has been defined in settings.json - if (!pass) { + + // Just pass if password is an empty string + if (pass === '') { return 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() == pass) { + + + // If a password has been set and auth headers are present... + if (pass && req.headers.authorization && req.headers.authorization.search('Basic ') === 0) { + // ...check login and password + if (new Buffer(req.headers.authorization.split(' ')[1], 'base64').toString() === pass) { return next(); } } + // Otherwise return Auth required Headers, delayed for 1 second, if auth failed. res.header('WWW-Authenticate', 'Basic realm="Protected Area"'); if (req.headers.authorization) { setTimeout(function () { diff --git a/src/node/server.js b/src/node/server.js index 8e6d6fa0..6b443edb 100644 --- a/src/node/server.js +++ b/src/node/server.js @@ -51,10 +51,6 @@ 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, by default -var hour = 60*60; -exports.maxAge = settings.maxAge || 6 * hour; - //set loglevel log4js.setGlobalLogLevel(settings.loglevel); @@ -92,7 +88,12 @@ async.waterfall([ //let the server listen app.listen(settings.port, settings.ip); console.log("Server is listening at " + settings.ip + ":" + settings.port); - + if(settings.adminHttpAuth){ + console.log("Plugin admin page listening at " + settings.ip + ":" + settings.port + "/admin/plugins"); + } + else{ + console.log("Admin username and password not set in settings.json. To access admin please uncomment and edit adminHttpAuth in settings.json"); + } callback(null); } ]); diff --git a/src/node/utils/Minify.js b/src/node/utils/Minify.js index b5d7b472..c5996565 100644 --- a/src/node/utils/Minify.js +++ b/src/node/utils/Minify.js @@ -108,7 +108,7 @@ exports.minify = function(req, res, next) date = new Date(date); res.setHeader('last-modified', date.toUTCString()); res.setHeader('date', (new Date()).toUTCString()); - if (settings.maxAge) { + if (settings.maxAge !== undefined) { var expiresDate = new Date((new Date()).getTime()+settings.maxAge*1000); res.setHeader('expires', expiresDate.toUTCString()); res.setHeader('cache-control', 'max-age=' + settings.maxAge); @@ -131,7 +131,10 @@ exports.minify = function(req, res, next) res.end(); } else if (req.method == 'GET') { getFileCompressed(filename, contentType, function (error, content) { - if(ERR(error)) return; + if(ERR(error, function(){ + res.writeHead(500, {}); + res.end(); + })) return; res.header("Content-Type", contentType); res.writeHead(200, {}); res.write(content); diff --git a/src/node/utils/tar.json b/src/node/utils/tar.json index af31fb80..14c93f5c 100644 --- a/src/node/utils/tar.json +++ b/src/node/utils/tar.json @@ -40,7 +40,7 @@ , "pad_modals.js" , "pad_savedrevs.js" , "pad_impexp.js" - , "AttributePoolFactory.js" + , "AttributePool.js" , "Changeset.js" , "domline.js" , "linestylefilter.js" @@ -54,7 +54,7 @@ "ace2_common.js" , "underscore.js" , "rjquery.js" - , "AttributePoolFactory.js" + , "AttributePool.js" , "Changeset.js" , "security.js" , "skiplist.js" diff --git a/src/package.json b/src/package.json index 0d4ad538..83441da0 100644 --- a/src/package.json +++ b/src/package.json @@ -23,9 +23,8 @@ "log4js" : "0.4.1", "jsdom-nocontextifiy" : "0.2.10", "async-stacktrace" : "0.0.2", - "npm" : "1.1", - "ejs" : "0.6.1", - "node.extend" : "1.0.0", + "npm" : "1.1", + "ejs" : "0.6.1", "graceful-fs" : "1.1.5", "slide" : "1.1.3", "semver" : "1.0.13", diff --git a/src/static/css/admin.css b/src/static/css/admin.css new file mode 100644 index 00000000..80089c4c --- /dev/null +++ b/src/static/css/admin.css @@ -0,0 +1,49 @@ +table { + border-collapse: collapse; +} +td, th { + border: 1px solid black; + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + padding-bottom: 2px; +} +.template { + display: none; +} +.dialog { + display: none; + position: absolute; + left: 50%; + top: 50%; + width: 700px; + height: 500px; + margin-left: -350px; + margin-top: -250px; + border: 3px solid #999999; + background: #eeeeee; +} +.dialog .title { + margin: 0; + padding: 2px; + border-bottom: 3px solid #999999; + font-size: 24px; + line-height: 24px; + height: 24px; + overflow: hidden; +} +.dialog .title .close { + float: right; +} +.dialog .history { + background: #222222; + color: #eeeeee; + position: absolute; + top: 41px; + bottom: 10px; + left: 10px; + right: 10px; + padding: 2px; + overflow: auto; +} + diff --git a/src/static/js/AttributePool.js b/src/static/js/AttributePool.js new file mode 100644 index 00000000..a9245daf --- /dev/null +++ b/src/static/js/AttributePool.js @@ -0,0 +1,90 @@ +/** + * This code represents the Attribute Pool Object of the original Etherpad. + * 90% of the code is still like in the original Etherpad + * Look at https://github.com/ether/pad/blob/master/infrastructure/ace/www/easysync2.js + * You can find a explanation what a attribute pool is here: + * https://github.com/Pita/etherpad-lite/blob/master/doc/easysync/easysync-notes.txt + */ + +/* + * Copyright 2009 Google Inc., 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 AttributePool = function () { + this.numToAttrib = {}; // e.g. {0: ['foo','bar']} + this.attribToNum = {}; // e.g. {'foo,bar': 0} + this.nextNum = 0; +}; + +AttributePool.prototype.putAttrib = function (attrib, dontAddIfAbsent) { + var str = String(attrib); + if (str in this.attribToNum) { + return this.attribToNum[str]; + } + if (dontAddIfAbsent) { + return -1; + } + var num = this.nextNum++; + this.attribToNum[str] = num; + this.numToAttrib[num] = [String(attrib[0] || ''), String(attrib[1] || '')]; + return num; +}; + +AttributePool.prototype.getAttrib = function (num) { + var pair = this.numToAttrib[num]; + if (!pair) { + return pair; + } + return [pair[0], pair[1]]; // return a mutable copy +}; + +AttributePool.prototype.getAttribKey = function (num) { + var pair = this.numToAttrib[num]; + if (!pair) return ''; + return pair[0]; +}; + +AttributePool.prototype.getAttribValue = function (num) { + var pair = this.numToAttrib[num]; + if (!pair) return ''; + return pair[1]; +}; + +AttributePool.prototype.eachAttrib = function (func) { + for (var n in this.numToAttrib) { + var pair = this.numToAttrib[n]; + func(pair[0], pair[1]); + } +}; + +AttributePool.prototype.toJsonable = function () { + return { + numToAttrib: this.numToAttrib, + nextNum: this.nextNum + }; +}; + +AttributePool.prototype.fromJsonable = function (obj) { + this.numToAttrib = obj.numToAttrib; + this.nextNum = obj.nextNum; + this.attribToNum = {}; + for (var n in this.numToAttrib) { + this.attribToNum[String(this.numToAttrib[n])] = Number(n); + } + return this; +}; + + +module.exports = AttributePool;
\ No newline at end of file diff --git a/src/static/js/AttributePoolFactory.js b/src/static/js/AttributePoolFactory.js deleted file mode 100644 index 00b58dbb..00000000 --- a/src/static/js/AttributePoolFactory.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * This code represents the Attribute Pool Object of the original Etherpad. - * 90% of the code is still like in the original Etherpad - * Look at https://github.com/ether/pad/blob/master/infrastructure/ace/www/easysync2.js - * You can find a explanation what a attribute pool is here: - * https://github.com/Pita/etherpad-lite/blob/master/doc/easysync/easysync-notes.txt - */ - -/* - * Copyright 2009 Google Inc., 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. - */ - -exports.createAttributePool = function () { - var p = {}; - p.numToAttrib = {}; // e.g. {0: ['foo','bar']} - p.attribToNum = {}; // e.g. {'foo,bar': 0} - p.nextNum = 0; - - p.putAttrib = function (attrib, dontAddIfAbsent) { - var str = String(attrib); - if (str in p.attribToNum) { - return p.attribToNum[str]; - } - if (dontAddIfAbsent) { - return -1; - } - var num = p.nextNum++; - p.attribToNum[str] = num; - p.numToAttrib[num] = [String(attrib[0] || ''), String(attrib[1] || '')]; - return num; - }; - - p.getAttrib = function (num) { - var pair = p.numToAttrib[num]; - if (!pair) { - return pair; - } - return [pair[0], pair[1]]; // return a mutable copy - }; - - p.getAttribKey = function (num) { - var pair = p.numToAttrib[num]; - if (!pair) return ''; - return pair[0]; - }; - - p.getAttribValue = function (num) { - var pair = p.numToAttrib[num]; - if (!pair) return ''; - return pair[1]; - }; - - p.eachAttrib = function (func) { - for (var n in p.numToAttrib) { - var pair = p.numToAttrib[n]; - func(pair[0], pair[1]); - } - }; - - p.toJsonable = function () { - return { - numToAttrib: p.numToAttrib, - nextNum: p.nextNum - }; - }; - - p.fromJsonable = function (obj) { - p.numToAttrib = obj.numToAttrib; - p.nextNum = obj.nextNum; - p.attribToNum = {}; - for (var n in p.numToAttrib) { - p.attribToNum[String(p.numToAttrib[n])] = Number(n); - } - return p; - }; - - return p; -} diff --git a/src/static/js/Changeset.js b/src/static/js/Changeset.js index fd1900ba..738ee1ba 100644 --- a/src/static/js/Changeset.js +++ b/src/static/js/Changeset.js @@ -25,7 +25,7 @@ * limitations under the License. */ -var AttributePoolFactory = require("./AttributePoolFactory"); +var AttributePool = require("./AttributePool"); var _opt = null; @@ -1731,7 +1731,7 @@ exports.appendATextToAssembler = function (atext, assem) { * @param pool {AtributePool} */ exports.prepareForWire = function (cs, pool) { - var newPool = AttributePoolFactory.createAttributePool();; + var newPool = new AttributePool(); var newCs = exports.moveOpsToNewPool(cs, pool, newPool); return { translated: newCs, diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index a831bb04..f8393d0b 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -21,7 +21,6 @@ */ var editor, _, $, jQuery, plugins, Ace2Common; - Ace2Common = require('./ace2_common'); plugins = require('ep_etherpad-lite/static/js/pluginfw/plugins'); @@ -44,10 +43,10 @@ function Ace2Inner(){ var makeContentCollector = require('./contentcollector').makeContentCollector; var makeCSSManager = require('./cssmanager').makeCSSManager; var domline = require('./domline').domline; - var AttribPool = require('./AttributePoolFactory').createAttributePool; + var AttribPool = require('./AttributePool'); var Changeset = require('./Changeset'); var linestylefilter = require('./linestylefilter').linestylefilter; - var newSkipList = require('./skiplist').newSkipList; + var SkipList = require('./skiplist'); var undoModule = require('./undomodule').undoModule; var makeVirtualLineView = require('./virtual_lines').makeVirtualLineView; @@ -93,7 +92,7 @@ function Ace2Inner(){ // native IE selections have that behavior (which we try not to interfere with). // Must be false if selection is collapsed! var rep = { - lines: newSkipList(), + lines: new SkipList(), selStart: null, selEnd: null, selFocusAtStart: false, diff --git a/src/static/js/broadcast.js b/src/static/js/broadcast.js index f8b6341d..1c7bdcfd 100644 --- a/src/static/js/broadcast.js +++ b/src/static/js/broadcast.js @@ -22,7 +22,7 @@ var makeCSSManager = require('./cssmanager').makeCSSManager; var domline = require('./domline').domline; -var AttribPool = require('./AttributePoolFactory').createAttributePool; +var AttribPool = require('./AttributePool'); var Changeset = require('./Changeset'); var linestylefilter = require('./linestylefilter').linestylefilter; var colorutils = require('./colorutils').colorutils; diff --git a/src/static/js/changesettracker.js b/src/static/js/changesettracker.js index b0219852..58ef21cb 100644 --- a/src/static/js/changesettracker.js +++ b/src/static/js/changesettracker.js @@ -20,7 +20,7 @@ * limitations under the License. */ -var AttribPool = require('./AttributePoolFactory').createAttributePool; +var AttributePool = require('./AttributePool'); var Changeset = require('./Changeset'); function makeChangesetTracker(scheduler, apool, aceCallbacksProvider) @@ -83,7 +83,7 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider) baseAText = Changeset.cloneAText(atext); if (apoolJsonObj) { - var wireApool = (new AttribPool()).fromJsonable(apoolJsonObj); + var wireApool = (new AttributePool()).fromJsonable(apoolJsonObj); baseAText.attribs = Changeset.moveOpsToNewPool(baseAText.attribs, wireApool, apool); } submittedChangeset = null; @@ -117,7 +117,7 @@ function makeChangesetTracker(scheduler, apool, aceCallbacksProvider) if (apoolJsonObj) { - var wireApool = (new AttribPool()).fromJsonable(apoolJsonObj); + var wireApool = (new AttributePool()).fromJsonable(apoolJsonObj); c = Changeset.moveOpsToNewPool(c, wireApool, apool); } diff --git a/src/static/js/pad_editor.js b/src/static/js/pad_editor.js index 12f83aeb..b8a4ea0e 100644 --- a/src/static/js/pad_editor.js +++ b/src/static/js/pad_editor.js @@ -87,8 +87,6 @@ var padeditor = (function() return defaultValue; } - self.ace.setProperty("showsauthorcolors", !settings.noColors); - self.ace.setProperty("rtlIsTrue", settings.rtlIsTrue); var v; @@ -100,6 +98,8 @@ var padeditor = (function() v = getOption('showAuthorColors', true); self.ace.setProperty("showsauthorcolors", v); padutils.setCheckbox($("#options-colorscheck"), v); + // Override from parameters + self.ace.setProperty("showsauthorcolors", !settings.noColors); v = getOption('useMonospaceFont', false); self.ace.setProperty("textface", (v ? "monospace" : "Arial, sans-serif")); diff --git a/src/static/js/pluginfw/plugins.js b/src/static/js/pluginfw/plugins.js index 7eb82d38..5f44bb6f 100644 --- a/src/static/js/pluginfw/plugins.js +++ b/src/static/js/pluginfw/plugins.js @@ -12,10 +12,9 @@ if (!exports.isClient) { var fs = require("fs"); var tsort = require("./tsort"); var util = require("util"); - var extend = require("node.extend"); _ = require("underscore"); }else{ - var $, jQuery + var $, jQuery; $ = jQuery = require("ep_etherpad-lite/static/js/rjquery").$; _ = require("ep_etherpad-lite/static/js/underscore"); } @@ -31,15 +30,15 @@ exports.ensure = function (cb) { exports.update(cb); else cb(); -} +}; exports.formatPlugins = function () { return _.keys(exports.plugins).join(", "); -} +}; exports.formatParts = function () { return _.map(exports.parts, function (part) { return part.full_name; }).join("\n"); -} +}; exports.formatHooks = function () { var res = []; @@ -49,33 +48,39 @@ exports.formatHooks = function () { }); }); return res.join("\n"); -} +}; -exports.loadFn = function (path) { +exports.loadFn = function (path, hookName) { var x = path.split(":"); var fn = require(x[0]); - _.each(x[1].split("."), function (name) { + var functionName = x[1] ? x[1] : hookName; + + _.each(functionName.split("."), function (name) { fn = fn[name]; }); return fn; -} +}; exports.extractHooks = function (parts, hook_set_name) { var hooks = {}; _.each(parts,function (part) { - _.chain(part[hook_set_name] || {}).keys().each(function (hook_name) { + _.chain(part[hook_set_name] || {}) + .keys() + .each(function (hook_name) { if (hooks[hook_name] === undefined) hooks[hook_name] = []; + + var hook_fn_name = part[hook_set_name][hook_name]; - var hook_fn = exports.loadFn(part[hook_set_name][hook_name]); + var hook_fn = exports.loadFn(hook_fn_name, hook_name); if (hook_fn) { hooks[hook_name].push({"hook_name": hook_name, "hook_fn": hook_fn, "hook_fn_name": hook_fn_name, "part": part}); } else { - console.error("Unable to load hook function for " + part.full_name + " for hook " + hook_name + ": " + part.hooks[hook_name]); + console.error("Unable to load hook function for " + part.full_name + " for hook " + hook_name + ": " + part.hooks[hook_name]); } }); }); return hooks; -} +}; if (exports.isClient) { @@ -90,7 +95,7 @@ if (exports.isClient) { console.error("Failed to load plugin-definitions: " + err); cb(); }); - } + }; } else { exports.callInit = function (cb) { @@ -135,7 +140,7 @@ exports.update = function (cb) { } ); }); -} + }; exports.getPackages = function (cb) { // Load list of installed NPM packages, flatten it to a list, and filter out only packages with names that @@ -145,49 +150,50 @@ exports.getPackages = function (cb) { var packages = {}; function flatten(deps) { _.chain(deps).keys().each(function (name) { - if (name.indexOf(exports.prefix) == 0) { - packages[name] = extend({}, deps[name]); + if (name.indexOf(exports.prefix) === 0) { + packages[name] = _.clone(deps[name]); // Delete anything that creates loops so that the plugin // list can be sent as JSON to the web client delete packages[name].dependencies; delete packages[name].parent; - } - if (deps[name].dependencies !== undefined) - flatten(deps[name].dependencies); + } + + if (deps[name].dependencies !== undefined) flatten(deps[name].dependencies); }); } + var tmp = {}; tmp[data.name] = data; flatten(tmp); cb(null, packages); }); -} + }; -exports.loadPlugin = function (packages, plugin_name, plugins, parts, cb) { + exports.loadPlugin = function (packages, plugin_name, plugins, parts, cb) { var plugin_path = path.resolve(packages[plugin_name].path, "ep.json"); fs.readFile( plugin_path, function (er, data) { if (er) { - console.error("Unable to load plugin definition file " + plugin_path); + console.error("Unable to load plugin definition file " + plugin_path); return cb(); } try { var plugin = JSON.parse(data); - plugin.package = packages[plugin_name]; - plugins[plugin_name] = plugin; - _.each(plugin.parts, function (part) { - part.plugin = plugin_name; - part.full_name = plugin_name + "/" + part.name; - parts[part.full_name] = part; - }); + plugin['package'] = packages[plugin_name]; + plugins[plugin_name] = plugin; + _.each(plugin.parts, function (part) { + part.plugin = plugin_name; + part.full_name = plugin_name + "/" + part.name; + parts[part.full_name] = part; + }); } catch (ex) { - console.error("Unable to parse plugin definition file " + plugin_path + ": " + ex.toString()); + console.error("Unable to parse plugin definition file " + plugin_path + ": " + ex.toString()); } cb(); } ); -} + }; exports.partsToParentChildList = function (parts) { var res = []; @@ -203,7 +209,7 @@ exports.partsToParentChildList = function (parts) { } }); return res; -} +}; // Used only in Node, so no need for _ diff --git a/src/static/js/skiplist.js b/src/static/js/skiplist.js index 190bc55b..58477acc 100644 --- a/src/static/js/skiplist.js +++ b/src/static/js/skiplist.js @@ -20,11 +20,12 @@ * limitations under the License. */ +var Ace2Common = require('./ace2_common'), + _ = require('./underscore'); -var noop = require('./ace2_common').noop; +var noop = Ace2Common.noop; - -function newSkipList() +function SkipList() { var PROFILER = window.PROFILER; if (!PROFILER) @@ -284,27 +285,6 @@ function newSkipList() } return dist; } -/*function _debugToString() { - var array = [start]; - while (array[array.length-1] !== end) { - array[array.length] = array[array.length-1].downPtrs[0]; - } - function getIndex(node) { - if (!node) return null; - for(var i=0;i<array.length;i++) { - if (array[i] === node) - return i-1; - } - return false; - } - var processedArray = map(array, function(node) { - var x = {key:node.key, levels: node.levels, downSkips: node.downSkips, - upPtrs: map(node.upPtrs, getIndex), downPtrs: map(node.downPtrs, getIndex), - downSkipWidths: node.downSkipWidths}; - return x; - }); - return map(processedArray, function (x) { return x.toSource(); }).join("\n"); - }*/ function _getNodeByKey(key) { @@ -345,8 +325,9 @@ function newSkipList() /* The skip-list contains "entries", JavaScript objects that each must have a unique "key" property that is a string. -*/ - var self = { + */ + var self = this; + _.extend(this, { length: function() { return numNodes; @@ -482,8 +463,7 @@ that is a string. { return start.levels; } - } - return self; + }); } -exports.newSkipList = newSkipList; +module.exports = SkipList; diff --git a/src/templates/admin/plugins.html b/src/templates/admin/plugins.html index 7dcb6fa3..5e5a1b03 100644 --- a/src/templates/admin/plugins.html +++ b/src/templates/admin/plugins.html @@ -1,56 +1,7 @@ <html> <head> <title>Plugin manager</title> - <style> - table { - border-collapse: collapse; - } - td, th { - border: 1px solid black; - padding-left: 10px; - padding-right: 10px; - padding-top: 2px; - padding-bottom: 2px; - } - .template { - display: none; - } - .dialog { - display: none; - position: absolute; - left: 50%; - top: 50%; - width: 700px; - height: 500px; - margin-left: -350px; - margin-top: -250px; - border: 3px solid #999999; - background: #eeeeee; - } - .dialog .title { - margin: 0; - padding: 2px; - border-bottom: 3px solid #999999; - font-size: 24px; - line-height: 24px; - height: 24px; - overflow: hidden; - } - .dialog .title .close { - float: right; - } - .dialog .history { - background: #222222; - color: #eeeeee; - position: absolute; - top: 41px; - bottom: 10px; - left: 10px; - right: 10px; - padding: 2px; - overflow: auto; - } - </style> + <link href="../../static/css/admin.css" rel="stylesheet" type="text/css" /> <script src="../../static/js/jquery.js"></script> <script src="../../socket.io/socket.io.js"></script> <script> @@ -167,7 +118,7 @@ <td class="name"></td> <td class="description"></td> <td class="actions"> - <input type="button" value="I" class="do-uninstall"> + <input type="button" value="Uninstall" class="do-uninstall"> </td> </tr> </tbody> @@ -180,7 +131,7 @@ <h1>Search for plugins to install</h1> <form> <input type="text" name="search" value="" id="search-query"> - <input type="button" value="S" id="do-search"> + <input type="button" value="Search" id="do-search"> </form> <table> <thead> @@ -195,7 +146,7 @@ <td class="name"></td> <td class="description"></td> <td class="actions"> - <input type="button" value="I" class="do-install"> + <input type="button" value="Install" class="do-install"> </td> </tr> </tbody> |