diff options
author | Matthias Bartelmeß <mba@fourplusone.de> | 2012-03-13 19:40:33 +0100 |
---|---|---|
committer | Matthias Bartelmeß <mba@fourplusone.de> | 2012-03-13 19:40:33 +0100 |
commit | 70940521f2cdc3cdb3361bd148e141f43505ee4d (patch) | |
tree | 96eb9974ee057b9fc3c8947d33bdd1601de8cd30 /src/static/js/pad.js | |
parent | cfb58a80a30486156a15515164c9c0f4647f165b (diff) | |
parent | cccd8a923cfa21c7e248a2a5fcffa54caf512e0b (diff) | |
download | etherpad-lite-70940521f2cdc3cdb3361bd148e141f43505ee4d.zip |
Merge branch 'develop' of git://github.com/Pita/etherpad-lite
Diffstat (limited to 'src/static/js/pad.js')
-rw-r--r-- | src/static/js/pad.js | 1000 |
1 files changed, 1000 insertions, 0 deletions
diff --git a/src/static/js/pad.js b/src/static/js/pad.js new file mode 100644 index 00000000..d19cface --- /dev/null +++ b/src/static/js/pad.js @@ -0,0 +1,1000 @@ +/** + * 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 + */ + +/** + * 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. + */ + +/* 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'); +require('./prefixfree'); + +var chat = require('./chat').chat; +var getCollabClient = require('./collab_client').getCollabClient; +var padconnectionstatus = require('./pad_connectionstatus').padconnectionstatus; +var padcookie = require('./pad_cookie').padcookie; +var paddocbar = require('./pad_docbar').paddocbar; +var padeditbar = require('./pad_editbar').padeditbar; +var padeditor = require('./pad_editor').padeditor; +var padimpexp = require('./pad_impexp').padimpexp; +var padmodals = require('./pad_modals').padmodals; +var padsavedrevs = require('./pad_savedrevs').padsavedrevs; +var paduserlist = require('./pad_userlist').paduserlist; +var padutils = require('./pad_utils').padutils; + +var createCookie = require('./pad_utils').createCookie; +var readCookie = require('./pad_utils').readCookie; +var randomString = require('./pad_utils').randomString; + +function getParams() +{ + var params = getUrlVars() + var showControls = params["showControls"]; + var showChat = params["showChat"]; + var userName = params["userName"]; + var showLineNumbers = params["showLineNumbers"]; + var useMonospaceFont = params["useMonospaceFont"]; + var IsnoColors = params["noColors"]; + var hideQRCode = params["hideQRCode"]; + var rtl = params["rtl"]; + var alwaysShowChat = params["alwaysShowChat"]; + + if(IsnoColors) + { + if(IsnoColors == "true") + { + settings.noColors = true; + $('#clearAuthorship').hide(); + } + } + if(showControls) + { + if(showControls == "false") + { + $('#editbar').hide(); + $('#editorcontainer').css({"top":"0px"}); + } + } + 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 = decodeURIComponent(userName); + } + if(hideQRCode) + { + $('#qrcode').hide(); + } + if(rtl) + { + if(rtl == "true") + { + settings.rtlIsTrue = true + } + } + if(alwaysShowChat) + { + if(alwaysShowChat == "true") + { + chat.stickToScreen(); + } + } +} + +function getUrlVars() +{ + var vars = [], hash; + var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); + for(var i = 0; i < hashes.length; 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 ieTestXMLHTTP(){ + // Test for IE known XML HTTP issue + if ($.browser.msie && !window.XMLHttpRequest){ + $("#editorloadingbox").html("You do not have XML HTTP enabled in your browser. <a target='_blank' href='https://github.com/Pita/etherpad-lite/wiki/How-to-enable-native-XMLHTTP-support-in-IE'>Fix this issue</a>"); + } +} +function handshake() +{ + var loc = document.location; + //get the correct port + var port = loc.port == "" ? (loc.protocol == "https:" ? 443 : 80) : loc.port; + //create the url + var url = loc.protocol + "//" + loc.hostname + ":" + port + "/"; + //find out in which subfolder we are + var resource = loc.pathname.substr(1, loc.pathname.indexOf("/p/")) + "socket.io"; + //connect + socket = pad.socket = io.connect(url, { + resource: resource, + 'max reconnection attempts': 3, + 'sync disconnect on unload' : false + }); + + function sendClientReady(isReconnect) + { + var padId = document.location.pathname.substring(document.location.pathname.lastIndexOf("/") + 1); + padId = decodeURIComponent(padId); // unescape neccesary due to Safari and Opera interpretation of spaces + + if(!isReconnect) + document.title = padId.replace(/_+/g, ' ') + " | " + document.title; + + var token = readCookie("token"); + if (token == null) + { + token = "t." + randomString(); + createCookie("token", token, 60); + } + + var sessionID = readCookie("sessionID"); + var password = readCookie("password"); + + var 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 revisionnumber + if(isReconnect == true) + { + msg.client_rev=pad.collabClient.getCurrentRevisionNumber(); + msg.reconnect=true; + } + + socket.json.send(msg); + }; + + var disconnectTimeout; + + socket.once('connect', function () { + sendClientReady(false); + }); + + socket.on('reconnect', function () { + //reconnect is before the timeout, lets stop the timeout + if(disconnectTimeout) + { + clearTimeout(disconnectTimeout); + } + + pad.collabClient.setChannelState("CONNECTED"); + sendClientReady(true); + }); + + socket.on('disconnect', function (reason) { + if(reason == "booted"){ + pad.collabClient.setChannelState("DISCONNECTED"); + } else { + function disconnectEvent() + { + pad.collabClient.setChannelState("DISCONNECTED", "reconnect_timeout"); + } + + pad.collabClient.setChannelState("RECONNECTING"); + + disconnectTimeout = setTimeout(disconnectEvent, 10000); + } + }); + + var receivedClientVars = false; + var initalized = false; + + socket.on('message', function(obj) + { + //the 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>"); + } + } + + //if we haven't recieved the clientVars yet, then this message should it be + else if (!receivedClientVars) + { + //log the message + if (window.console) console.log(obj); + + receivedClientVars = true; + + //set some client vars + clientVars = obj; + clientVars.userAgent = "Anonymous"; + clientVars.collab_client_vars.clientAgent = "Anonymous"; + + //initalize the pad + pad._afterHandshake(); + initalized = true; + + // If the LineNumbersDisabled value is set to true then we need to hide the Line Numbers + if (settings.LineNumbersDisabled == true) + { + pad.changeViewOption('showLineNumbers', false); + } + + // If the noColors value is set to true then we need to hide the background colors on the ace spans + if (settings.noColors == true) + { + pad.changeViewOption('noColors', true); + } + + if (settings.rtlIsTrue == true) + { + pad.changeViewOption('rtl', true); + } + + // If the Monospacefont value is set to true then change it to monospace. + if (settings.useMonospaceFontGlobal == true) + { + pad.changeViewOption('useMonospaceFont', true); + } + // if the globalUserName value is set we need to tell the server and the client about the new authorname + if (settings.globalUserName !== false) + { + pad.notifyChangeName(settings.globalUserName); // Notifies the server + pad.myUserInfo.name = settings.globalUserName; + $('#myusernameedit').attr({"value":settings.globalUserName}); // Updates the current users UI + } + } + //This handles every Message after the clientVars + else + { + //this message advices the client to disconnect + if (obj.disconnect) + { + padconnectionstatus.disconnected(obj.disconnect); + socket.disconnect(); + return; + } + else + { + pad.collabClient.handleMessageFromServer(obj); + } + } + }); + // Bind the colorpicker + var fb = $('#colorpicker').farbtastic({ callback: '#mycolorpickerpreview', width: 220}); +} + +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: {}, + + // these don't require init; clientVars should all go through here + getPadId: function() + { + return clientVars.padId; + }, + getClientIp: function() + { + return clientVars.clientIp; + }, + getIsProPad: function() + { + return clientVars.isProPad; + }, + getColorPalette: function() + { + return clientVars.colorPalette; + }, + getDisplayUserAgent: function() + { + return padutils.uaDisplay(clientVars.userAgent); + }, + getIsDebugEnabled: function() + { + return clientVars.debugEnabled; + }, + getPrivilege: function(name) + { + return clientVars.accountPrivs[name]; + }, + getUserIsGuest: function() + { + return clientVars.userIsGuest; + }, + getUserId: function() + { + return pad.myUserInfo.userId; + }, + getUserName: function() + { + return pad.myUserInfo.name; + }, + sendClientMessage: function(msg) + { + pad.collabClient.sendClientMessage(msg); + }, + + init: function() + { + padutils.setupGlobalExceptionHandler(); + + $(document).ready(function() + { + // test for XML HTTP capabiites + ieTestXMLHTTP(); + // start the custom js + if (typeof customStart == "function") customStart(); + getParams(); + handshake(); + }); + }, + _afterHandshake: function() + { + pad.clientTimeOffset = new Date().getTime() - clientVars.serverTimestamp; + + //initialize the chat + chat.init(this); + pad.initTime = +(new Date()); + pad.padOptions = clientVars.initialOptions; + + if ((!$.browser.msie) && (!($.browser.mozilla && $.browser.version.indexOf("1.8.") == 0))) + { + document.domain = document.domain; // for comet + } + + // for IE + if ($.browser.msie) + { + try + { + doc.execCommand("BackgroundImageCache", false, true); + } + catch (e) + {} + } + + // order of inits is important here: + padcookie.init(clientVars.cookiePrefsToSet, this); + + $("#widthprefcheck").click(pad.toggleWidthPref); + // $("#sidebarcheck").click(pad.togglewSidebar); + + pad.myUserInfo = { + userId: clientVars.userId, + name: clientVars.userName, + ip: pad.getClientIp(), + colorId: clientVars.userColor, + userAgent: pad.getDisplayUserAgent() + }; + + if (clientVars.specialKey) + { + pad.myUserInfo.specialKey = clientVars.specialKey; + if (clientVars.specialKeyTranslation) + { + $("#specialkeyarea").html("mode: " + String(clientVars.specialKeyTranslation).toUpperCase()); + } + } + 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); + // padchat.init(clientVars.chatHistory, pad.myUserInfo); + padconnectionstatus.init(); + padmodals.init(this); + + pad.collabClient = getCollabClient(padeditor.ace, clientVars.collab_client_vars, pad.myUserInfo, { + colorPalette: pad.getColorPalette() + }, pad); + 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() + { + padeditbar.init(); + setTimeout(function() + { + padeditor.ace.focus(); + }, 0); + if(padcookie.getPref("chatAlwaysVisible")){ // if we have a cookie for always showing chat then show it + chat.stickToScreen(true); // stick it to the screen + $('#options-stickychat').prop("checked", true); // set the checkbox to on + } + if(padcookie.getPref("showAuthorshipColors") == false){ + pad.changeViewOption('showAuthorColors', false); + } + } + }, + dispose: function() + { + padeditor.dispose(); + }, + notifyChangeName: function(newName) + { + pad.myUserInfo.name = newName; + pad.collabClient.updateUserInfo(pad.myUserInfo); + //padchat.handleUserJoinOrUpdate(pad.myUserInfo); + }, + notifyChangeColor: function(newColorId) + { + pad.myUserInfo.colorId = newColorId; + pad.collabClient.updateUserInfo(pad.myUserInfo); + //padchat.handleUserJoinOrUpdate(pad.myUserInfo); + }, + notifyChangeTitle: function(newTitle) + { + pad.collabClient.sendClientMessage( + { + type: 'padtitle', + title: newTitle, + changedBy: pad.myUserInfo.name || "unnamed" + }); + }, + notifyChangePassword: function(newPass) + { + pad.collabClient.sendClientMessage( + { + type: 'padpassword', + password: newPass, + changedBy: pad.myUserInfo.name || "unnamed" + }); + }, + changePadOption: function(key, value) + { + var options = {}; + options[key] = value; + pad.handleOptionsChange(options); + pad.collabClient.sendClientMessage( + { + type: 'padoptions', + options: options, + changedBy: pad.myUserInfo.name || "unnamed" + }); + }, + changeViewOption: function(key, value) + { + var options = { + view: {} + }; + 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) + { + if (!pad.padOptions.view) + { + pad.padOptions.view = {}; + } + for (var k in opts.view) + { + pad.padOptions.view[k] = opts.view[k]; + } + padeditor.setViewOptions(pad.padOptions.view); + } + if (opts.guestPolicy) + { + // order important here + pad.padOptions.guestPolicy = opts.guestPolicy; + paddocbar.setGuestPolicy(opts.guestPolicy); + } + }, + getPadOptions: function() + { + // caller shouldn't mutate the object + return pad.padOptions; + }, + isPadPublic: function() + { + return (!pad.getIsProPad()) || (pad.getPadOptions().guestPolicy == 'allow'); + }, + suggestUserName: function(userId, name) + { + pad.collabClient.sendClientMessage( + { + type: 'suggestUserName', + unnamedId: userId, + newName: name + }); + }, + handleUserJoin: function(userInfo) + { + paduserlist.userJoinOrUpdate(userInfo); + //padchat.handleUserJoinOrUpdate(userInfo); + }, + handleUserUpdate: function(userInfo) + { + paduserlist.userJoinOrUpdate(userInfo); + //padchat.handleUserJoinOrUpdate(userInfo); + }, + handleUserLeave: function(userInfo) + { + paduserlist.userLeave(userInfo); + //padchat.handleUserLeave(userInfo); + }, + handleClientMessage: function(msg) + { + if (msg.type == 'suggestUserName') + { + if (msg.unnamedId == pad.myUserInfo.userId && msg.newName && !pad.myUserInfo.name) + { + pad.notifyChangeName(msg.newName); + paduserlist.setMyUserInfo(pad.myUserInfo); + } + } + else if (msg.type == 'chat') + { + //padchat.receiveChat(msg); + } + else if (msg.type == 'padtitle') + { + paddocbar.changeTitle(msg.title); + } + else if (msg.type == 'padpassword') + { + paddocbar.changePassword(msg.password); + } + else if (msg.type == 'newRevisionList') + { + padsavedrevs.newRevisionList(msg.revisionList); + } + else if (msg.type == 'revisionLabel') + { + padsavedrevs.newRevisionList(msg.revisionList); + } + else if (msg.type == 'padoptions') + { + var opts = msg.options; + pad.handleOptionsChange(opts); + } + else if (msg.type == 'guestanswer') + { + // someone answered a prompt, remove it + paduserlist.removeGuestPrompt(msg.guestId); + } + }, + editbarClick: function(cmd) + { + if (padeditbar) + { + padeditbar.toolbarClick(cmd); + } + }, + dmesg: function(m) + { + if (pad.getIsDebugEnabled()) + { + var djs = $('#djs').get(0); + var wasAtBottom = (djs.scrollTop - (djs.scrollHeight - $(djs).height()) >= -20); + $('#djs').append('<p>' + m + '</p>'); + if (wasAtBottom) + { + 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); + }); + } + if (m.js) + { + window['ev' + 'al'](m.js); + } + } + else if (m.type == 'GUEST_PROMPT') + { + paduserlist.showGuestPrompt(m.userId, m.displayName); + } + }, + handleChannelStateChange: function(newState, message) + { + var oldFullyConnected = !! padconnectionstatus.isFullyConnected(); + var wasConnecting = (padconnectionstatus.getStatus().what == 'connecting'); + if (newState == "CONNECTED") + { + padconnectionstatus.connected(); + } + else if (newState == "RECONNECTING") + { + padconnectionstatus.reconnecting(); + } + else if (newState == "DISCONNECTED") + { + 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]; + var type = typeof value; + + if(type == "string" || type == "number") + { + pad.diagnosticInfo.socket[i] = value; + } + } + + pad.asyncSendDiagnosticInfo(); + if (typeof window.ajlog == "string") + { + window.ajlog += ("Disconnected: " + message + '\n'); + } + padeditor.disable(); + padeditbar.disable(); + paddocbar.disable(); + padimpexp.disable(); + + padconnectionstatus.disconnected(message); + } + var newFullyConnected = !! padconnectionstatus.isFullyConnected(); + if (newFullyConnected != oldFullyConnected) + { + pad.handleIsFullyConnected(newFullyConnected, wasConnecting); + } + }, + handleIsFullyConnected: function(isConnected, isInitialConnect) + { + // 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) + { + pad.preloadImages(); + pad.preloadedImages = true; + } + }, 1000); + } + + padsavedrevs.handleIsFullyConnected(isConnected); + + // pad.determineSidebarVisibility(isConnected && !isInitialConnect); + pad.determineChatVisibility(isConnected && !isInitialConnect); + pad.determineAuthorshipColorsVisibility(); + + }, +/* determineSidebarVisibility: function(asNowConnectedFeedback) + { + if (pad.isFullyConnected()) + { + var setSidebarVisibility = padutils.getCancellableAction("set-sidebar-visibility", function() + { + // $("body").toggleClass('hidesidebar', !! padcookie.getPref('hideSidebar')); + }); + window.setTimeout(setSidebarVisibility, asNowConnectedFeedback ? 3000 : 0); + } + else + { + 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 it to the screen + $('#options-stickychat').prop("checked", true); // set the checkbox to on + } + else{ + $('#options-stickychat').prop("checked", false); // set the checkbox for off + } + }, + determineAuthorshipColorsVisibility: function(){ + var authColCookie = padcookie.getPref('showAuthorshipColors'); + if (authColCookie){ + pad.changeViewOption('showAuthorColors', true); + $('#options-colorscheck').prop("checked", true); + } + else { + $('#options-colorscheck').prop("checked", false); + } + }, + handleCollabAction: function(action) + { + if (action == "commitPerformed") + { + padeditbar.setSyncStatus("syncing"); + } + else if (action == "newlyIdle") + { + padeditbar.setSyncStatus("done"); + } + }, + hideServerMessage: function() + { + alertBar.hideMessage(); + }, + asyncSendDiagnosticInfo: function() + { + window.setTimeout(function() + { + $.ajax( + { + type: 'post', + url: '/ep/pad/connection-diagnostic-info', + data: { + diagnosticInfo: JSON.stringify(pad.diagnosticInfo) + }, + success: function() + {}, + error: function() + {} + }); + }, 0); + }, + forceReconnect: function() + { + $('form#reconnectform input.padId').val(pad.getPadId()); + pad.diagnosticInfo.collabDiagnosticInfo = pad.collabClient.getDiagnosticInfo(); + $('form#reconnectform input.diagnosticInfo').val(JSON.stringify(pad.diagnosticInfo)); + $('form#reconnectform input.missedChanges').val(JSON.stringify(pad.collabClient.getMissedChanges())); + $('form#reconnectform').submit(); + }, + toggleWidthPref: function() + { + var newValue = !padcookie.getPref('fullWidth'); + padcookie.setPref('fullWidth', newValue); + $("#widthprefcheck").toggleClass('widthprefchecked', !! newValue).toggleClass('widthprefunchecked', !newValue); + pad.handleWidthChange(); + }, +/* + toggleSidebar: function() + { + var newValue = !padcookie.getPref('hideSidebar'); + padcookie.setPref('hideSidebar', newValue); + $("#sidebarcheck").toggleClass('sidebarchecked', !newValue).toggleClass('sidebarunchecked', !! newValue); + pad.determineSidebarVisibility(); + }, +*/ + handleWidthChange: function() + { + var isFullWidth = padcookie.getPref('fullWidth'); + if (isFullWidth) + { + $("body").addClass('fullwidth').removeClass('limwidth').removeClass('squish1width').removeClass('squish2width'); + } + else + { + $("body").addClass('limwidth').removeClass('fullwidth'); + + var pageWidth = $(window).width(); + $("body").toggleClass('squish1width', (pageWidth < 912 && pageWidth > 812)).toggleClass('squish2width', (pageWidth <= 812)); + } + }, + // this is called from code put into a frame from the server: + handleImportExportFrameCall: function(callName, varargs) + { + padimpexp.handleFrameCall.call(padimpexp, callName, Array.prototype.slice.call(arguments, 1)); + }, + callWhenNotCommitting: function(f) + { + pad.collabClient.callWhenNotCommitting(f); + }, + getCollabRevisionNumber: function() + { + return pad.collabClient.getCurrentRevisionNumber(); + }, + isFullyConnected: function() + { + return padconnectionstatus.isFullyConnected(); + }, + addHistoricalAuthors: function(data) + { + if (!pad.collabClient) + { + window.setTimeout(function() + { + pad.addHistoricalAuthors(data); + }, 1000); + } + else + { + pad.collabClient.addHistoricalAuthors(data); + } + }, + preloadImages: function() + { + var images = ["../static/img/connectingbar.gif"]; + + function loadNextImage() + { + if (images.length == 0) + { + return; + } + var img = new Image(); + img.src = images.shift(); + if (img.complete) + { + scheduleLoadNextImage(); + } + else + { + $(img).bind('error load onreadystatechange', scheduleLoadNextImage); + } + } + + function scheduleLoadNextImage() + { + window.setTimeout(loadNextImage, 0); + } + scheduleLoadNextImage(); + } +}; + +var alertBar = (function() +{ + + var animator = padutils.makeShowHideAnimator(arriveAtAnimationState, false, 25, 400); + + function arriveAtAnimationState(state) + { + if (state == -1) + { + $("#alertbar").css('opacity', 0).css('display', 'block'); + } + else if (state == 0) + { + $("#alertbar").css('opacity', 1); + } + else if (state == 1) + { + $("#alertbar").css('opacity', 0).css('display', 'none'); + } + else if (state < 0) + { + $("#alertbar").css('opacity', state + 1); + } + else if (state > 0) + { + $("#alertbar").css('opacity', 1 - state); + } + } + + var self = { + displayMessage: function(setupFunc) + { + animator.show(); + setupFunc($("#alertbar")); + }, + hideMessage: function() + { + animator.hide(); + } + }; + return self; +}()); + +function init() { + return pad.init(); +} + +var settings = { + LineNumbersDisabled: false +, noColors: false +, useMonospaceFontGlobal: false +, globalUserName: false +, hideQRCode: false +, rtlIsTrue: false +}; + +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; + |