mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-02-19 20:40:02 +00:00
Remove the obsolete Dropbox plugins
This commit is contained in:
parent
d066c074e5
commit
00a06f744c
@ -1,54 +0,0 @@
|
|||||||
/*\
|
|
||||||
title: $:/plugins/tiddlywiki/dropbox-app/dropbox-app.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: dropbox-startup
|
|
||||||
|
|
||||||
Startup the Dropbox wiki app
|
|
||||||
|
|
||||||
\*/
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
/*jslint node: true, browser: true */
|
|
||||||
/*global $tw: false */
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
exports.startup = function(loggedIn) {
|
|
||||||
// Load any tiddlers embedded in the index file
|
|
||||||
var index = $tw.wiki.getTiddlerData($tw.plugins.dropbox.titleTiddlerIndex);
|
|
||||||
if(index) {
|
|
||||||
$tw.wiki.addTiddlers(index.tiddlers);
|
|
||||||
$tw.wiki.addTiddlers(index.systemTiddlers,true);
|
|
||||||
$tw.plugins.dropbox.fileInfo = index.fileInfo;
|
|
||||||
}
|
|
||||||
if(loggedIn) {
|
|
||||||
// Figure out the wiki name
|
|
||||||
var url = (window.location.protocol + "//" + window.location.host + window.location.pathname),
|
|
||||||
wikiName;
|
|
||||||
if(url.indexOf($tw.plugins.dropbox.userInfo.publicAppUrl) === 0) {
|
|
||||||
var p = url.indexOf("/",$tw.plugins.dropbox.userInfo.publicAppUrl.length + 1);
|
|
||||||
if(p !== -1 && url.substr(p) === "/index.html") {
|
|
||||||
wikiName = decodeURIComponent(url.substring($tw.plugins.dropbox.userInfo.publicAppUrl.length + 1,p));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(wikiName) {
|
|
||||||
// Save the wiki name for later
|
|
||||||
$tw.plugins.dropbox.wikiName = wikiName;
|
|
||||||
$tw.wiki.addTiddler({title: $tw.plugins.dropbox.titleWikiName, text: $tw.plugins.dropbox.wikiName},true);
|
|
||||||
// Check for later versions of files on Dropbox
|
|
||||||
$tw.plugins.dropbox.refreshTiddlerFiles("/" + $tw.plugins.dropbox.wikiName + "/tiddlers",function(hadChanges) {
|
|
||||||
// Save the tiddler index if we had changes
|
|
||||||
if(hadChanges) {
|
|
||||||
$tw.plugins.dropbox.saveTiddlerIndex("/" + $tw.plugins.dropbox.wikiName + "/index.html",function(error) {
|
|
||||||
console.log("Saved tiddler index");
|
|
||||||
// Sync any subsequent tiddler changes
|
|
||||||
$tw.plugins.dropbox.setupSyncer($tw.wiki);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
alert("This TiddlyWiki file must be in Dropbox");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"title": "$:/plugins/tiddlywiki/dropbox-app",
|
|
||||||
"description": "Dropbox app components",
|
|
||||||
"author": "JeremyRuston",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"coreVersion": ">=5.0.0"
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
/*\
|
|
||||||
title: $:/plugins/tiddlywiki/dropbox-main/dropbox-main.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: dropbox-startup
|
|
||||||
|
|
||||||
Startup the Dropbox main app
|
|
||||||
|
|
||||||
\*/
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
/*jslint node: true, browser: true */
|
|
||||||
/*global $tw: false */
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
exports.startup = function(loggedIn) {
|
|
||||||
if(loggedIn) {
|
|
||||||
$tw.wiki.addTiddler({title: $tw.plugins.dropbox.titleLoadedWikis, text: "no"},true);
|
|
||||||
// Load tiddlers
|
|
||||||
$tw.plugins.dropbox.loadWikiFiles("/",function() {
|
|
||||||
$tw.wiki.addTiddler({title: $tw.plugins.dropbox.titleLoadedWikis, text: "yes"},true);
|
|
||||||
console.log("Loaded all wikis",$tw.wiki.tiddlers);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"title": "$:/plugins/tiddlywiki/dropbox-main",
|
|
||||||
"description": "Dropbox main components",
|
|
||||||
"author": "JeremyRuston",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"coreVersion": ">=5.0.0"
|
|
||||||
}
|
|
@ -1,700 +0,0 @@
|
|||||||
/*global setTimeout: false, console: false */
|
|
||||||
(function () {
|
|
||||||
|
|
||||||
var async = {};
|
|
||||||
|
|
||||||
// global on the server, window in the browser
|
|
||||||
var root = this,
|
|
||||||
previous_async = root.async;
|
|
||||||
|
|
||||||
async.noConflict = function () {
|
|
||||||
root.async = previous_async;
|
|
||||||
return async;
|
|
||||||
};
|
|
||||||
|
|
||||||
//// cross-browser compatiblity functions ////
|
|
||||||
|
|
||||||
var _forEach = function (arr, iterator) {
|
|
||||||
if (arr.forEach) {
|
|
||||||
return arr.forEach(iterator);
|
|
||||||
}
|
|
||||||
for (var i = 0; i < arr.length; i += 1) {
|
|
||||||
iterator(arr[i], i, arr);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var _map = function (arr, iterator) {
|
|
||||||
if (arr.map) {
|
|
||||||
return arr.map(iterator);
|
|
||||||
}
|
|
||||||
var results = [];
|
|
||||||
_forEach(arr, function (x, i, a) {
|
|
||||||
results.push(iterator(x, i, a));
|
|
||||||
});
|
|
||||||
return results;
|
|
||||||
};
|
|
||||||
|
|
||||||
var _reduce = function (arr, iterator, memo) {
|
|
||||||
if (arr.reduce) {
|
|
||||||
return arr.reduce(iterator, memo);
|
|
||||||
}
|
|
||||||
_forEach(arr, function (x, i, a) {
|
|
||||||
memo = iterator(memo, x, i, a);
|
|
||||||
});
|
|
||||||
return memo;
|
|
||||||
};
|
|
||||||
|
|
||||||
var _keys = function (obj) {
|
|
||||||
if (Object.keys) {
|
|
||||||
return Object.keys(obj);
|
|
||||||
}
|
|
||||||
var keys = [];
|
|
||||||
for (var k in obj) {
|
|
||||||
if (obj.hasOwnProperty(k)) {
|
|
||||||
keys.push(k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return keys;
|
|
||||||
};
|
|
||||||
|
|
||||||
//// exported async module functions ////
|
|
||||||
|
|
||||||
//// nextTick implementation with browser-compatible fallback ////
|
|
||||||
if (typeof process === 'undefined' || !(process.nextTick)) {
|
|
||||||
async.nextTick = function (fn) {
|
|
||||||
setTimeout(fn, 0);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
async.nextTick = process.nextTick;
|
|
||||||
}
|
|
||||||
|
|
||||||
async.forEach = function (arr, iterator, callback) {
|
|
||||||
callback = callback || function () {};
|
|
||||||
if (!arr.length) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
var completed = 0;
|
|
||||||
_forEach(arr, function (x) {
|
|
||||||
iterator(x, function (err) {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
callback = function () {};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
completed += 1;
|
|
||||||
if (completed === arr.length) {
|
|
||||||
callback(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
async.forEachSeries = function (arr, iterator, callback) {
|
|
||||||
callback = callback || function () {};
|
|
||||||
if (!arr.length) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
var completed = 0;
|
|
||||||
var iterate = function () {
|
|
||||||
iterator(arr[completed], function (err) {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
callback = function () {};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
completed += 1;
|
|
||||||
if (completed === arr.length) {
|
|
||||||
callback(null);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
iterate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
iterate();
|
|
||||||
};
|
|
||||||
|
|
||||||
async.forEachLimit = function (arr, limit, iterator, callback) {
|
|
||||||
callback = callback || function () {};
|
|
||||||
if (!arr.length || limit <= 0) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
var completed = 0;
|
|
||||||
var started = 0;
|
|
||||||
var running = 0;
|
|
||||||
|
|
||||||
(function replenish () {
|
|
||||||
if (completed === arr.length) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (running < limit && started < arr.length) {
|
|
||||||
started += 1;
|
|
||||||
running += 1;
|
|
||||||
iterator(arr[started - 1], function (err) {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
callback = function () {};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
completed += 1;
|
|
||||||
running -= 1;
|
|
||||||
if (completed === arr.length) {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
replenish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var doParallel = function (fn) {
|
|
||||||
return function () {
|
|
||||||
var args = Array.prototype.slice.call(arguments);
|
|
||||||
return fn.apply(null, [async.forEach].concat(args));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
var doSeries = function (fn) {
|
|
||||||
return function () {
|
|
||||||
var args = Array.prototype.slice.call(arguments);
|
|
||||||
return fn.apply(null, [async.forEachSeries].concat(args));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var _asyncMap = function (eachfn, arr, iterator, callback) {
|
|
||||||
var results = [];
|
|
||||||
arr = _map(arr, function (x, i) {
|
|
||||||
return {index: i, value: x};
|
|
||||||
});
|
|
||||||
eachfn(arr, function (x, callback) {
|
|
||||||
iterator(x.value, function (err, v) {
|
|
||||||
results[x.index] = v;
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
}, function (err) {
|
|
||||||
callback(err, results);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
async.map = doParallel(_asyncMap);
|
|
||||||
async.mapSeries = doSeries(_asyncMap);
|
|
||||||
|
|
||||||
|
|
||||||
// reduce only has a series version, as doing reduce in parallel won't
|
|
||||||
// work in many situations.
|
|
||||||
async.reduce = function (arr, memo, iterator, callback) {
|
|
||||||
async.forEachSeries(arr, function (x, callback) {
|
|
||||||
iterator(memo, x, function (err, v) {
|
|
||||||
memo = v;
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
}, function (err) {
|
|
||||||
callback(err, memo);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// inject alias
|
|
||||||
async.inject = async.reduce;
|
|
||||||
// foldl alias
|
|
||||||
async.foldl = async.reduce;
|
|
||||||
|
|
||||||
async.reduceRight = function (arr, memo, iterator, callback) {
|
|
||||||
var reversed = _map(arr, function (x) {
|
|
||||||
return x;
|
|
||||||
}).reverse();
|
|
||||||
async.reduce(reversed, memo, iterator, callback);
|
|
||||||
};
|
|
||||||
// foldr alias
|
|
||||||
async.foldr = async.reduceRight;
|
|
||||||
|
|
||||||
var _filter = function (eachfn, arr, iterator, callback) {
|
|
||||||
var results = [];
|
|
||||||
arr = _map(arr, function (x, i) {
|
|
||||||
return {index: i, value: x};
|
|
||||||
});
|
|
||||||
eachfn(arr, function (x, callback) {
|
|
||||||
iterator(x.value, function (v) {
|
|
||||||
if (v) {
|
|
||||||
results.push(x);
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}, function (err) {
|
|
||||||
callback(_map(results.sort(function (a, b) {
|
|
||||||
return a.index - b.index;
|
|
||||||
}), function (x) {
|
|
||||||
return x.value;
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
async.filter = doParallel(_filter);
|
|
||||||
async.filterSeries = doSeries(_filter);
|
|
||||||
// select alias
|
|
||||||
async.select = async.filter;
|
|
||||||
async.selectSeries = async.filterSeries;
|
|
||||||
|
|
||||||
var _reject = function (eachfn, arr, iterator, callback) {
|
|
||||||
var results = [];
|
|
||||||
arr = _map(arr, function (x, i) {
|
|
||||||
return {index: i, value: x};
|
|
||||||
});
|
|
||||||
eachfn(arr, function (x, callback) {
|
|
||||||
iterator(x.value, function (v) {
|
|
||||||
if (!v) {
|
|
||||||
results.push(x);
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}, function (err) {
|
|
||||||
callback(_map(results.sort(function (a, b) {
|
|
||||||
return a.index - b.index;
|
|
||||||
}), function (x) {
|
|
||||||
return x.value;
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
async.reject = doParallel(_reject);
|
|
||||||
async.rejectSeries = doSeries(_reject);
|
|
||||||
|
|
||||||
var _detect = function (eachfn, arr, iterator, main_callback) {
|
|
||||||
eachfn(arr, function (x, callback) {
|
|
||||||
iterator(x, function (result) {
|
|
||||||
if (result) {
|
|
||||||
main_callback(x);
|
|
||||||
main_callback = function () {};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, function (err) {
|
|
||||||
main_callback();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
async.detect = doParallel(_detect);
|
|
||||||
async.detectSeries = doSeries(_detect);
|
|
||||||
|
|
||||||
async.some = function (arr, iterator, main_callback) {
|
|
||||||
async.forEach(arr, function (x, callback) {
|
|
||||||
iterator(x, function (v) {
|
|
||||||
if (v) {
|
|
||||||
main_callback(true);
|
|
||||||
main_callback = function () {};
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}, function (err) {
|
|
||||||
main_callback(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// any alias
|
|
||||||
async.any = async.some;
|
|
||||||
|
|
||||||
async.every = function (arr, iterator, main_callback) {
|
|
||||||
async.forEach(arr, function (x, callback) {
|
|
||||||
iterator(x, function (v) {
|
|
||||||
if (!v) {
|
|
||||||
main_callback(false);
|
|
||||||
main_callback = function () {};
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}, function (err) {
|
|
||||||
main_callback(true);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// all alias
|
|
||||||
async.all = async.every;
|
|
||||||
|
|
||||||
async.sortBy = function (arr, iterator, callback) {
|
|
||||||
async.map(arr, function (x, callback) {
|
|
||||||
iterator(x, function (err, criteria) {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
callback(null, {value: x, criteria: criteria});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, function (err, results) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var fn = function (left, right) {
|
|
||||||
var a = left.criteria, b = right.criteria;
|
|
||||||
return a < b ? -1 : a > b ? 1 : 0;
|
|
||||||
};
|
|
||||||
callback(null, _map(results.sort(fn), function (x) {
|
|
||||||
return x.value;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
async.auto = function (tasks, callback) {
|
|
||||||
callback = callback || function () {};
|
|
||||||
var keys = _keys(tasks);
|
|
||||||
if (!keys.length) {
|
|
||||||
return callback(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
var results = {};
|
|
||||||
|
|
||||||
var listeners = [];
|
|
||||||
var addListener = function (fn) {
|
|
||||||
listeners.unshift(fn);
|
|
||||||
};
|
|
||||||
var removeListener = function (fn) {
|
|
||||||
for (var i = 0; i < listeners.length; i += 1) {
|
|
||||||
if (listeners[i] === fn) {
|
|
||||||
listeners.splice(i, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var taskComplete = function () {
|
|
||||||
_forEach(listeners.slice(0), function (fn) {
|
|
||||||
fn();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
addListener(function () {
|
|
||||||
if (_keys(results).length === keys.length) {
|
|
||||||
callback(null, results);
|
|
||||||
callback = function () {};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_forEach(keys, function (k) {
|
|
||||||
var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
|
|
||||||
var taskCallback = function (err) {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
// stop subsequent errors hitting callback multiple times
|
|
||||||
callback = function () {};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var args = Array.prototype.slice.call(arguments, 1);
|
|
||||||
if (args.length <= 1) {
|
|
||||||
args = args[0];
|
|
||||||
}
|
|
||||||
results[k] = args;
|
|
||||||
taskComplete();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var requires = task.slice(0, Math.abs(task.length - 1)) || [];
|
|
||||||
var ready = function () {
|
|
||||||
return _reduce(requires, function (a, x) {
|
|
||||||
return (a && results.hasOwnProperty(x));
|
|
||||||
}, true) && !results.hasOwnProperty(k);
|
|
||||||
};
|
|
||||||
if (ready()) {
|
|
||||||
task[task.length - 1](taskCallback, results);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var listener = function () {
|
|
||||||
if (ready()) {
|
|
||||||
removeListener(listener);
|
|
||||||
task[task.length - 1](taskCallback, results);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
addListener(listener);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
async.waterfall = function (tasks, callback) {
|
|
||||||
callback = callback || function () {};
|
|
||||||
if (!tasks.length) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
var wrapIterator = function (iterator) {
|
|
||||||
return function (err) {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
callback = function () {};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var args = Array.prototype.slice.call(arguments, 1);
|
|
||||||
var next = iterator.next();
|
|
||||||
if (next) {
|
|
||||||
args.push(wrapIterator(next));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
args.push(callback);
|
|
||||||
}
|
|
||||||
async.nextTick(function () {
|
|
||||||
iterator.apply(null, args);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
wrapIterator(async.iterator(tasks))();
|
|
||||||
};
|
|
||||||
|
|
||||||
async.parallel = function (tasks, callback) {
|
|
||||||
callback = callback || function () {};
|
|
||||||
if (tasks.constructor === Array) {
|
|
||||||
async.map(tasks, function (fn, callback) {
|
|
||||||
if (fn) {
|
|
||||||
fn(function (err) {
|
|
||||||
var args = Array.prototype.slice.call(arguments, 1);
|
|
||||||
if (args.length <= 1) {
|
|
||||||
args = args[0];
|
|
||||||
}
|
|
||||||
callback.call(null, err, args);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, callback);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var results = {};
|
|
||||||
async.forEach(_keys(tasks), function (k, callback) {
|
|
||||||
tasks[k](function (err) {
|
|
||||||
var args = Array.prototype.slice.call(arguments, 1);
|
|
||||||
if (args.length <= 1) {
|
|
||||||
args = args[0];
|
|
||||||
}
|
|
||||||
results[k] = args;
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
}, function (err) {
|
|
||||||
callback(err, results);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
async.series = function (tasks, callback) {
|
|
||||||
callback = callback || function () {};
|
|
||||||
if (tasks.constructor === Array) {
|
|
||||||
async.mapSeries(tasks, function (fn, callback) {
|
|
||||||
if (fn) {
|
|
||||||
fn(function (err) {
|
|
||||||
var args = Array.prototype.slice.call(arguments, 1);
|
|
||||||
if (args.length <= 1) {
|
|
||||||
args = args[0];
|
|
||||||
}
|
|
||||||
callback.call(null, err, args);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, callback);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var results = {};
|
|
||||||
async.forEachSeries(_keys(tasks), function (k, callback) {
|
|
||||||
tasks[k](function (err) {
|
|
||||||
var args = Array.prototype.slice.call(arguments, 1);
|
|
||||||
if (args.length <= 1) {
|
|
||||||
args = args[0];
|
|
||||||
}
|
|
||||||
results[k] = args;
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
}, function (err) {
|
|
||||||
callback(err, results);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
async.iterator = function (tasks) {
|
|
||||||
var makeCallback = function (index) {
|
|
||||||
var fn = function () {
|
|
||||||
if (tasks.length) {
|
|
||||||
tasks[index].apply(null, arguments);
|
|
||||||
}
|
|
||||||
return fn.next();
|
|
||||||
};
|
|
||||||
fn.next = function () {
|
|
||||||
return (index < tasks.length - 1) ? makeCallback(index + 1): null;
|
|
||||||
};
|
|
||||||
return fn;
|
|
||||||
};
|
|
||||||
return makeCallback(0);
|
|
||||||
};
|
|
||||||
|
|
||||||
async.apply = function (fn) {
|
|
||||||
var args = Array.prototype.slice.call(arguments, 1);
|
|
||||||
return function () {
|
|
||||||
return fn.apply(
|
|
||||||
null, args.concat(Array.prototype.slice.call(arguments))
|
|
||||||
);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var _concat = function (eachfn, arr, fn, callback) {
|
|
||||||
var r = [];
|
|
||||||
eachfn(arr, function (x, cb) {
|
|
||||||
fn(x, function (err, y) {
|
|
||||||
r = r.concat(y || []);
|
|
||||||
cb(err);
|
|
||||||
});
|
|
||||||
}, function (err) {
|
|
||||||
callback(err, r);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
async.concat = doParallel(_concat);
|
|
||||||
async.concatSeries = doSeries(_concat);
|
|
||||||
|
|
||||||
async.whilst = function (test, iterator, callback) {
|
|
||||||
if (test()) {
|
|
||||||
iterator(function (err) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
async.whilst(test, iterator, callback);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
async.until = function (test, iterator, callback) {
|
|
||||||
if (!test()) {
|
|
||||||
iterator(function (err) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
async.until(test, iterator, callback);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
async.queue = function (worker, concurrency) {
|
|
||||||
var workers = 0;
|
|
||||||
var q = {
|
|
||||||
tasks: [],
|
|
||||||
concurrency: concurrency,
|
|
||||||
saturated: null,
|
|
||||||
empty: null,
|
|
||||||
drain: null,
|
|
||||||
push: function (data, callback) {
|
|
||||||
if(data.constructor !== Array) {
|
|
||||||
data = [data];
|
|
||||||
}
|
|
||||||
_forEach(data, function(task) {
|
|
||||||
q.tasks.push({
|
|
||||||
data: task,
|
|
||||||
callback: typeof callback === 'function' ? callback : null
|
|
||||||
});
|
|
||||||
if (q.saturated && q.tasks.length == concurrency) {
|
|
||||||
q.saturated();
|
|
||||||
}
|
|
||||||
async.nextTick(q.process);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
process: function () {
|
|
||||||
if (workers < q.concurrency && q.tasks.length) {
|
|
||||||
var task = q.tasks.shift();
|
|
||||||
if(q.empty && q.tasks.length == 0) q.empty();
|
|
||||||
workers += 1;
|
|
||||||
worker(task.data, function () {
|
|
||||||
workers -= 1;
|
|
||||||
if (task.callback) {
|
|
||||||
task.callback.apply(task, arguments);
|
|
||||||
}
|
|
||||||
if(q.drain && q.tasks.length + workers == 0) q.drain();
|
|
||||||
q.process();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
length: function () {
|
|
||||||
return q.tasks.length;
|
|
||||||
},
|
|
||||||
running: function () {
|
|
||||||
return workers;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return q;
|
|
||||||
};
|
|
||||||
|
|
||||||
var _console_fn = function (name) {
|
|
||||||
return function (fn) {
|
|
||||||
var args = Array.prototype.slice.call(arguments, 1);
|
|
||||||
fn.apply(null, args.concat([function (err) {
|
|
||||||
var args = Array.prototype.slice.call(arguments, 1);
|
|
||||||
if (typeof console !== 'undefined') {
|
|
||||||
if (err) {
|
|
||||||
if (console.error) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (console[name]) {
|
|
||||||
_forEach(args, function (x) {
|
|
||||||
console[name](x);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
async.log = _console_fn('log');
|
|
||||||
async.dir = _console_fn('dir');
|
|
||||||
/*async.info = _console_fn('info');
|
|
||||||
async.warn = _console_fn('warn');
|
|
||||||
async.error = _console_fn('error');*/
|
|
||||||
|
|
||||||
async.memoize = function (fn, hasher) {
|
|
||||||
var memo = {};
|
|
||||||
var queues = {};
|
|
||||||
hasher = hasher || function (x) {
|
|
||||||
return x;
|
|
||||||
};
|
|
||||||
var memoized = function () {
|
|
||||||
var args = Array.prototype.slice.call(arguments);
|
|
||||||
var callback = args.pop();
|
|
||||||
var key = hasher.apply(null, args);
|
|
||||||
if (key in memo) {
|
|
||||||
callback.apply(null, memo[key]);
|
|
||||||
}
|
|
||||||
else if (key in queues) {
|
|
||||||
queues[key].push(callback);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
queues[key] = [callback];
|
|
||||||
fn.apply(null, args.concat([function () {
|
|
||||||
memo[key] = arguments;
|
|
||||||
var q = queues[key];
|
|
||||||
delete queues[key];
|
|
||||||
for (var i = 0, l = q.length; i < l; i++) {
|
|
||||||
q[i].apply(null, arguments);
|
|
||||||
}
|
|
||||||
}]));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
memoized.unmemoized = fn;
|
|
||||||
return memoized;
|
|
||||||
};
|
|
||||||
|
|
||||||
async.unmemoize = function (fn) {
|
|
||||||
return function () {
|
|
||||||
return (fn.unmemoized || fn).apply(null, arguments);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// AMD / RequireJS
|
|
||||||
if (typeof define !== 'undefined' && define.amd) {
|
|
||||||
define('async', [], function () {
|
|
||||||
return async;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Node.js
|
|
||||||
else if (typeof module !== 'undefined' && module.exports) {
|
|
||||||
module.exports = async;
|
|
||||||
}
|
|
||||||
// included directly via <script> tag
|
|
||||||
else {
|
|
||||||
root.async = async;
|
|
||||||
}
|
|
||||||
|
|
||||||
}());
|
|
@ -1,3 +0,0 @@
|
|||||||
title: $:/plugins/tiddlywiki/dropbox/async.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: library
|
|
@ -1,480 +0,0 @@
|
|||||||
/*\
|
|
||||||
title: $:/plugins/tiddlywiki/dropbox/dropbox.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: browser-startup
|
|
||||||
|
|
||||||
Main Dropbox integration module. It creates the `$tw.plugins.dropbox` object that includes static methods for various Dropbox operations. It also contains a startup function that kicks off the login process
|
|
||||||
|
|
||||||
\*/
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
/*jslint node: true, browser: true */
|
|
||||||
/*global $tw: false */
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Obfuscated API key
|
|
||||||
var apiKey = "m+qwjj8wFRA=|1TSoitGS9Nz2RTwv+jrUJnsAj0yy57NhQJ4TkZ/+Hw==";
|
|
||||||
|
|
||||||
// Query string marker for forcing authentication
|
|
||||||
var queryLoginMarker = "login=true";
|
|
||||||
|
|
||||||
// Require async.js
|
|
||||||
var async = require("./async.js");
|
|
||||||
|
|
||||||
$tw.plugins.dropbox = {
|
|
||||||
// State data
|
|
||||||
client: null, // Dropbox.js client object
|
|
||||||
fileInfo: {}, // Hashmap of each filename as retrieved from Dropbox (including .meta files): {versionTag:,title:}
|
|
||||||
titleInfo: {}, // Hashmap of each tiddler title retrieved from Dropbox to filename
|
|
||||||
// Titles of various system tiddlers used by the plugin
|
|
||||||
titleIsLoggedIn: "$:/plugins/dropbox/IsLoggedIn",
|
|
||||||
titleUserName: "$:/plugins/dropbox/UserName",
|
|
||||||
titlePublicAppUrl: "$:/plugins/dropbox/PublicAppUrl",
|
|
||||||
titleAppTemplateHtml: "$:/plugins/dropbox/apptemplate.html",
|
|
||||||
titleTiddlerIndex: "$:/plugins/dropbox/Index",
|
|
||||||
titleAppIndexTemplate: "$:/plugins/dropbox/index.template.html",
|
|
||||||
titleWikiName: "$:/plugins/dropbox/WikiName",
|
|
||||||
titleLoadedWikis: "$:/plugins/dropbox/LoadedWikis"
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Startup function that sets up Dropbox and, if the queryLoginMarker is present, logs the user in. After login, any dropbox-startup modules are executed.
|
|
||||||
*/
|
|
||||||
exports.startup = function() {
|
|
||||||
if(!$tw.browser) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Mark us as not logged in
|
|
||||||
$tw.wiki.addTiddler({title: $tw.plugins.dropbox.titleIsLoggedIn, text: "no"},true);
|
|
||||||
// Initialise Dropbox for sandbox access
|
|
||||||
$tw.plugins.dropbox.client = new Dropbox.Client({key: apiKey, sandbox: true});
|
|
||||||
// Use the basic redirection authentication driver
|
|
||||||
$tw.plugins.dropbox.client.authDriver(new Dropbox.Drivers.Redirect({rememberUser: true}));
|
|
||||||
// Authenticate ourselves if the marker is in the document query string
|
|
||||||
if(document.location.search.indexOf(queryLoginMarker) !== -1) {
|
|
||||||
$tw.plugins.dropbox.login();
|
|
||||||
} else {
|
|
||||||
$tw.plugins.dropbox.invokeDropboxStartupModules(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Error handling
|
|
||||||
*/
|
|
||||||
$tw.plugins.dropbox.showError = function(error) {
|
|
||||||
alert("Dropbox error: " + error);
|
|
||||||
console.log("Dropbox error: " + error);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Authenticate
|
|
||||||
*/
|
|
||||||
$tw.plugins.dropbox.login = function() {
|
|
||||||
$tw.plugins.dropbox.client.authenticate(function(error, client) {
|
|
||||||
if(error) {
|
|
||||||
return $tw.plugins.dropbox.showError(error);
|
|
||||||
}
|
|
||||||
// Mark us as logged in
|
|
||||||
$tw.wiki.addTiddler({title: $tw.plugins.dropbox.titleIsLoggedIn, text: "yes"},true);
|
|
||||||
// Get user information
|
|
||||||
$tw.plugins.dropbox.getUserInfo(function() {
|
|
||||||
// Invoke any dropbox-startup modules
|
|
||||||
$tw.plugins.dropbox.invokeDropboxStartupModules(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Invoke any dropbox-startup modules
|
|
||||||
*/
|
|
||||||
$tw.plugins.dropbox.invokeDropboxStartupModules = function(loggedIn) {
|
|
||||||
$tw.modules.forEachModuleOfType("dropbox-startup",function(title,module) {
|
|
||||||
module.startup(loggedIn);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Get user information
|
|
||||||
*/
|
|
||||||
$tw.plugins.dropbox.getUserInfo = function(callback) {
|
|
||||||
$tw.plugins.dropbox.client.getUserInfo(function(error,userInfo) {
|
|
||||||
if(error) {
|
|
||||||
callback(error);
|
|
||||||
return $tw.plugins.dropbox.showError(error);
|
|
||||||
}
|
|
||||||
$tw.plugins.dropbox.userInfo = userInfo;
|
|
||||||
// Save the username
|
|
||||||
$tw.wiki.addTiddler({title: $tw.plugins.dropbox.titleUserName, text: userInfo.name},true);
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Logout
|
|
||||||
*/
|
|
||||||
$tw.plugins.dropbox.logout = function() {
|
|
||||||
$tw.plugins.dropbox.client.signOut(function(error) {
|
|
||||||
if(error) {
|
|
||||||
return $tw.plugins.dropbox.showError(error);
|
|
||||||
}
|
|
||||||
// Mark us as logged out
|
|
||||||
$tw.wiki.deleteTiddler($tw.plugins.dropbox.titleUserName);
|
|
||||||
$tw.wiki.addTiddler({title: $tw.plugins.dropbox.titleIsLoggedIn, text: "no"},true);
|
|
||||||
// Remove any marker from the query string
|
|
||||||
document.location.search = "";
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Load tiddlers representing each wiki in a folder
|
|
||||||
*/
|
|
||||||
$tw.plugins.dropbox.loadWikiFiles = function(path,callback) {
|
|
||||||
// First get the list of tiddler files
|
|
||||||
$tw.plugins.dropbox.client.stat(path,{readDir: true},function(error,stat,stats) {
|
|
||||||
if(error) {
|
|
||||||
return $tw.plugins.dropbox.showError(error);
|
|
||||||
}
|
|
||||||
// Create a tiddler for each folder
|
|
||||||
for(var s=0; s<stats.length; s++) {
|
|
||||||
var stat = stats[s];
|
|
||||||
if(!stat.isFile && stat.isFolder) {
|
|
||||||
var url = $tw.plugins.dropbox.userInfo.publicAppUrl + stat.path + "/index.html";
|
|
||||||
$tw.wiki.addTiddler({title: "'" + stat.name + "'", text: "wiki", tags: ["wiki"], wikiName: stat.name, urlView: url, urlEdit: url + "?login=true"});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Synchronise the local state with the files in Dropbox
|
|
||||||
*/
|
|
||||||
$tw.plugins.dropbox.refreshTiddlerFiles = function(path,callback) {
|
|
||||||
// First get the list of tiddler files
|
|
||||||
$tw.plugins.dropbox.client.stat(path,{readDir: true},function(error,stat,stats) {
|
|
||||||
if(error) {
|
|
||||||
return $tw.plugins.dropbox.showError(error);
|
|
||||||
}
|
|
||||||
// Make a hashmap of each of the file names
|
|
||||||
var filenames = {},f,hadDeletions;
|
|
||||||
for(f=0; f<stats.length; f++) {
|
|
||||||
filenames[stats[f].name] = true;
|
|
||||||
}
|
|
||||||
console.log("filenames",filenames);
|
|
||||||
console.log("fileinfo",$tw.plugins.dropbox.fileInfo)
|
|
||||||
// Check to see if any files have been deleted, and remove the associated tiddlers
|
|
||||||
for(f in $tw.plugins.dropbox.fileInfo) {
|
|
||||||
if(!$tw.utils.hop(filenames,f)) {
|
|
||||||
$tw.wiki.deleteTiddler($tw.plugins.dropbox.fileInfo[f].title);
|
|
||||||
hadDeletions = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Process the files via an asynchronous queue, with concurrency set to 2 at a time
|
|
||||||
var q = async.queue(function(task,callback) {
|
|
||||||
$tw.plugins.dropbox.loadTiddlerFile(task.path,task.type,task.stats,callback);
|
|
||||||
}, 2);
|
|
||||||
// Call the callback when we've processed all the files
|
|
||||||
q.drain = function () {
|
|
||||||
callback(true); // Indicate that there were changes
|
|
||||||
};
|
|
||||||
// Push a task onto the queue for each file to be processed
|
|
||||||
for(var s=0; s<stats.length; s++) {
|
|
||||||
var stat = stats[s],
|
|
||||||
isMetaFile = stat.path.lastIndexOf(".meta") === stat.path.length - 5;
|
|
||||||
if(stat.isFile && !stat.isFolder && !isMetaFile) {
|
|
||||||
// Don't load the file if the version tag shows it hasn't changed
|
|
||||||
var fileInfo = $tw.plugins.dropbox.fileInfo[stat.name] || {},
|
|
||||||
hasChanged = stat.versionTag !== fileInfo.versionTag;
|
|
||||||
if(!hasChanged) {
|
|
||||||
// Check if there is a metafile and whether it has changed
|
|
||||||
var metafileName = stat.name + ".meta";
|
|
||||||
for(var p=0; p<stats.length; p++) {
|
|
||||||
if(stats[p].name === metafileName) {
|
|
||||||
fileInfo = $tw.plugins.dropbox.fileInfo[metafileName] || {};
|
|
||||||
hasChanged = stats[p].versionTag !== fileInfo.versionTag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(hasChanged) {
|
|
||||||
q.push({path: stat.path, type: stat.mimeType, stats: stats});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If we didn't queue anything for loading we'll have to manually trigger our callback
|
|
||||||
if(q.length() === 0) {
|
|
||||||
callback(hadDeletions); // And tell it that there are changes if there were deletions
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Load a tiddler file
|
|
||||||
*/
|
|
||||||
$tw.plugins.dropbox.loadTiddlerFile = function(path,mimeType,stats,callback) {
|
|
||||||
console.log("loading tiddler from",path);
|
|
||||||
// If the mime type is "application/octet-stream" then we'll take the type from the extension
|
|
||||||
var isBinary = false,
|
|
||||||
p = path.lastIndexOf(".");
|
|
||||||
if(mimeType === "application/octet-stream" && p !== -1) {
|
|
||||||
var ext = path.substr(p);
|
|
||||||
if($tw.utils.hop($tw.config.fileExtensionInfo,ext)) {
|
|
||||||
mimeType = $tw.config.fileExtensionInfo[ext].type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($tw.utils.hop($tw.config.contentTypeInfo,mimeType)) {
|
|
||||||
isBinary = $tw.config.contentTypeInfo[mimeType].encoding === "base64";
|
|
||||||
}
|
|
||||||
var xhr = $tw.plugins.dropbox.client.readFile(path,{binary: isBinary},function(error,data,stat) {
|
|
||||||
if(error) {
|
|
||||||
callback(error);
|
|
||||||
return $tw.plugins.dropbox.showError(error);
|
|
||||||
}
|
|
||||||
// Compute the default title
|
|
||||||
var defaultTitle = path,
|
|
||||||
p = path.lastIndexOf("/");
|
|
||||||
if(p !== -1) {
|
|
||||||
defaultTitle = path.substr(p+1);
|
|
||||||
}
|
|
||||||
// Deserialise the tiddler(s) out of the text
|
|
||||||
var tiddlers;
|
|
||||||
if(isBinary) {
|
|
||||||
tiddlers = [{
|
|
||||||
title: defaultTitle,
|
|
||||||
text: $tw.plugins.dropbox.base64EncodeString(data),
|
|
||||||
type: mimeType
|
|
||||||
}];
|
|
||||||
} else {
|
|
||||||
tiddlers = $tw.wiki.deserializeTiddlers(mimeType,data,{title: defaultTitle});
|
|
||||||
}
|
|
||||||
// Check to see if there's a metafile
|
|
||||||
var metafilePath = path + ".meta",
|
|
||||||
metafileIndex = null;
|
|
||||||
for(var t=0; t<stats.length; t++) {
|
|
||||||
if(stats[t].path === metafilePath) {
|
|
||||||
metafileIndex = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Process the metafile if it's there
|
|
||||||
if(tiddlers.length === 1 && metafileIndex !== null) {
|
|
||||||
var mainStat = stat;
|
|
||||||
$tw.plugins.dropbox.client.readFile(metafilePath,function(error,data,stat) {
|
|
||||||
if(error) {
|
|
||||||
callback(error);
|
|
||||||
return $tw.plugins.dropbox.showError(error);
|
|
||||||
}
|
|
||||||
// Extract the metadata and add the tiddlers
|
|
||||||
tiddlers = [$tw.utils.parseFields(data,tiddlers[0])];
|
|
||||||
$tw.wiki.addTiddlers(tiddlers);
|
|
||||||
// Save the revision of the files so we can detect changes later
|
|
||||||
$tw.plugins.dropbox.fileInfo[mainStat.name] = {versionTag: mainStat.versionTag,title: tiddlers[0].title};
|
|
||||||
$tw.plugins.dropbox.titleInfo[tiddlers[0].title] = mainStat.name;
|
|
||||||
$tw.plugins.dropbox.fileInfo[stat.name] = {versionTag: stat.versionTag,title: tiddlers[0].title};
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Add the tiddlers
|
|
||||||
$tw.wiki.addTiddlers(tiddlers);
|
|
||||||
// Save the revision of this file so we can detect changes
|
|
||||||
$tw.plugins.dropbox.fileInfo[stat.name] = {versionTag: stat.versionTag,title: tiddlers[0].title};
|
|
||||||
for(t=0; t<tiddlers.length; t++) {
|
|
||||||
$tw.plugins.dropbox.titleInfo[tiddlers[t].title] = stat.name;
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Encode a binary file as returned by Dropbox into the base 64 equivalent
|
|
||||||
Adapted from Jon Leighton, https://gist.github.com/958841
|
|
||||||
*/
|
|
||||||
$tw.plugins.dropbox.base64EncodeString = function(data) {
|
|
||||||
var base64 = [],
|
|
||||||
charmap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
|
|
||||||
byteRemainder = data.length % 3,
|
|
||||||
mainLength = data.length - byteRemainder,
|
|
||||||
a, b, c, d,
|
|
||||||
chunk;
|
|
||||||
// Main loop deals with bytes in chunks of 3
|
|
||||||
for(var i=0; i<mainLength; i=i+3) {
|
|
||||||
// Combine the three bytes into a single integer
|
|
||||||
chunk = (data.charCodeAt(i) << 16) | (data.charCodeAt(i + 1) << 8) | data.charCodeAt(i + 2);
|
|
||||||
// Use bitmasks to extract 6-bit segments from the triplet
|
|
||||||
a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18
|
|
||||||
b = (chunk & 258048) >> 12; // 258048 = (2^6 - 1) << 12
|
|
||||||
c = (chunk & 4032) >> 6; // 4032 = (2^6 - 1) << 6
|
|
||||||
d = chunk & 63; // 63 = 2^6 - 1
|
|
||||||
// Convert the raw binary segments to the appropriate ASCII encoding
|
|
||||||
base64.push(charmap[a],charmap[b],charmap[c],charmap[d]);
|
|
||||||
}
|
|
||||||
// Deal with the remaining bytes and padding
|
|
||||||
if(byteRemainder === 1) {
|
|
||||||
chunk = data[mainLength];
|
|
||||||
a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2
|
|
||||||
// Set the 4 least significant bits to zero
|
|
||||||
b = (chunk & 3) << 4; // 3 = 2^2 - 1
|
|
||||||
base64.push(charmap[a],charmap[b],"==");
|
|
||||||
} else if(byteRemainder === 2) {
|
|
||||||
chunk = (data[mainLength] << 8) | data[mainLength + 1];
|
|
||||||
a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10
|
|
||||||
b = (chunk & 1008) >> 4; // 1008 = (2^6 - 1) << 4
|
|
||||||
// Set the 2 least significant bits to zero
|
|
||||||
c = (chunk & 15) << 2; // 15 = 2^4 - 1
|
|
||||||
base64.push(charmap[a],charmap[b],charmap[c],"=");
|
|
||||||
}
|
|
||||||
return base64.join("");
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Rewrite the document location to include a force login marker
|
|
||||||
*/
|
|
||||||
$tw.plugins.dropbox.forceLogin = function() {
|
|
||||||
if(document.location.search.indexOf(queryLoginMarker) === -1) {
|
|
||||||
document.location.search = queryLoginMarker;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Create a new empty TiddlyWiki
|
|
||||||
*/
|
|
||||||
$tw.plugins.dropbox.createWiki = function(wikiName) {
|
|
||||||
// Remove any dodgy characters from the wiki name
|
|
||||||
wikiName = wikiName.replace(/[\!\@\€\£\%\^\*\+\$\:\?\#\/\\\<\>\|\"\'\`\~\=]/g,"");
|
|
||||||
// Check that the name isn't now empty
|
|
||||||
if(wikiName.length === 0) {
|
|
||||||
return alert("Bad wiki name");
|
|
||||||
}
|
|
||||||
// Create the wiki
|
|
||||||
async.series([
|
|
||||||
function(callback) {
|
|
||||||
// First create the wiki folder
|
|
||||||
$tw.plugins.dropbox.client.mkdir(wikiName,function(error,stat) {
|
|
||||||
callback(error);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function(callback) {
|
|
||||||
// Second create the tiddlers folder
|
|
||||||
$tw.plugins.dropbox.client.mkdir(wikiName + "/tiddlers",function(error,stat) {
|
|
||||||
callback(error);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function(callback) {
|
|
||||||
// Third save the template app HTML file
|
|
||||||
var tiddler = $tw.wiki.getTiddler($tw.plugins.dropbox.titleAppTemplateHtml);
|
|
||||||
if(!tiddler) {
|
|
||||||
callback("Cannot find app template tiddler");
|
|
||||||
} else {
|
|
||||||
$tw.plugins.dropbox.client.writeFile(wikiName + "/index.html",tiddler.fields.text,function(error,stat) {
|
|
||||||
callback(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
// optional callback
|
|
||||||
function(error,results) {
|
|
||||||
if(error) {
|
|
||||||
$tw.plugins.dropbox.showError(error);
|
|
||||||
} else {
|
|
||||||
alert("Created wiki " + wikiName);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Save the index file
|
|
||||||
*/
|
|
||||||
$tw.plugins.dropbox.saveTiddlerIndex = function(path,callback) {
|
|
||||||
// Get the tiddler index information
|
|
||||||
var index = {tiddlers: [],systemTiddlers: [], fileInfo: $tw.plugins.dropbox.fileInfo};
|
|
||||||
// First all the tiddlers
|
|
||||||
$tw.wiki.forEachTiddler(function(title,tiddler) {
|
|
||||||
if(tiddler.isSystem) {
|
|
||||||
index.systemTiddlers.push(tiddler.fields);
|
|
||||||
} else {
|
|
||||||
index.tiddlers.push(tiddler.fields);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Save everything to a tiddler
|
|
||||||
$tw.wiki.addTiddler({title: $tw.plugins.dropbox.titleTiddlerIndex, type: "application/json", text: JSON.stringify(index,null,$tw.config.preferences.jsonSpaces)},true);
|
|
||||||
// Generate the index file
|
|
||||||
var file = $tw.wiki.renderTiddler("text/plain",$tw.plugins.dropbox.titleAppIndexTemplate);
|
|
||||||
// Save the index to Dropbox
|
|
||||||
$tw.plugins.dropbox.client.writeFile(path,file,function(error,stat) {
|
|
||||||
callback(error);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Setup synchronisation back to Dropbox
|
|
||||||
*/
|
|
||||||
$tw.plugins.dropbox.setupSyncer = function(wiki) {
|
|
||||||
wiki.addEventListener("change",function(changes) {
|
|
||||||
$tw.plugins.dropbox.syncChanges(changes,wiki);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$tw.plugins.dropbox.syncChanges = function(changes,wiki) {
|
|
||||||
// Create a queue of tasks to save or delete tiddlers
|
|
||||||
var q = async.queue($tw.plugins.dropbox.syncTask,2);
|
|
||||||
// Called when we've processed all the files
|
|
||||||
q.drain = function () {
|
|
||||||
};
|
|
||||||
// Process each of the changes
|
|
||||||
for(var title in changes) {
|
|
||||||
var tiddler = wiki.getTiddler(title),
|
|
||||||
filename = $tw.plugins.dropbox.titleInfo[title],
|
|
||||||
contentType = tiddler ? tiddler.fields.type : null;
|
|
||||||
contentType = contentType || "text/vnd.tiddlywiki";
|
|
||||||
var contentTypeInfo = $tw.config.contentTypeInfo[contentType],
|
|
||||||
isNew = false;
|
|
||||||
// Figure out the pathname of the tiddler
|
|
||||||
if(!filename) {
|
|
||||||
var extension = contentTypeInfo ? contentTypeInfo.extension : "";
|
|
||||||
filename = encodeURIComponent(title) + extension;
|
|
||||||
$tw.plugins.dropbox.titleInfo[title] = filename;
|
|
||||||
isNew = true;
|
|
||||||
}
|
|
||||||
// Push the appropriate task
|
|
||||||
if(tiddler) {
|
|
||||||
if(contentType === "text/vnd.tiddlywiki") {
|
|
||||||
// .tid file
|
|
||||||
q.push({
|
|
||||||
type: "save",
|
|
||||||
title: title,
|
|
||||||
path: $tw.plugins.dropbox.titleInfo[title],
|
|
||||||
content: wiki.serializeTiddlers([tiddler],"application/x-tiddler"),
|
|
||||||
isNew: isNew
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// main file plus meta file
|
|
||||||
q.push({
|
|
||||||
type: "save",
|
|
||||||
title: title,
|
|
||||||
path: $tw.plugins.dropbox.titleInfo[title],
|
|
||||||
content: tiddler.fields.text,
|
|
||||||
metadata: tiddler.getFieldStringBlock({exclude: ["text"]}),
|
|
||||||
isNew: isNew
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
q.push({
|
|
||||||
type: "delete",
|
|
||||||
title: title,
|
|
||||||
path: $tw.plugins.dropbox.titleInfo[title]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Perform a single sync task
|
|
||||||
*/
|
|
||||||
$tw.plugins.dropbox.syncTask = function(task,callback) {
|
|
||||||
if(task.type === "delete") {
|
|
||||||
console.log("Deleting",task.path);
|
|
||||||
} else if(task.type === "save") {
|
|
||||||
console.log("Saving",task.path,task);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
@ -1,41 +0,0 @@
|
|||||||
/*\
|
|
||||||
title: $:/plugins/tiddlywiki/dropbox/loginmacro.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: macro
|
|
||||||
|
|
||||||
Dropbox login plugin
|
|
||||||
|
|
||||||
\*/
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
/*jslint node: true, browser: true */
|
|
||||||
/*global $tw: false */
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
exports.info = {
|
|
||||||
name: "dropbox.login",
|
|
||||||
params: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.handleEvent = function (event) {
|
|
||||||
if(event.type === "click") {
|
|
||||||
$tw.plugins.dropbox.forceLogin();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.executeMacro = function() {
|
|
||||||
// Create the link
|
|
||||||
var child = $tw.Tree.Element(
|
|
||||||
"a",
|
|
||||||
null,
|
|
||||||
this.content,
|
|
||||||
{
|
|
||||||
events: ["click"],
|
|
||||||
eventHandler: this
|
|
||||||
}
|
|
||||||
);
|
|
||||||
child.execute(this.parents,this.tiddlerTitle);
|
|
||||||
return child;
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
@ -1,41 +0,0 @@
|
|||||||
/*\
|
|
||||||
title: $:/plugins/tiddlywiki/dropbox/logoutmacro.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: macro
|
|
||||||
|
|
||||||
Dropbox logout plugin
|
|
||||||
|
|
||||||
\*/
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
/*jslint node: true, browser: true */
|
|
||||||
/*global $tw: false */
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
exports.info = {
|
|
||||||
name: "dropbox.logout",
|
|
||||||
params: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.handleEvent = function (event) {
|
|
||||||
if(event.type === "click") {
|
|
||||||
$tw.plugins.dropbox.logout();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.executeMacro = function() {
|
|
||||||
// Create the link
|
|
||||||
var child = $tw.Tree.Element(
|
|
||||||
"a",
|
|
||||||
null,
|
|
||||||
this.content,
|
|
||||||
{
|
|
||||||
events: ["click"],
|
|
||||||
eventHandler: this
|
|
||||||
}
|
|
||||||
);
|
|
||||||
child.execute(this.parents,this.tiddlerTitle);
|
|
||||||
return child;
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
@ -1,62 +0,0 @@
|
|||||||
/*\
|
|
||||||
title: $:/plugins/tiddlywiki/dropbox/newwikimacro.js
|
|
||||||
type: application/javascript
|
|
||||||
module-type: macro
|
|
||||||
|
|
||||||
Dropbox new wiki plugin
|
|
||||||
|
|
||||||
\*/
|
|
||||||
(function(){
|
|
||||||
|
|
||||||
/*jslint node: true, browser: true */
|
|
||||||
/*global $tw: false */
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
exports.info = {
|
|
||||||
name: "dropbox.newwiki",
|
|
||||||
params: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.handleEvent = function (event) {
|
|
||||||
if(event.type === "click") {
|
|
||||||
var wikiName = this.child.children[0].domNode.value;
|
|
||||||
$tw.plugins.dropbox.createWiki(wikiName);
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.executeMacro = function() {
|
|
||||||
// Create the link
|
|
||||||
var child = $tw.Tree.Element(
|
|
||||||
"form",
|
|
||||||
{
|
|
||||||
"class": "form-inline"
|
|
||||||
},
|
|
||||||
[
|
|
||||||
$tw.Tree.Element(
|
|
||||||
"input",
|
|
||||||
{
|
|
||||||
type: "text"
|
|
||||||
},
|
|
||||||
null
|
|
||||||
),
|
|
||||||
$tw.Tree.Element(
|
|
||||||
"button",
|
|
||||||
{
|
|
||||||
type: "submit",
|
|
||||||
"class": "btn"
|
|
||||||
},
|
|
||||||
[
|
|
||||||
$tw.Tree.Text("New")
|
|
||||||
],
|
|
||||||
{
|
|
||||||
events: ["click"],
|
|
||||||
eventHandler: this
|
|
||||||
})
|
|
||||||
]);
|
|
||||||
child.execute(this.parents,this.tiddlerTitle);
|
|
||||||
return child;
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"title": "$:/plugins/tiddlywiki/dropbox",
|
|
||||||
"description": "Dropbox components",
|
|
||||||
"author": "JeremyRuston",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"coreVersion": ">=5.0.0"
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user