diff --git a/node/utils/Minify.js b/node/utils/Minify.js index ea7834dc171d..98774d1953fa 100644 --- a/node/utils/Minify.js +++ b/node/utils/Minify.js @@ -306,11 +306,6 @@ function tarCode(filesInOrder, files, write) { write("\n\n\n/*** File: static/js/" + filename + " ***/\n\n\n"); write(isolateJS(files[filename], filename)); } - - for(var i = 0, ii = filesInOrder.length; i < filesInOrder.length; i++) { - var filename = filesInOrder[i]; - write('require(' + JSON.stringify('/' + filename.replace(/^\/+/, '')) + ');\n'); - } } // Wrap the following code in a self executing function and assign exports to diff --git a/node/utils/tar.json b/node/utils/tar.json index fd285b94dde9..e1e6fb2b10ce 100644 --- a/node/utils/tar.json +++ b/node/utils/tar.json @@ -1,6 +1,7 @@ { "pad.js": [ "jquery.js" + , "pad.js" , "ace2_common.js" , "pad_utils.js" , "plugins.js" @@ -17,7 +18,6 @@ , "pad_impexp.js" , "pad_savedrevs.js" , "pad_connectionstatus.js" - , "pad2.js" , "jquery-ui.js" , "chat.js" , "excanvas.js" @@ -46,5 +46,6 @@ , "broadcast.js" , "broadcast_slider.js" , "broadcast_revisions.js" + , "timeslider.js" ] } diff --git a/static/js/broadcast.js b/static/js/broadcast.js index b49b185a503a..2aa0b5d065ff 100644 --- a/static/js/broadcast.js +++ b/static/js/broadcast.js @@ -20,16 +20,17 @@ * limitations under the License. */ -var global = this; - var makeCSSManager = require('/cssmanager_client').makeCSSManager; var domline = require('/domline_client').domline; var Changeset = require('/easysync2_client').Changeset; var AttribPool = require('/easysync2_client').AttribPool; var linestylefilter = require('/linestylefilter_client').linestylefilter; -function loadBroadcastJS() +// These parameters were global, now they are injected. A reference to the +// Timeslider controller would probably be more appropriate. +function loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, BroadcastSlider) { + var changesetLoader = undefined; // just in case... (todo: this must be somewhere else in the client code.) // Below Array#map code was direct pasted by AppJet/Etherpad, licence unknown. Possible source: http://www.tutorialspoint.com/javascript/array_map.htm if (!Array.prototype.map) @@ -423,7 +424,7 @@ function loadBroadcastJS() })); } - global.changesetLoader = { + changesetLoader = { running: false, resolved: [], requestQueue1: [], @@ -763,6 +764,8 @@ function loadBroadcastJS() } receiveAuthorData(clientVars.historicalAuthorData); + + return changesetLoader; } exports.loadBroadcastJS = loadBroadcastJS; diff --git a/static/js/broadcast_revisions.js b/static/js/broadcast_revisions.js index 364ac3e8cc0b..19f3f5ff7d56 100644 --- a/static/js/broadcast_revisions.js +++ b/static/js/broadcast_revisions.js @@ -22,7 +22,6 @@ // revision info is a skip list whos entries represent a particular revision // of the document. These revisions are connected together by various // changesets, or deltas, between any two revisions. -var global = this; function loadBroadcastRevisionsJS() { diff --git a/static/js/broadcast_slider.js b/static/js/broadcast_slider.js index 972190acbc10..0bdc2cabc32b 100644 --- a/static/js/broadcast_slider.js +++ b/static/js/broadcast_slider.js @@ -19,10 +19,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -var global = this; -function loadBroadcastSliderJS() + // These parameters were global, now they are injected. A reference to the + // Timeslider controller would probably be more appropriate. +function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded) { + var BroadcastSlider; (function() { // wrap this code in its own namespace @@ -203,7 +205,7 @@ function loadBroadcastSliderJS() } } - global.BroadcastSlider = { + BroadcastSlider = { onSlider: onSlider, getSliderPosition: getSliderPosition, setSliderPosition: setSliderPosition, @@ -495,6 +497,8 @@ function loadBroadcastSliderJS() { $("#viewlatest").html(loc == BroadcastSlider.getSliderLength() ? "Viewing latest content" : "View latest content"); }) + + return BroadcastSlider; } exports.loadBroadcastSliderJS = loadBroadcastSliderJS; diff --git a/static/js/pad2.js b/static/js/pad.js similarity index 95% rename from static/js/pad2.js rename to static/js/pad.js index 2c7d7e0e9a37..fb297d4afb68 100644 --- a/static/js/pad2.js +++ b/static/js/pad.js @@ -24,13 +24,14 @@ var socket; -var settings = {}; -settings.LineNumbersDisabled = false; -settings.noColors = false; -settings.useMonospaceFontGlobal = false; -settings.globalUserName = false; -settings.hideQRCode = false; -settings.rtlIsTrue = false; +// These jQuery things should create local references, but for now `require()` +// assigns to the global `$` and augments it with plugins. +require('/jquery'); +require('/jquery-ui'); +require('/farbtastic'); +require('/excanvas'); +require('/json2'); +require('/undo-xpopup'); var chat = require('/chat').chat; var getCollabClient = require('/collab_client').getCollabClient; @@ -45,19 +46,6 @@ var padsavedrevs = require('/pad_savedrevs').padsavedrevs; var paduserlist = require('/pad_userlist').paduserlist; var padutils = require('/pad_utils').padutils; -$(document).ready(function() -{ - //start the costum js - if(typeof costumStart == "function") costumStart(); - getParams(); - handshake(); -}); - -$(window).unload(function() -{ - pad.dispose(); -}); - function createCookie(name, value, days, path) { if (days) @@ -309,7 +297,7 @@ function handshake() clientVars.collab_client_vars.clientAgent = "Anonymous"; //initalize the pad - pad.init(); + pad._afterHandshake(); initalized = true; // If the LineNumbersDisabled value is set to true then we need to hide the Line Numbers @@ -421,6 +409,23 @@ var pad = { }, init: function() + { + padutils.setupGlobalExceptionHandler(); + + $(document).ready(function() + { + //start the costum js + if(typeof costumStart == "function") costumStart(); + getParams(); + handshake(); + }); + + $(window).unload(function() + { + pad.dispose(); + }); + }, + _afterHandshake: function() { pad.clientTimeOffset = new Date().getTime() - clientVars.serverTimestamp; @@ -446,7 +451,7 @@ var pad = { } // order of inits is important here: - padcookie.init(clientVars.cookiePrefsToSet); + padcookie.init(clientVars.cookiePrefsToSet, this); $("#widthprefcheck").click(pad.toggleWidthPref); // $("#sidebarcheck").click(pad.togglewSidebar); @@ -473,16 +478,16 @@ var pad = { initialTitle: clientVars.initialTitle, initialPassword: clientVars.initialPassword, guestPolicy: pad.padOptions.guestPolicy - }); - padimpexp.init(); - padsavedrevs.init(clientVars.initialRevisionList); + }, this); + padimpexp.init(this); + padsavedrevs.init(clientVars.initialRevisionList, this); - padeditor.init(postAceInit, pad.padOptions.view || {}); + padeditor.init(postAceInit, pad.padOptions.view || {}, this); - paduserlist.init(pad.myUserInfo); + paduserlist.init(pad.myUserInfo, this); // padchat.init(clientVars.chatHistory, pad.myUserInfo); padconnectionstatus.init(); - padmodals.init(); + padmodals.init(this); pad.collabClient = getCollabClient(padeditor.ace, clientVars.collab_client_vars, pad.myUserInfo, { colorPalette: pad.getColorPalette() @@ -981,6 +986,21 @@ var alertBar = (function() 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; @@ -990,4 +1010,5 @@ exports.getUrlVars = getUrlVars; exports.savePassword = savePassword; exports.handshake = handshake; exports.pad = pad; +exports.init = init; exports.alertBar = alertBar; diff --git a/static/js/pad_cookie.js b/static/js/pad_cookie.js index 24dc1e3fac65..1bb5700ade6b 100644 --- a/static/js/pad_cookie.js +++ b/static/js/pad_cookie.js @@ -87,9 +87,9 @@ var padcookie = (function() var pad = undefined; var self = { - init: function(prefsToSet) + init: function(prefsToSet, _pad) { - pad = require('/pad2').pad; // Sidestep circular dependency (should be injected). + pad = _pad; var rawCookie = getRawCookie(); if (rawCookie) diff --git a/static/js/pad_docbar.js b/static/js/pad_docbar.js index cf461c93dfa6..b83bf3bfef75 100644 --- a/static/js/pad_docbar.js +++ b/static/js/pad_docbar.js @@ -118,9 +118,9 @@ var paddocbar = (function() var self = { title: null, password: null, - init: function(opts) + init: function(opts, _pad) { - pad = require('/pad2').pad; // Sidestep circular dependency (should be injected). + pad = _pad; panels = { impexp: { diff --git a/static/js/pad_editor.js b/static/js/pad_editor.js index e7be81753e9b..6d3cbf409ef6 100644 --- a/static/js/pad_editor.js +++ b/static/js/pad_editor.js @@ -32,11 +32,11 @@ var padeditor = (function() ace: null, // this is accessed directly from other files viewZoom: 100, - init: function(readyFunc, initialViewOptions) + init: function(readyFunc, initialViewOptions, _pad) { Ace2Editor = require('/ace').Ace2Editor; - pad = require('/pad2').pad; // Sidestep circular dependency (should be injected). - settings = require('/pad2').settings; + pad = _pad; + settings = pad.settings; function aceReady() { diff --git a/static/js/pad_impexp.js b/static/js/pad_impexp.js index aa99541eaf08..0037195f253f 100644 --- a/static/js/pad_impexp.js +++ b/static/js/pad_impexp.js @@ -236,13 +236,9 @@ var padimpexp = (function() ///// var pad = undefined; var self = { - init: function() + init: function(_pad) { - try { - pad = require('/pad2').pad; // Sidestep circular dependency (should be injected). - } catch (e) { - // skip (doesn't require pad when required by timeslider) - } + pad = _pad; //get /p/padname var pad_root_path = new RegExp(/.*\/p\/[^\/]+/).exec(document.location.pathname) diff --git a/static/js/pad_modals.js b/static/js/pad_modals.js index 81ef0776bd2d..b78e28f40b51 100644 --- a/static/js/pad_modals.js +++ b/static/js/pad_modals.js @@ -75,9 +75,9 @@ var padmodals = (function() var pad = undefined; var self = { - init: function() + init: function(_pad) { - pad = require('/pad2').pad; // Sidestep circular dependency (should be injected). + pad = _pad; self.initFeedback(); self.initShareBox(); diff --git a/static/js/pad_savedrevs.js b/static/js/pad_savedrevs.js index bb52658b2cb8..6d37dfa81fe0 100644 --- a/static/js/pad_savedrevs.js +++ b/static/js/pad_savedrevs.js @@ -349,9 +349,9 @@ var padsavedrevs = (function() var pad = undefined; var self = { - init: function(initialRevisions) + init: function(initialRevisions, _pad) { - pad = require('/pad2').pad; // Sidestep circular dependency (should be injected). + pad = _pad; self.newRevisionList(initialRevisions, true); $("#savedrevs-savenow").click(function() diff --git a/static/js/pad_userlist.js b/static/js/pad_userlist.js index e0a12f838d2b..2c063d74c7de 100644 --- a/static/js/pad_userlist.js +++ b/static/js/pad_userlist.js @@ -464,9 +464,9 @@ var paduserlist = (function() var pad = undefined; var self = { - init: function(myInitialUserInfo) + init: function(myInitialUserInfo, _pad) { - pad = require('/pad2').pad; // Sidestep circular dependency (should be injected). + pad = _pad; self.setMyUserInfo(myInitialUserInfo); diff --git a/static/js/pad_utils.js b/static/js/pad_utils.js index 8583ca9e369b..071185a80bd5 100644 --- a/static/js/pad_utils.js +++ b/static/js/pad_utils.js @@ -34,7 +34,7 @@ var padutils = { }, uniqueId: function() { - var pad = require('/pad2').pad; // Sidestep circular dependency + var pad = require('/pad').pad; // Sidestep circular dependency function encodeNum(n, width) { // returns string that is exactly 'width' chars, padding with zeros @@ -209,7 +209,7 @@ var padutils = { }, timediff: function(d) { - var pad = require('/pad2').pad; // Sidestep circular dependency + var pad = require('/pad').pad; // Sidestep circular dependency function format(n, word) { n = Math.round(n); @@ -459,17 +459,25 @@ var padutils = { } }; -//send javascript errors to the server -window.onerror = function test (msg, url, linenumber) -{ - var errObj = {errorInfo: JSON.stringify({msg: msg, url: url, linenumber: linenumber, userAgent: navigator.userAgent})}; - var loc = document.location; - var url = loc.protocol + "//" + loc.hostname + ":" + loc.port + "/" + loc.pathname.substr(1, loc.pathname.indexOf("/p/")) + "jserror"; +var globalExceptionHandler = undefined; +function setupGlobalExceptionHandler() { + //send javascript errors to the server + if (!globalExceptionHandler) { + globalExceptionHandler = function test (msg, url, linenumber) + { + var errObj = {errorInfo: JSON.stringify({msg: msg, url: url, linenumber: linenumber, userAgent: navigator.userAgent})}; + var loc = document.location; + var url = loc.protocol + "//" + loc.hostname + ":" + loc.port + "/" + loc.pathname.substr(1, loc.pathname.indexOf("/p/")) + "jserror"; - $.post(url, errObj); + $.post(url, errObj); - return false; -}; + return false; + }; + window.onerror = globalExceptionHandler; + } +} + +padutils.setupGlobalExceptionHandler = setupGlobalExceptionHandler; padutils.binarySearch = require('/ace2_common').binarySearch; diff --git a/static/js/timeslider.js b/static/js/timeslider.js new file mode 100644 index 000000000000..939c4c642154 --- /dev/null +++ b/static/js/timeslider.js @@ -0,0 +1,184 @@ +/** + * 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. + * + * 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. + */ + +// These jQuery things should create local references, but for now `require()` +// assigns to the global `$` and augments it with plugins. +require('/jquery'); +require('/json2'); +require('/undo-xpopup'); + +function createCookie(name,value,days) +{ + if (days) { + var date = new Date(); + date.setTime(date.getTime()+(days*24*60*60*1000)); + var expires = "; expires="+date.toGMTString(); + } + else var expires = ""; + document.cookie = name+"="+value+expires+"; path=/"; +} + +function readCookie(name) +{ + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for(var i=0;i < ca.length;i++) { + var c = ca[i]; + while (c.charAt(0)==' ') c = c.substring(1,c.length); + if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); + } + return null; +} + +function randomString() { + var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + var string_length = 20; + var randomstring = ''; + for (var i=0; iYou have no permission to access this pad") + } + }); + + //get all the export links + export_links = $('#export > .exportlink') + + if(document.referrer.length > 0 && document.referrer.substring(document.referrer.lastIndexOf("/")-1,document.referrer.lastIndexOf("/")) === "p") { + $("#returnbutton").attr("href", document.referrer); + } else { + $("#returnbutton").attr("href", document.location.href.substring(0,document.location.href.lastIndexOf("/"))); + } + }); +} + +//sends a message over the socket +function sendSocketMsg(type, data) +{ + var sessionID = readCookie("sessionID"); + var password = readCookie("password"); + + var msg = { "component" : "timeslider", + "type": type, + "data": data, + "padId": padId, + "token": token, + "sessionID": sessionID, + "password": password, + "protocolVersion": 2}; + + socket.json.send(msg); +} + +var fireWhenAllScriptsAreLoaded = []; + +var BroadcastSlider, changesetLoader; +function handleClientVars(message) +{ + //save the client Vars + clientVars = message.data; + + //load all script that doesn't work without the clientVars + BroadcastSlider = require('/broadcast_slider').loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded); + require('/broadcast_revisions').loadBroadcastRevisionsJS(); + changesetLoader = require('/broadcast').loadBroadcastJS(socket, sendSocketMsg, fireWhenAllScriptsAreLoaded, BroadcastSlider); + + //initialize export ui + require('/pad_impexp').padimpexp.init(); + + //change export urls when the slider moves + var export_rev_regex = /(\/\d+)?\/export/ + BroadcastSlider.onSlider(function(revno) + { + export_links.each(function() + { + this.setAttribute('href', this.href.replace(export_rev_regex, '/' + revno + '/export')); + }); + }); + + //fire all start functions of these scripts, formerly fired with window.load + for(var i=0;i < fireWhenAllScriptsAreLoaded.length;i++) + { + fireWhenAllScriptsAreLoaded[i](); + } +} + +exports.init = init; diff --git a/static/pad.html b/static/pad.html index 2d8889b1b1c5..e2e4690c25bc 100644 --- a/static/pad.html +++ b/static/pad.html @@ -298,10 +298,14 @@

No Authorization.

diff --git a/static/timeslider.html b/static/timeslider.html index 2bef2f7501be..886c84201c8e 100644 --- a/static/timeslider.html +++ b/static/timeslider.html @@ -15,163 +15,6 @@ - - @@ -298,13 +141,6 @@

Authors

Return to pad -
@@ -366,6 +202,18 @@

+ +