Merge branch 'better-slides'
commit
8e86be81b2
|
@ -72,9 +72,7 @@
|
|||
<th>Link</th>
|
||||
<th>Created</th>
|
||||
<th>Last Accessed</th>
|
||||
<th class="table-refresh" title="refresh list">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 861.143 861.144" style="enable-background:new 0 0 861.143 861.144;" xml:space="preserve"><path d="M803.661,613.847c21.129-49.956,31.842-102.991,31.842-157.634c0-46.664-7.883-92.431-23.43-136.031 c-15.025-42.134-36.846-81.294-64.859-116.393c-27.734-34.751-60.746-64.539-98.117-88.534 c-38.072-24.445-79.621-42.192-123.492-52.748c-28.191-6.782-56.543,10.571-63.326,38.761s10.572,56.542,38.762,63.325 c64.291,15.47,122.572,52.651,164.109,104.694c20.75,26.001,36.908,54.99,48.023,86.162c11.5,32.249,17.332,66.151,17.332,100.764 c0,80.114-31.197,155.435-87.848,212.083c-56.65,56.649-131.971,87.848-212.084,87.848c-80.114,0-155.434-31.198-212.083-87.849 c-56.65-56.648-87.848-131.969-87.848-212.083c0-59.197,17.208-116.435,49.763-165.521c28.053-42.3,66.007-76.562,110.547-100.007 v58.027c0,28.995,23.505,52.5,52.5,52.5s52.5-23.505,52.5-52.5V52.5c0-28.995-23.505-52.5-52.5-52.5H144.567 c-28.995,0-52.5,23.505-52.5,52.5c0,28.995,23.505,52.5,52.5,52.5h84.328C174.456,136.276,127.939,179.822,92.9,232.655 c-44.001,66.346-67.259,143.65-67.259,223.557c0,54.643,10.714,107.679,31.843,157.634c20.398,48.225,49.587,91.524,86.759,128.695 c37.171,37.171,80.471,66.361,128.696,86.759c49.956,21.13,102.991,31.844,157.634,31.844c54.644,0,107.677-10.714,157.634-31.844 c48.225-20.397,91.523-49.587,128.695-86.759C754.073,705.371,783.262,662.071,803.661,613.847z"/></svg>
|
||||
</th> <!-- remove column -->
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
|
|
|
@ -384,7 +384,8 @@ form.realtime #adduser {
|
|||
form.realtime #addoption {
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
div.modal {
|
||||
div.modal,
|
||||
div#modal {
|
||||
box-sizing: border-box;
|
||||
z-index: 9001;
|
||||
position: fixed;
|
||||
|
@ -395,7 +396,75 @@ div.modal {
|
|||
display: none;
|
||||
background-color: #302B28;
|
||||
}
|
||||
div.modal .center {
|
||||
div.modal #content,
|
||||
div#modal #content {
|
||||
box-sizing: border-box;
|
||||
border: 1px solid white;
|
||||
vertical-align: middle;
|
||||
padding: 2.5vw;
|
||||
width: 100vw;
|
||||
height: 56.25vw;
|
||||
max-height: 100vh;
|
||||
max-width: 177.78vh;
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
div.modal #content p,
|
||||
div#modal #content p,
|
||||
div.modal #content li,
|
||||
div#modal #content li,
|
||||
div.modal #content pre,
|
||||
div#modal #content pre,
|
||||
div.modal #content code,
|
||||
div#modal #content code {
|
||||
font-size: 2.5vw;
|
||||
line-height: 3vw;
|
||||
}
|
||||
div.modal #content h1,
|
||||
div#modal #content h1 {
|
||||
font-size: 5vw;
|
||||
line-height: 6vw;
|
||||
}
|
||||
div.modal #content h2,
|
||||
div#modal #content h2 {
|
||||
font-size: 4.2vw;
|
||||
line-height: 5.04vw;
|
||||
}
|
||||
div.modal #content h3,
|
||||
div#modal #content h3 {
|
||||
font-size: 3.6vw;
|
||||
line-height: 4.32vw;
|
||||
}
|
||||
div.modal #content h4,
|
||||
div#modal #content h4 {
|
||||
font-size: 3vw;
|
||||
line-height: 3.6vw;
|
||||
}
|
||||
div.modal #content h5,
|
||||
div#modal #content h5 {
|
||||
font-size: 2.2vw;
|
||||
line-height: 2.64vw;
|
||||
}
|
||||
div.modal #content h6,
|
||||
div#modal #content h6 {
|
||||
font-size: 1.6vw;
|
||||
line-height: 1.92vw;
|
||||
}
|
||||
div.modal #content pre > code,
|
||||
div#modal #content pre > code {
|
||||
display: block;
|
||||
position: relative;
|
||||
border: 1px solid #333;
|
||||
width: 90%;
|
||||
margin: auto;
|
||||
padding-left: .25vw;
|
||||
}
|
||||
div.modal .center,
|
||||
div#modal .center {
|
||||
position: relative;
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
|
@ -403,31 +472,39 @@ div.modal .center {
|
|||
border: 1px solid #685d56;
|
||||
text-align: center;
|
||||
}
|
||||
div.modal.shown {
|
||||
div.modal.shown,
|
||||
div#modal.shown {
|
||||
display: block;
|
||||
}
|
||||
div.modal table {
|
||||
div.modal table,
|
||||
div#modal table {
|
||||
margin: 30px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
div.modal table input {
|
||||
div.modal table input,
|
||||
div#modal table input {
|
||||
height: 100%;
|
||||
width: 90%;
|
||||
border: 3px solid #302B28;
|
||||
}
|
||||
div.modal table tfoot tr td {
|
||||
div.modal table tfoot tr td,
|
||||
div#modal table tfoot tr td {
|
||||
z-index: 4000;
|
||||
cursor: pointer;
|
||||
}
|
||||
div.modal #addtime,
|
||||
div.modal #adddate {
|
||||
div#modal #addtime,
|
||||
div.modal #adddate,
|
||||
div#modal #adddate {
|
||||
color: #46E981;
|
||||
border: 1px solid #46E981;
|
||||
padding: 15px;
|
||||
}
|
||||
div.modal #adddate {
|
||||
div.modal #adddate,
|
||||
div#modal #adddate {
|
||||
border-top-left-radius: 5px;
|
||||
}
|
||||
div.modal #addtime {
|
||||
div.modal #addtime,
|
||||
div#modal #addtime {
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,10 @@ define([
|
|||
], function (Messages, DecorateToolbar, Cryptpad, LilUri, Email) {
|
||||
var $ = window.$;
|
||||
|
||||
var APP = window.APP = {
|
||||
Cryptpad: Cryptpad,
|
||||
};
|
||||
|
||||
var email = Email.makeScrambler(1);
|
||||
|
||||
// slip past the spammers, then unscramble mailto links
|
||||
|
@ -22,14 +26,6 @@ define([
|
|||
DecorateToolbar.main($('#bottom-bar'));
|
||||
Cryptpad.styleAlerts();
|
||||
|
||||
var $table = $('table.scroll');
|
||||
var $tbody = $table.find('tbody');
|
||||
var $tryit = $('#tryit');
|
||||
var now = new Date();
|
||||
var hasRecent = false;
|
||||
|
||||
var forgetPad = Cryptpad.forgetPad;
|
||||
|
||||
var padTypes = {
|
||||
'/pad/': 'Pad',
|
||||
'/code/': 'Code',
|
||||
|
@ -37,16 +33,13 @@ define([
|
|||
'/slide/': 'Presentation',
|
||||
};
|
||||
|
||||
var truncateTitle = function (title, len) {
|
||||
if (typeof(title) === 'string' && title.length > len) {
|
||||
return title.slice(0, len) + '…';
|
||||
}
|
||||
return title;
|
||||
};
|
||||
var $table = $('table.scroll');
|
||||
var $tbody = $table.find('tbody');
|
||||
var $tryit = $('#tryit');
|
||||
var now = new Date();
|
||||
var hasRecent = false;
|
||||
|
||||
var fixHTML = function (html) {
|
||||
return html.replace(/</g, '<');
|
||||
};
|
||||
var forgetPad = Cryptpad.forgetPad;
|
||||
|
||||
var makeRecentPadsTable = function (recentPads) {
|
||||
if (!recentPads.length) { return; }
|
||||
|
@ -68,7 +61,7 @@ define([
|
|||
var name = padTypes[uri.path()];
|
||||
|
||||
var title = pad.title || uri.parts.hash.slice(0,8);
|
||||
var shortTitle = truncateTitle(pad.title, 48);
|
||||
var shortTitle = Cryptpad.truncate(pad.title, 48);
|
||||
|
||||
var date = new Date(pad.atime).toLocaleDateString();
|
||||
var created = new Date(pad.ctime).toLocaleDateString();
|
||||
|
@ -87,7 +80,7 @@ define([
|
|||
'class': 'remove',
|
||||
title: "forget '"+shortTitle + "'"
|
||||
}).text('✖').click(function () {
|
||||
Cryptpad.confirm(Messages.forgetPrompt + ' (' + fixHTML(shortTitle) + ')', function (yes) {
|
||||
Cryptpad.confirm(Messages.forgetPrompt + ' (' + Cryptpad.fixHTML(shortTitle) + ')', function (yes) {
|
||||
if (!yes) { return; }
|
||||
forgetPad(pad.href, function (err, data) {
|
||||
if (err) {
|
||||
|
@ -142,7 +135,14 @@ define([
|
|||
Cryptpad.ready(function () {
|
||||
console.log("ready");
|
||||
refreshTable();
|
||||
$('.table-refresh').click(refreshTable);
|
||||
|
||||
if (Cryptpad.store && Cryptpad.store.change) {
|
||||
Cryptpad.store.change(function (data) {
|
||||
if (data.key === 'CryptPad_RECENTPADS') {
|
||||
refreshTable();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -70,5 +70,8 @@ define(function () {
|
|||
'*/'
|
||||
].join('');
|
||||
|
||||
out.loginText = '<p>Your username and password are used to generate a unique key which is never known by our server.</p>\n' +
|
||||
'<p>Be careful not to forget your credentials, as they are impossible to recover</p>';
|
||||
|
||||
return out;
|
||||
});
|
||||
|
|
|
@ -49,6 +49,15 @@
|
|||
});
|
||||
};
|
||||
|
||||
var changeHandlers = frame.changeHandlers = [];
|
||||
|
||||
var change = frame.change = function (f) {
|
||||
if (typeof(f) !== 'function') {
|
||||
throw new Error('[Frame.change] expected callback');
|
||||
}
|
||||
changeHandlers.push(f);
|
||||
};
|
||||
|
||||
var _listener = function (e) {
|
||||
if (!frame.accepts(e.origin)) {
|
||||
console.log("message from %s rejected!", e.origin);
|
||||
|
@ -63,6 +72,14 @@
|
|||
console.log("No uid!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (uid === 'change' && changeHandlers.length) {
|
||||
changeHandlers.forEach(function (f) {
|
||||
f(data);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (timeouts[uid]) {
|
||||
window.clearTimeout(timeouts[uid]);
|
||||
}
|
||||
|
@ -89,6 +106,11 @@
|
|||
};
|
||||
|
||||
var id = req._uid = uid();
|
||||
// uid must not equal 'change'
|
||||
while(id === 'change') {
|
||||
id = req._uid = uid();
|
||||
}
|
||||
|
||||
if (typeof(cb) === 'function') {
|
||||
//console.log("setting callback!");
|
||||
listeners[id] = cb;
|
||||
|
|
|
@ -81,3 +81,13 @@ window.addEventListener('message', function(e) {
|
|||
}
|
||||
});
|
||||
|
||||
window.addEventListener('storage', function (ev) {
|
||||
parent.postMessage(JSON.stringify({
|
||||
_uid: 'change',
|
||||
data: {
|
||||
key: ev.key,
|
||||
oldValue: ev.oldValue,
|
||||
newValue: ev.newValue,
|
||||
}
|
||||
}), '*');
|
||||
});
|
||||
|
|
|
@ -471,7 +471,63 @@ form.realtime {
|
|||
#addoption { .bottom-left; }
|
||||
}
|
||||
|
||||
div.modal {
|
||||
.viewportRatio (@x, @y, @p: 100) {
|
||||
width: @p * 100vw;
|
||||
height: @y * (@p * 100vw) / @x;
|
||||
max-width: @x / @y * (@p * 100vh);
|
||||
max-height: (@p * 100vh);
|
||||
}
|
||||
|
||||
div.modal, div#modal {
|
||||
|
||||
#content {
|
||||
box-sizing: border-box;
|
||||
.size (@n) {
|
||||
font-size: @n * 1vw;
|
||||
line-height: @n * 1.2vw;
|
||||
}
|
||||
|
||||
border: 1px solid white;
|
||||
|
||||
vertical-align: middle;
|
||||
padding: 2.5vw;
|
||||
|
||||
|
||||
width: 100vw;
|
||||
height: 56.25vw; // height:width ratio = 9/16 = .5625
|
||||
//background: pink;
|
||||
max-height: 100vh;
|
||||
max-width: 177.78vh; // 16/9 = 1.778
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
top:0;bottom:0; // vertical center
|
||||
left:0;right:0; // horizontal center
|
||||
|
||||
p, li, pre, code {
|
||||
.size(2.5);
|
||||
}
|
||||
|
||||
h1 { .size(5); }
|
||||
h2 { .size(4.2); }
|
||||
h3 { .size(3.6); }
|
||||
h4 { .size (3); }
|
||||
h5 { .size(2.2); }
|
||||
h6 { .size(1.6); }
|
||||
|
||||
|
||||
pre > code {
|
||||
|
||||
display: block;
|
||||
position: relative;
|
||||
border: 1px solid #333;
|
||||
width: 90%;
|
||||
margin: auto;
|
||||
padding-left: .25vw;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
box-sizing: border-box;
|
||||
z-index: 9001;
|
||||
position: fixed;
|
||||
|
|
|
@ -71,5 +71,27 @@ define(function () {
|
|||
}
|
||||
};
|
||||
|
||||
var changeHandlers = Store.changeHandlers = [];
|
||||
|
||||
Store.change = function (f) {
|
||||
if (typeof(f) !== 'function') {
|
||||
throw new Error('[Store.change] callback must be a function');
|
||||
}
|
||||
changeHandlers.push(f);
|
||||
|
||||
if (changeHandlers.length === 1) {
|
||||
// start listening for changes
|
||||
window.addEventListener('storage', function (e) {
|
||||
changeHandlers.forEach(function (f) {
|
||||
f({
|
||||
key: e.key,
|
||||
oldValue: e.oldValue,
|
||||
newValue: e.newValue,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return Store;
|
||||
});
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
define([
|
||||
'/api/config?cb=' + Math.random().toString().slice(2),
|
||||
'/customize/messages.js',
|
||||
'/bower_components/chainpad-listmap/chainpad-listmap.js',
|
||||
'/bower_components/chainpad-crypto/crypto.js',
|
||||
'/bower_components/scrypt-async/scrypt-async.min.js',
|
||||
'/bower_components/tweetnacl/nacl-fast.min.js',
|
||||
], function (Config, Messages, Listmap, Crypto) {
|
||||
var Scrypt = window.scrypt;
|
||||
var Nacl = window.nacl;
|
||||
|
||||
var localKey = 'cryptpad_user_session';
|
||||
|
||||
var User = {};
|
||||
|
||||
var isArray = function (o) { return Object.prototype.toString.call(o) === '[object Array]'; };
|
||||
|
||||
var session = User.session = function (secret) {
|
||||
// TODO use store.js, not localStorage?
|
||||
if (secret) {
|
||||
localStorage.setItem(localKey, JSON.stringify(secret));
|
||||
return;
|
||||
}
|
||||
if (secret === null) {
|
||||
localStorage.removeItem(localKey);
|
||||
return;
|
||||
}
|
||||
var temp = localStorage.getItem(localKey);
|
||||
try {
|
||||
return JSON.parse(temp);
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/* 64 uint8s symmetric keys
|
||||
32 b64 channel
|
||||
16 b64 key
|
||||
16 b64 junk
|
||||
32 uint8s ed signing key
|
||||
32 uint8s curve public key */
|
||||
var parse128 = function (A) {
|
||||
if (A.length !== 128) {
|
||||
throw new Error("Expected 128 uint8s!");
|
||||
}
|
||||
var symmetric = Nacl.util.encodeBase64(A.slice(0, 36));
|
||||
return {
|
||||
ed: A.slice(96),
|
||||
curve: A.slice(64, 96),
|
||||
channel: symmetric.slice(0, 32),
|
||||
key: symmetric.slice(32),
|
||||
extra: A.slice(36, 64),
|
||||
};
|
||||
};
|
||||
|
||||
var initialize = User.initialize = function (proxy, secret, cb) {
|
||||
proxy.on('ready', function (info) {
|
||||
var now = ''+new Date();
|
||||
// old atime
|
||||
var otime = proxy.atime;
|
||||
|
||||
var atime = proxy.atime = now;
|
||||
|
||||
// creation time
|
||||
proxy.ctime = proxy.ctime || now;
|
||||
|
||||
proxy.username = proxy.username || secret.username;
|
||||
proxy.schema = proxy.schema || 'login_data-v0';
|
||||
|
||||
proxy.documents = proxy.documents || [];
|
||||
cb(void 0, proxy);
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
cb(proxy);
|
||||
*/
|
||||
var connect = User.connect = function (secret, cb) {
|
||||
if (!secret) {
|
||||
// FIXME
|
||||
return;
|
||||
}
|
||||
var config = {
|
||||
websocketURL: Config.websocketURL,
|
||||
channel: secret.channel,
|
||||
data: {},
|
||||
crypto: Crypto.createEncryptor(secret.key),
|
||||
logLevel: 0,
|
||||
};
|
||||
var rt = Listmap.create(config);
|
||||
initialize(rt.proxy, secret, cb);
|
||||
};
|
||||
|
||||
/* Asynchronously derive 128 random uint8s given a uname and password
|
||||
|
||||
cb(proxy, secret)
|
||||
*/
|
||||
var login = User.login = function (uname, pw, cb) {
|
||||
Scrypt(pw,
|
||||
uname,
|
||||
15, // memory cost parameter
|
||||
8, // block size parameter
|
||||
128, // derived key length
|
||||
200, // interruptStep
|
||||
function (bytes) {
|
||||
var secret = parse128(bytes);
|
||||
secret.username = uname;
|
||||
session(secret);
|
||||
connect(secret, cb);
|
||||
});
|
||||
};
|
||||
|
||||
var prepareStore = User.prepareStore = function (proxy) {
|
||||
var store = {};
|
||||
|
||||
var ps = proxy.store = proxy.store || {};
|
||||
|
||||
var set = store.set = function (key, val, cb) {
|
||||
ps[key] = val;
|
||||
cb();
|
||||
};
|
||||
|
||||
var batchset = store.setBatch = function (map, cb) {
|
||||
if (isArray(map) || typeof(map) !== 'object') {
|
||||
cb('[setBatch.TypeError] expected key-value pairs to set');
|
||||
return;
|
||||
}
|
||||
Object.keys(map).forEach(function (k) {
|
||||
ps[k] = map[k];
|
||||
});
|
||||
cb();
|
||||
};
|
||||
|
||||
var get = store.get = function (key, cb) {
|
||||
cb(void 0, ps[key]);
|
||||
};
|
||||
|
||||
var batchget = store.getBatch = function (keys, cb) {
|
||||
if (!isArray(keys)) {
|
||||
cb('[getBatch.TypeError] expected array of keys to return');
|
||||
return;
|
||||
}
|
||||
var map = {};
|
||||
keys.forEach(function (k) {
|
||||
map[k] = ps[k];
|
||||
});
|
||||
cb(void 0, map);
|
||||
};
|
||||
|
||||
var remove = store.remove = function (key, cb) {
|
||||
ps[key] = undefined;
|
||||
cb();
|
||||
};
|
||||
|
||||
var batchremove = store.removeBatch = function (keys, cb) {
|
||||
if (!isArray(keys)) {
|
||||
cb('[batchremove.TypeError] expected array of keys to remove');
|
||||
return;
|
||||
}
|
||||
keys.forEach(function (k) {
|
||||
ps[k] = undefined;
|
||||
});
|
||||
cb();
|
||||
};
|
||||
|
||||
var keys = store.keys = function (cb) {
|
||||
cb(void 0, Object.keys(ps));
|
||||
};
|
||||
|
||||
return store;
|
||||
};
|
||||
|
||||
return User;
|
||||
});
|
|
@ -4,8 +4,11 @@ define([
|
|||
'/bower_components/chainpad-crypto/crypto.js',
|
||||
'/bower_components/alertifyjs/dist/js/alertify.js',
|
||||
'/bower_components/spin.js/spin.min.js',
|
||||
|
||||
'/customize/user.js',
|
||||
|
||||
'/bower_components/jquery/dist/jquery.min.js',
|
||||
], function (Messages, Store, Crypto, Alertify, Spinner) {
|
||||
], function (Messages, Store, Crypto, Alertify, Spinner, User) {
|
||||
/* This file exposes functionality which is specific to Cryptpad, but not to
|
||||
any particular pad type. This includes functions for committing metadata
|
||||
about pads to your local storage for future use and improved usability.
|
||||
|
@ -14,13 +17,32 @@ define([
|
|||
*/
|
||||
var $ = window.jQuery;
|
||||
|
||||
var common = {};
|
||||
var store;
|
||||
var userProxy;
|
||||
var userStore;
|
||||
|
||||
var getStore = function () {
|
||||
if (!store) {
|
||||
throw new Error("Store is not ready!");
|
||||
var getStore = common.getStore = function (legacy) {
|
||||
if (!legacy && userStore) { return userStore; }
|
||||
if (store) { return store; }
|
||||
throw new Error("Store is not ready!");
|
||||
};
|
||||
|
||||
/*
|
||||
* cb(err, proxy);
|
||||
*/
|
||||
var authorize = common.authorize = function (cb) {
|
||||
console.log("Authorizing");
|
||||
var secret = User.session();
|
||||
if (!secret) {
|
||||
// user is not authenticated
|
||||
cb('user is not authenticated', void 0);
|
||||
}
|
||||
return store;
|
||||
|
||||
// for now we assume that things always work
|
||||
User.connect(secret, function (err, proxy) {
|
||||
cb(void 0, proxy);
|
||||
});
|
||||
};
|
||||
|
||||
Store.ready(function (err, Store) {
|
||||
|
@ -31,7 +53,6 @@ define([
|
|||
store = Store;
|
||||
});
|
||||
|
||||
var common = {};
|
||||
|
||||
var isArray = function (o) { return Object.prototype.toString.call(o) === '[object Array]'; };
|
||||
|
||||
|
@ -83,6 +104,9 @@ define([
|
|||
|
||||
var storageKey = common.storageKey = 'CryptPad_RECENTPADS';
|
||||
|
||||
/*
|
||||
* localStorage formatting
|
||||
*/
|
||||
/*
|
||||
the first time this gets called, your local storage will migrate to a
|
||||
new format. No more indices for values, everything is named now.
|
||||
|
@ -129,41 +153,6 @@ define([
|
|||
return window.location.hash.slice(1);
|
||||
};
|
||||
|
||||
var setPadAttribute = common.setPadAttribute = function (attr, value, cb) {
|
||||
getStore().set([getHash(), attr].join('.'), value, function (err, data) {
|
||||
cb(err, data);
|
||||
});
|
||||
};
|
||||
|
||||
var getPadAttribute = common.getPadAttribute = function (attr, cb) {
|
||||
getStore().get([getHash(), attr].join('.'), function (err, data) {
|
||||
cb(err, data);
|
||||
});
|
||||
};
|
||||
|
||||
/* fetch and migrate your pad history from localStorage */
|
||||
var getRecentPads = common.getRecentPads = function (cb) {
|
||||
getStore().get(storageKey, function (err, recentPads) {
|
||||
if (isArray(recentPads)) {
|
||||
cb(void 0, migrateRecentPads(recentPads));
|
||||
return;
|
||||
}
|
||||
cb(void 0, []);
|
||||
});
|
||||
};
|
||||
|
||||
/* commit a list of pads to localStorage */
|
||||
var setRecentPads = common.setRecentPads = function (pads, cb) {
|
||||
getStore().set(storageKey, pads, function (err, data) {
|
||||
cb(err, data);
|
||||
});
|
||||
};
|
||||
|
||||
/* Sort pads according to how recently they were accessed */
|
||||
var mostRecent = common.mostRecent = function (a, b) {
|
||||
return new Date(b.atime).getTime() - new Date(a.atime).getTime();
|
||||
};
|
||||
|
||||
var parsePadUrl = common.parsePadUrl = function (href) {
|
||||
var patt = /^https*:\/\/([^\/]*)\/(.*?)\/#(.*)$/i;
|
||||
|
||||
|
@ -177,7 +166,57 @@ define([
|
|||
return ret;
|
||||
};
|
||||
|
||||
var forgetPad = common.forgetPad = function (href, cb) {
|
||||
var makePad = function (href, title) {
|
||||
var now = ''+new Date();
|
||||
return {
|
||||
href: href,
|
||||
atime: now,
|
||||
ctime: now,
|
||||
title: title || window.location.hash.slice(1, 9),
|
||||
};
|
||||
};
|
||||
|
||||
/* Sort pads according to how recently they were accessed */
|
||||
var mostRecent = common.mostRecent = function (a, b) {
|
||||
return new Date(b.atime).getTime() - new Date(a.atime).getTime();
|
||||
};
|
||||
|
||||
// STORAGE
|
||||
var setPadAttribute = common.setPadAttribute = function (attr, value, cb, legacy) {
|
||||
getStore(legacy).set([getHash(), attr].join('.'), value, function (err, data) {
|
||||
cb(err, data);
|
||||
});
|
||||
};
|
||||
|
||||
// STORAGE
|
||||
var getPadAttribute = common.getPadAttribute = function (attr, cb, legacy) {
|
||||
getStore(legacy).get([getHash(), attr].join('.'), function (err, data) {
|
||||
cb(err, data);
|
||||
});
|
||||
};
|
||||
|
||||
// STORAGE
|
||||
/* fetch and migrate your pad history from localStorage */
|
||||
var getRecentPads = common.getRecentPads = function (cb, legacy) {
|
||||
getStore(legacy).get(storageKey, function (err, recentPads) {
|
||||
if (isArray(recentPads)) {
|
||||
cb(void 0, migrateRecentPads(recentPads));
|
||||
return;
|
||||
}
|
||||
cb(void 0, []);
|
||||
});
|
||||
};
|
||||
|
||||
// STORAGE
|
||||
/* commit a list of pads to localStorage */
|
||||
var setRecentPads = common.setRecentPads = function (pads, cb, legacy) {
|
||||
getStore(legacy).set(storageKey, pads, function (err, data) {
|
||||
cb(err, data);
|
||||
});
|
||||
};
|
||||
|
||||
// STORAGE
|
||||
var forgetPad = common.forgetPad = function (href, cb, legacy) {
|
||||
var parsed = parsePadUrl(href);
|
||||
|
||||
getRecentPads(function (err, recentPads) {
|
||||
|
@ -195,7 +234,7 @@ define([
|
|||
return;
|
||||
}
|
||||
|
||||
getStore().keys(function (err, keys) {
|
||||
getStore(legacy).keys(function (err, keys) {
|
||||
if (err) {
|
||||
cb(err);
|
||||
return;
|
||||
|
@ -208,24 +247,15 @@ define([
|
|||
cb();
|
||||
return;
|
||||
}
|
||||
getStore().removeBatch(toRemove, function (err, data) {
|
||||
getStore(legacy).removeBatch(toRemove, function (err, data) {
|
||||
cb(err, data);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var makePad = function (href, title) {
|
||||
var now = ''+new Date();
|
||||
return {
|
||||
href: href,
|
||||
atime: now,
|
||||
ctime: now,
|
||||
title: title || window.location.hash.slice(1, 9),
|
||||
};
|
||||
}, legacy);
|
||||
}, legacy);
|
||||
};
|
||||
|
||||
// STORAGE
|
||||
var rememberPad = common.rememberPad = window.rememberPad = function (title, cb) {
|
||||
// bail out early
|
||||
if (!/#/.test(window.location.hash)) { return; }
|
||||
|
@ -265,6 +295,7 @@ define([
|
|||
});
|
||||
};
|
||||
|
||||
// STORAGE
|
||||
var setPadTitle = common.setPadTitle = function (name, cb) {
|
||||
var href = window.location.href;
|
||||
var parsed = parsePadUrl(href);
|
||||
|
@ -301,6 +332,7 @@ define([
|
|||
});
|
||||
};
|
||||
|
||||
// STORAGE
|
||||
var getPadTitle = common.getPadTitle = function (cb) {
|
||||
var href = window.location.href;
|
||||
var parsed = parsePadUrl(window.location.href);
|
||||
|
@ -324,6 +356,7 @@ define([
|
|||
});
|
||||
};
|
||||
|
||||
// STORAGE
|
||||
var causesNamingConflict = common.causesNamingConflict = function (title, cb) {
|
||||
var href = window.location.href;
|
||||
|
||||
|
@ -364,13 +397,30 @@ define([
|
|||
}
|
||||
};
|
||||
|
||||
state++;
|
||||
state = 2;
|
||||
Store.ready(function (err, store) {
|
||||
env.store = store;
|
||||
common.store = env.store = store;
|
||||
cb();
|
||||
});
|
||||
|
||||
// HERE
|
||||
authorize(function (err, proxy) {
|
||||
if (err) {
|
||||
// not logged in
|
||||
}
|
||||
if (!proxy) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
userProxy = env.proxy = proxy;
|
||||
userStore = env.userStore = User.prepareStore(proxy);
|
||||
cb();
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Saving files
|
||||
*/
|
||||
var fixFileName = common.fixFileName = function (filename) {
|
||||
return filename.replace(/ /g, '-').replace(/[\/\?]/g, '_')
|
||||
.replace(/_+/g, '_');
|
||||
|
@ -388,6 +438,9 @@ define([
|
|||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Alertifyjs
|
||||
*/
|
||||
var styleAlerts = common.styleAlerts = function (href) {
|
||||
var $link = $('link[href="/customize/alertify.css"]');
|
||||
if ($link.length) { return; }
|
||||
|
@ -492,6 +545,9 @@ define([
|
|||
Alertify.error(msg);
|
||||
};
|
||||
|
||||
/*
|
||||
* spinner
|
||||
*/
|
||||
common.spinner = function (parent) {
|
||||
var $target = $('<div>', {
|
||||
//
|
||||
|
|
|
@ -102,7 +102,7 @@ define([
|
|||
console.log("Couldn't get pad title");
|
||||
return;
|
||||
}
|
||||
document.title = title || window.location.hash.slice(1, 9);
|
||||
document.title = APP.title = title || window.location.hash.slice(1, 9);
|
||||
Cryptpad.rememberPad(title, function (err, data) {
|
||||
if (err) {
|
||||
console.log("Couldn't remember pad");
|
||||
|
@ -140,7 +140,7 @@ define([
|
|||
console.log(err);
|
||||
return;
|
||||
}
|
||||
document.title = window.location.hash.slice(1,9);
|
||||
document.title = APP.title = window.location.hash.slice(1,9);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -167,7 +167,7 @@ define([
|
|||
console.error(err);
|
||||
return;
|
||||
}
|
||||
document.title = title;
|
||||
document.title = APP.title = title;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -267,6 +267,15 @@ define([
|
|||
});
|
||||
}
|
||||
|
||||
Slide.onChange(function (o, n, l) {
|
||||
if (n !== null) {
|
||||
document.title = APP.title + ' (' + (++n) + '/' + l + ')';
|
||||
return;
|
||||
}
|
||||
console.log("Exiting presentation mode");
|
||||
document.title = APP.title;
|
||||
});
|
||||
|
||||
setEditable(true);
|
||||
initializing = false;
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@ define([
|
|||
index: 0,
|
||||
lastIndex: 0,
|
||||
content: [],
|
||||
changeHandlers: [],
|
||||
};
|
||||
var $modal;
|
||||
var $content;
|
||||
|
@ -20,6 +21,25 @@ define([
|
|||
$content = Slide.$content = $c;
|
||||
};
|
||||
|
||||
Slide.onChange = function (f) {
|
||||
if (typeof(f) === 'function') {
|
||||
Slide.changeHandlers.push(f);
|
||||
}
|
||||
};
|
||||
|
||||
var change = function (oldIndex, newIndex) {
|
||||
if (oldIndex === newIndex) {
|
||||
return false;
|
||||
}
|
||||
if (Slide.changeHandlers.length) {
|
||||
Slide.changeHandlers.some(function (f, i) {
|
||||
// HERE
|
||||
f(oldIndex, newIndex, Slide.content.length);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
var forbiddenTags = Slide.forbiddenTags = [
|
||||
'SCRIPT',
|
||||
'IFRAME',
|
||||
|
@ -87,10 +107,10 @@ define([
|
|||
|
||||
if (typeof(patch) === 'string') {
|
||||
$content.html(Marked(c));
|
||||
return;
|
||||
} else {
|
||||
DD.apply($content[0], patch);
|
||||
}
|
||||
change(Slide.lastIndex, Slide.index);
|
||||
};
|
||||
|
||||
var show = Slide.show = function (bool, content) {
|
||||
|
@ -99,8 +119,10 @@ define([
|
|||
Slide.update(content);
|
||||
Slide.draw(Slide.index);
|
||||
$modal.addClass('shown');
|
||||
change(null, Slide.index);
|
||||
return;
|
||||
}
|
||||
change(Slide.index, null);
|
||||
$modal.removeClass('shown');
|
||||
};
|
||||
|
||||
|
@ -115,12 +137,16 @@ define([
|
|||
|
||||
var left = Slide.left = function () {
|
||||
console.log('left');
|
||||
Slide.lastIndex = Slide.index;
|
||||
|
||||
var i = Slide.index = Math.max(0, Slide.index - 1);
|
||||
Slide.draw(i);
|
||||
};
|
||||
|
||||
var right = Slide.right = function () {
|
||||
console.log('right');
|
||||
Slide.lastIndex = Slide.index;
|
||||
|
||||
var i = Slide.index = Math.min(Slide.content.length -1, Slide.index + 1);
|
||||
Slide.draw(i);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue