From afc90604bfad7ab5805873cb5bafc3bbb74c4b01 Mon Sep 17 00:00:00 2001 From: Charlie DeTar Date: Sat, 15 Sep 2012 17:48:04 -0400 Subject: [PATCH 01/32] Add `userColor` query param to set initial color Add a URL parameter which sets the initial color for a user, e.g.: http://example.com/p/mypad?userColor=%2300ff00 Sanitize the given color value to ensure that it's a valid css value (could be any supported CSS color format -- #fff, rgba(), "red", etc). Shortly after rejoining a pad, the server responds with a USER_NEWINFO message which may contain an old color value; however, this message arrives after we have set and sent the new color value to the server. To avoid this race condition, if the query parameter has been set, ignore the color value in a USER_NEWINFO message which matches our user ID. --- src/static/js/collab_client.js | 8 ++++++++ src/static/js/pad.js | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/static/js/collab_client.js b/src/static/js/collab_client.js index d149b256..b3e17c25 100644 --- a/src/static/js/collab_client.js +++ b/src/static/js/collab_client.js @@ -358,6 +358,14 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) { var userInfo = msg.userInfo; var id = userInfo.userId; + + // Avoid a race condition when setting colors. If our color was set by a + // query param, ignore our own "new user" message's color value. + if (id === initialUserInfo.userId && initialUserInfo.globalUserColor) + { + msg.userInfo.colorId = initialUserInfo.globalUserColor; + } + if (userSet[id]) { diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 737f5dc6..8f8e8729 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -114,6 +114,7 @@ function getParams() var showControls = params["showControls"]; var showChat = params["showChat"]; var userName = params["userName"]; + var userColor = params["userColor"]; var showLineNumbers = params["showLineNumbers"]; var useMonospaceFont = params["useMonospaceFont"]; var IsnoColors = params["noColors"]; @@ -162,6 +163,11 @@ function getParams() // If the username is set as a parameter we should set a global value that we can call once we have initiated the pad. settings.globalUserName = decodeURIComponent(userName); } + if(userColor) + // If the userColor is set as a parameter, set a global value to use once we have initiated hte pad. + { + settings.globalUserColor = decodeURIComponent(userColor); + } if(rtl) { if(rtl == "true") @@ -363,6 +369,24 @@ function handshake() pad.myUserInfo.name = settings.globalUserName; $('#myusernameedit').attr({"value":settings.globalUserName}); // Updates the current users UI } + if (settings.globalUserColor !== false) + { + // First, check the color to ensure it's a valid css color value. + var check = $("").css("background-color", "white"); + $("body").append(check); + var white = check.css("background-color"); + check.css("background-color", settings.globalUserColor); + // Ensure that setting the element changed the color. + if (check.css("background-color") === white) { + settings.globalUserColor = "#ff0000"; + } + check.remove(); + + // Add a 'globalUserColor' property to myUserInfo, so collabClient knows we have a query parameter. + pad.myUserInfo.globalUserColor = settings.globalUserColor; + pad.notifyChangeColor(settings.globalUserColor); // Updates pad.myUserInfo.colorId + paduserlist.setMyUserInfo(pad.myUserInfo); + } } //This handles every Message after the clientVars else @@ -1025,6 +1049,7 @@ var settings = { , noColors: false , useMonospaceFontGlobal: false , globalUserName: false +, globalUserColor: false , rtlIsTrue: false }; From bc6e495e8c691a3e3ce047b1dbe8ba600ef49eef Mon Sep 17 00:00:00 2001 From: Charlie DeTar Date: Mon, 17 Sep 2012 00:19:57 -0400 Subject: [PATCH 02/32] Use 'transparent' as reference to validate css Use 'transparent' instead of 'white' as a reference color for validating CSS color values. Presumably, a user setting a userColor wants some color other than 'transparent' if they are setting it (they could always duplicate the background's color if not). --- src/static/js/pad.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 8f8e8729..3e2663c8 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -164,7 +164,7 @@ function getParams() settings.globalUserName = decodeURIComponent(userName); } if(userColor) - // If the userColor is set as a parameter, set a global value to use once we have initiated hte pad. + // If the userColor is set as a parameter, set a global value to use once we have initiated the pad. { settings.globalUserColor = decodeURIComponent(userColor); } @@ -372,12 +372,12 @@ function handshake() if (settings.globalUserColor !== false) { // First, check the color to ensure it's a valid css color value. - var check = $("").css("background-color", "white"); + var check = $("").css("background-color", "transparent"); $("body").append(check); - var white = check.css("background-color"); + var transparent = check.css("background-color"); check.css("background-color", settings.globalUserColor); // Ensure that setting the element changed the color. - if (check.css("background-color") === white) { + if (check.css("background-color") === transparent) { settings.globalUserColor = "#ff0000"; } check.remove(); From 53113644a0464929316be67ea878d47d13714aba Mon Sep 17 00:00:00 2001 From: Charlie DeTar Date: Mon, 17 Sep 2012 10:59:12 -0400 Subject: [PATCH 03/32] Require userColor to be valid css hex The utility functions colorutils.js assume that background colors are in CSS hex format, so require userColor to do the same, rather than allowing inputs like "red" and "rgba(...)", to insure that inversion checks will succeed. --- src/static/js/colorutils.js | 7 +++++++ src/static/js/pad.js | 13 ++----------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/static/js/colorutils.js b/src/static/js/colorutils.js index 5fbefb4d..74a2e463 100644 --- a/src/static/js/colorutils.js +++ b/src/static/js/colorutils.js @@ -24,6 +24,13 @@ var colorutils = {}; +// Check that a given value is a css hex color value, e.g. +// "#ffffff" or "#fff" +colorutils.isCssHex = function(cssColor) +{ + return /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(cssColor); +} + // "#ffffff" or "#fff" or "ffffff" or "fff" to [1.0, 1.0, 1.0] colorutils.css2triple = function(cssColor) { diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 3e2663c8..21dea440 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -43,6 +43,7 @@ var padmodals = require('./pad_modals').padmodals; var padsavedrevs = require('./pad_savedrevs'); var paduserlist = require('./pad_userlist').paduserlist; var padutils = require('./pad_utils').padutils; +var colorutils = require('./colorutils').colorutils; var createCookie = require('./pad_utils').createCookie; var readCookie = require('./pad_utils').readCookie; @@ -369,18 +370,8 @@ function handshake() pad.myUserInfo.name = settings.globalUserName; $('#myusernameedit').attr({"value":settings.globalUserName}); // Updates the current users UI } - if (settings.globalUserColor !== false) + if (settings.globalUserColor !== false && colorutils.isCssHex(settings.globalUserColor)) { - // First, check the color to ensure it's a valid css color value. - var check = $("").css("background-color", "transparent"); - $("body").append(check); - var transparent = check.css("background-color"); - check.css("background-color", settings.globalUserColor); - // Ensure that setting the element changed the color. - if (check.css("background-color") === transparent) { - settings.globalUserColor = "#ff0000"; - } - check.remove(); // Add a 'globalUserColor' property to myUserInfo, so collabClient knows we have a query parameter. pad.myUserInfo.globalUserColor = settings.globalUserColor; From 07c33c77c4b41a3181064beacc407565738c4929 Mon Sep 17 00:00:00 2001 From: d-a-n Date: Tue, 2 Oct 2012 22:10:18 +0300 Subject: [PATCH 04/32] Updated docs for new pad hooks (add, edit, remove) --- doc/api/hooks_server-side.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md index 06ec7374..be5564a6 100644 --- a/doc/api/hooks_server-side.md +++ b/doc/api/hooks_server-side.md @@ -64,6 +64,34 @@ This hook gets called upon the rendering of an ejs template block. For any speci Have a look at `src/templates/pad.html` and `src/templates/timeslider.html` to see which blocks are available. +## padCreated +Called from: src/node/db/Pad.js + +1. pad - the pad instance + +This hook gets called when a new pad was created. + +## padLoaded +Called from: src/node/db/Pad.js + +1. pad - the pad instance + +This hook gets called when an pad was loaded. + +## padUpdated +Called from: src/node/db/Pad.js + +1. pad - the pad instance + +This hook gets called when an existing pad was updated. + +## padRemoved +Called from: src/node/db/Pad.js + +1. pad - the pad instance + +This hook gets called when an existing pad was removed/deleted. + ## socketio Called from: src/node/hooks/express/socketio.js From c0f2e557d36f5b13604fff603ff26d5a9e4d0f64 Mon Sep 17 00:00:00 2001 From: d-a-n Date: Tue, 2 Oct 2012 22:11:54 +0300 Subject: [PATCH 05/32] Updated docs for new pad hooks (add, edit, remove) --- doc/api/hooks_server-side.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md index be5564a6..b6ee1604 100644 --- a/doc/api/hooks_server-side.md +++ b/doc/api/hooks_server-side.md @@ -67,6 +67,8 @@ Have a look at `src/templates/pad.html` and `src/templates/timeslider.html` to s ## padCreated Called from: src/node/db/Pad.js +Things in context: + 1. pad - the pad instance This hook gets called when a new pad was created. @@ -74,6 +76,8 @@ This hook gets called when a new pad was created. ## padLoaded Called from: src/node/db/Pad.js +Things in context: + 1. pad - the pad instance This hook gets called when an pad was loaded. @@ -81,6 +85,8 @@ This hook gets called when an pad was loaded. ## padUpdated Called from: src/node/db/Pad.js +Things in context: + 1. pad - the pad instance This hook gets called when an existing pad was updated. @@ -88,6 +94,8 @@ This hook gets called when an existing pad was updated. ## padRemoved Called from: src/node/db/Pad.js +Things in context: + 1. pad - the pad instance This hook gets called when an existing pad was removed/deleted. From 64a3d60b943bdf7ae643f3fcb5791ffbc95b77ae Mon Sep 17 00:00:00 2001 From: d-a-n Date: Tue, 2 Oct 2012 22:30:13 +0300 Subject: [PATCH 06/32] Added pad hooks (create, load, edit, remove) --- src/node/db/Pad.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/node/db/Pad.js b/src/node/db/Pad.js index ad2d59f3..cf04f9bc 100644 --- a/src/node/db/Pad.js +++ b/src/node/db/Pad.js @@ -16,6 +16,7 @@ var padMessageHandler = require("../handler/PadMessageHandler"); var readOnlyManager = require("./ReadOnlyManager"); var crypto = require("crypto"); var randomString = require("../utils/randomstring"); +var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks'); //serialization/deserialization attributes var attributeBlackList = ["id"]; @@ -86,6 +87,12 @@ Pad.prototype.appendRevision = function appendRevision(aChangeset, author) { // set the author to pad if(author) authorManager.addPad(author, this.id); + + if (this.head == 0) { + hooks.callAll("padCreated", this); + } else { + hooks.callAll("padUpdated", this); + } }; //save all attributes to the database @@ -368,6 +375,7 @@ Pad.prototype.init = function init(text, callback) { _this.appendRevision(firstChangeset, ''); } + hooks.callAll("padLoaded", _this); callback(null); }); }; @@ -467,6 +475,7 @@ Pad.prototype.remove = function remove(callback) { { db.remove("pad:"+padID); padManager.unloadPad(padID); + hooks.callAll("padRemoved", padID ); callback(); } ], function(err) From 4652751285ed4c4788442910574350f163f51ca9 Mon Sep 17 00:00:00 2001 From: d-a-n Date: Tue, 2 Oct 2012 22:32:30 +0300 Subject: [PATCH 07/32] Updated docs for new pad hooks (add, edit, remove) --- doc/api/hooks_server-side.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md index b6ee1604..84ca4490 100644 --- a/doc/api/hooks_server-side.md +++ b/doc/api/hooks_server-side.md @@ -96,7 +96,7 @@ Called from: src/node/db/Pad.js Things in context: -1. pad - the pad instance +1. pad id This hook gets called when an existing pad was removed/deleted. From 85b44119aee2339856a2fccadef99f9629f68895 Mon Sep 17 00:00:00 2001 From: Richard Braakman Date: Tue, 2 Oct 2012 23:27:30 +0300 Subject: [PATCH 08/32] USERINFO_UPDATE: construct a new message for broadcast The server was reusing the client's message when broadcasting userinfo updates. This would allow a malicious client to insert arbitrary fields into a message that the other clients would trust as coming from the server. For example, adding "disconnect" or renaming other authors. This commit fixes it by having the server construct a new message with known fields before broadcasting. --- src/node/handler/PadMessageHandler.js | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 10b259ae..28797a3a 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -415,22 +415,34 @@ function handleUserInfoUpdate(client, message) authorManager.setAuthorName(author, message.data.userInfo.name); var padId = sessioninfos[client.id].padId; + + var infoMsg = { + type: "COLLABROOM", + data: { + // The Client doesn't know about USERINFO_UPDATE, use USER_NEWINFO + type: "USER_NEWINFO", + userInfo: { + userId: author, + name: message.data.userInfo.name, + colorId: message.data.userInfo.colorId, + userAgent: "Anonymous", + ip: "127.0.0.1", + } + } + }; //set a null name, when there is no name set. cause the client wants it null - if(message.data.userInfo.name == null) + if(infoMsg.data.userInfo.name == null) { - message.data.userInfo.name = null; + infoMsg.data.userInfo.name = null; } - //The Client don't know about a USERINFO_UPDATE, it can handle only new user_newinfo, so change the message type - message.data.type = "USER_NEWINFO"; - //Send the other clients on the pad the update message for(var i in pad2sessions[padId]) { if(pad2sessions[padId][i] != client.id) { - socketio.sockets.sockets[pad2sessions[padId][i]].json.send(message); + socketio.sockets.sockets[pad2sessions[padId][i]].json.send(infoMsg); } } } From 754c559d632c08be58f06c3eedb3a9494c51dedf Mon Sep 17 00:00:00 2001 From: d-a-n Date: Wed, 3 Oct 2012 13:35:31 +0300 Subject: [PATCH 09/32] Changed pad hook names to follow naming conventions. --- doc/api/hooks_server-side.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md index 84ca4490..bc56f19b 100644 --- a/doc/api/hooks_server-side.md +++ b/doc/api/hooks_server-side.md @@ -64,7 +64,7 @@ This hook gets called upon the rendering of an ejs template block. For any speci Have a look at `src/templates/pad.html` and `src/templates/timeslider.html` to see which blocks are available. -## padCreated +## padCreate Called from: src/node/db/Pad.js Things in context: @@ -73,16 +73,16 @@ Things in context: This hook gets called when a new pad was created. -## padLoaded +## padLoad Called from: src/node/db/Pad.js Things in context: 1. pad - the pad instance -This hook gets called when an pad was loaded. +This hook gets called when an pad was loaded. If a new pad was created and loaded this event will be emitted too. -## padUpdated +## padUpdate Called from: src/node/db/Pad.js Things in context: @@ -91,7 +91,7 @@ Things in context: This hook gets called when an existing pad was updated. -## padRemoved +## padRemove Called from: src/node/db/Pad.js Things in context: From 358e4817310eceec8df664f3c428ba0afdc430dc Mon Sep 17 00:00:00 2001 From: d-a-n Date: Wed, 3 Oct 2012 13:41:40 +0300 Subject: [PATCH 10/32] Changed pad hook names to follow naming conventions. Arguments will now be passed as hash. --- src/node/db/Pad.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/node/db/Pad.js b/src/node/db/Pad.js index cf04f9bc..d6ea8277 100644 --- a/src/node/db/Pad.js +++ b/src/node/db/Pad.js @@ -89,9 +89,9 @@ Pad.prototype.appendRevision = function appendRevision(aChangeset, author) { authorManager.addPad(author, this.id); if (this.head == 0) { - hooks.callAll("padCreated", this); + hooks.callAll("padCreate", {'pad':this}); } else { - hooks.callAll("padUpdated", this); + hooks.callAll("padUpdate", {'pad':this}); } }; @@ -375,7 +375,7 @@ Pad.prototype.init = function init(text, callback) { _this.appendRevision(firstChangeset, ''); } - hooks.callAll("padLoaded", _this); + hooks.callAll("padLoad", {'pad':_this}); callback(null); }); }; @@ -475,7 +475,7 @@ Pad.prototype.remove = function remove(callback) { { db.remove("pad:"+padID); padManager.unloadPad(padID); - hooks.callAll("padRemoved", padID ); + hooks.callAll("padRemove", {'pad_id':padID}); callback(); } ], function(err) From 0fd8490ca6e3f2218c9ab16bf722725d173caa34 Mon Sep 17 00:00:00 2001 From: d-a-n Date: Wed, 3 Oct 2012 15:49:28 +0300 Subject: [PATCH 11/32] Changed pad_id to padID to follow projct standards. --- doc/api/hooks_server-side.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/hooks_server-side.md b/doc/api/hooks_server-side.md index bc56f19b..49eb6cc5 100644 --- a/doc/api/hooks_server-side.md +++ b/doc/api/hooks_server-side.md @@ -96,7 +96,7 @@ Called from: src/node/db/Pad.js Things in context: -1. pad id +1. padID This hook gets called when an existing pad was removed/deleted. From a521a125830a18213d71991d55c5d04269c5ee94 Mon Sep 17 00:00:00 2001 From: d-a-n Date: Wed, 3 Oct 2012 15:50:43 +0300 Subject: [PATCH 12/32] Changed pad_id to padID to follow projct standards. --- src/node/db/Pad.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/db/Pad.js b/src/node/db/Pad.js index d6ea8277..dba791fd 100644 --- a/src/node/db/Pad.js +++ b/src/node/db/Pad.js @@ -475,7 +475,7 @@ Pad.prototype.remove = function remove(callback) { { db.remove("pad:"+padID); padManager.unloadPad(padID); - hooks.callAll("padRemove", {'pad_id':padID}); + hooks.callAll("padRemove", {'padID':padID}); callback(); } ], function(err) From 90373964d31c61013fff941459c84688170636a8 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sat, 6 Oct 2012 02:36:51 +0200 Subject: [PATCH 13/32] Remove two instances of the same function name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both functions did the same thing, the first function was buggy.  Might be worth someone looking through the history of this file and pointing out when I made this heinous error ;) --- src/node/db/AuthorManager.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/node/db/AuthorManager.js b/src/node/db/AuthorManager.js index 2a6625c8..28b2dd91 100644 --- a/src/node/db/AuthorManager.js +++ b/src/node/db/AuthorManager.js @@ -141,22 +141,6 @@ exports.getAuthor = function (author, callback) db.get("globalAuthor:" + author, callback); } -/** - * Returns the Author Name of the author - * @param {String} author The id of the author - * @param {Function} callback callback(err, name) - */ - -exports.getAuthorName = function (authorID, callback) -{ - db.getSub("globalAuthor:" + author, ["name"], callback); - console.log(authorID); - db.getSub("globalAuthor:" + authorID, ["name"], function(err, authorName){ - if(ERR(err, callback)) return; - callback(null, {authorName: authorName}); - }); -} - /** From 9d1274abafb1887c2d4c7586946954e6e6532347 Mon Sep 17 00:00:00 2001 From: Chad Weider Date: Tue, 9 Oct 2012 01:32:21 -0700 Subject: [PATCH 14/32] Drop method deprecated in Express 3.x. --- src/node/utils/caching_middleware.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/utils/caching_middleware.js b/src/node/utils/caching_middleware.js index 1f533673..c6b23713 100644 --- a/src/node/utils/caching_middleware.js +++ b/src/node/utils/caching_middleware.js @@ -48,7 +48,7 @@ CachingMiddleware.prototype = new function () { var old_res = {}; var supportsGzip = - req.header('Accept-Encoding', '').indexOf('gzip') != -1; + (req.get('Accept-Encoding') || '').indexOf('gzip') != -1; var path = require('url').parse(req.url).path; var cacheKey = (new Buffer(path)).toString('base64').replace(/[\/\+=]/g, ''); From 0fa954c1a0d2a7e2c6c1d3dcc9987889857f77d9 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 11 Oct 2012 17:51:57 +0400 Subject: [PATCH 15/32] fixed variable name in handleMessageHook the code would never work as expected with this type --- src/node/handler/PadMessageHandler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 10b259ae..831acdbb 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -178,7 +178,7 @@ exports.handleMessage = function(client, message) // handleMessage will be called, even if the client is not authorized hooks.aCallAll("handleMessage", { client: client, message: message }, function ( messages ) { _.each(messages, function(newMessage){ - if ( newmessage === null ) { + if ( newMessage === null ) { dropMessage = true; } }); From dbcdc2f956172d4d0c89424ff5114c57b71cb4e3 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 11 Oct 2012 18:07:45 +0400 Subject: [PATCH 16/32] fix for error handling in callback code The callback code does not follow error handling guidelines, thus always receiving NULL instead of results array. --- src/node/handler/PadMessageHandler.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index 831acdbb..b889a8a0 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -176,7 +176,9 @@ exports.handleMessage = function(client, message) // Call handleMessage hook. If a plugin returns null, the message will be dropped. Note that for all messages // handleMessage will be called, even if the client is not authorized - hooks.aCallAll("handleMessage", { client: client, message: message }, function ( messages ) { + hooks.aCallAll("handleMessage", { client: client, message: message }, function ( err, messages ) { + if(ERR(err, callback)) return; + _.each(messages, function(newMessage){ if ( newMessage === null ) { dropMessage = true; From 957a0aa873f2df13483a9b17589c064cc229a80a Mon Sep 17 00:00:00 2001 From: "NAGOYA, Yoshihiko" Date: Thu, 11 Oct 2012 23:39:01 +0900 Subject: [PATCH 17/32] fix Pita/etherpad-lite #1032 refact inInternationalComposition --- src/static/js/ace.js | 5 +++++ src/static/js/ace2_inner.js | 21 ++++++++++++++++++--- src/static/js/collab_client.js | 4 ++-- src/static/js/pad.js | 16 ---------------- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/static/js/ace.js b/src/static/js/ace.js index e50f75c7..83ad9447 100644 --- a/src/static/js/ace.js +++ b/src/static/js/ace.js @@ -122,6 +122,11 @@ function Ace2Editor() return info.ace_getDebugProperty(prop); }; + editor.getInInternationalComposition = function() + { + return info.ace_getInInternationalComposition(); + }; + // prepareUserChangeset: // Returns null if no new changes or ACE not ready. Otherwise, bundles up all user changes // to the latest base text into a Changeset, which is returned (as a string if encodeAsString). diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index 652a3d25..2e56b950 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -1173,7 +1173,7 @@ function Ace2Inner(){ //if (! top.BEFORE) top.BEFORE = []; //top.BEFORE.push(magicdom.root.dom.innerHTML); //if (! isEditable) return; // and don't reschedule - if (window.parent.parent.inInternationalComposition) + if (inInternationalComposition) { // don't do idle input incorporation during international input composition idleWorkTimer.atLeast(500); @@ -3729,7 +3729,7 @@ function Ace2Inner(){ thisKeyDoesntTriggerNormalize = true; } - if ((!specialHandled) && (!thisKeyDoesntTriggerNormalize) && (!window.parent.parent.inInternationalComposition)) + if ((!specialHandled) && (!thisKeyDoesntTriggerNormalize) && (!inInternationalComposition)) { if (type != "keyup" || !incorpIfQuick()) { @@ -4589,9 +4589,24 @@ function Ace2Inner(){ } } + + var inInternationalComposition = false; function handleCompositionEvent(evt) { - window.parent.parent.handleCompositionEvent(evt); + // international input events, fired in FF3, at least; allow e.g. Japanese input + if (evt.type == "compositionstart") + { + inInternationalComposition = true; + } + else if (evt.type == "compositionend") + { + inInternationalComposition = false; + } + } + + editorInfo.ace_getInInternationalComposition = function () + { + return inInternationalComposition; } function bindTheEventHandlers() diff --git a/src/static/js/collab_client.js b/src/static/js/collab_client.js index b3e17c25..b700fc49 100644 --- a/src/static/js/collab_client.js +++ b/src/static/js/collab_client.js @@ -111,7 +111,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) function handleUserChanges() { - if (window.parent.parent.inInternationalComposition) return; + if (editor.getInInternationalComposition()) return; if ((!getSocket()) || channelState == "CONNECTING") { if (channelState == "CONNECTING" && (((+new Date()) - initialStartConnectTime) > 20000)) @@ -288,7 +288,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) var apool = msg.apool; // When inInternationalComposition, msg pushed msgQueue. - if (msgQueue.length > 0 || window.parent.parent.inInternationalComposition) { + if (msgQueue.length > 0 || editor.getInInternationalComposition()) { if (msgQueue.length > 0) oldRev = msgQueue[msgQueue.length - 1].newRev; else oldRev = rev; diff --git a/src/static/js/pad.js b/src/static/js/pad.js index 21dea440..89777040 100644 --- a/src/static/js/pad.js +++ b/src/static/js/pad.js @@ -51,22 +51,6 @@ var randomString = require('./pad_utils').randomString; var hooks = require('./pluginfw/hooks'); -window.inInternationalComposition = false; -var inInternationalComposition = window.inInternationalComposition; - -window.handleCompositionEvent = function handleCompositionEvent(evt) - { - // international input events, fired in FF3, at least; allow e.g. Japanese input - if (evt.type == "compositionstart") - { - this.inInternationalComposition = true; - } - else if (evt.type == "compositionend") - { - this.inInternationalComposition = false; - } - } - function createCookie(name, value, days, path) { if (days) From c45739becb27d5031cd8983c4fcce8f3a5b98e1b Mon Sep 17 00:00:00 2001 From: John McLear Date: Thu, 11 Oct 2012 23:38:56 +0200 Subject: [PATCH 18/32] Update src/package.json Bump version # --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index f729b3c1..c5a4d0aa 100644 --- a/src/package.json +++ b/src/package.json @@ -42,5 +42,5 @@ "engines" : { "node" : ">=0.6.0", "npm" : ">=1.0" }, - "version" : "1.1.2" + "version" : "1.1.4" } From b7d0751b185cd55e74390a87353b7df02640090d Mon Sep 17 00:00:00 2001 From: John McLear Date: Mon, 15 Oct 2012 13:09:55 +0200 Subject: [PATCH 19/32] couch, level, mongo, postgres, redis DB support Support for additional underlying databases --- src/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.json b/src/package.json index c5a4d0aa..504b88c2 100644 --- a/src/package.json +++ b/src/package.json @@ -15,7 +15,7 @@ "require-kernel" : "1.0.5", "resolve" : "0.2.x", "socket.io" : "0.9.x", - "ueberDB" : "0.1.7", + "ueberDB" : "0.1.8", "async" : "0.1.22", "express" : "3.x", "connect" : "2.4.x", From 6c89187f952ee248ff78c3ab9b3cbf4a78ae9e9f Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Tue, 16 Oct 2012 20:46:27 +0200 Subject: [PATCH 20/32] Fix #1067 Corrected exports links regexp --- src/static/js/timeslider.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/static/js/timeslider.js b/src/static/js/timeslider.js index e630bde0..a2156b16 100644 --- a/src/static/js/timeslider.js +++ b/src/static/js/timeslider.js @@ -144,13 +144,12 @@ function handleClientVars(message) require('./pad_impexp').padimpexp.init(); //change export urls when the slider moves - var export_rev_regex = /(\/\d+)?\/export/ BroadcastSlider.onSlider(function(revno) { // export_links is a jQuery Array, so .each is allowed. export_links.each(function() { - this.setAttribute('href', this.href.replace(export_rev_regex, '/' + revno + '/export')); + this.setAttribute('href', this.href.replace( /(.+?)\/\w+\/(\d+\/)?export/ , '$1/' + padId + '/' + revno + '/export')); }); }); From a770910a3a7285be3e45a16255b078051c5afa26 Mon Sep 17 00:00:00 2001 From: johnyma22 Date: Wed, 17 Oct 2012 17:53:28 +0100 Subject: [PATCH 21/32] Add LibreJS Licensing information to headers of HTML templates --- src/templates/index.html | 23 +++++++++++++++++++++++ src/templates/pad.html | 24 +++++++++++++++++++++++- src/templates/timeslider.html | 27 ++++++++++++++++++++++++--- 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/templates/index.html b/src/templates/index.html index 4a45d6a5..a6e5123f 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -2,6 +2,29 @@ Etherpad Lite + diff --git a/src/templates/pad.html b/src/templates/pad.html index 425e476d..5cbae7aa 100644 --- a/src/templates/pad.html +++ b/src/templates/pad.html @@ -3,8 +3,30 @@ %> - Etherpad Lite + diff --git a/src/templates/timeslider.html b/src/templates/timeslider.html index 469ddd94..bc3c176b 100644 --- a/src/templates/timeslider.html +++ b/src/templates/timeslider.html @@ -1,11 +1,32 @@ +Etherpad Lite Timeslider + - - Etherpad Lite Timeslider - From 8199bf8377a110168a23dab1b8b074b722d18ffe Mon Sep 17 00:00:00 2001 From: Chia-liang Kao Date: Tue, 23 Oct 2012 15:21:05 +0800 Subject: [PATCH 22/32] Do not assume window object exists --- src/static/js/contentcollector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/static/js/contentcollector.js b/src/static/js/contentcollector.js index 6a75de43..dd4fd1e5 100644 --- a/src/static/js/contentcollector.js +++ b/src/static/js/contentcollector.js @@ -311,7 +311,7 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class ['insertorder', 'first'] ].concat( _.map(state.lineAttributes,function(value,key){ - if (window.console) console.log([key, value]) + if (typeof(window)!= 'undefined' && window.console) console.log([key, value]) return [key, value]; }) ); From 526610e2e7a3d3ec687dc7ea8736081c7d69255b Mon Sep 17 00:00:00 2001 From: neurolit Date: Wed, 24 Oct 2012 19:48:13 +0200 Subject: [PATCH 23/32] =?UTF-8?q?Templates:=20relative=20links=20instead?= =?UTF-8?q?=20of=20absolute=20ones=20for=20/static=20directory=20=E2=80=A6?= =?UTF-8?q?irector?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two links were absolute ("/static/...") instead of relative ("../static"). The image was not loaded with sites behind reverse proxies and subdirectory. --- src/templates/pad.html | 2 +- src/templates/timeslider.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/templates/pad.html b/src/templates/pad.html index 425e476d..7e19535e 100644 --- a/src/templates/pad.html +++ b/src/templates/pad.html @@ -233,7 +233,7 @@

Reestablishing connection...

-

+

Opened in another window.

diff --git a/src/templates/timeslider.html b/src/templates/timeslider.html index 469ddd94..c7defcc0 100644 --- a/src/templates/timeslider.html +++ b/src/templates/timeslider.html @@ -83,7 +83,7 @@

Reestablishing connection...

-

+

Opened in another window.

From cb760aae5287a3cddbff31118194806323939a66 Mon Sep 17 00:00:00 2001 From: 0ip Date: Thu, 25 Oct 2012 14:37:41 +0300 Subject: [PATCH 24/32] Fix broken layout (Chrome Mobile) --- src/templates/index.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/templates/index.html b/src/templates/index.html index 4a45d6a5..b1d34eb4 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -9,9 +9,11 @@