mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-06-27 23:53:01 +00:00
First commit of TiddlyWiki5 in the Sky for Dropbox
This is a new build of TiddlyWiki5 that pulls it's content from a Dropbox App folder. (This naming strategy is seeming increasingly stupid).
This commit is contained in:
parent
6b6def8725
commit
35d8ff871a
61
core/templates/tw5dropbox.template.html.tid
Normal file
61
core/templates/tw5dropbox.template.html.tid
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
title: $:/core/templates/tw5dropbox.template.html
|
||||||
|
type: text/x-tiddlywiki-html
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||||
|
<meta name="application-name" content="TiddlyWiki" />
|
||||||
|
<meta name="generator" content="TiddlyWiki" />
|
||||||
|
<meta name="tiddlywiki-version" content="<<version>>" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<meta name="copyright" content="
|
||||||
|
<<serialize "$:/core/copyright.txt" text/plain>>
|
||||||
|
" />
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/dropbox.js/0.6.1/dropbox.min.js"></script>
|
||||||
|
<title><<tiddler "$:/core/wiki/title">></title>
|
||||||
|
<!----------- This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ----------->
|
||||||
|
|
||||||
|
<!----------- Raw markup ----------->
|
||||||
|
<<serialize "[tag[$:/core/wiki/rawmarkup]]" text/plain>>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!----------- Static styles ----------->
|
||||||
|
<div id="styleArea">
|
||||||
|
<<serialize "[is[shadow]type[text/css]]" application/x-tiddler-css>>
|
||||||
|
</div>
|
||||||
|
<!----------- Static content for Google and browsers without JavaScript ----------->
|
||||||
|
<noscript>
|
||||||
|
<div id="splashArea">
|
||||||
|
<<serialize "$:/templates/StaticContent" text/html>>
|
||||||
|
</div>
|
||||||
|
</noscript>
|
||||||
|
<!----------- Miscellaneous shadow tiddlers ----------->
|
||||||
|
<div id="shadowArea" style="display:none;">
|
||||||
|
<<serialize "[is[shadow]] -[type[text/css]] -[type[application/javascript]has[module-type]] -[type[application/javascript]library[yes]] -[[$:/core/boot.js]] -[[$:/core/bootprefix.js]]" application/x-tiddler-html-div>>
|
||||||
|
</div>
|
||||||
|
<!----------- Ordinary tiddlers ----------->
|
||||||
|
<div id="storeArea" style="display:none;">
|
||||||
|
<<serialize "$1" application/x-tiddler-html-div>>
|
||||||
|
</div>
|
||||||
|
<!----------- Library modules ----------->
|
||||||
|
<div id="libraryModules" style="display:none;">
|
||||||
|
<<serialize "[[$:/core/lib/jquery.min.js]]" application/x-tiddler-library>>
|
||||||
|
<<serialize "[is[shadow]type[application/javascript]library[yes]] -[[$:/core/lib/jquery.min.js]]" application/x-tiddler-library>>
|
||||||
|
</div>
|
||||||
|
<!----------- Boot kernel prologue ----------->
|
||||||
|
<div id="bootKernelPrefix" style="display:none;">
|
||||||
|
<<serialize "$:/core/bootprefix.js" application/javascript>>
|
||||||
|
</div>
|
||||||
|
<!----------- Plugin modules ----------->
|
||||||
|
<div id="modules" style="display:none;">
|
||||||
|
<<serialize "[is[shadow]type[application/javascript]has[module-type]]" application/x-tiddler-module>>
|
||||||
|
</div>
|
||||||
|
<!----------- Boot kernel ----------->
|
||||||
|
<div id="bootKernel" style="display:none;">
|
||||||
|
<<serialize "$:/core/boot.js" application/javascript>>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
12
dbld.sh
Executable file
12
dbld.sh
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# build TiddlyWiki5 in the Sky for Dropbox
|
||||||
|
|
||||||
|
pushd tw5dropbox > /dev/null
|
||||||
|
|
||||||
|
node ../core/boot.js \
|
||||||
|
--verbose \
|
||||||
|
--savetiddler $:/core/templates/tw5dropbox.template.html ../../../../Apps/Static\ Web\ Apps/TiddlyWiki5/public/index.html text/plain [!is[shadow]] \
|
||||||
|
|| exit 1
|
||||||
|
|
||||||
|
popd > /dev/null
|
700
tw5dropbox/plugins/async.js
Normal file
700
tw5dropbox/plugins/async.js
Normal file
@ -0,0 +1,700 @@
|
|||||||
|
/*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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}());
|
3
tw5dropbox/plugins/async.js.meta
Normal file
3
tw5dropbox/plugins/async.js.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
title: $:/plugins/dropbox/async.js
|
||||||
|
type: application/javascript
|
||||||
|
library: yes
|
204
tw5dropbox/plugins/dropbox.js
Normal file
204
tw5dropbox/plugins/dropbox.js
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/plugins/dropbox/dropbox.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: startup
|
||||||
|
|
||||||
|
Startup the Dropbox integration plugin
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Obfuscated API key
|
||||||
|
var apiKey = "m+qwjj8wFRA=|1TSoitGS9Nz2RTwv+jrUJnsAj0yy57NhQJ4TkZ/+Hw==";
|
||||||
|
|
||||||
|
// Tiddler titles
|
||||||
|
var titleIsLoggedIn = "$:/plugins/dropbox/IsLoggedIn",
|
||||||
|
titleUserName = "$:/plugins/dropbox/UserName";
|
||||||
|
|
||||||
|
$tw.plugins.dropbox = {
|
||||||
|
client: null // Dropbox.js client object
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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: titleIsLoggedIn, text: "yes"});
|
||||||
|
// Get user information
|
||||||
|
$tw.plugins.dropbox.getUserInfo();
|
||||||
|
// Get tiddler file metadata
|
||||||
|
$tw.plugins.dropbox.loadTiddlerFiles("/My TiddlyWiki/tiddlers",function() {
|
||||||
|
console.log("Loaded all tiddlers",$tw.wiki.tiddlers);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get user information
|
||||||
|
$tw.plugins.dropbox.getUserInfo = function() {
|
||||||
|
$tw.plugins.dropbox.client.getUserInfo(function(error,userInfo) {
|
||||||
|
if(error) {
|
||||||
|
return $tw.plugins.dropbox.showError(error);
|
||||||
|
}
|
||||||
|
// Save the username
|
||||||
|
$tw.wiki.addTiddler({title: titleUserName, text: userInfo.name});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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(titleUserName);
|
||||||
|
$tw.wiki.addTiddler({title: titleIsLoggedIn, text: "no"});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Load tiddler files from a folder
|
||||||
|
$tw.plugins.dropbox.loadTiddlerFiles = 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);
|
||||||
|
}
|
||||||
|
// 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 = callback;
|
||||||
|
// 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) {
|
||||||
|
q.push({path: stat.path, type: stat.mimeType, stats: stats});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Load a tiddler file
|
||||||
|
$tw.plugins.dropbox.loadTiddlerFile = function(path,mimeType,stats,callback) {
|
||||||
|
// 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) {
|
||||||
|
if(error) {
|
||||||
|
callback(error);
|
||||||
|
return $tw.plugins.dropbox.showError(error);
|
||||||
|
}
|
||||||
|
// Deserialise the tiddler(s) out of the text
|
||||||
|
var tiddlers;
|
||||||
|
if(isBinary) {
|
||||||
|
tiddlers = [{
|
||||||
|
title: path,
|
||||||
|
text: $tw.plugins.dropbox.base64EncodeString(data),
|
||||||
|
type: mimeType
|
||||||
|
}];
|
||||||
|
} else {
|
||||||
|
tiddlers = $tw.wiki.deserializeTiddlers(mimeType,data,{title: path});
|
||||||
|
}
|
||||||
|
// 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) {
|
||||||
|
$tw.plugins.dropbox.client.readFile(metafilePath,function(error,data) {
|
||||||
|
if(error) {
|
||||||
|
callback(error);
|
||||||
|
return $tw.plugins.dropbox.showError(error);
|
||||||
|
}
|
||||||
|
tiddlers = [$tw.utils.parseFields(data,tiddlers[0])];
|
||||||
|
$tw.wiki.addTiddlers(tiddlers);
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$tw.wiki.addTiddlers(tiddlers);
|
||||||
|
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("");
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.startup = function() {
|
||||||
|
if(!$tw.browser) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Mark us as not logged in
|
||||||
|
$tw.wiki.addTiddler({title: titleIsLoggedIn, text: "no"});
|
||||||
|
// 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
|
||||||
|
$tw.plugins.dropbox.login();
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
43
tw5dropbox/plugins/logoutmacro.js
Normal file
43
tw5dropbox/plugins/logoutmacro.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/plugins/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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
6
tw5dropbox/wiki/AllTiddlers.tid
Normal file
6
tw5dropbox/wiki/AllTiddlers.tid
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
title: AllTiddlers
|
||||||
|
tags: navigation
|
||||||
|
|
||||||
|
Current tiddlers:
|
||||||
|
|
||||||
|
<<list all>>
|
3
tw5dropbox/wiki/DefaultTiddlers.tid
Normal file
3
tw5dropbox/wiki/DefaultTiddlers.tid
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
title: $:/DefaultTiddlers
|
||||||
|
|
||||||
|
AllTiddlers
|
82
tw5dropbox/wiki/PageTemplate.tid
Normal file
82
tw5dropbox/wiki/PageTemplate.tid
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
title: $:/templates/PageTemplate
|
||||||
|
|
||||||
|
<!-- The navigator catches navigation events and updates the story and history tiddlers -->
|
||||||
|
<<navigator story:"$:/StoryTiddlers" history:"$:/History" ><
|
||||||
|
|
||||||
|
<!-- Zooming chooser -->
|
||||||
|
{{navigation-panel{
|
||||||
|
<<chooser><
|
||||||
|
<<list all>>
|
||||||
|
>>
|
||||||
|
}}}
|
||||||
|
|
||||||
|
<!-- Zooming navigator -->
|
||||||
|
<<zoomigator>>
|
||||||
|
|
||||||
|
<!-- The top navigation bar -->
|
||||||
|
<div class="navbar navbar-fixed-top">
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<div class="container">
|
||||||
|
{{nav{
|
||||||
|
|
||||||
|
<<reveal state:[[$:/plugins/dropbox/IsLoggedIn]] type:match text:no><
|
||||||
|
Not logged in
|
||||||
|
>>
|
||||||
|
<<reveal state:[[$:/plugins/dropbox/IsLoggedIn]] type:match text:yes><
|
||||||
|
Logged in as (($:/plugins/dropbox/UserName))
|
||||||
|
<<dropbox.logout>< Log me out >>
|
||||||
|
>>
|
||||||
|
|
||||||
|
((Bugger))
|
||||||
|
|
||||||
|
<!-- Navigation menu -->
|
||||||
|
* HelloThere
|
||||||
|
* [[Docs]]
|
||||||
|
*{{divider-vertical}}
|
||||||
|
|
||||||
|
<!-- Full screen button -->
|
||||||
|
<<button full-screen class:"btn btn-warning"><Full screen>>
|
||||||
|
|
||||||
|
<!-- View button -->
|
||||||
|
<<button popup:ViewDropDownState class:"btn btn-danger"><View <span class="caret"></span>>>
|
||||||
|
|
||||||
|
<!-- View dropdown -->
|
||||||
|
{{pull-right{
|
||||||
|
<<reveal state:[[$:/EditMode]] type:nomatch text:yes><
|
||||||
|
<<button modal param:[[$:/messages/EnterEditMode]] set:[[$:/EditMode]] setTo:yes class:"btn btn-success"><Edit>>
|
||||||
|
>>
|
||||||
|
|
||||||
|
<!-- Save changes is only visible in edit mode -->
|
||||||
|
<<reveal state:[[$:/EditMode]] type:match text:yes><
|
||||||
|
<<button save-wiki param:"$:/core/templates/tiddlywiki5.encrypted.template.html" class:"btn pull-right"><Save Changes (encrypted)>>
|
||||||
|
>>
|
||||||
|
<<reveal state:[[$:/EditMode]] type:match text:yes><
|
||||||
|
<<button save-wiki class:"btn pull-right"><Save Changes>>
|
||||||
|
>>
|
||||||
|
}}}
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
<!-- This navigator intercepts navigation events and sets the text of the specified tiddler to the target tiddler title -->
|
||||||
|
<<navigator set:[[$:/CurrentView]]><
|
||||||
|
<<reveal state:ViewDropDownState type:popup position:below><
|
||||||
|
<div class="open">
|
||||||
|
{{dropdown-menu tw-suppress-missing-tiddlylink{
|
||||||
|
* <<link to:classic>< <<reveal state:[[$:/CurrentView]] type:match text:classic>< <span class="tw-ticked-menu-item"></span> >> Classic>>
|
||||||
|
* <<link to:sideways>< <<reveal state:[[$:/CurrentView]] type:match text:sideways>< <span class="tw-ticked-menu-item"></span> >> Sideways>>
|
||||||
|
* <<link to:zoomin>< <<reveal state:[[$:/CurrentView]] type:match text:zoomin>< <span class="tw-ticked-menu-item"></span> >> Zoomin>>
|
||||||
|
}}}
|
||||||
|
</div>
|
||||||
|
>>
|
||||||
|
>>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- The main story references the same story and history tiddlers as the outer navigator -->
|
||||||
|
<div class="container">
|
||||||
|
<<story story:"$:/StoryTiddlers" history:"$:/History" storyviewTiddler:[[$:/CurrentView]] storyview:classic >>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
>>
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user