diff --git a/www/common/common-language.js b/www/common/common-language.js index 1af06df33..8b27a64bf 100644 --- a/www/common/common-language.js +++ b/www/common/common-language.js @@ -10,7 +10,6 @@ define([ // Add handler to the language selector Msg.setLanguage = function (l, sframeChan, cb) { - console.log(sframeChan); if (sframeChan) { // We're in the sandbox sframeChan.query("Q_LANGUAGE_SET", l, cb); diff --git a/www/common/common-messenger.js b/www/common/common-messenger.js index 9efe72586..cd0a5626d 100644 --- a/www/common/common-messenger.js +++ b/www/common/common-messenger.js @@ -1,12 +1,11 @@ define([ - 'jquery', '/bower_components/chainpad-crypto/crypto.js', '/common/curve.js', '/common/common-hash.js', '/common/common-util.js', '/common/common-realtime.js', '/common/common-constants.js', -], function ($, Crypto, Curve, Hash, Util, Realtime, Constants) { +], function (Crypto, Curve, Hash, Util, Realtime, Constants) { 'use strict'; var Msg = { inputs: [], @@ -485,7 +484,7 @@ define([ }; var msg = ['GET_HISTORY', chan.id, cfg]; network.sendto(network.historyKeeper, JSON.stringify(msg)) - .then($.noop, function (err) { + .then(function () {}, function (err) { throw new Error(err); }); }; diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index ee04ee19b..aeadac105 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -5,7 +5,6 @@ define([ '/common/common-hash.js', '/common/common-messaging.js', '/common/common-realtime.js', - '/common/common-language.js', '/common/common-constants.js', '/common/common-feedback.js', '/common/outer/local-store.js', @@ -15,7 +14,7 @@ define([ '/customize/application_config.js', '/bower_components/nthen/index.js', ], function (Config, Messages, Util, Hash, - Messaging, Realtime, Language, Constants, Feedback, LocalStore, AStore, + Messaging, Realtime, Constants, Feedback, LocalStore, AStore, Pinpad, AppConfig, Nthen) { /* This file exposes functionality which is specific to Cryptpad, but not to @@ -52,7 +51,9 @@ define([ return Messages._languageUsed; }; common.setLanguage = function (l, cb) { - Language.setLanguage(l, null, cb); + var LS_LANG = "CRYPTPAD_LANG"; + localStorage.setItem(LS_LANG, l); + cb(); }; @@ -743,10 +744,5 @@ define([ }()); - // MAGIC that happens implicitly - /*$(function () { - Language.applyTranslation(); - });*/ - return common; }); diff --git a/www/common/dom-ready.js b/www/common/dom-ready.js new file mode 100644 index 000000000..69a484493 --- /dev/null +++ b/www/common/dom-ready.js @@ -0,0 +1,10 @@ +define(function () { + return { + onReady: function (cb) { + if (document.readyState === 'complete') { return void cb(); } + document.onreadystatechange = function () { + if (document.readyState === 'complete') { cb(); } + }; + } + }; +}); diff --git a/www/common/fsStore.js b/www/common/fsStore.js deleted file mode 100644 index 27ed42d34..000000000 --- a/www/common/fsStore.js +++ /dev/null @@ -1,360 +0,0 @@ -define([ - 'jquery', - '/bower_components/chainpad-listmap/chainpad-listmap.js', - '/bower_components/chainpad-crypto/crypto.js?v=0.1.5', - '/common/userObject.js', - '/common/common-interface.js', - '/common/common-hash.js', - '/common/common-util.js', - '/common/common-constants.js', - '/common/migrate-user-object.js', - '/bower_components/chainpad/chainpad.dist.js', - '/common/outer/network-config.js', - '/common/outer/local-store.js', -], function ($, Listmap, Crypto, FO, UI, Hash, Util, Constants, Migrate, ChainPad, NetConfig, - LocalStore) { - /* - This module uses localStorage, which is synchronous, but exposes an - asyncronous API. This is so that we can substitute other storage - methods. - - To override these methods, create another file at: - /customize/storage.js - */ - - var Store = {}; - var store; - - var initStore = function (filesOp, storeObj, exp) { - var ret = {}; - - var safeSet = function (key, val) { - storeObj[key] = val; - }; - - // Store uses nodebacks... - ret.set = function (key, val, cb) { - safeSet(key, val); - cb(); - }; - - // implement in alternative store - ret.setBatch = function (map, cb) { - Object.keys(map).forEach(function (key) { - safeSet(key, map[key]); - }); - cb(void 0, map); - }; - - ret.setDrive = function (key, val, cb) { - storeObj.drive[key] = val; - cb(); - }; - - var safeGet = function (key) { - return storeObj[key]; - }; - - ret.get = function (key, cb) { - cb(void 0, safeGet(key)); - }; - - // implement in alternative store - ret.getBatch = function (keys, cb) { - var res = {}; - keys.forEach(function (key) { - res[key] = safeGet(key); - }); - cb(void 0, res); - }; - - var getAttributeObject = function (attr) { - if (typeof attr === "string") { - console.error('DEPRECATED: use setAttribute with an array, not a string'); - return { - obj: storeObj.settings, - key: attr - }; - } - if (!Array.isArray(attr)) { throw new Error("Attribute must be string or array"); } - if (attr.length === 0) { throw new Error("Attribute can't be empty"); } - var obj = storeObj.settings; - attr.forEach(function (el, i) { - if (i === attr.length-1) { return; } - if (!obj[el]) { - obj[el] = {}; - } - else if (typeof obj[el] !== "object") { throw new Error("Wrong attribute"); } - obj = obj[el]; - }); - return { - obj: obj, - key: attr[attr.length-1] - }; - }; - ret.setAttribute = function (attr, value, cb) { - try { - var object = getAttributeObject(attr); - object.obj[object.key] = value; - } catch (e) { return void cb(e); } - cb(); - }; - ret.getAttribute = function (attr, cb) { - var object; - try { - object = getAttributeObject(attr); - } catch (e) { return void cb(e); } - cb(null, object.obj[object.key]); - }; - ret.setPadAttribute = filesOp.setPadAttribute; - ret.getPadAttribute = filesOp.getPadAttribute; - ret.getIdFromHref = filesOp.getIdFromHref; - - ret.getDrive = function (key, cb) { - cb(void 0, storeObj.drive[key]); - }; - - var safeRemove = function (key) { - delete storeObj[key]; - }; - - ret.remove = function (key, cb) { - safeRemove(key); - cb(); - }; - - // implement in alternative store - ret.removeBatch = function (keys, cb) { - keys.forEach(function (key) { - safeRemove(key); - }); - cb(); - }; - - ret.keys = function (cb) { - cb(void 0, Object.keys(storeObj)); - }; - - ret.removeData = filesOp.removeData; - ret.pushData = filesOp.pushData; - ret.addPad = filesOp.add; - - ret.forgetPad = function (href, cb) { - filesOp.forget(href); - cb(); - }; - - ret.listTemplates = function () { - var templateFiles = filesOp.getFiles(['template']); - var res = []; - templateFiles.forEach(function (f) { - var data = filesOp.getFileData(f); - res.push(JSON.parse(JSON.stringify(data))); - }); - return res; - }; - - ret.getProxy = function () { - return exp; - }; - - ret.getLoginName = function () { - return storeObj.login_name; - }; - - ret.repairDrive = function () { - filesOp.fixFiles(); - }; - - ret.getEmptyObject = function () { - return filesOp.getStructure(); - }; - - ret.replace = filesOp.replace; - - ret.restoreHref = filesOp.restoreHref; - - ret.changeHandlers = []; - - ret.change = function () {}; - - ret.getProfile = function () { - return storeObj.profile; - }; - - return ret; - }; - - var tryParsing = function (x) { - try { return JSON.parse(x); } - catch (e) { - console.error(e); - return null; - } - }; - - var onReady = function (f, proxy, Cryptpad, exp) { - var fo = exp.userObject = exp.fo = FO.init(proxy.drive, { - pinPads: Cryptpad.pinPads, - loggedIn: LocalStore.isLoggedIn() - }); - var todo = function () { - fo.fixFiles(); - - Migrate(proxy, Cryptpad); - - store = initStore(fo, proxy, exp); - if (typeof(f) === 'function') { - f(void 0, store); - } - //storeObj = proxy; - - var requestLogin = function () { - // log out so that you don't go into an endless loop... - LocalStore.logout(); - - // redirect them to log in, and come back when they're done. - sessionStorage.redirectTo = window.location.href; - window.location.href = '/login/'; - }; - - var tokenKey = 'loginToken'; - if (LocalStore.isLoggedIn()) { - /* This isn't truly secure, since anyone who can read the user's object can - set their local loginToken to match that in the object. However, it exposes - a UI that will work most of the time. */ - - // every user object should have a persistent, random number - if (typeof(proxy.loginToken) !== 'number') { - proxy[tokenKey] = Math.floor(Math.random()*Number.MAX_SAFE_INTEGER); - } - - // copy User_hash into sessionStorage because cross-domain iframes - // on safari replaces localStorage with sessionStorage or something - if (sessionStorage) { sessionStorage.setItem('User_hash', localStorage.getItem('User_hash')); } - - var localToken = tryParsing(localStorage.getItem(tokenKey)); - if (localToken === null) { - // if that number hasn't been set to localStorage, do so. - localStorage.setItem(tokenKey, proxy.loginToken); - } else if (localToken !== proxy[tokenKey]) { - // if it has been, and the local number doesn't match that in - // the user object, request that they reauthenticate. - return void requestLogin(); - } - } - - if (!proxy.settings || !proxy.settings.general || - typeof(proxy.settings.general.allowUserFeedback) !== 'boolean') { - proxy.settings = proxy.settings || {}; - proxy.settings.general = proxy.settings.general || {}; - proxy.settings.general.allowUserFeedback = true; - } - - if (typeof(proxy.uid) !== 'string' || proxy.uid.length !== 32) { - // even anonymous users should have a persistent, unique-ish id - console.log('generating a persistent identifier'); - proxy.uid = Hash.createChannelId(); - } - - // if the user is logged in, but does not have signing keys... - if (LocalStore.isLoggedIn() && (!Cryptpad.hasSigningKeys(proxy) || - !Cryptpad.hasCurveKeys(proxy))) { - return void requestLogin(); - } - - proxy.on('change', [Constants.displayNameKey], function (o, n) { - if (typeof(n) !== "string") { return; } - Cryptpad.changeMetadata(); - }); - proxy.on('change', ['profile'], function () { - // Trigger userlist update when the avatar has changed - Cryptpad.changeMetadata(); - }); - proxy.on('change', ['friends'], function () { - // Trigger userlist update when the friendlist has changed - Cryptpad.changeMetadata(); - }); - proxy.on('change', [tokenKey], function () { - var localToken = tryParsing(localStorage.getItem(tokenKey)); - if (localToken !== proxy[tokenKey]) { - return void requestLogin(); - } - }); - }; - fo.migrate(todo); - }; - - var initialized = false; - - var init = function (f, Cryptpad) { - if (!Cryptpad || initialized) { return; } - initialized = true; - - var hash = LocalStore.getUserHash() || LocalStore.getFSHash() || Hash.createRandomHash(); - if (!hash) { - throw new Error('[Store.init] Unable to find or create a drive hash. Aborting...'); - } - var secret = Hash.getSecrets('drive', hash); - var listmapConfig = { - data: {}, - websocketURL: NetConfig.getWebsocketURL(), - channel: secret.channel, - readOnly: false, - validateKey: secret.keys.validateKey || undefined, - crypto: Crypto.createEncryptor(secret.keys), - userName: 'fs', - logLevel: 1, - ChainPad: ChainPad, - classic: true, - }; - - var exp = {}; - - var rt = window.rt = Listmap.create(listmapConfig); - - exp.realtime = rt.realtime; - exp.proxy = rt.proxy; - exp.loggedIn = Cryptpad.isLoggedIn(); - rt.proxy.on('create', function (info) { - exp.info = info; - if (!LocalStore.getUserHash()) { - LocalStore.setFSHash(Hash.getEditHashFromKeys(info.channel, secret.keys)); - } - }).on('ready', function () { - if (store) { return; } // the store is already ready, it is a reconnection - if (!rt.proxy.drive || typeof(rt.proxy.drive) !== 'object') { rt.proxy.drive = {}; } - var drive = rt.proxy.drive; - // Creating a new anon drive: import anon pads from localStorage - if ((!drive[Constants.oldStorageKey] || !Array.isArray(drive[Constants.oldStorageKey])) - && !drive['filesData']) { - drive[Constants.oldStorageKey] = []; - onReady(f, rt.proxy, Cryptpad, exp); - return; - } - // Drive already exist: return the existing drive, don't load data from legacy store - onReady(f, rt.proxy, Cryptpad, exp); - }) - .on('change', ['drive', 'migrate'], function () { - var path = arguments[2]; - var value = arguments[1]; - if (path[0] === 'drive' && path[1] === "migrate" && value === 1) { - rt.network.disconnect(); - rt.realtime.abort(); - UI.alert(Cryptpad.Messages.fs_migration, null, true); - } - }); - }; - - Store.ready = function (f, Cryptpad) { - if (store) { // Store.ready probably called twice, store already ready - if (typeof(f) === 'function') { - f(void 0, store); - } - } else { - init(f, Cryptpad); - } - }; - - return Store; -}); diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index fe94d1a38..7415843b1 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -328,7 +328,7 @@ define([ edPublic: store.proxy.edPublic, friends: store.proxy.friends, settings: store.proxy.settings, - thumbnails: !((store.proxy.settings || {}).general || {}).disableThumbnails + thumbnails: !Util.find(store.proxy, ['settings', 'general', 'disableThumbnails']) } }; cb(JSON.parse(JSON.stringify(metadata))); diff --git a/www/common/sframe-app-outer.js b/www/common/sframe-app-outer.js index 3c675a4c3..d0dcb631c 100644 --- a/www/common/sframe-app-outer.js +++ b/www/common/sframe-app-outer.js @@ -2,14 +2,14 @@ define([ '/bower_components/nthen/index.js', '/api/config', - 'jquery', + '/common/dom-ready.js', '/common/requireconfig.js', '/common/sframe-common-outer.js' -], function (nThen, ApiConfig, $, RequireConfig, SFCommonO) { +], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO) { var requireConfig = RequireConfig(); nThen(function (waitFor) { - $(waitFor()); + DomReady.onReady(waitFor()); }).nThen(function (waitFor) { var req = { cfg: requireConfig, @@ -18,7 +18,7 @@ define([ }; window.rc = requireConfig; window.apiconf = ApiConfig; - $('#sbox-iframe').attr('src', + document.getElementById('sbox-iframe').setAttribute('src', ApiConfig.httpSafeOrigin + window.location.pathname + 'inner.html?' + requireConfig.urlArgs + '#' + encodeURIComponent(JSON.stringify(req))); @@ -37,4 +37,4 @@ define([ }).nThen(function (/*waitFor*/) { SFCommonO.start(); }); -}); \ No newline at end of file +}); diff --git a/www/contacts/main.js b/www/contacts/main.js index f99e7d472..38d6c5e71 100644 --- a/www/contacts/main.js +++ b/www/contacts/main.js @@ -2,15 +2,15 @@ define([ '/bower_components/nthen/index.js', '/api/config', - 'jquery', + '/common/dom-ready.js', '/common/requireconfig.js', '/common/sframe-common-outer.js' -], function (nThen, ApiConfig, $, RequireConfig, SFCommonO) { +], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO) { var requireConfig = RequireConfig(); // Loaded in load #2 nThen(function (waitFor) { - $(waitFor()); + DomReady.onReady(waitFor()); }).nThen(function (waitFor) { var req = { cfg: requireConfig, @@ -19,7 +19,7 @@ define([ }; window.rc = requireConfig; window.apiconf = ApiConfig; - $('#sbox-iframe').attr('src', + document.getElementById('sbox-iframe').setAttribute('src', ApiConfig.httpSafeOrigin + '/contacts/inner.html?' + requireConfig.urlArgs + '#' + encodeURIComponent(JSON.stringify(req))); diff --git a/www/drive/main.js b/www/drive/main.js index 01fc98554..de668fc4d 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -2,15 +2,15 @@ define([ '/bower_components/nthen/index.js', '/api/config', - 'jquery', + '/common/dom-ready.js', '/common/requireconfig.js', '/common/sframe-common-outer.js', -], function (nThen, ApiConfig, $, RequireConfig, SFCommonO) { +], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO) { var requireConfig = RequireConfig(); // Loaded in load #2 nThen(function (waitFor) { - $(waitFor()); + DomReady.onReady(waitFor()); }).nThen(function (waitFor) { var req = { cfg: requireConfig, @@ -19,7 +19,7 @@ define([ }; window.rc = requireConfig; window.apiconf = ApiConfig; - $('#sbox-iframe').attr('src', + document.getElementById('sbox-iframe').setAttribute('src', ApiConfig.httpSafeOrigin + '/drive/inner.html?' + requireConfig.urlArgs + '#' + encodeURIComponent(JSON.stringify(req))); diff --git a/www/file/main.js b/www/file/main.js index 0af6558ef..e59957299 100644 --- a/www/file/main.js +++ b/www/file/main.js @@ -2,15 +2,15 @@ define([ '/bower_components/nthen/index.js', '/api/config', - 'jquery', + '/common/dom-ready.js', '/common/requireconfig.js', '/common/sframe-common-outer.js' -], function (nThen, ApiConfig, $, RequireConfig, SFCommonO) { +], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO) { var requireConfig = RequireConfig(); // Loaded in load #2 nThen(function (waitFor) { - $(waitFor()); + DomReady.onReady(waitFor()); }).nThen(function (waitFor) { var req = { cfg: requireConfig, @@ -19,7 +19,7 @@ define([ }; window.rc = requireConfig; window.apiconf = ApiConfig; - $('#sbox-iframe').attr('src', + document.getElementById('sbox-iframe').setAttribute('src', ApiConfig.httpSafeOrigin + '/file/inner.html?' + requireConfig.urlArgs + '#' + encodeURIComponent(JSON.stringify(req))); diff --git a/www/poll/main.js b/www/poll/main.js index 04c9b8f2f..737038ead 100644 --- a/www/poll/main.js +++ b/www/poll/main.js @@ -2,15 +2,15 @@ define([ '/bower_components/nthen/index.js', '/api/config', - 'jquery', + '/common/dom-ready.js', '/common/requireconfig.js', '/common/sframe-common-outer.js', -], function (nThen, ApiConfig, $, RequireConfig, SFCommonO) { +], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO) { var requireConfig = RequireConfig(); // Loaded in load #2 nThen(function (waitFor) { - $(waitFor()); + DomReady.onReady(waitFor()); }).nThen(function (waitFor) { var req = { cfg: requireConfig, @@ -19,7 +19,7 @@ define([ }; window.rc = requireConfig; window.apiconf = ApiConfig; - $('#sbox-iframe').attr('src', + document.getElementById('sbox-iframe').setAttribute('src', ApiConfig.httpSafeOrigin + '/poll/inner.html?' + requireConfig.urlArgs + '#' + encodeURIComponent(JSON.stringify(req))); diff --git a/www/profile/main.js b/www/profile/main.js index e325cdf6d..22823d0d9 100644 --- a/www/profile/main.js +++ b/www/profile/main.js @@ -2,15 +2,15 @@ define([ '/bower_components/nthen/index.js', '/api/config', - 'jquery', + '/common/dom-ready.js', '/common/requireconfig.js', '/common/sframe-common-outer.js', -], function (nThen, ApiConfig, $, RequireConfig, SFCommonO) { +], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO) { var requireConfig = RequireConfig(); // Loaded in load #2 nThen(function (waitFor) { - $(waitFor()); + DomReady.onReady(waitFor()); }).nThen(function (waitFor) { var req = { cfg: requireConfig, @@ -19,7 +19,7 @@ define([ }; window.rc = requireConfig; window.apiconf = ApiConfig; - $('#sbox-iframe').attr('src', + document.getElementById('sbox-iframe').setAttribute('src', ApiConfig.httpSafeOrigin + '/profile/inner.html?' + requireConfig.urlArgs + '#' + encodeURIComponent(JSON.stringify(req))); diff --git a/www/settings/main.js b/www/settings/main.js index 7075ccc8c..42f501075 100644 --- a/www/settings/main.js +++ b/www/settings/main.js @@ -2,15 +2,15 @@ define([ '/bower_components/nthen/index.js', '/api/config', - 'jquery', + '/common/dom-ready.js', '/common/requireconfig.js', '/common/sframe-common-outer.js' -], function (nThen, ApiConfig, $, RequireConfig, SFCommonO) { +], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO) { var requireConfig = RequireConfig(); // Loaded in load #2 nThen(function (waitFor) { - $(waitFor()); + DomReady.onReady(waitFor()); }).nThen(function (waitFor) { var req = { cfg: requireConfig, @@ -19,7 +19,7 @@ define([ }; window.rc = requireConfig; window.apiconf = ApiConfig; - $('#sbox-iframe').attr('src', + document.getElementById('sbox-iframe').setAttribute('src', ApiConfig.httpSafeOrigin + '/settings/inner.html?' + requireConfig.urlArgs + '#' + encodeURIComponent(JSON.stringify(req))); diff --git a/www/todo/main.js b/www/todo/main.js index 9caeb16ef..2898434fd 100644 --- a/www/todo/main.js +++ b/www/todo/main.js @@ -2,15 +2,15 @@ define([ '/bower_components/nthen/index.js', '/api/config', - 'jquery', + '/common/dom-ready.js', '/common/requireconfig.js', '/common/sframe-common-outer.js' -], function (nThen, ApiConfig, $, RequireConfig, SFCommonO) { +], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO) { var requireConfig = RequireConfig(); // Loaded in load #2 nThen(function (waitFor) { - $(waitFor()); + DomReady.onReady(waitFor()); }).nThen(function (waitFor) { var req = { cfg: requireConfig, @@ -19,7 +19,7 @@ define([ }; window.rc = requireConfig; window.apiconf = ApiConfig; - $('#sbox-iframe').attr('src', + document.getElementById('sbox-iframe').setAttribute('src', ApiConfig.httpSafeOrigin + '/todo/inner.html?' + requireConfig.urlArgs + '#' + encodeURIComponent(JSON.stringify(req))); diff --git a/www/whiteboard/main.js b/www/whiteboard/main.js index 4c8a3887c..ce1f14d9c 100644 --- a/www/whiteboard/main.js +++ b/www/whiteboard/main.js @@ -2,15 +2,15 @@ define([ '/bower_components/nthen/index.js', '/api/config', - 'jquery', + '/common/dom-ready.js', '/common/requireconfig.js', '/common/sframe-common-outer.js' -], function (nThen, ApiConfig, $, RequireConfig, SFCommonO) { +], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO) { var requireConfig = RequireConfig(); // Loaded in load #2 nThen(function (waitFor) { - $(waitFor()); + DomReady.onReady(waitFor()); }).nThen(function (waitFor) { var req = { cfg: requireConfig, @@ -19,7 +19,7 @@ define([ }; window.rc = requireConfig; window.apiconf = ApiConfig; - $('#sbox-iframe').attr('src', + document.getElementById('sbox-iframe').setAttribute('src', ApiConfig.httpSafeOrigin + '/whiteboard/inner.html?' + requireConfig.urlArgs + '#' + encodeURIComponent(JSON.stringify(req)));