From 8a32b72ffc19cb6fa8cad786dddd8bad00c34d88 Mon Sep 17 00:00:00 2001 From: Caleb James DeLisle Date: Thu, 14 Sep 2017 10:23:05 +0200 Subject: [PATCH] 1. implement cryptpadCache which has put() and get() functions that can be used like a localStorage that auto-flushes when a new version is released 2. change loading.js to use packaged css in order to get the loading screen up as quick as possible. 3. change LessLoader to cache less in cryptpadCache --- www/common/loading.js | 69 +++++++++++++++++++++++++++++-- www/common/sframe-boot.js | 40 +++++++----------- www/common/sframe-boot2.js | 2 + www/common/sframe-channel.js | 13 +++--- www/common/sframe-common-outer.js | 24 ++++++++++- www/common/sframe-common.js | 13 ++++++ www/common/sframe-protocol.js | 3 ++ 7 files changed, 127 insertions(+), 37 deletions(-) diff --git a/www/common/loading.js b/www/common/loading.js index d9c3b8df9..da327f8f9 100644 --- a/www/common/loading.js +++ b/www/common/loading.js @@ -1,10 +1,73 @@ -define([ - 'less!/customize/src/less/loading.less' -], function () { +define([], function () { + var loadingStyle = (function(){/* + #loading { + position: fixed; + z-index: 9999999; + top: 0px; + bottom: 0px; + left: 0px; + right: 0px; + background: #222; + color: #fafafa; + text-align: center; + font-size: 1.5em; + } + #loading .loadingContainer { + margin-top: 50vh; + transform: translateY(-50%); + } + #loading .cryptofist { + margin-left: auto; + margin-right: auto; + height: 300px; + margin-bottom: 2em; + } + @media screen and (max-height: 450px) { + #loading .cryptofist { + display: none; + } + } + #loading .spinnerContainer { + position: relative; + height: 100px; + } + #loading .spinnerContainer > div { + height: 100px; + } + #loadingTip { + position: fixed; + z-index: 99999; + top: 80%; + left: 0; + right: 0; + text-align: center; + transition: opacity 750ms; + transition-delay: 3000ms; + } + @media screen and (max-height: 600px) { + #loadingTip { + display: none; + } + } + #loadingTip span { + background-color: #222; + color: #fafafa; + text-align: center; + font-size: 1.5em; + opacity: 0.7; + font-family: 'Open Sans', 'Helvetica Neue', sans-serif; + padding: 15px; + max-width: 60%; + display: inline-block; + }*/ + }).toString().slice(14, -3); var urlArgs = window.location.href.replace(/^.*\?([^\?]*)$/, function (all, x) { return x; }); var elem = document.createElement('div'); elem.setAttribute('id', 'loading'); elem.innerHTML = [ + '', '
', '', '
', diff --git a/www/common/sframe-boot.js b/www/common/sframe-boot.js index 4489db89f..f2fcadc37 100644 --- a/www/common/sframe-boot.js +++ b/www/common/sframe-boot.js @@ -6,32 +6,6 @@ // sed -i -e 's@/common/sframe-boot.js?ver=[^"]*@/common/sframe-boot.js?ver=1.3@' $x; done ;(function () { var afterLoaded = function (req) { - var localStorage = {}; - if (req.cfg && req.cfg.urlArgs) { - try { - localStorage = window.localStorage; - if (localStorage['CRYPTPAD_VERSION'] !== req.cfg.urlArgs) { - // new version, flush - Object.keys(localStorage).forEach(function (k) { - if (!k.indexOf('CRYPTPAD_CACHE_')) { delete localStorage[k]; } - }); - localStorage['CRYPTPAD_VERSION'] = req.cfg.urlArgs; - } - } catch (e) { - console.error(e); - localStorage = {}; - } - } - window.cryptpadCache = Object.freeze({ - put: function (k, v, cb) { - cb = cb || function () { }; - setTimeout(function () { localStorage['CRYPTPAD_CACHE_' + k] = v; cb(); }); - }, - get: function (k, cb) { - if (!cb) { throw new Error(); } - setTimeout(function () { cb(localStorage['CRYPTPAD_CACHE_' + k]); }); - } - }); req.cfg = req.cfg || {}; if (req.pfx) { req.cfg.onNodeCreated = function (node /*, config, module, path*/) { @@ -54,6 +28,20 @@ var afterLoaded = function (req) { clearInterval(intr); txid = {}; window.removeEventListener('message', onReply); + data.cache = data.cache || {}; + var updated = {}; + window.cryptpadCache = { + get: function (k, cb) { + setTimeout(function () { cb(data.cache[k]); }); + }, + put: function (k, v, cb) { + cb = cb || function () { }; + updated[k] = v; + setTimeout(function () { data.cache[k] = v; cb(); }); + }, + updated: updated, + cache: data.cache + }; require(['/common/sframe-boot2.js'], function () { }); }; window.addEventListener('message', onReply); diff --git a/www/common/sframe-boot2.js b/www/common/sframe-boot2.js index e6845bcbe..dd0370ca8 100644 --- a/www/common/sframe-boot2.js +++ b/www/common/sframe-boot2.js @@ -20,5 +20,7 @@ define(['/common/requireconfig.js'], function (RequireConfig) { window.__defineGetter__('localStorage', function () { return mkFakeStore(); }); window.__defineGetter__('sessionStorage', function () { return mkFakeStore(); }); + window.CRYPTPAD_INSIDE = true; + require([document.querySelector('script[data-bootload]').getAttribute('data-bootload')]); }); diff --git a/www/common/sframe-channel.js b/www/common/sframe-channel.js index 300491e1f..a091452c3 100644 --- a/www/common/sframe-channel.js +++ b/www/common/sframe-channel.js @@ -8,7 +8,7 @@ define([ return Math.random().toString(16).replace('0.', '') + Math.random().toString(16).replace('0.', ''); }; - var create = function (ow, cb, isSandbox) { + var create = function (ow, cb, isSandbox, sendData) { var otherWindow; var evReady = Util.mkEvent(true); var handlers = {}; @@ -47,7 +47,6 @@ define([ // Fire an event. channel.event('EV_SOMETHING', { args: "whatever" }); var event = chan.event = function (e, content) { - if (!otherWindow) { throw new Error('not yet initialized'); } if (!SFrameProtocol[e]) { throw new Error('please only fire events that are defined in sframe-protocol.js'); } @@ -63,7 +62,6 @@ define([ // If the type is a query, your handler will be invoked with a reply function that takes // one argument (the content to reply with). chan.on = function (queryType, handler, quiet) { - if (!otherWindow && !quiet) { throw new Error('not yet initialized'); } if (!SFrameProtocol[queryType]) { throw new Error('please only register handlers which are defined in sframe-protocol.js'); } @@ -85,7 +83,6 @@ define([ // when that handler is first registered. // channel.whenReg('Q_SOMETHING', function () { ...query Q_SOMETHING?... }); chan.whenReg = function (queryType, cb, always) { - if (!otherWindow) { throw new Error('not yet initialized'); } if (!SFrameProtocol[queryType]) { throw new Error('please only register handlers which are defined in sframe-protocol.js'); } @@ -109,7 +106,8 @@ define([ delete callWhenRegistered[content]; } insideHandlers.push(content); - }, true); + }); + chan.whenReg('EV_REGISTER_HANDLER', evReady.fire); // Make sure both iframes are ready chan.onReady = function (h) { @@ -131,8 +129,9 @@ define([ //console.log(msg); } else if (!otherWindow) { otherWindow = ow; - evReady.fire(); - ow.postMessage(JSON.stringify({ txid: data.txid }), '*'); + sendData = sendData || {}; + sendData.txid = data.txid; + ow.postMessage(JSON.stringify(sendData), '*'); cb(chan); } else if (typeof(data.q) === 'string' && handlers[data.q]) { handlers[data.q].forEach(function (f) { diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index 32143cb8f..00bd0e0ea 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -34,12 +34,34 @@ define([ Crypto = _Crypto; Cryptget = _Cryptget; FilePicker = _FilePicker; + + if (localStorage.CRYPTPAD_URLARGS !== ApiConfig.requireConf.urlArgs) { + console.log("New version, flushing cache"); + Object.keys(localStorage).forEach(function (k) { + if (k.indexOf('CRYPTPAD_CACHE|') !== 0) { return; } + delete localStorage[k]; + }); + localStorage.CRYPTPAD_URLARGS = ApiConfig.requireConf.urlArgs; + } + var cache = {}; + Object.keys(localStorage).forEach(function (k) { + if (k.indexOf('CRYPTPAD_CACHE|') !== 0) { return; } + cache[k.slice(('CRYPTPAD_CACHE|').length)] = localStorage[k]; + }); + SFrameChannel.create($('#sbox-iframe')[0].contentWindow, waitFor(function (sfc) { sframeChan = sfc; - })); + }), false, { cache: cache }); Cryptpad.ready(waitFor()); })); }).nThen(function (waitFor) { + + sframeChan.on('EV_CACHE_PUT', function (x) { + Object.keys(x).forEach(function (k) { + localStorage['CRYPTPAD_CACHE|' + k] = x[k]; + }); + }); + secret = Cryptpad.getSecrets(); if (!secret.channel) { // New pad: create a new random channel id diff --git a/www/common/sframe-common.js b/www/common/sframe-common.js index 5fd99d3d5..cf278dd1c 100644 --- a/www/common/sframe-common.js +++ b/www/common/sframe-common.js @@ -259,6 +259,19 @@ define([ }).nThen(function () { ctx.metadataMgr = MetadataMgr.create(ctx.sframeChan); + ctx.sframeChan.whenReg('EV_CACHE_PUT', function () { + if (Object.keys(window.cryptpadCache.updated).length) { + ctx.sframeChan.event('EV_CACHE_PUT', window.cryptpadCache.updated); + } + window.cryptpadCache._put = window.cryptpadCache.put; + window.cryptpadCache.put = function (k, v, cb) { + window.cryptpadCache._put(k, v, cb); + var x = {}; + x[k] = v; + ctx.sframeChan.event('EV_CACHE_PUT', x); + }; + }); + UI.addTooltips(); ctx.sframeChan.on('EV_RT_CONNECT', function () { CommonRealtime.setConnectionState(true); }); diff --git a/www/common/sframe-protocol.js b/www/common/sframe-protocol.js index 1be9d7476..cab662df0 100644 --- a/www/common/sframe-protocol.js +++ b/www/common/sframe-protocol.js @@ -127,4 +127,7 @@ define({ // Present mode URL 'Q_PRESENT_URL_GET_VALUE': true, 'EV_PRESENT_URL_SET_VALUE': true, + + // Put one or more entries to the cache which will go in localStorage. + 'EV_CACHE_PUT': true, });