big ugly commit that will be really hard to audit
This changeset applies new styles to the poll. it also uses the new asynchronous wrappers around the localStorage api. this is necessary because we're migrating to a storage system that will use an async api. The changes to the poll just happened to coincide with the async stuff. My apologies to anyone who wants to read this whole thing
This commit is contained in:
@@ -28,8 +28,6 @@ define([
|
|||||||
var now = new Date();
|
var now = new Date();
|
||||||
var hasRecent = false;
|
var hasRecent = false;
|
||||||
|
|
||||||
var memorySpan = Cryptpad.timeframe; // thirty days
|
|
||||||
|
|
||||||
var forgetPad = Cryptpad.forgetPad;
|
var forgetPad = Cryptpad.forgetPad;
|
||||||
|
|
||||||
var padTypes = {
|
var padTypes = {
|
||||||
@@ -45,23 +43,17 @@ define([
|
|||||||
return title;
|
return title;
|
||||||
};
|
};
|
||||||
|
|
||||||
var recentPads = Cryptpad.getRecentPads();
|
|
||||||
recentPads.sort(Cryptpad.mostRecent);
|
|
||||||
|
|
||||||
var fixHTML = function (html) {
|
var fixHTML = function (html) {
|
||||||
return html.replace(/</g, '<');
|
return html.replace(/</g, '<');
|
||||||
};
|
};
|
||||||
|
|
||||||
var makeRecentPadsTable = function () {
|
|
||||||
|
|
||||||
|
var makeRecentPadsTable = function (recentPads) {
|
||||||
if (!recentPads.length) { return; }
|
if (!recentPads.length) { return; }
|
||||||
recentPads.some(function (pad, index) {
|
recentPads.some(function (pad, index) {
|
||||||
if (!pad) { return; }
|
if (!pad) { return; }
|
||||||
|
|
||||||
//console.log(pad);
|
|
||||||
|
|
||||||
// don't link to old pads
|
|
||||||
if (now.getTime() - new Date(pad.atime).getTime() > memorySpan) { return true; }
|
|
||||||
|
|
||||||
hasRecent = true;
|
hasRecent = true;
|
||||||
|
|
||||||
// split up the uri
|
// split up the uri
|
||||||
@@ -92,7 +84,12 @@ define([
|
|||||||
}).text('✖').click(function () {
|
}).text('✖').click(function () {
|
||||||
Cryptpad.confirm(Messages.forgetPrompt + ' (' + fixHTML(shortTitle) + ')', function (yes) {
|
Cryptpad.confirm(Messages.forgetPrompt + ' (' + fixHTML(shortTitle) + ')', function (yes) {
|
||||||
if (!yes) { return; }
|
if (!yes) { return; }
|
||||||
forgetPad(pad.href);
|
forgetPad(pad.href, function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.log("Unable to forget pad");
|
||||||
|
console.log(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
$row.fadeOut(750, function () {
|
$row.fadeOut(750, function () {
|
||||||
$row.remove();
|
$row.remove();
|
||||||
if (!$table.find('tr').find('td').length) {
|
if (!$table.find('tr').find('td').length) {
|
||||||
@@ -102,6 +99,7 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$row
|
$row
|
||||||
.append($('<td>').text(name))
|
.append($('<td>').text(name))
|
||||||
@@ -116,13 +114,23 @@ define([
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Cryptpad.getRecentPads(function (err, recentPads) {
|
||||||
|
if (err) {
|
||||||
|
console.log("unable to get recent pads");
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (recentPads.length) {
|
if (recentPads.length) {
|
||||||
recentPads.sort(Cryptpad.mostRecent);
|
recentPads.sort(Cryptpad.mostRecent);
|
||||||
makeRecentPadsTable();
|
makeRecentPadsTable(recentPads);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasRecent) {
|
if (hasRecent) {
|
||||||
$('table').attr('style', '');
|
$('table').attr('style', '');
|
||||||
$tryit.text(Messages.recentPads);
|
$tryit.text(Messages.recentPads);
|
||||||
}
|
}
|
||||||
|
//recentPads.sort(Cryptpad.mostRecent);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
112
www/code/main.js
112
www/code/main.js
@@ -166,23 +166,32 @@ define([
|
|||||||
name: myUserName
|
name: myUserName
|
||||||
};
|
};
|
||||||
addToUserList(myData);
|
addToUserList(myData);
|
||||||
Cryptpad.setPadAttribute('username', myUserName);
|
Cryptpad.setPadAttribute('username', myUserName, function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.log("Couldn't set username");
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
onLocal();
|
onLocal();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var getLastName = function () {
|
var getLastName = function (cb) {
|
||||||
return Cryptpad.getPadAttribute('username') || '';
|
Cryptpad.getPadAttribute('username', function (err, userName) {
|
||||||
|
cb(err, userName || '');
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var createChangeName = function(id, $container) {
|
var createChangeName = function(id, $container) {
|
||||||
var buttonElmt = $container.find('#'+id)[0];
|
var buttonElmt = $container.find('#'+id)[0];
|
||||||
|
|
||||||
var lastName = getLastName();
|
getLastName(function (err, lastName) {
|
||||||
buttonElmt.addEventListener("click", function() {
|
buttonElmt.addEventListener("click", function() {
|
||||||
Cryptpad.prompt(Messages.changeNamePrompt, lastName, function (newName) {
|
Cryptpad.prompt(Messages.changeNamePrompt, lastName, function (newName) {
|
||||||
setName(newName);
|
setName(newName);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var getHeadingText = function () {
|
var getHeadingText = function () {
|
||||||
@@ -228,8 +237,7 @@ define([
|
|||||||
if (document.title === hash) {
|
if (document.title === hash) {
|
||||||
return getHeadingText() || hash;
|
return getHeadingText() || hash;
|
||||||
} else {
|
} else {
|
||||||
return document.title || getHeadingText() ||
|
return document.title || getHeadingText() || hash;
|
||||||
Cryptpad.getPadTitle() || hash;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -250,7 +258,6 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
var onInit = config.onInit = function (info) {
|
var onInit = config.onInit = function (info) {
|
||||||
//Cryptpad.warn("Initializing realtime session...");
|
|
||||||
var $bar = $('#pad-iframe')[0].contentWindow.$('#cme_toolbox');
|
var $bar = $('#pad-iframe')[0].contentWindow.$('#cme_toolbox');
|
||||||
toolbarList = info.userList;
|
toolbarList = info.userList;
|
||||||
var config = {
|
var config = {
|
||||||
@@ -309,14 +316,30 @@ define([
|
|||||||
Cryptpad.prompt(Messages.renamePrompt,
|
Cryptpad.prompt(Messages.renamePrompt,
|
||||||
suggestion, function (title, ev) {
|
suggestion, function (title, ev) {
|
||||||
if (title === null) { return; }
|
if (title === null) { return; }
|
||||||
if (Cryptpad.causesNamingConflict(title)) {
|
|
||||||
|
Cryptpad.causesNamingConflict(title, function (err, conflicts) {
|
||||||
|
if (err) {
|
||||||
|
console.log("Unable to determine if name caused a conflict");
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conflicts) {
|
||||||
Cryptpad.alert(Messages.renameConflict);
|
Cryptpad.alert(Messages.renameConflict);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Cryptpad.setPadTitle(title);
|
|
||||||
|
Cryptpad.setPadTitle(title, function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.log("unable to set pad title");
|
||||||
|
console.log(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
document.title = title;
|
document.title = title;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
$rightside.append($setTitle);
|
$rightside.append($setTitle);
|
||||||
|
|
||||||
/* add a forget button */
|
/* add a forget button */
|
||||||
@@ -330,13 +353,27 @@ define([
|
|||||||
var href = window.location.href;
|
var href = window.location.href;
|
||||||
Cryptpad.confirm(Messages.forgetPrompt, function (yes) {
|
Cryptpad.confirm(Messages.forgetPrompt, function (yes) {
|
||||||
if (!yes) { return; }
|
if (!yes) { return; }
|
||||||
Cryptpad.forgetPad(href);
|
Cryptpad.forgetPad(href, function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.log("unable to forget pad");
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
document.title = window.location.hash.slice(1,9);
|
document.title = window.location.hash.slice(1,9);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
$rightside.append($forgetPad);
|
$rightside.append($forgetPad);
|
||||||
|
|
||||||
var lastLanguage = Cryptpad.getPadAttribute('language') || 'javascript';
|
// TODO use cb
|
||||||
|
var configureLanguage = function (cb) {
|
||||||
|
// FIXME this is async so make it happen as early as possible
|
||||||
|
Cryptpad.getPadAttribute('language', function (err, lastLanguage) {
|
||||||
|
if (err) {
|
||||||
|
console.log("Unable to get pad language");
|
||||||
|
}
|
||||||
|
|
||||||
|
lastLanguage = lastLanguage || 'javascript';
|
||||||
|
|
||||||
/* Let the user select different syntax highlighting modes */
|
/* Let the user select different syntax highlighting modes */
|
||||||
var syntaxDropdown = '<select title="syntax highlighting" id="language-mode">\n' +
|
var syntaxDropdown = '<select title="syntax highlighting" id="language-mode">\n' +
|
||||||
@@ -348,6 +385,21 @@ define([
|
|||||||
|
|
||||||
setMode(lastLanguage);
|
setMode(lastLanguage);
|
||||||
|
|
||||||
|
$rightside.append(syntaxDropdown);
|
||||||
|
|
||||||
|
var $language = module.$language = $bar.find('#language-mode').on('change', function () {
|
||||||
|
var mode = $language.val();
|
||||||
|
setMode(mode);
|
||||||
|
Cryptpad.setPadAttribute('language', mode, function (err, data) {
|
||||||
|
// TODO
|
||||||
|
});
|
||||||
|
});
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var configureTheme = function () {
|
||||||
/* Remember the user's last choice of theme using localStorage */
|
/* Remember the user's last choice of theme using localStorage */
|
||||||
var themeKey = 'CRYPTPAD_CODE_THEME';
|
var themeKey = 'CRYPTPAD_CODE_THEME';
|
||||||
var lastTheme = localStorage.getItem(themeKey) || 'default';
|
var lastTheme = localStorage.getItem(themeKey) || 'default';
|
||||||
@@ -363,13 +415,6 @@ define([
|
|||||||
}).val(o.name).text(o.name));
|
}).val(o.name).text(o.name));
|
||||||
});
|
});
|
||||||
|
|
||||||
$rightside.append(syntaxDropdown);
|
|
||||||
|
|
||||||
var $language = module.$language = $bar.find('#language-mode').on('change', function () {
|
|
||||||
var mode = $language.val();
|
|
||||||
setMode(mode);
|
|
||||||
Cryptpad.setPadAttribute('language', mode);
|
|
||||||
});
|
|
||||||
|
|
||||||
$rightside.append($themeDropdown);
|
$rightside.append($themeDropdown);
|
||||||
|
|
||||||
@@ -384,11 +429,28 @@ define([
|
|||||||
// remember user choices
|
// remember user choices
|
||||||
localStorage.setItem(themeKey, theme);
|
localStorage.setItem(themeKey, theme);
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
configureLanguage(function () {
|
||||||
|
configureTheme();
|
||||||
|
});
|
||||||
|
|
||||||
window.location.hash = info.channel + secret.key;
|
window.location.hash = info.channel + secret.key;
|
||||||
var title = document.title = Cryptpad.getPadTitle();
|
Cryptpad.getPadTitle(function (err, title) {
|
||||||
Cryptpad.rememberPad(title);
|
if (err) {
|
||||||
|
console.log("Unable to get pad title");
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
document.title = title || window.location.hash.slice(1,9);
|
||||||
|
Cryptpad.rememberPad(title, function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.log("Unable to set pad title");
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var updateUserList = function(shjson) {
|
var updateUserList = function(shjson) {
|
||||||
@@ -446,10 +508,16 @@ define([
|
|||||||
initializing = false;
|
initializing = false;
|
||||||
//Cryptpad.log("Your document is ready");
|
//Cryptpad.log("Your document is ready");
|
||||||
|
|
||||||
var lastName = getLastName();
|
getLastName(function (err, lastName) {
|
||||||
|
if (err) {
|
||||||
|
console.log("Could not get previous name");
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (typeof(lastName) === 'string' && lastName.length) {
|
if (typeof(lastName) === 'string' && lastName.length) {
|
||||||
setName(lastName);
|
setName(lastName);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var cursorToPos = function(cursor, oldText) {
|
var cursorToPos = function(cursor, oldText) {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
define([
|
define([
|
||||||
'/customize/messages.js',
|
'/customize/messages.js',
|
||||||
|
'/customize/store.js',
|
||||||
'/bower_components/chainpad-crypto/crypto.js',
|
'/bower_components/chainpad-crypto/crypto.js',
|
||||||
'/bower_components/alertifyjs/dist/js/alertify.js',
|
'/bower_components/alertifyjs/dist/js/alertify.js',
|
||||||
'/bower_components/jquery/dist/jquery.min.js',
|
'/bower_components/jquery/dist/jquery.min.js',
|
||||||
], function (Messages, Crypto, Alertify) {
|
], function (Messages, Store, Crypto, Alertify) {
|
||||||
/* This file exposes functionality which is specific to Cryptpad, but not to
|
/* This file exposes functionality which is specific to Cryptpad, but not to
|
||||||
any particular pad type. This includes functions for committing metadata
|
any particular pad type. This includes functions for committing metadata
|
||||||
about pads to your local storage for future use and improved usability.
|
about pads to your local storage for future use and improved usability.
|
||||||
@@ -28,8 +29,8 @@ define([
|
|||||||
return secret;
|
return secret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var storageKey = common.storageKey = 'CryptPad_RECENTPADS';
|
var storageKey = common.storageKey = 'CryptPad_RECENTPADS';
|
||||||
//var timeframe = common.timeframe = 1000 * 60 * 60 * 24 * 30;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
the first time this gets called, your local storage will migrate to a
|
the first time this gets called, your local storage will migrate to a
|
||||||
@@ -75,20 +76,21 @@ define([
|
|||||||
return window.location.hash.slice(1);
|
return window.location.hash.slice(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
var setPadAttribute = common.setPadAttribute = function (attr, value) {
|
var setPadAttribute = common.setPadAttribute = function (attr, value, cb) {
|
||||||
var hash = getHash();
|
Store.set([getHash(), attr].join('.'), value, function (err, data) {
|
||||||
localStorage.setItem([getHash(),attr].join('.'), value);
|
cb(err, data);
|
||||||
return value;
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
var getPadAttribute = common.getPadAttribute = function (attr) {
|
var getPadAttribute = common.getPadAttribute = function (attr, cb) {
|
||||||
return localStorage.getItem([getHash(),attr].join('.'));
|
Store.get([getHash(), attr].join('.'), function (err, data) {
|
||||||
|
cb(err, data);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/* fetch and migrate your pad history from localStorage */
|
/* fetch and migrate your pad history from localStorage */
|
||||||
var getRecentPads = common.getRecentPads = function () {
|
var getRecentPads = common.getRecentPads = function (cb) {
|
||||||
var recentPadsStr = localStorage[storageKey];
|
Store.get(storageKey, function (err, recentPadsStr) {
|
||||||
|
|
||||||
var recentPads = [];
|
var recentPads = [];
|
||||||
if (recentPadsStr) {
|
if (recentPadsStr) {
|
||||||
try {
|
try {
|
||||||
@@ -98,12 +100,16 @@ define([
|
|||||||
// just overwrite it.
|
// just overwrite it.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return migrateRecentPads(recentPads);
|
|
||||||
|
cb(void 0, migrateRecentPads(recentPads));
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/* commit a list of pads to localStorage */
|
/* commit a list of pads to localStorage */
|
||||||
var setRecentPads = common.setRecentPads = function (pads) {
|
var setRecentPads = common.setRecentPads = function (pads, cb) {
|
||||||
localStorage.setItem(storageKey, JSON.stringify(pads));
|
Store.set(storageKey, JSON.stringify(pads), function (err, data) {
|
||||||
|
cb(err, data);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Sort pads according to how recently they were accessed */
|
/* Sort pads according to how recently they were accessed */
|
||||||
@@ -111,26 +117,53 @@ define([
|
|||||||
return new Date(b.atime).getTime() - new Date(a.atime).getTime();
|
return new Date(b.atime).getTime() - new Date(a.atime).getTime();
|
||||||
};
|
};
|
||||||
|
|
||||||
var forgetPad = common.forgetPad = function (href) {
|
var forgetPad = common.forgetPad = function (href, cb) {
|
||||||
var recentPads = getRecentPads().filter(function (pad) {
|
|
||||||
return pad.href !== href;
|
|
||||||
});
|
|
||||||
setRecentPads(recentPads);
|
|
||||||
|
|
||||||
var hash;
|
var hash;
|
||||||
href.replace(/#(.*)$/, function (h) { hash = h; });
|
href.replace(/#(.*)$/, function (x, h) { hash = h; });
|
||||||
if (!hash) { return; }
|
if (!hash) {
|
||||||
Object.keys(localStorage).forEach(function (k) {
|
return;
|
||||||
if (k.indexOf(hash) === 0) { localStorage.removeItem(k); }
|
}
|
||||||
|
|
||||||
|
getRecentPads(function (err, recentPads) {
|
||||||
|
setRecentPads(recentPads.filter(function (pad) {
|
||||||
|
return pad.href !== href;
|
||||||
|
}), function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
cb(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Store.dump(function (err, storage) {
|
||||||
|
if (err) {
|
||||||
|
cb(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var toRemove = [];
|
||||||
|
Object.keys(storage).forEach(function (k) {
|
||||||
|
if (k.indexOf(hash) === 0) {
|
||||||
|
toRemove.push(k);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Store.removeBatch(toRemove, function (err, data) {
|
||||||
|
cb(err, data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var rememberPad = common.rememberPad = window.rememberPad = function (title) {
|
var rememberPad = common.rememberPad = window.rememberPad = function (title, cb) {
|
||||||
// bail out early
|
// bail out early
|
||||||
if (!/#/.test(window.location.hash)) { return; }
|
if (!/#/.test(window.location.hash)) { return; }
|
||||||
|
|
||||||
var pads = getRecentPads();
|
getRecentPads(function (err, pads) {
|
||||||
|
if (err) {
|
||||||
|
cb(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//var pads = getRecentPads();
|
||||||
|
|
||||||
var now = new Date();
|
var now = new Date();
|
||||||
var href = window.location.href;
|
var href = window.location.href;
|
||||||
@@ -157,13 +190,20 @@ define([
|
|||||||
title: title || window.location.hash.slice(1,9),
|
title: title || window.location.hash.slice(1,9),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setRecentPads(out);
|
setRecentPads(out, function (err, data) {
|
||||||
|
cb(err, data);
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var setPadTitle = common.setPadTitle = function (name) {
|
var setPadTitle = common.setPadTitle = function (name, cb) {
|
||||||
var href = window.location.href;
|
var href = window.location.href;
|
||||||
var recent = getRecentPads();
|
|
||||||
|
|
||||||
|
getRecentPads(function (err, recent) {
|
||||||
|
if (err) {
|
||||||
|
cb(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
var renamed = recent.map(function (pad) {
|
var renamed = recent.map(function (pad) {
|
||||||
if (pad.href === href) {
|
if (pad.href === href) {
|
||||||
// update the atime
|
// update the atime
|
||||||
@@ -175,32 +215,52 @@ define([
|
|||||||
return pad;
|
return pad;
|
||||||
});
|
});
|
||||||
|
|
||||||
setRecentPads(renamed);
|
setRecentPads(renamed, function (err, data) {
|
||||||
|
cb(err, data);
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var getPadTitle = common.getPadTitle = function () {
|
var getPadTitle = common.getPadTitle = function (cb) {
|
||||||
var href = window.location.href;
|
var href = window.location.href;
|
||||||
var hashSlice = window.location.hash.slice(1,9);
|
var hashSlice = window.location.hash.slice(1,9);
|
||||||
var title = '';
|
var title = '';
|
||||||
getRecentPads().some(function (pad) {
|
|
||||||
|
getRecentPads(function (err, pads) {
|
||||||
|
if (err) {
|
||||||
|
cb(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pads.some(function (pad) {
|
||||||
if (pad.href === href) {
|
if (pad.href === href) {
|
||||||
title = pad.title || hashSlice;
|
title = pad.title || hashSlice;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return title;
|
|
||||||
|
cb(void 0, title);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var fixFileName = common.fixFileName = function (filename) {
|
var causesNamingConflict = common.causesNamingConflict = function (title, cb) {
|
||||||
return filename.replace(/ /g, '-').replace(/\//g, '_');
|
|
||||||
};
|
|
||||||
|
|
||||||
var causesNamingConflict = common.causesNamingConflict = function (title) {
|
|
||||||
var href = window.location.href;
|
var href = window.location.href;
|
||||||
return getRecentPads().some(function (pad) {
|
|
||||||
|
getRecentPads(function (err, pads) {
|
||||||
|
if (err) {
|
||||||
|
cb(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var conflicts = pads.some(function (pad) {
|
||||||
return pad.title === title &&
|
return pad.title === title &&
|
||||||
pad.href !== href;
|
pad.href !== href;
|
||||||
});
|
});
|
||||||
|
cb(void 0, conflicts);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var fixFileName = common.fixFileName = function (filename) {
|
||||||
|
return filename.replace(/ /g, '-').replace(/\//g, '_');
|
||||||
};
|
};
|
||||||
|
|
||||||
var importContent = common.importContent = function (type, f) {
|
var importContent = common.importContent = function (type, f) {
|
||||||
|
|||||||
@@ -234,8 +234,10 @@ define([
|
|||||||
myID = info.myID || null;
|
myID = info.myID || null;
|
||||||
};
|
};
|
||||||
|
|
||||||
var getLastName = function () {
|
var getLastName = function (cb) {
|
||||||
return Cryptpad.getPadAttribute('username') || '';
|
Cryptpad.getPadAttribute('username', function (err, userName) {
|
||||||
|
cb(err, userName || '');
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var setName = module.setName = function (newName) {
|
var setName = module.setName = function (newName) {
|
||||||
@@ -251,17 +253,23 @@ define([
|
|||||||
addToUserList(myData);
|
addToUserList(myData);
|
||||||
editor.fire('change');
|
editor.fire('change');
|
||||||
|
|
||||||
Cryptpad.setPadAttribute('username', newName);
|
Cryptpad.setPadAttribute('username', newName, function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.error("Couldn't set username");
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var createChangeName = function(id, $container) {
|
var createChangeName = function(id, $container) {
|
||||||
var buttonElmt = $container.find('#'+id)[0];
|
var buttonElmt = $container.find('#'+id)[0];
|
||||||
var lastName = getLastName();
|
//var lastName = getLastName();
|
||||||
|
getLastName(function (err, lastName) {
|
||||||
buttonElmt.addEventListener("click", function() {
|
buttonElmt.addEventListener("click", function() {
|
||||||
Cryptpad.prompt(Messages.changeNamePrompt, lastName, function (newName) {
|
Cryptpad.prompt(Messages.changeNamePrompt, lastName, function (newName) {
|
||||||
setName(newName);
|
setName(newName);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var DD = new DiffDom(diffOptions);
|
var DD = new DiffDom(diffOptions);
|
||||||
@@ -479,15 +487,23 @@ define([
|
|||||||
|
|
||||||
Cryptpad.prompt(Messages.renamePrompt, suggestion, function (title) {
|
Cryptpad.prompt(Messages.renamePrompt, suggestion, function (title) {
|
||||||
if (title === null) { return; }
|
if (title === null) { return; }
|
||||||
if (Cryptpad.causesNamingConflict(title)) {
|
Cryptpad.causesNamingConflict(title, function (err, conflicts) {
|
||||||
|
if (conflicts) {
|
||||||
Cryptpad.alert(Messages.renameConflict);
|
Cryptpad.alert(Messages.renameConflict);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cryptpad.setPadTitle(title);
|
Cryptpad.setPadTitle(title, function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.log("Couldn't set pad title");
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
document.title = title;
|
document.title = title;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
$rightside.append($rename);
|
$rightside.append($rename);
|
||||||
|
|
||||||
/* add a forget button */
|
/* add a forget button */
|
||||||
@@ -501,17 +517,31 @@ define([
|
|||||||
var href = window.location.href;
|
var href = window.location.href;
|
||||||
Cryptpad.confirm(Messages.forgetPrompt, function (yes) {
|
Cryptpad.confirm(Messages.forgetPrompt, function (yes) {
|
||||||
if (!yes) { return; }
|
if (!yes) { return; }
|
||||||
Cryptpad.forgetPad(href);
|
Cryptpad.forgetPad(href, function (err, data) {
|
||||||
document.title = window.location.hash.slice(1,9);
|
document.title = window.location.hash.slice(1,9);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
$rightside.append($forgetPad);
|
$rightside.append($forgetPad);
|
||||||
|
|
||||||
// set the hash
|
// set the hash
|
||||||
window.location.hash = info.channel + secret.key;
|
window.location.hash = info.channel + secret.key;
|
||||||
|
|
||||||
var title = document.title = Cryptpad.getPadTitle();
|
Cryptpad.getPadTitle(function (err, title) {
|
||||||
Cryptpad.rememberPad(title);
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
console.log("Couldn't get pad title");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
document.title = title || window.location.hash.slice(1, 9);
|
||||||
|
Cryptpad.rememberPad(title, function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.log("Couldn't remember pad");
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
Cryptpad.styleAlerts();
|
Cryptpad.styleAlerts();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -536,10 +566,13 @@ define([
|
|||||||
console.log("Unlocking editor");
|
console.log("Unlocking editor");
|
||||||
setEditable(true);
|
setEditable(true);
|
||||||
initializing = false;
|
initializing = false;
|
||||||
var lastName = getLastName();
|
|
||||||
|
getLastName(function (err, lastName) {
|
||||||
if (typeof(lastName) === 'string' && lastName.length) {
|
if (typeof(lastName) === 'string' && lastName.length) {
|
||||||
setName(lastName);
|
setName(lastName);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
//var lastName = getLastName();
|
||||||
};
|
};
|
||||||
|
|
||||||
var onAbort = realtimeOptions.onAbort = function (info) {
|
var onAbort = realtimeOptions.onAbort = function (info) {
|
||||||
|
|||||||
@@ -36,16 +36,20 @@
|
|||||||
<sub><a href="/"></a></sub>
|
<sub><a href="/"></a></sub>
|
||||||
</div>
|
</div>
|
||||||
<h1>CryptPoll</h1>
|
<h1>CryptPoll</h1>
|
||||||
<h2>Schedule or vote in <em>real time</em></h2>
|
<h2>Zero Knowledge, <em>realtime</em> scheduling</h2>
|
||||||
|
|
||||||
<p>Enter your name in the input field below and check the box for times when you are available</p>
|
<p>Your settings are updated instantly, so you never need to save.</p>
|
||||||
|
<p>All your input is encrypted so only people who have the link can access it. Even the server cannot see what you change.</p>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
<br>
|
||||||
|
|
||||||
<form class="realtime">
|
<form class="realtime">
|
||||||
<input type="text" id="title" placeholder="title"><br />
|
<input type="text" id="title" placeholder="title"><br />
|
||||||
<textarea id="description" placeholder="description"></textarea>
|
<textarea id="description" placeholder="description"></textarea>
|
||||||
|
|
||||||
|
<p>Enter your name in the input field below and check the box for times when you are available</p>
|
||||||
|
|
||||||
<!-- Table markup-->
|
<!-- Table markup-->
|
||||||
<table id="table">
|
<table id="table">
|
||||||
|
|
||||||
|
|||||||
158
www/poll/main.js
158
www/poll/main.js
@@ -78,15 +78,33 @@ define([
|
|||||||
|
|
||||||
var proxy = module.rt.proxy;
|
var proxy = module.rt.proxy;
|
||||||
|
|
||||||
|
var $div = $('<div>', {
|
||||||
|
'class': 'checkbox-contain',
|
||||||
|
});
|
||||||
|
|
||||||
|
var $label = $('<label>', {
|
||||||
|
'for': id,
|
||||||
|
});
|
||||||
|
|
||||||
var $check = Input({
|
var $check = Input({
|
||||||
id: id,
|
id: id,
|
||||||
name: id,
|
name: id,
|
||||||
type:'checkbox'
|
type:'checkbox',
|
||||||
}).click(function () {
|
}).on('change', function () {
|
||||||
console.log("(%s, %s) => %s", p.x, p.y, $check[0].checked);
|
console.log("(%s, %s) => %s", p.x, p.y, $check[0].checked);
|
||||||
proxy.table.cells[id] = $check[0].checked? 1: 0;
|
var checked = proxy.table.cells[id] = $check[0].checked? 1: 0;
|
||||||
|
if (checked) {
|
||||||
|
$label.addClass('yes');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$label.removeClass('yes');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return $check;
|
|
||||||
|
$div.append($check);
|
||||||
|
$check.after($label);
|
||||||
|
|
||||||
|
return $div; //$check;
|
||||||
};
|
};
|
||||||
var Text = function () { return Input({type:'text'}); };
|
var Text = function () { return Input({type:'text'}); };
|
||||||
|
|
||||||
@@ -163,7 +181,9 @@ define([
|
|||||||
proxy.table.cols[id] = $user.val() || "";
|
proxy.table.cols[id] = $user.val() || "";
|
||||||
});
|
});
|
||||||
|
|
||||||
var $wrapper = $('<div>')
|
var $wrapper = $('<div>', {
|
||||||
|
'class': 'text-cell',
|
||||||
|
})
|
||||||
.append($user)
|
.append($user)
|
||||||
.append($('<span>', {
|
.append($('<span>', {
|
||||||
'class': 'remove',
|
'class': 'remove',
|
||||||
@@ -198,7 +218,9 @@ define([
|
|||||||
proxy.table.rows[id] = $option.val();
|
proxy.table.rows[id] = $option.val();
|
||||||
});
|
});
|
||||||
|
|
||||||
var $wrapper = $('<div>')
|
var $wrapper = $('<div>', {
|
||||||
|
'class': 'text-cell',
|
||||||
|
})
|
||||||
.append($option)
|
.append($option)
|
||||||
.append($('<span>', {
|
.append($('<span>', {
|
||||||
'class': 'remove',
|
'class': 'remove',
|
||||||
@@ -267,9 +289,15 @@ define([
|
|||||||
|
|
||||||
var proxy = module.rt.proxy;
|
var proxy = module.rt.proxy;
|
||||||
|
|
||||||
|
var First = false;
|
||||||
|
|
||||||
// ensure that proxy.info and proxy.table exist
|
// ensure that proxy.info and proxy.table exist
|
||||||
['info', 'table'].forEach(function (k) {
|
['info', 'table'].forEach(function (k) {
|
||||||
if (typeof(proxy[k]) === 'undefined') { proxy[k] = {}; }
|
if (typeof(proxy[k]) === 'undefined') {
|
||||||
|
// you seem to be the first person to have visited this pad...
|
||||||
|
First = true;
|
||||||
|
proxy[k] = {};
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// table{cols,rows,cells}
|
// table{cols,rows,cells}
|
||||||
@@ -305,8 +333,16 @@ define([
|
|||||||
|
|
||||||
// cells
|
// cells
|
||||||
Object.keys(proxy.table.cells).forEach(function (uid) {
|
Object.keys(proxy.table.cells).forEach(function (uid) {
|
||||||
var p = parseXY(uid);
|
//var p = parseXY(uid);
|
||||||
document.getElementById(uid).checked = proxy.table.cells[uid] ? true : false;
|
var box = document.getElementById(uid);
|
||||||
|
if (!box) {
|
||||||
|
console.log("Couldn't find an element with uid [%s]", uid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var checked = box.checked = proxy.table.cells[uid] ? true : false;
|
||||||
|
if (checked) {
|
||||||
|
$(box).parent().find('label').addClass('yes');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
items.forEach(function ($item) {
|
items.forEach(function ($item) {
|
||||||
@@ -330,6 +366,9 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
proxy
|
proxy
|
||||||
|
.on('change', [], function () {
|
||||||
|
notify();
|
||||||
|
})
|
||||||
.on('change', ['info'], function (o, n, p) {
|
.on('change', ['info'], function (o, n, p) {
|
||||||
var $target = $('#' + p[1]);
|
var $target = $('#' + p[1]);
|
||||||
var el = $target[0];
|
var el = $target[0];
|
||||||
@@ -352,7 +391,6 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log("change: (%s, %s, [%s])", o, n, p.join(', '));
|
console.log("change: (%s, %s, [%s])", o, n, p.join(', '));
|
||||||
notify();
|
|
||||||
})
|
})
|
||||||
.on('change', ['table'], function (o, n, p) {
|
.on('change', ['table'], function (o, n, p) {
|
||||||
var id = p[p.length -1];
|
var id = p[p.length -1];
|
||||||
@@ -393,7 +431,18 @@ define([
|
|||||||
break;
|
break;
|
||||||
case 'cells':
|
case 'cells':
|
||||||
console.log("[Table.cell change] %s (%s => %s)@[%s]", id, o, n, p.slice(0, -1).join(', '));
|
console.log("[Table.cell change] %s (%s => %s)@[%s]", id, o, n, p.slice(0, -1).join(', '));
|
||||||
el.checked = proxy.table.cells[id] ? true: false;
|
var checked = el.checked = proxy.table.cells[id] ? true: false;
|
||||||
|
|
||||||
|
var $parent = $(el).parent();
|
||||||
|
|
||||||
|
if (!$parent.length) { console.log("couldn't find parent element of checkbox"); return; }
|
||||||
|
|
||||||
|
if (checked) {
|
||||||
|
$parent.find('label').addClass('yes');
|
||||||
|
//$(el).parent().
|
||||||
|
} else {
|
||||||
|
$parent.find('label').removeClass('yes');
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log("[Table change] (%s => %s)@[%s]", o, n, p.join(', '));
|
console.log("[Table change] (%s => %s)@[%s]", o, n, p.join(', '));
|
||||||
@@ -401,14 +450,61 @@ define([
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on('remove', [], function (o, p, root) {
|
.on('remove', [], function (o, p, root) {
|
||||||
console.log("remove: (%s, [%s])", o, p.join(', '));
|
//console.log("remove: (%s, [%s])", o, p.join(', '));
|
||||||
|
//console.log(p, o, p.length);
|
||||||
|
|
||||||
|
switch (p[1]) {
|
||||||
|
case 'cols':
|
||||||
|
console.log("[Table.cols removal] [%s]", p[2]);
|
||||||
|
table.removeColumn(p[2]);
|
||||||
|
return false;
|
||||||
|
case 'rows':
|
||||||
|
console.log("[Table.rows removal] [%s]", p[2]);
|
||||||
|
table.removeRow(p[2]);
|
||||||
|
return false;
|
||||||
|
case 'rowsOrder':
|
||||||
|
Object.keys(proxy.table.rows)
|
||||||
|
.forEach(function (rowId) {
|
||||||
|
if (proxy.table.rowsOrder.indexOf(rowId) === -1) {
|
||||||
|
proxy.table.rows[rowId] = undefined;
|
||||||
|
delete proxy.table.rows[rowId];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'colsOrder':
|
||||||
|
Object.keys(proxy.table.cols)
|
||||||
|
.forEach(function (colId) {
|
||||||
|
if (proxy.table.colsOrder.indexOf(colId) === -1) {
|
||||||
|
proxy.table.cols[colId] = undefined;
|
||||||
|
delete proxy.table.cols[colId];
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'cells':
|
||||||
|
// cool story bro
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log("[Table removal] [%s]", p.join(', '));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.on('disconnect', function (info) {
|
.on('disconnect', function (info) {
|
||||||
setEditable(false);
|
setEditable(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
var title = document.title = Cryptpad.getPadTitle();
|
Cryptpad.getPadTitle(function (err, title) {
|
||||||
Cryptpad.rememberPad(title);
|
title = document.title = title || window.location.hash.slice(1, 9);
|
||||||
|
|
||||||
|
Cryptpad.rememberPad(title, function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.log("unable to remember pad");
|
||||||
|
console.log(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
var $toolbar = $('#toolbar');
|
var $toolbar = $('#toolbar');
|
||||||
|
|
||||||
@@ -434,9 +530,15 @@ define([
|
|||||||
var href = window.location.href;
|
var href = window.location.href;
|
||||||
Cryptpad.confirm(Messages.forgetPrompt, function (yes) {
|
Cryptpad.confirm(Messages.forgetPrompt, function (yes) {
|
||||||
if (!yes) { return; }
|
if (!yes) { return; }
|
||||||
Cryptpad.forgetPad(href);
|
Cryptpad.forgetPad(href, function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.log("unable to forget pad");
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
document.title = window.location.hash.slice(1, 9);
|
document.title = window.location.hash.slice(1, 9);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
$toolbar.append(Button({
|
$toolbar.append(Button({
|
||||||
@@ -448,13 +550,22 @@ define([
|
|||||||
Cryptpad.prompt(Messages.renamePrompt,
|
Cryptpad.prompt(Messages.renamePrompt,
|
||||||
suggestion, function (title, ev) {
|
suggestion, function (title, ev) {
|
||||||
if (title === null) { return; }
|
if (title === null) { return; }
|
||||||
if (Cryptpad.causesNamingConflict(title)) {
|
|
||||||
|
Cryptpad.causesNamingConflict(title, function (err, conflicts) {
|
||||||
|
if (conflicts) {
|
||||||
Cryptpad.alert(Messages.renameConflict);
|
Cryptpad.alert(Messages.renameConflict);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Cryptpad.setPadTitle(title);
|
Cryptpad.setPadTitle(title, function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.log("unable to set pad title");
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
document.title = title;
|
document.title = title;
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
$toolbar.append(Button({
|
$toolbar.append(Button({
|
||||||
@@ -469,6 +580,19 @@ define([
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
setEditable(true);
|
setEditable(true);
|
||||||
|
|
||||||
|
if (First) {
|
||||||
|
// assume the first user to the poll wants to be the administrator...
|
||||||
|
// TODO prompt them with questions to set up their poll...
|
||||||
|
}
|
||||||
|
/* TODO
|
||||||
|
even if the user isn't the first, check their storage to see if
|
||||||
|
they've visited before and if they 'own' a column in the table.
|
||||||
|
if they do, make it editable and suggest that they fill it in.
|
||||||
|
|
||||||
|
if they have not visited, make a column for them.
|
||||||
|
don't propogate changes from this column until they make changes
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
var config = {
|
var config = {
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ define([
|
|||||||
|
|
||||||
$head.find('th').each(function (i) {
|
$head.find('th').each(function (i) {
|
||||||
var colId = $(this).data('rt-uid');
|
var colId = $(this).data('rt-uid');
|
||||||
$row.append($('<td>').append(Rest(xy(colId, uid))));
|
$row.append($('<td>', {
|
||||||
|
'class': 'checkbox-cell',
|
||||||
|
}).append(Rest(xy(colId, uid))));
|
||||||
});
|
});
|
||||||
|
|
||||||
rows.push(uid);
|
rows.push(uid);
|
||||||
@@ -35,7 +37,9 @@ define([
|
|||||||
var $width = $body.find('tr').each(function (i) {
|
var $width = $body.find('tr').each(function (i) {
|
||||||
// each checkbox needs a uid corresponding to its role
|
// each checkbox needs a uid corresponding to its role
|
||||||
var rowId = $(this).data('rt-uid');
|
var rowId = $(this).data('rt-uid');
|
||||||
$(this).append($('<td>').append(Rest(xy(uid, rowId))));
|
$(this).append($('<td>', {
|
||||||
|
'class': 'checkbox-cell',
|
||||||
|
}).append(Rest(xy(uid, rowId))));
|
||||||
});
|
});
|
||||||
|
|
||||||
cols.push(uid);
|
cols.push(uid);
|
||||||
@@ -92,6 +96,14 @@ define([
|
|||||||
removeFromArray(rows, uid);
|
removeFromArray(rows, uid);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var colExists = function (uid) {
|
||||||
|
return cols.indexOf(uid) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
var rowExists = function (uid) {
|
||||||
|
return rows.indexOf(uid) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
$: $t,
|
$: $t,
|
||||||
addRow: addRow,
|
addRow: addRow,
|
||||||
@@ -99,7 +111,9 @@ define([
|
|||||||
removeRow: removeRow,
|
removeRow: removeRow,
|
||||||
removeColumn: removeColumn,
|
removeColumn: removeColumn,
|
||||||
rows: rows,
|
rows: rows,
|
||||||
|
rowExists: rowExists,
|
||||||
cols: cols,
|
cols: cols,
|
||||||
|
colExists: colExists,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
return Table;
|
return Table;
|
||||||
|
|||||||
Reference in New Issue
Block a user