etherpad-lite/static/js/pad.js

743 lines
25 KiB
JavaScript
Raw Normal View History

/**
* This code is mostly from the old Etherpad. Please help us to comment this code.
* This helps other people to understand this code better and helps them to improve it.
* TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
*/
2011-03-26 13:10:41 +00:00
/**
* Copyright 2009 Google Inc., 2011 Peter 'Pita' Martischka (Primary Technology Ltd)
2011-07-07 18:59:34 +01:00
*
2011-03-26 13:10:41 +00:00
* 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
2011-07-07 18:59:34 +01:00
*
2011-03-26 13:10:41 +00:00
* http://www.apache.org/licenses/LICENSE-2.0
2011-07-07 18:59:34 +01:00
*
2011-03-26 13:10:41 +00:00
* 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.
*/
/* global $, window */
var socket;
// These jQuery things should create local references, but for now `require()`
// assigns to the global `$` and augments it with plugins.
require('/jquery');
require('/farbtastic');
require('/excanvas');
JSON = require('/json2');
require('/undo-xpopup');
2012-02-04 18:11:41 +01:00
require('/prefixfree');
var chat = require('/chat').chat,
getCollabClient = require('/collab_client').getCollabClient,
padconnectionstatus = require('/pad_connectionstatus').padconnectionstatus,
padcookie = require('/pad_cookie').padcookie,
paddocbar = require('/pad_docbar').paddocbar,
padeditbar = require('/pad_editbar').padeditbar,
padeditor = require('/pad_editor').padeditor,
padimpexp = require('/pad_impexp').padimpexp,
padmodals = require('/pad_modals').padmodals,
padsavedrevs = require('/pad_savedrevs').padsavedrevs,
paduserlist = require('/pad_userlist').paduserlist,
padutils = require('/pad_utils').padutils,
createCookie = require('/pad_utils').createCookie,
readCookie = require('/pad_utils').readCookie,
randomString = require('/pad_utils').randomString;
function getParams() {
var params = getUrlVars(),
showControls = params['showControls'],
showChat = params['showChat'],
userName = params['userName'],
showLineNumbers = params['showLineNumbers'],
useMonospaceFont = params['useMonospaceFont'],
IsnoColors = params['noColors'],
hideQRCode = params['hideQRCode'],
rtl = params['rtl'],
alwaysShowChat = params['alwaysShowChat'];
if (IsnoColors) {
if (IsnoColors == 'true') {
settings.noColors = true;
$('#buttonicon-clearauthorship').hide();
}
}
if (showControls) {
if (showControls == 'false') {
$('#editbar').hide();
$('#editorcontainer').css({top:0});
}
}
if (showChat) {
if (showChat == 'false') {
$('#chaticon').hide();
}
}
if (showLineNumbers) {
if (showLineNumbers == 'false')
settings.LineNumbersDisabled = true;
}
if (useMonospaceFont) {
if (useMonospaceFont == 'true')
settings.useMonospaceFontGlobal = true;
}
if (userName) {
// 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 = unescape(userName);
}
if (hideQRCode) {
$('#qrcode').hide();
}
if (rtl) {
if (rtl == 'true')
settings.rtlIsTrue = true;
2011-12-04 18:55:35 +00:00
}
if (alwaysShowChat) {
if (alwaysShowChat == 'true')
chat.stickToScreen();
}
}
function getUrlVars() {
var vars = [], hash,
hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i=0, l=hashes.length; i < l; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
function savePassword() {
// set the password cookie
createCookie('password', $('#passwordinput').val(), null, document.location.pathname);
// reload
document.location = document.location;
}
function handshake() {
var loc = document.location,
port = loc.port == '' ? (loc.protocol == 'https:' ? 443 : 80) : loc.port, // get the correct port
url = loc.protocol + '//' + loc.hostname + ':' + port + '/', // create the url
resource = loc.pathname.substr(1, loc.pathname.indexOf('/p/')) + 'socket.io'; // determine current subfolder
// connect
socket = pad.socket = io.connect(url, {
resource: resource,
'max reconnection attempts': 3
2011-07-07 18:59:34 +01:00
});
function sendClientReady(isReconnect) {
var padId = document.location.pathname.substring(document.location.pathname.lastIndexOf('/') + 1);
2011-11-28 11:26:36 -08:00
padId = decodeURIComponent(padId); // unescape neccesary due to Safari and Opera interpretation of spaces
2011-08-15 15:40:38 +01:00
if (!isReconnect)
document.title = padId.replace(/_+/g, ' ') + " | " + document.title;
2011-07-07 18:59:34 +01:00
var token = readCookie('token');
if (token == null) {
token = 't.' + randomString();
createCookie('token', token, 60);
}
var sessionID = readCookie('sessionID'),
password = readCookie('password'),
msg = {
'component' : 'pad',
'type' : 'CLIENT_READY',
'padId' : padId,
'sessionID' : sessionID,
'password' : password,
'token' : token,
'protocolVersion' : 2
};
// this is a reconnect, lets tell the server our revision number
if (isReconnect == true) {
msg.client_rev=pad.collabClient.getCurrentRevisionNumber();
msg.reconnect=true;
}
2011-07-07 18:59:34 +01:00
socket.json.send(msg);
};
var disconnectTimeout;
socket.once('connect', function() {
sendClientReady(false);
});
socket.on('reconnect', function() {
// reconnect is before timeout, let´s stop the timeout
if (disconnectTimeout)
clearTimeout(disconnectTimeout);
pad.collabClient.setChannelState('CONNECTED');
sendClientReady(true);
});
socket.on('disconnect', function() {
function disconnectEvent() {
pad.collabClient.setChannelState('DISCONNECTED', 'reconnect_timeout');
}
pad.collabClient.setChannelState('RECONNECTING');
disconnectTimeout = setTimeout(disconnectEvent, 10000);
2011-07-07 18:59:34 +01:00
});
var receivedClientVars = false,
initalized = false;
2011-07-07 18:59:34 +01:00
socket.on('message', function(obj) {
// access was not granted, give the user a message
if (!receivedClientVars && obj.accessStatus) {
if (obj.accessStatus == 'deny')
$('#editorloadingbox').html("<b>You do not have permission to access this pad</b>");
else if (obj.accessStatus == "needPassword") {
$('#editorloadingbox').html("<b>You need a password to access this pad</b><br>" +
"<input id='passwordinput' type='password' name='password'>"+
"<button type='button' onclick=\"" + padutils.escapeHtml('require('+JSON.stringify(module.id)+").savePassword()") + "\">ok</button>");
} else if (obj.accessStatus == 'wrongPassword') {
$("#editorloadingbox").html("<b>You're password was wrong</b><br>" +
"<input id='passwordinput' type='password' name='password'>"+
"<button type='button' onclick=\"" + padutils.escapeHtml('require('+JSON.stringify(module.id)+").savePassword()") + "\">ok</button>");
}
} else if (!receivedClientVars) { // if we haven't received the clientVars yet, then this message should it be
// log the message
if (window.console)
console.log(obj);
2011-07-07 18:59:34 +01:00
receivedClientVars = true;
// set some client vars
2011-07-07 18:59:34 +01:00
clientVars = obj;
clientVars.userAgent = 'Anonymous';
clientVars.collab_client_vars.clientAgent = 'Anonymous';
2011-07-07 18:59:34 +01:00
// initalize the pad
pad._afterHandshake();
2011-07-07 18:59:34 +01:00
initalized = true;
// if LineNumbersDisabled is set to true, we need to hide the line numbers
if (settings.LineNumbersDisabled == true)
pad.changeViewOption('showLineNumbers', false);
// if noColors is set to true, we need to hide the backround colors on the ace spans
if (settings.noColors == true)
pad.changeViewOption('noColors', true);
if (settings.rtlIsTrue == true)
2011-12-04 18:55:35 +00:00
pad.changeViewOption('rtl', true);
// if Monospacefont is set to true, change it to monospace
if (settings.useMonospaceFontGlobal == true)
pad.changeViewOption('useMonospaceFont', true);
// if globalUserName is set, tell the server and the client about the new authorname
if (settings.globalUserName !== false) {
pad.notifyChangeName(settings.globalUserName); // notify the server
pad.myUserInfo.name = settings.globalUserName;
$('#myusernameedit').attr({"value":settings.globalUserName}); // update the current user´s UI
}
2011-07-07 18:59:34 +01:00
}
// handle every message after the clientVars
else {
// advice the client to disconnect
if (obj.disconnect) {
2011-08-16 20:02:30 +01:00
padconnectionstatus.disconnected(obj.disconnect);
2011-07-07 18:59:34 +01:00
socket.disconnect();
return;
} else {
2011-07-07 18:59:34 +01:00
pad.collabClient.handleMessageFromServer(obj);
2011-03-26 13:10:41 +00:00
}
2011-07-07 18:59:34 +01:00
}
});
// bind the colorpicker
2011-08-20 18:22:10 +01:00
var fb = $('#colorpicker').farbtastic({ callback: '#mycolorpickerpreview', width: 220});
2011-03-26 13:10:41 +00:00
}
var pad = {
// don't access these directly from outside this file, except for debugging
collabClient : null,
myUserInfo : null,
diagnosticInfo : {},
initTime : 0,
clientTimeOffset : null,
preloadedImages : false,
padOptions : {},
2011-03-26 13:10:41 +00:00
// these don't require init; clientVars should all go through here
getPadId : function() {
2011-07-07 18:59:34 +01:00
return clientVars.padId;
},
getClientIp : function() {
2011-07-07 18:59:34 +01:00
return clientVars.clientIp;
},
getIsProPad : function() {
2011-07-07 18:59:34 +01:00
return clientVars.isProPad;
},
getColorPalette : function() {
2011-07-07 18:59:34 +01:00
return clientVars.colorPalette;
},
getDisplayUserAgent: function() {
2011-03-26 13:10:41 +00:00
return padutils.uaDisplay(clientVars.userAgent);
},
getIsDebugEnabled : function() {
2011-07-07 18:59:34 +01:00
return clientVars.debugEnabled;
},
getPrivilege : function(name) {
2011-07-07 18:59:34 +01:00
return clientVars.accountPrivs[name];
},
getUserIsGuest : function() {
2011-07-07 18:59:34 +01:00
return clientVars.userIsGuest;
},
getUserId : function() {
2011-07-07 18:59:34 +01:00
return pad.myUserInfo.userId;
},
getUserName : function() {
2011-07-07 18:59:34 +01:00
return pad.myUserInfo.name;
},
sendClientMessage : function(msg) {
2011-03-26 13:10:41 +00:00
pad.collabClient.sendClientMessage(msg);
},
init : function() {
padutils.setupGlobalExceptionHandler();
$(document).ready(function() {
// start the custom js
if (typeof customStart == 'function')
customStart();
getParams();
handshake();
});
$(window).unload(function() {
pad.dispose();
});
},
_afterHandshake : function() {
2011-07-14 16:15:38 +01:00
pad.clientTimeOffset = new Date().getTime() - clientVars.serverTimestamp;
// initialize the chat
2012-01-15 21:05:19 -08:00
chat.init(this);
2011-03-26 13:10:41 +00:00
pad.initTime = +(new Date());
pad.padOptions = clientVars.initialOptions;
2011-07-07 18:59:34 +01:00
if ((!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf("1.8.") == 0)))
2011-03-26 13:10:41 +00:00
document.domain = document.domain; // for comet
// for IE
if ($.browser.msie) {
try {
doc.execCommand('BackgroundImageCache', false, true);
2011-07-07 18:59:34 +01:00
}
catch (e)
{}
2011-03-26 13:10:41 +00:00
}
// order of inits is important here:
padcookie.init(clientVars.cookiePrefsToSet, this);
$('#widthprefcheck').click(pad.toggleWidthPref);
2011-03-26 13:10:41 +00:00
pad.myUserInfo = {
userId : clientVars.userId,
name : clientVars.userName,
ip : pad.getClientIp(),
colorId : clientVars.userColor,
userAgent : pad.getDisplayUserAgent()
2011-03-26 13:10:41 +00:00
};
2011-08-20 18:22:10 +01:00
if (clientVars.specialKey) {
2011-03-26 13:10:41 +00:00
pad.myUserInfo.specialKey = clientVars.specialKey;
2011-07-07 18:59:34 +01:00
if (clientVars.specialKeyTranslation)
$('#specialkeyarea').html('mode: ' + String(clientVars.specialKeyTranslation).toUpperCase());
2011-03-26 13:10:41 +00:00
}
paddocbar.init({
isTitleEditable : pad.getIsProPad(),
initialTitle : clientVars.initialTitle,
initialPassword : clientVars.initialPassword,
guestPolicy : pad.padOptions.guestPolicy
}, this);
padimpexp.init(this);
padsavedrevs.init(clientVars.initialRevisionList, this);
padeditor.init(postAceInit, pad.padOptions.view || {}, this);
paduserlist.init(pad.myUserInfo, this);
2011-07-07 18:59:34 +01:00
// padchat.init(clientVars.chatHistory, pad.myUserInfo);
2011-03-26 13:10:41 +00:00
padconnectionstatus.init();
padmodals.init(this);
2011-07-07 18:59:34 +01:00
pad.collabClient = getCollabClient(padeditor.ace, clientVars.collab_client_vars, pad.myUserInfo, {
colorPalette: pad.getColorPalette()
}, pad);
2011-03-26 13:10:41 +00:00
pad.collabClient.setOnUserJoin(pad.handleUserJoin);
pad.collabClient.setOnUpdateUserInfo(pad.handleUserUpdate);
pad.collabClient.setOnUserLeave(pad.handleUserLeave);
pad.collabClient.setOnClientMessage(pad.handleClientMessage);
pad.collabClient.setOnServerMessage(pad.handleServerMessage);
pad.collabClient.setOnChannelStateChange(pad.handleChannelStateChange);
pad.collabClient.setOnInternalAction(pad.handleCollabAction);
function postAceInit() {
2011-03-26 13:10:41 +00:00
padeditbar.init();
setTimeout(function() {padeditor.ace.focus();}, 0);
2011-03-26 13:10:41 +00:00
}
},
dispose: function() {
2011-03-26 13:10:41 +00:00
padeditor.dispose();
},
notifyChangeName: function(newName) {
2011-03-26 13:10:41 +00:00
pad.myUserInfo.name = newName;
pad.collabClient.updateUserInfo(pad.myUserInfo);
2011-03-27 10:06:16 +00:00
//padchat.handleUserJoinOrUpdate(pad.myUserInfo);
2011-03-26 13:10:41 +00:00
},
notifyChangeColor: function(newColorId) {
2011-03-26 13:10:41 +00:00
pad.myUserInfo.colorId = newColorId;
pad.collabClient.updateUserInfo(pad.myUserInfo);
2011-03-27 10:06:16 +00:00
//padchat.handleUserJoinOrUpdate(pad.myUserInfo);
2011-03-26 13:10:41 +00:00
},
notifyChangeTitle: function(newTitle) {
pad.collabClient.sendClientMessage({
type : 'padtitle',
title : newTitle,
changedBy : pad.myUserInfo.name || 'unnamed'
2011-03-26 13:10:41 +00:00
});
},
notifyChangePassword: function(newPass) {
pad.collabClient.sendClientMessage({
type : 'padpassword',
password : newPass,
changedBy : pad.myUserInfo.name || 'unnamed'
2011-03-26 13:10:41 +00:00
});
},
changePadOption: function(key, value) {
2011-03-26 13:10:41 +00:00
var options = {};
options[key] = value;
pad.handleOptionsChange(options);
pad.collabClient.sendClientMessage({
type : 'padoptions',
options : options,
changedBy : pad.myUserInfo.name || 'unnamed'
2011-03-26 13:10:41 +00:00
});
},
changeViewOption: function(key, value) {
2011-07-07 18:59:34 +01:00
var options = {
view: {}
};
2011-03-26 13:10:41 +00:00
options.view[key] = value;
pad.handleOptionsChange(options);
},
handleOptionsChange: function(opts) {
// opts object is a full set of options or just some options to change
if (opts.view) {
2011-07-07 18:59:34 +01:00
if (!pad.padOptions.view)
2011-03-26 13:10:41 +00:00
pad.padOptions.view = {};
for (var k in opts.view) {
2011-03-26 13:10:41 +00:00
pad.padOptions.view[k] = opts.view[k];
}
padeditor.setViewOptions(pad.padOptions.view);
}
if (opts.guestPolicy) {
// order is important here:
2011-03-26 13:10:41 +00:00
pad.padOptions.guestPolicy = opts.guestPolicy;
paddocbar.setGuestPolicy(opts.guestPolicy);
}
},
getPadOptions: function() {
2011-03-26 13:10:41 +00:00
// caller shouldn't mutate the object
return pad.padOptions;
},
isPadPublic: function() {
2011-07-07 18:59:34 +01:00
return (!pad.getIsProPad()) || (pad.getPadOptions().guestPolicy == 'allow');
2011-03-26 13:10:41 +00:00
},
suggestUserName: function(userId, name) {
pad.collabClient.sendClientMessage({
type : 'suggestUserName',
unnamedId : userId,
newName : name
2011-03-26 13:10:41 +00:00
});
},
handleUserJoin: function(userInfo) {
2011-03-26 13:10:41 +00:00
paduserlist.userJoinOrUpdate(userInfo);
2011-03-27 10:06:16 +00:00
//padchat.handleUserJoinOrUpdate(userInfo);
2011-03-26 13:10:41 +00:00
},
handleUserUpdate: function(userInfo) {
2011-03-26 13:10:41 +00:00
paduserlist.userJoinOrUpdate(userInfo);
2011-03-27 10:06:16 +00:00
//padchat.handleUserJoinOrUpdate(userInfo);
2011-03-26 13:10:41 +00:00
},
handleUserLeave: function(userInfo) {
2011-03-26 13:10:41 +00:00
paduserlist.userLeave(userInfo);
2011-03-27 10:06:16 +00:00
//padchat.handleUserLeave(userInfo);
2011-03-26 13:10:41 +00:00
},
handleClientMessage: function(msg) {
switch (msg.type) {
case 'suggestUserName':
if (msg.unnamedId == pad.myUserInfo.userId && msg.newName && !pad.myUserInfo.name) {
pad.notifyChangeName(msg.newName);
paduserlist.setMyUserInfo(pad.myUserInfo);
}
break;
case 'chat':
// padchat.receiveChat(msg);
break;
case 'padtitle':
paddocbar.changeTitle(msg.title);
break;
case 'padpassword':
paddocbar.changePassword(msg.password);
break;
case 'newRevisionList':
padsavedrevs.newRevisionList(msg.revisionList);
break;
case 'revisionLabel':
padsavedrevs.newRevisionList(msg.revisionList);
break;
case 'padoptions':
var opts = msg.options;
pad.handleOptionsChange(opts);
break;
case 'guestanswer':
// someone answered a prompt, remove it
paduserlist.removeGuestPrompt(msg.guestId);
break;
}
},
editbarClick: function(cmd) {
2011-07-07 18:59:34 +01:00
if (padeditbar)
2011-03-26 13:10:41 +00:00
padeditbar.toolbarClick(cmd);
},
dmesg: function(m) {
if (pad.getIsDebugEnabled()) {
var djs = $('#djs').get(0),
wasAtBottom = (djs.scrollTop - (djs.scrollHeight - $(djs).height()) >= -20);
2011-07-07 18:59:34 +01:00
$('#djs').append('<p>' + m + '</p>');
if (wasAtBottom)
2011-03-26 13:10:41 +00:00
djs.scrollTop = djs.scrollHeight;
}
},
handleServerMessage: function(m) {
if (m.type == 'NOTICE') {
if (m.text) {
alertBar.displayMessage(function(abar) {
abar.find('#servermsgdate').html(' (' + padutils.simpleDateTime(new Date) + ')');
abar.find('#servermsgtext').html(m.text);
2011-03-26 13:10:41 +00:00
});
}
2011-07-07 18:59:34 +01:00
if (m.js)
window['ev' + 'al'](m.js);
} else if (m.type == 'GUEST_PROMPT') {
2011-03-26 13:10:41 +00:00
paduserlist.showGuestPrompt(m.userId, m.displayName);
}
},
handleChannelStateChange: function(newState, message) {
var oldFullyConnected = !! padconnectionstatus.isFullyConnected(),
wasConnecting = (padconnectionstatus.getStatus().what == 'connecting');
if (newState == 'CONNECTED')
2011-03-26 13:10:41 +00:00
padconnectionstatus.connected();
else if (newState == 'RECONNECTING')
2011-03-26 13:10:41 +00:00
padconnectionstatus.reconnecting();
else if (newState == 'DISCONNECTED') {
2011-03-26 13:10:41 +00:00
pad.diagnosticInfo.disconnectedMessage = message;
pad.diagnosticInfo.padId = pad.getPadId();
pad.diagnosticInfo.socket = {};
// we filter non objects from the socket object and put them in the diagnosticInfo
// this ensures we have no cyclic data - this allows us to stringify the data
for (var i in socket.socket) {
var value = socket.socket[i],
type = typeof value;
if (type == 'string' || type == 'number')
pad.diagnosticInfo.socket[i] = value;
}
2011-03-26 13:10:41 +00:00
pad.asyncSendDiagnosticInfo();
if (typeof window.ajlog == 'string')
window.ajlog += ('Disconnected: ' + message + '\n');
2011-03-26 13:10:41 +00:00
padeditor.disable();
padeditbar.disable();
paddocbar.disable();
padimpexp.disable();
padconnectionstatus.disconnected(message);
}
var newFullyConnected = !! padconnectionstatus.isFullyConnected();
2011-07-07 18:59:34 +01:00
if (newFullyConnected != oldFullyConnected)
2011-03-26 13:10:41 +00:00
pad.handleIsFullyConnected(newFullyConnected, wasConnecting);
},
handleIsFullyConnected: function(isConnected, isInitialConnect) {
2011-03-26 13:10:41 +00:00
// load all images referenced from CSS, one at a time,
// starting one second after connection is first established.
if (isConnected && !pad.preloadedImages) {
window.setTimeout(function() {
if (!pad.preloadedImages) {
2011-03-26 13:10:41 +00:00
pad.preloadImages();
pad.preloadedImages = true;
}
}, 1000);
}
padsavedrevs.handleIsFullyConnected(isConnected);
// pad.determineSidebarVisibility(isConnected && !isInitialConnect);
pad.determineChatVisibility(isConnected && !isInitialConnect);
2011-07-07 18:59:34 +01:00
},
/* determineSidebarVisibility: function(asNowConnectedFeedback)
2011-07-07 18:59:34 +01:00
{
if (pad.isFullyConnected())
{
var setSidebarVisibility = padutils.getCancellableAction("set-sidebar-visibility", function()
{
// $("body").toggleClass('hidesidebar', !! padcookie.getPref('hideSidebar'));
2011-07-07 18:59:34 +01:00
});
window.setTimeout(setSidebarVisibility, asNowConnectedFeedback ? 3000 : 0);
}
else
{
2011-03-26 13:10:41 +00:00
padutils.cancelActions("set-sidebar-visibility");
$("body").removeClass('hidesidebar');
}
},
*/
determineChatVisibility: function(asNowConnectedFeedback) {
var chatVisCookie = padcookie.getPref('chatAlwaysVisible');
if (chatVisCookie) { // if the cookie is set for chat always visible
chat.stickToScreen(true); // stick chat to the screen
$('#options-stickychat').prop('checked', true); // set the checkbox to on
} else {
$('#options-stickychat').prop('checked', false); // set the checkbox for off
}
},
handleCollabAction: function(action) {
if (action == 'commitPerformed')
padeditbar.setSyncStatus('syncing');
else if (action == 'newlyIdle')
padeditbar.setSyncStatus('done');
2011-03-26 13:10:41 +00:00
},
hideServerMessage: function() {
2011-03-26 13:10:41 +00:00
alertBar.hideMessage();
},
asyncSendDiagnosticInfo: function() {
window.setTimeout(function() {
$.post({
url : '/ep/pad/connection-diagnostic-info',
data: {diagnosticInfo: JSON.stringify(pad.diagnosticInfo)}
2011-03-26 13:10:41 +00:00
});
}, 0);
},
forceReconnect: function() {
$('#reconnectform .padId').val(pad.getPadId());
2011-03-26 13:10:41 +00:00
pad.diagnosticInfo.collabDiagnosticInfo = pad.collabClient.getDiagnosticInfo();
$('#reconnectform .diagnosticInfo').val(JSON.stringify(pad.diagnosticInfo));
$('#reconnectform .missedChanges').val(JSON.stringify(pad.collabClient.getMissedChanges()));
$('#reconnectform').submit();
2011-03-26 13:10:41 +00:00
},
toggleWidthPref: function() {
2011-07-07 18:59:34 +01:00
var newValue = !padcookie.getPref('fullWidth');
2011-03-26 13:10:41 +00:00
padcookie.setPref('fullWidth', newValue);
$('#widthprefcheck').toggleClass('widthprefchecked', !! newValue).toggleClass('widthprefunchecked', !newValue);
2011-03-26 13:10:41 +00:00
pad.handleWidthChange();
},
/*
2011-07-07 18:59:34 +01:00
toggleSidebar: function()
{
var newValue = !padcookie.getPref('hideSidebar');
2011-03-26 13:10:41 +00:00
padcookie.setPref('hideSidebar', newValue);
2011-07-07 18:59:34 +01:00
$("#sidebarcheck").toggleClass('sidebarchecked', !newValue).toggleClass('sidebarunchecked', !! newValue);
2011-03-26 13:10:41 +00:00
pad.determineSidebarVisibility();
},
*/
handleWidthChange: function() {
2011-03-26 13:10:41 +00:00
var isFullWidth = padcookie.getPref('fullWidth');
2011-07-07 18:59:34 +01:00
if (isFullWidth)
$('BODY').addClass('fullwidth').removeClass('limwidth squish1width squish2width');
else {
$('BODY').addClass('limwidth').removeClass('fullwidth');
2011-03-26 13:10:41 +00:00
var pageWidth = $(window).width();
$('BODY').toggleClass('squish1width', (pageWidth < 912 && pageWidth > 812)).toggleClass('squish2width', (pageWidth <= 812));
2011-03-26 13:10:41 +00:00
}
},
// this is called from code put into a frame from the server:
handleImportExportFrameCall: function(callName, varargs) {
2011-07-07 18:59:34 +01:00
padimpexp.handleFrameCall.call(padimpexp, callName, Array.prototype.slice.call(arguments, 1));
2011-03-26 13:10:41 +00:00
},
callWhenNotCommitting: function(f) {
2011-03-26 13:10:41 +00:00
pad.collabClient.callWhenNotCommitting(f);
},
getCollabRevisionNumber: function() {
2011-03-26 13:10:41 +00:00
return pad.collabClient.getCurrentRevisionNumber();
},
isFullyConnected: function() {
2011-03-26 13:10:41 +00:00
return padconnectionstatus.isFullyConnected();
},
addHistoricalAuthors: function(data) {
if (!pad.collabClient) {
window.setTimeout(function() {
2011-07-07 18:59:34 +01:00
pad.addHistoricalAuthors(data);
}, 1000);
} else {
2011-03-26 13:10:41 +00:00
pad.collabClient.addHistoricalAuthors(data);
}
},
preloadImages: function() {
var images = ["../static/img/connectingbar.gif"];
function loadNextImage() {
2011-07-07 18:59:34 +01:00
if (images.length == 0)
2011-03-26 13:10:41 +00:00
return;
var img = new Image();
img.src = images.shift();
2011-07-07 18:59:34 +01:00
if (img.complete)
2011-03-26 13:10:41 +00:00
scheduleLoadNextImage();
2011-07-07 18:59:34 +01:00
else
2011-03-26 13:10:41 +00:00
$(img).bind('error load onreadystatechange', scheduleLoadNextImage);
}
function scheduleLoadNextImage() {
2011-03-26 13:10:41 +00:00
window.setTimeout(loadNextImage, 0);
}
scheduleLoadNextImage();
}
};
var alertBar = (function() {
2011-03-26 13:10:41 +00:00
var animator = padutils.makeShowHideAnimator(arriveAtAnimationState, false, 25, 400);
function arriveAtAnimationState(state) {
2011-07-07 18:59:34 +01:00
if (state == -1)
$('#alertbar').css('opacity', 0).css('display', 'block');
2011-07-07 18:59:34 +01:00
else if (state == 0)
$('#alertbar').css('opacity', 1);
2011-07-07 18:59:34 +01:00
else if (state == 1)
$('#alertbar').css('opacity', 0).css('display', 'none');
2011-07-07 18:59:34 +01:00
else if (state < 0)
$('#alertbar').css('opacity', state + 1);
2011-07-07 18:59:34 +01:00
else if (state > 0)
$('#alertbar').css('opacity', 1 - state);
2011-03-26 13:10:41 +00:00
}
var self = {
displayMessage: function(setupFunc) {
2011-03-26 13:10:41 +00:00
animator.show();
setupFunc($('#alertbar'));
2011-03-26 13:10:41 +00:00
},
hideMessage: function() {
2011-03-26 13:10:41 +00:00
animator.hide();
}
};
return self;
}());
function init() {
return pad.init();
}
2012-01-26 21:40:13 -08:00
var settings = {
LineNumbersDisabled : false,
noColors : false,
useMonospaceFontGlobal: false,
globalUserName : false,
hideQRCode : false,
rtlIsTrue : false
2012-01-26 21:40:13 -08:00
};
pad.settings = settings;
exports.settings = settings;
exports.createCookie = createCookie;
exports.readCookie = readCookie;
exports.randomString = randomString;
exports.getParams = getParams;
exports.getUrlVars = getUrlVars;
exports.savePassword = savePassword;
exports.handshake = handshake;
exports.pad = pad;
exports.init = init;
exports.alertBar = alertBar;