Merge branch 'develop' of github.com:ether/etherpad-lite into develop

This commit is contained in:
John McLear 2014-11-27 02:24:12 +00:00
commit 65fb25d71f
33 changed files with 346 additions and 237 deletions

View file

@ -99,7 +99,7 @@ fi
echo "Clear minfified cache..."
rm -f var/minified*
echo "ensure custom css/js files are created..."
echo "Ensure custom css/js files are created..."
for f in "index" "pad" "timeslider"
do

View file

@ -1,9 +0,0 @@
#!/bin/sh
if [ -d "../bin" ]; then
cd "../"
fi
JSHINT=./node_modules/jshint/bin/hint
$JSHINT ./node/

View file

@ -1,79 +0,0 @@
This is the new load testing file: https://bitbucket.org/rbraakman/etherpad-stresstest
BELOW is the original load testing file.
This load tester is extremely useful for testing how many dormant clients can connect to etherpad.
TODO:
Emulate characters being typed into a pad
HOW TO USE (from @mjd75) proper formatting at: https://github.com/ether/etherpad-lite/issues/360
Server 1:
Installed Node.js (etc), EtherPad and MySQL
Server 2:
Installed Xvfb and PhantomJS
I installed Xvfb following (roughly) this guide: http://blog.martin-lyness.com/archives/installing-xvfb-on-ubuntu-9-10-karmic-koala
#sudo apt-get install xvfb
#sudo apt-get install xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic
Launched two instances of Xvfb directly from the terminal:
#Xvfb :0 -ac
#Xvfb :1 -ac
I installed PhantomJS following this guide: http://code.google.com/p/phantomjs/wiki/Installation
#sudo add-apt-repository ppa:jerome-etienne/neoip
#sudo apt-get update
#sudo apt-get install phantomjs
I created a small JavaScript file for PhatomJS to use to control the browser instances:
### BEGIN JAVASCRIPT ###
var page = new WebPage(),
t, address;
if (phantom.args.length === 0) {
console.log('Usage: loader.js <some URL>');
phantom.exit();
} else {
t = Date.now();
address = phantom.args[0];
var page = new WebPage();
page.onResourceRequested = function (request) {
console.log('Request ' + JSON.stringify(request, undefined, 4));
};
page.onResourceReceived = function (response) {
console.log('Receive ' + JSON.stringify(response, undefined, 4));
};
page.open(address);
}
### END JAVASCRIPT ###
And finally a launcher script that uses screen to run 400 instances of PhantomJS with the above script:
### BEGIN SHELL SCRIPT ###
#!/bin/bash
# connect 200 instances to display :0
for i in {1..200}
do
DISPLAY=:0 screen -d -m phantomjs loader.js http://ec2-50-17-168-xx.compute-1.amazonaws.com:9001/p/pad2 && sleep 2
done
# connect 200 instances to display :1
for i in {1..200}
do
DISPLAY=:1 screen -d -m phantomjs loader.js http://ec2-50-17-168-xx.compute-1.amazonaws.com:9001/p/pad2 && sleep 2
done
### END SHELL SCRIPT ###

View file

@ -1,16 +0,0 @@
#!/bin/bash
# connect 500 instances to display :0
for i in {1..500}
do
echo $i
echo "Displaying Some shit"
DISPLAY=:0 screen -d -m /home/phantomjs/bin/phantomjs loader.js http://10.0.0.55:9001/p/pad2 && sleep 2
done
# connect 500 instances to display :1
for i in {1..500}
do
echo $i
DISPLAY=:1 screen -d -m /home/phantomjs/bin/phantomjs loader.js http://10.0.0.55:9001/p/pad2 && sleep 2
done

View file

@ -1,20 +0,0 @@
var page = new WebPage(),
t, address;
if (phantom.args.length === 0) {
console.log('Usage: loader.js <some URL>');
phantom.exit();
} else {
t = Date.now();
address = phantom.args[0];
var page = new WebPage();
page.onResourceRequested = function (request) {
console.log('Request ' + JSON.stringify(request, undefined, 4));
};
page.onResourceReceived = function (response) {
console.log('Receive ' + JSON.stringify(response, undefined, 4));
};
page.open(address);
}

View file

@ -32,7 +32,7 @@ fi
bin/installDeps.sh $* || exit 1
#Move to the node folder and start
echo "start..."
echo "Started Etherpad..."
SCRIPTPATH=`pwd -P`
node $SCRIPTPATH/node_modules/ep_etherpad-lite/node/server.js $*

View file

@ -234,7 +234,19 @@ exports.doImport = function(req, res, padId)
ERR(err);
//close the connection
res.send("<head><script type='text/javascript' src='../../static/js/jquery.js'></script><script type='text/javascript' src='../../static/js/jquery_browser.js'></script></head><script>$(window).load(function(){if ( (!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf(\"1.8.\") == 0)) ){document.domain = document.domain;}var impexp = window.parent.padimpexp.handleFrameCall('" + status + "');})</script>", 200);
res.send(
"<head> \
<script type='text/javascript' src='../../static/js/jquery.js'></script> \
</head> \
<script> \
$(window).load(function(){ \
if(navigator.userAgent.indexOf('MSIE') === -1){ \
document.domain = document.domain; \
} \
var impexp = window.parent.padimpexp.handleFrameCall('" + status + "'); \
}) \
</script>"
, 200);
});
}

View file

@ -94,8 +94,18 @@ exports.handleConnect = function(client)
*/
exports.kickSessionsFromPad = function(padID)
{
if(typeof socketio.sockets['clients'] !== 'function')
return;
//skip if there is nobody on this pad
if(socketio.sockets.clients(padID).length == 0)
var roomClients = [], room = socketio.sockets.adapter.rooms[padID];
if (room) {
for (var id in room) {
roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
}
}
if(roomClients.length == 0)
return;
//disconnect everyone from this pad
@ -496,14 +506,19 @@ function handleSuggestUserName(client, message)
return;
}
var padId = sessioninfos[client.id].padId,
clients = socketio.sockets.clients(padId);
var padId = sessioninfos[client.id].padId;
var roomClients = [], room = socketio.sockets.adapter.rooms[padId];
if (room) {
for (var id in room) {
roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
}
}
//search the author and send him this message
for(var i = 0; i < clients.length; i++) {
var session = sessioninfos[clients[i].id];
for(var i = 0; i < roomClients.length; i++) {
var session = sessioninfos[roomClients[i].id];
if(session && session.author == message.data.payload.unnamedId) {
clients[i].json.send(message);
roomClients[i].json.send(message);
break;
}
}
@ -1581,8 +1596,16 @@ function composePadChangesets(padId, startNum, endNum, callback)
* Get the number of users in a pad
*/
exports.padUsersCount = function (padID, callback) {
var roomClients = [], room = socketio.sockets.adapter.rooms[padID];
if (room) {
for (var id in room) {
roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
}
}
callback(null, {
padUsersCount: socketio.sockets.clients(padID).length
padUsersCount: roomClients.length
});
}
@ -1592,7 +1615,14 @@ exports.padUsersCount = function (padID, callback) {
exports.padUsers = function (padID, callback) {
var result = [];
async.forEach(socketio.sockets.clients(padID), function(roomClient, callback) {
var roomClients = [], room = socketio.sockets.adapter.rooms[padID];
if (room) {
for (var id in room) {
roomClients.push(socketio.sockets.adapter.nsp.connected[id]);
}
}
async.forEach(roomClients, function(roomClient, callback) {
var s = sessioninfos[roomClient.id];
if(s) {
authorManager.getAuthor(s.author, function(err, author) {

View file

@ -14,7 +14,6 @@ exports.expressCreateServer = function (hook_name, args, cb) {
search_results: {},
errors: [],
};
res.send( eejs.require("ep_etherpad-lite/templates/admin/plugins.html", render_args) );
});
args.app.get('/admin/plugins/info', function(req, res) {
@ -25,7 +24,8 @@ exports.expressCreateServer = function (hook_name, args, cb) {
exports.socketio = function (hook_name, args, cb) {
var io = args.io.of("/pluginfw/installer");
io.on('connection', function (socket) {
if (!socket.handshake.session.user || !socket.handshake.session.user.is_admin) return;
if (!socket.conn.request.session || !socket.conn.request.session.user || !socket.conn.request.session.user.is_admin) return;
socket.on("getInstalled", function (query) {
// send currently installed plugins
@ -107,4 +107,4 @@ function sortPluginList(plugins, property, /*ASC?*/dir) {
// a must be equal to b
return 0;
})
}
}

View file

@ -22,7 +22,8 @@ exports.expressCreateServer = function (hook_name, args, cb) {
exports.socketio = function (hook_name, args, cb) {
var io = args.io.of("/settings");
io.on('connection', function (socket) {
if (!socket.handshake.session.user || !socket.handshake.session.user.is_admin) return;
if (!socket.conn.request.session || !socket.conn.request.session.user || !socket.conn.request.session.user.is_admin) return;
socket.on("load", function (query) {
fs.readFile('settings.json', 'utf8', function (err,data) {

View file

@ -1,24 +1,22 @@
var log4js = require('log4js');
var settings = require('../../utils/Settings');
var socketio = require('socket.io');
var socketIORouter = require("../../handler/SocketIORouter");
var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks");
var webaccess = require("ep_etherpad-lite/node/hooks/express/webaccess");
// there shouldn't be a browser that isn't compatible to all
// transports in this list at once
// e.g. XHR is disabled in IE by default, so in IE it should use jsonp-polling
var socketio = require('socket.io')({
transports: settings.socketTransportProtocols
});
var padMessageHandler = require("../../handler/PadMessageHandler");
var connect = require('connect');
exports.expressCreateServer = function (hook_name, args, cb) {
//init socket.io and redirect all requests to the MessageHandler
var io = socketio.listen(args.server);
// there shouldn't be a browser that isn't compatible to all
// transports in this list at once
// e.g. XHR is disabled in IE by default, so in IE it should use jsonp-polling
var io = socketio({
transports: settings.socketTransportProtocols
}).listen(args.server);
/* Require an express session cookie to be present, and load the
* session. See http://www.danielbaulig.de/socket-ioexpress for more

View file

@ -14,23 +14,22 @@
* limitations under the License.
*/
var jsdom = require('jsdom-nocontextifiy').jsdom;
var log4js = require('log4js');
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
var contentcollector = require("ep_etherpad-lite/static/js/contentcollector");
var cheerio = require("cheerio");
function setPadHTML(pad, html, callback)
{
var apiLogger = log4js.getLogger("ImportHtml");
// Parse the incoming HTML with jsdom
try{
var doc = jsdom(html.replace(/>\n+</g, '><'));
}catch(e){
apiLogger.warn("Error importing, possibly caused by malformed HTML");
var doc = jsdom("<html><body><div>Error during import, possibly malformed HTML</div></body></html>");
}
var $ = cheerio.load(html);
// Appends a line break, used by Etherpad to ensure a caret is available
// below the last line of an import
$('body').append("<p></p>");
var doc = $('html')[0];
apiLogger.debug('html:');
apiLogger.debug(html);
@ -38,7 +37,7 @@ function setPadHTML(pad, html, callback)
// using the content collector object
var cc = contentcollector.makeContentCollector(true, null, pad.pool);
try{ // we use a try here because if the HTML is bad it will blow up
cc.collectContent(doc.childNodes[0]);
cc.collectContent(doc);
}catch(e){
apiLogger.warn("HTML was not properly formed", e);
return; // We don't process the HTML because it was bad..

View file

@ -2,6 +2,7 @@
"pad.js": [
"pad.js"
, "pad_utils.js"
, "browser.js"
, "pad_cookie.js"
, "pad_editor.js"
, "pad_editbar.js"
@ -24,6 +25,7 @@
, "colorutils.js"
, "draggable.js"
, "pad_utils.js"
, "browser.js"
, "pad_cookie.js"
, "pad_editor.js"
, "pad_editbar.js"
@ -42,6 +44,7 @@
]
, "ace2_inner.js": [
"ace2_inner.js"
, "browser.js"
, "AttributePool.js"
, "Changeset.js"
, "ChangesetUtils.js"
@ -58,6 +61,7 @@
]
, "ace2_common.js": [
"ace2_common.js"
, "browser.js"
, "jquery.js"
, "rjquery.js"
, "$async.js"

View file

@ -25,7 +25,7 @@
"formidable" : "1.0.9",
"log4js" : "0.6.6",
"nodemailer" : "0.3.x",
"jsdom-nocontextifiy" : "0.2.10",
"cheerio" : "0.18.0",
"async-stacktrace" : "0.0.2",
"npm" : "1.4.x",
"ejs" : "0.6.1",

View file

@ -698,9 +698,6 @@ table#otheruserstable {
margin-top: 12px;
padding:2px 4px 2px 4px;
}
#importstatusball {
height: 50px
}
#chatthrob {
display: none;
position: absolute;

View file

@ -28,7 +28,6 @@ $ = jQuery = require('./rjquery').$;
_ = require("./underscore");
var isNodeText = Ace2Common.isNodeText,
browser = $.browser,
getAssoc = Ace2Common.getAssoc,
setAssoc = Ace2Common.setAssoc,
isTextNode = Ace2Common.isTextNode,
@ -52,6 +51,7 @@ function Ace2Inner(){
var SkipList = require('./skiplist');
var undoModule = require('./undomodule').undoModule;
var AttributeManager = require('./AttributeManager');
var browser = require('./browser');
var DEBUG = false; //$$ build script replaces the string "var DEBUG=true;//$$" with "var DEBUG=false;"
// changed to false
@ -3700,7 +3700,7 @@ function Ace2Inner(){
}, 0);
specialHandled = true;
}
if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "s" && (evt.metaKey || evt.ctrlKey)) /* Do a saved revision on ctrl S */
if ((!specialHandled) && isTypeForCmdKey && String.fromCharCode(which).toLowerCase() == "s" && (evt.metaKey || evt.ctrlKey) && !evt.altKey) /* Do a saved revision on ctrl S */
{
evt.preventDefault();
var originalBackground = parent.parent.$('#revisionlink').css("background")
@ -3857,7 +3857,7 @@ function Ace2Inner(){
/* Attempt to apply some sanity to cursor handling in Chrome after a copy / paste event
We have to do this the way we do because rep. doesn't hold the value for keyheld events IE if the user
presses and holds the arrow key .. Sorry if this is ugly, blame Chrome's weird handling of viewports after new content is added*/
if((evt.which == 37 || evt.which == 38 || evt.which == 39 || evt.which == 40) && $.browser.chrome){
if((evt.which == 37 || evt.which == 38 || evt.which == 39 || evt.which == 40) && browser.chrome){
var viewport = getViewPortTopBottom();
var myselection = document.getSelection(); // get the current caret selection, can't use rep. here because that only gives us the start position not the current
var caretOffsetTop = myselection.focusNode.parentNode.offsetTop || myselection.focusNode.offsetTop; // get the carets selection offset in px IE 214

View file

@ -10,7 +10,8 @@ $(document).ready(function () {
resource = baseURL.substring(1) + "socket.io";
//connect
socket = io.connect(url, {resource : resource}).of("/pluginfw/installer");
var room = url + "pluginfw/installer";
socket = io.connect(room, {resource : resource});
function search(searchTerm, limit) {
if(search.searchTerm != searchTerm) {

View file

@ -9,7 +9,8 @@ $(document).ready(function () {
resource = baseURL.substring(1) + "socket.io";
//connect
socket = io.connect(url, {resource : resource}).of("/settings");
var room = url + "settings";
socket = io.connect(room, {resource : resource});
socket.on('settings', function (settings) {

View file

@ -66,7 +66,7 @@ function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, Bro
}
// for IE
if ($.browser.msie)
if (browser.msie)
{
try
{

240
src/static/js/browser.js Normal file
View file

@ -0,0 +1,240 @@
/*!
* Bowser - a browser detector
* https://github.com/ded/bowser
* MIT License | (c) Dustin Diaz 2014
*/
!function (name, definition) {
if (typeof module != 'undefined' && module.exports) module.exports['browser'] = definition()
else if (typeof define == 'function' && define.amd) define(definition)
else this[name] = definition()
}('bowser', function () {
/**
* See useragents.js for examples of navigator.userAgent
*/
var t = true
function detect(ua) {
function getFirstMatch(regex) {
var match = ua.match(regex);
return (match && match.length > 1 && match[1]) || '';
}
var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase()
, likeAndroid = /like android/i.test(ua)
, android = !likeAndroid && /android/i.test(ua)
, versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i)
, tablet = /tablet/i.test(ua)
, mobile = !tablet && /[^-]mobi/i.test(ua)
, result
if (/opera|opr/i.test(ua)) {
result = {
name: 'Opera'
, opera: t
, version: versionIdentifier || getFirstMatch(/(?:opera|opr)[\s\/](\d+(\.\d+)?)/i)
}
}
else if (/windows phone/i.test(ua)) {
result = {
name: 'Windows Phone'
, windowsphone: t
, msie: t
, version: getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i)
}
}
else if (/msie|trident/i.test(ua)) {
result = {
name: 'Internet Explorer'
, msie: t
, version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i)
}
}
else if (/chrome|crios|crmo/i.test(ua)) {
result = {
name: 'Chrome'
, chrome: t
, version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i)
}
}
else if (iosdevice) {
result = {
name : iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod'
}
// WTF: version is not part of user agent in web apps
if (versionIdentifier) {
result.version = versionIdentifier
}
}
else if (/sailfish/i.test(ua)) {
result = {
name: 'Sailfish'
, sailfish: t
, version: getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i)
}
}
else if (/seamonkey\//i.test(ua)) {
result = {
name: 'SeaMonkey'
, seamonkey: t
, version: getFirstMatch(/seamonkey\/(\d+(\.\d+)?)/i)
}
}
else if (/firefox|iceweasel/i.test(ua)) {
result = {
name: 'Firefox'
, firefox: t
, version: getFirstMatch(/(?:firefox|iceweasel)[ \/](\d+(\.\d+)?)/i)
}
if (/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(ua)) {
result.firefoxos = t
}
}
else if (/silk/i.test(ua)) {
result = {
name: 'Amazon Silk'
, silk: t
, version : getFirstMatch(/silk\/(\d+(\.\d+)?)/i)
}
}
else if (android) {
result = {
name: 'Android'
, version: versionIdentifier
}
}
else if (/phantom/i.test(ua)) {
result = {
name: 'PhantomJS'
, phantom: t
, version: getFirstMatch(/phantomjs\/(\d+(\.\d+)?)/i)
}
}
else if (/blackberry|\bbb\d+/i.test(ua) || /rim\stablet/i.test(ua)) {
result = {
name: 'BlackBerry'
, blackberry: t
, version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i)
}
}
else if (/(web|hpw)os/i.test(ua)) {
result = {
name: 'WebOS'
, webos: t
, version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i)
};
/touchpad\//i.test(ua) && (result.touchpad = t)
}
else if (/bada/i.test(ua)) {
result = {
name: 'Bada'
, bada: t
, version: getFirstMatch(/dolfin\/(\d+(\.\d+)?)/i)
};
}
else if (/tizen/i.test(ua)) {
result = {
name: 'Tizen'
, tizen: t
, version: getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i) || versionIdentifier
};
}
else if (/safari/i.test(ua)) {
result = {
name: 'Safari'
, safari: t
, version: versionIdentifier
}
}
else result = {}
// set webkit or gecko flag for browsers based on these engines
if (/(apple)?webkit/i.test(ua)) {
result.name = result.name || "Webkit"
result.webkit = t
if (!result.version && versionIdentifier) {
result.version = versionIdentifier
}
} else if (!result.opera && /gecko\//i.test(ua)) {
result.name = result.name || "Gecko"
result.gecko = t
result.version = result.version || getFirstMatch(/gecko\/(\d+(\.\d+)?)/i)
}
// set OS flags for platforms that have multiple browsers
if (android || result.silk) {
result.android = t
} else if (iosdevice) {
result[iosdevice] = t
result.ios = t
}
// OS version extraction
var osVersion = '';
if (iosdevice) {
osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i);
osVersion = osVersion.replace(/[_\s]/g, '.');
} else if (android) {
osVersion = getFirstMatch(/android[ \/-](\d+(\.\d+)*)/i);
} else if (result.windowsphone) {
osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i);
} else if (result.webos) {
osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i);
} else if (result.blackberry) {
osVersion = getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i);
} else if (result.bada) {
osVersion = getFirstMatch(/bada\/(\d+(\.\d+)*)/i);
} else if (result.tizen) {
osVersion = getFirstMatch(/tizen[\/\s](\d+(\.\d+)*)/i);
}
if (osVersion) {
result.osversion = osVersion;
}
// device type extraction
var osMajorVersion = osVersion.split('.')[0];
if (tablet || iosdevice == 'ipad' || (android && (osMajorVersion == 3 || (osMajorVersion == 4 && !mobile))) || result.silk) {
result.tablet = t
} else if (mobile || iosdevice == 'iphone' || iosdevice == 'ipod' || android || result.blackberry || result.webos || result.bada) {
result.mobile = t
}
// Graded Browser Support
// http://developer.yahoo.com/yui/articles/gbs
if ((result.msie && result.version >= 10) ||
(result.chrome && result.version >= 20) ||
(result.firefox && result.version >= 20.0) ||
(result.safari && result.version >= 6) ||
(result.opera && result.version >= 10.0) ||
(result.ios && result.osversion && result.osversion.split(".")[0] >= 6) ||
(result.blackberry && result.version >= 10.1)
) {
result.a = t;
}
else if ((result.msie && result.version < 10) ||
(result.chrome && result.version < 20) ||
(result.firefox && result.version < 20.0) ||
(result.safari && result.version < 6) ||
(result.opera && result.version < 10.0) ||
(result.ios && result.osversion && result.osversion.split(".")[0] < 6)
) {
result.c = t
} else result.x = t
return result
}
var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent : '')
/*
* Set our detect method to the main bowser object so we can
* reuse it to test other user agents.
* This is needed to implement future tests.
*/
bowser._detect = detect;
return bowser
});

View file

@ -82,7 +82,7 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad)
{}
};
if ($.browser.mozilla)
if (browser.mozilla)
{
// Prevent "escape" from taking effect and canceling a comet connection;
// doesn't work if focus is on an iframe.

View file

@ -54,10 +54,14 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class
},
nodeNumChildren: function(n)
{
if(n.childNodes == null) return 0;
return n.childNodes.length;
},
nodeChild: function(n, i)
{
if(n.childNodes.item == null){
return n.childNodes[i];
}
return n.childNodes.item(i);
},
nodeProp: function(n, p)
@ -66,6 +70,7 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class
},
nodeAttr: function(n, a)
{
if(n.getAttribute == null) return null;
return n.getAttribute(a);
},
optNodeInnerHTML: function(n)

View file

@ -170,7 +170,7 @@ $._farbtastic = function (container, options) {
// New color
color2 = fb.pack(fb.HSLToRGB([d2, 1, 0.5]));
if (i > 0) {
if ($.browser.msie) {
if (browser.msie) {
// IE's gradient calculations mess up the colors. Correct along the diagonals.
var corr = (1 + Math.min(Math.abs(Math.tan(angle1)), Math.abs(Math.tan(Math.PI / 2 - angle1)))) / n;
color1 = fb.pack(fb.HSLToRGB([d1 - 0.15 * corr, 1, 0.5]));
@ -254,7 +254,7 @@ $._farbtastic = function (container, options) {
fb.ctxMask.drawImage(buffer, 0, 0, sz + 1, sz + 1, -sq, -sq, sq * 2, sq * 2);
}
// Method #2: drawing commands (old Canvas).
else if (!$.browser.msie) {
else if (!browser.msie) {
// Render directly at half-resolution
var sz = Math.floor(size / 2);
calculateMask(sz, sz, function (x, y, c, a) {

View file

@ -1,50 +0,0 @@
/*
Copied from jQuery 1.8, the last jquery version with browser recognition support
*/
(function(){
// Use of jQuery.browser is frowned upon.
// More details: http://api.jquery.com/jQuery.browser
// jQuery.uaMatch maintained for back-compat
var uaMatch = function( ua ) {
ua = ua.toLowerCase();
var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
/(msie) ([\w.]+)/.exec( ua ) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
[];
return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
var userAgent = navigator.userAgent;
var matched = uaMatch(userAgent);
var browser = {};
if ( matched.browser ) {
browser[ matched.browser ] = true;
browser.version = matched.version;
}
// Chrome is Webkit, but Webkit is also Safari.
if ( browser.chrome ) {
browser.webkit = true;
} else if ( browser.webkit ) {
browser.safari = true;
}
//custom extensions, the original jquery didn't have these
browser.windows = /windows/i.test(userAgent);
browser.mobile = /mobile/i.test(userAgent) || /android/i.test(userAgent);
if(typeof exports !== 'undefined'){
exports.browser = browser;
} else{
$.browser = browser;
}
})();

View file

@ -43,7 +43,6 @@ 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;
var randomString = require('./pad_utils').randomString;
@ -453,13 +452,13 @@ var pad = {
pad.initTime = +(new Date());
pad.padOptions = clientVars.initialOptions;
if ((!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf("1.8.") == 0)))
if ((!browser.msie) && (!(browser.mozilla && browser.version.indexOf("1.8.") == 0)))
{
document.domain = document.domain; // for comet
}
// for IE
if ($.browser.msie)
if (browser.msie)
{
try
{

View file

@ -730,7 +730,7 @@ var paduserlist = (function()
$("#myswatch").css({'background-color': myUserInfo.colorId});
if ($.browser.msie && parseInt($.browser.version) <= 8) {
if (browser.msie && parseInt(browser.version) <= 8) {
$("li[data-key=showusers] > a").css({'box-shadow': 'inset 0 0 30px ' + myUserInfo.colorId,'background-color': myUserInfo.colorId});
}
else

View file

@ -1,10 +1,5 @@
// Proviedes a require'able version of jQuery without leaking $ and jQuery;
require('./jquery');
var jq = window.$.noConflict(true);
//added the old browser recognition
jq.browser = require('./jquery_browser').browser;
exports.jQuery = exports.$ = jq;
exports.jQuery = exports.$ = jq;

View file

@ -10,7 +10,7 @@
<body>
<div id="wrapper">
<div class="menu">
<h1><a href="../../">Etherpad</a></h1>
<h1><a href="../">Etherpad</a></h1>
<ul>
<% e.begin_block("adminMenu"); %>
<li><a href="plugins">Plugin manager</a> </li>

View file

@ -11,7 +11,7 @@
<body>
<div id="wrapper">
<div class="menu">
<h1><a href="../../../">Etherpad</a></h1>
<h1><a href="../../">Etherpad</a></h1>
<ul>
<% e.begin_block("adminMenu"); %>
<li><a href="../plugins">Plugin manager</a> </li>

View file

@ -20,7 +20,7 @@
<% } %>
<div class="menu">
<h1><a href="../../">Etherpad</a></h1>
<h1><a href="../">Etherpad</a></h1>
<ul>
<% e.begin_block("adminMenu"); %>
<li><a href="plugins">Plugin manager</a> </li>

View file

@ -24,7 +24,7 @@
<div class="menu">
<h1><a href="../../">Etherpad</a></h1>
<h1><a href="../">Etherpad</a></h1>
<ul>
<% e.begin_block("adminMenu"); %>
<li><a href="plugins">Plugin manager</a> </li>

View file

@ -367,8 +367,8 @@
require.setGlobalKeyPath("require");
$ = jQuery = require('ep_etherpad-lite/static/js/rjquery').jQuery; // Expose jQuery #HACK
if ((!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf("1.8.") == 0))) {
browser = require('ep_etherpad-lite/static/js/browser').browser;
if ((!browser.msie) && (!(browser.mozilla && browser.version.indexOf("1.8.") == 0))) {
document.domain = document.domain; // for comet
}

View file

@ -215,8 +215,9 @@
require.setGlobalKeyPath("require");
$ = jQuery = require('ep_etherpad-lite/static/js/rjquery').jQuery; // Expose jQuery #HACK
browser = require('ep_etherpad-lite/static/js/browser').browser;
if ((!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf("1.8.") == 0))) {
if ((!browser.msie) && (!(browser.mozilla && browser.version.indexOf("1.8.") == 0))) {
document.domain = document.domain; // for comet
}