Remove inadvertently committed files
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 826 B |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 2 KiB |
|
Before Width: | Height: | Size: 577 B |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 9.3 KiB |
|
|
@ -1,191 +0,0 @@
|
||||||
body {
|
|
||||||
font-size: 62.5%;
|
|
||||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #BC4378;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ts-loggedin .ts-openidlogin,
|
|
||||||
.ts-loggedin .ts-login {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
form input {
|
|
||||||
width: 90px;
|
|
||||||
border: solid 1px #CCC;
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ts-login input,
|
|
||||||
.ts-logout input {
|
|
||||||
font-size: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
form input[type=text],
|
|
||||||
form input[type=password] {
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 0.1em 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
form input[type=submit] {
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ts-logout,
|
|
||||||
.ts-logout form {
|
|
||||||
font-size: 1.6em;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ts-logout form {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app-list {
|
|
||||||
background: #F0F4F8;
|
|
||||||
list-style: none;
|
|
||||||
padding: 0; margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app-list li {
|
|
||||||
height: 4.5em;
|
|
||||||
line-height: 4.5em;
|
|
||||||
background: url(/bags/common/tiddlers/double_angle_lightblue_42x42.png) no-repeat 90% #F0F4F8;
|
|
||||||
background-size: 24px 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app-list li:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background: url(/bags/common/tiddlers/double_angle_lightblue_42x42.png) no-repeat 90% #0082AF;
|
|
||||||
background-size: 24px 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app-list li form,
|
|
||||||
#app-list li a {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
font-size: 2em;
|
|
||||||
text-decoration: none;
|
|
||||||
color: #8C9DA7;
|
|
||||||
width: 100%;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app-list li input {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app-list li:hover a {
|
|
||||||
color: #E56AA0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tsbackstage #app-list li:hover a {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app-list .app-img {
|
|
||||||
position: relative;
|
|
||||||
top: 0.2125em;
|
|
||||||
margin: 0 1.25em 0 1em;
|
|
||||||
height: 1.25em;
|
|
||||||
width: 1.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#app-list .search .app-img {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ts-loggedin .login-method:target,
|
|
||||||
.login-method {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-method {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.login-method-hide {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.login-method p {
|
|
||||||
padding-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tsbackstage .message {
|
|
||||||
color: #4C4A54;
|
|
||||||
display: block;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tsbackstage .message a {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-action {
|
|
||||||
background: #0082AF;
|
|
||||||
color: #fff;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-action:hover {
|
|
||||||
box-shadow: 0 0 3px rgba(0,0,0,.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
form input.btn-system {
|
|
||||||
background: #F8F9F9;
|
|
||||||
color: #4C4A54;
|
|
||||||
border: 1px solid rgba(0,0,0,.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-system:hover {
|
|
||||||
color: #000;
|
|
||||||
cursor: pointer;
|
|
||||||
box-shadow: 0 0 3px rgba(0,0,0,.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
.search form {
|
|
||||||
height: 4.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search input {
|
|
||||||
font-size: 1em;
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
padding: 0.2em 0.5em;
|
|
||||||
background: transparent;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search:hover input {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search input:focus {
|
|
||||||
-webkit-box-shadow: inset 0 0 8px rgba(140,157,167,0.75);
|
|
||||||
-moz-box-shadow: inset 0 0 8px rgba(140,157,167,0.75);
|
|
||||||
box-shadow: inset 0 0 8px rgba(140,157,167,0.75);
|
|
||||||
}
|
|
||||||
|
|
||||||
.search:hover input:focus {
|
|
||||||
-webkit-box-shadow: inset 0 0 8px rgba(255,255,255,0.5);
|
|
||||||
-moz-box-shadow: inset 0 0 8px rgba(255,255,255,0.5);
|
|
||||||
box-shadow: inset 0 0 8px rgba(255,255,255,0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.logindetails {
|
|
||||||
background: #fff;
|
|
||||||
padding: 1em 1em 2em;
|
|
||||||
box-shadow: 0 0 6px 0px rgba(0, 0, 0, 0.25);
|
|
||||||
z-index: 1;
|
|
||||||
position: relative;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logindetails p {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<!-- saved from url=(0078)http://interview.tiddlyspace.com/bags/common/tiddlers/backstage#userpass-login -->
|
|
||||||
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
||||||
<link rel="stylesheet" href="./normalize.css">
|
|
||||||
<link rel="stylesheet" href="./app.css">
|
|
||||||
</head>
|
|
||||||
<body class="tsbackstage ts-loggedin ts-member">
|
|
||||||
<div class="logindetails">
|
|
||||||
<form class="ts-login login login-method" action="http://interview.tiddlyspace.com/bags/common/tiddlers/backstage" autocomplete="off" id="userpass-login">
|
|
||||||
<p>login via <a class="toggle-form" href="http://interview.tiddlyspace.com/bags/common/tiddlers/backstage#openid-login">openid</a></p>
|
|
||||||
<input autocapitalize="off" autocorrect="off" type="text" name="username" placeholder="username">
|
|
||||||
<input autocapitalize="off" autocorrect="off" type="password" name="password" placeholder="password">
|
|
||||||
<input type="hidden" name="redirect" value="/bags/common/tiddlers/backstage?action=login#refreshParent">
|
|
||||||
<input type="submit" class="btn btn-action" value="Log In">
|
|
||||||
</form>
|
|
||||||
<form class="ts-openidlogin login-method login-method-hide" id="openid-login" method="post" action="http://interview.tiddlyspace.com/challenge/tiddlywebplugins.tiddlyspace.openid">
|
|
||||||
<p>login with <a class="toggle-form" href="http://interview.tiddlyspace.com/bags/common/tiddlers/backstage#userpass-login">username and password</a></p>
|
|
||||||
<input name="tiddlyweb_redirect" type="hidden" value="/bags/common/tiddlers/backstage">
|
|
||||||
<input class="openid" autocapitalize="off" autocorrect="off" type="text" name="openid" placeholder="your openid">
|
|
||||||
<input class="button btn btn-action" type="submit" value="Sign In">
|
|
||||||
<a class="openid-help" href="http://openid.net/get-an-openid/">What is an open id?</a>
|
|
||||||
</form>
|
|
||||||
<div class="ts-logout logout"><span class="message">Welcome back <a href="http://jermolene.tiddlyspace.com/" target="_parent">jermolene</a><span>!</span></span>
|
|
||||||
<form method="post" action="http://interview.tiddlyspace.com/logout">
|
|
||||||
<input type="hidden" name="tiddlyweb_redirect" value="/bags/common/tiddlers/backstage?action=login#refreshParent">
|
|
||||||
<input type="submit" class="btn btn-system" value="Log out">
|
|
||||||
<input type="hidden" name="csrf_token" value="2016120917:jermolene:8cef480d1bd2bf774327ae085b2efa8bb7937fd1"></form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div><ul id="app-list">
|
|
||||||
<li class="search">
|
|
||||||
<form method="GET" target="_blank" action="http://interview.tiddlyspace.com/hsearch">
|
|
||||||
<img src="./search.png" alt="Search Icon" class="app-img">
|
|
||||||
<input type="text" name="q" placeholder="Search">
|
|
||||||
|
|
||||||
</form></li>
|
|
||||||
<li class="help">
|
|
||||||
<a href="http://help.tiddlyspace.com/" target="_blank">
|
|
||||||
<img src="./help.png" alt="Help SiteIcon" class="app-img">Help
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="space">
|
|
||||||
<a href="http://interview.tiddlyspace.com/_space" target="_blank">
|
|
||||||
<img src="./SiteIcon(24)" alt="Space SiteIcon" class="app-img">This space
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="account"><a target="_blank" href="http://jermolene.tiddlyspace.com/_account"><img class="app-img" alt="SiteIcon for jermolene" src="./SiteIcon">Your account</a></li></ul></div>
|
|
||||||
<script type="text/javascript" src="./jquery.js"></script>
|
|
||||||
<script type="text/javascript" src="./chrjs"></script>
|
|
||||||
<script type="text/javascript" src="./chrjs.users"></script>
|
|
||||||
<script type="text/javascript" src="./chrjs.space"></script>
|
|
||||||
<script type="text/javascript" src="./chrjs.identities"></script>
|
|
||||||
<script type="text/javascript" src="./ts.js"></script>
|
|
||||||
<script src="./status.js"></script>
|
|
||||||
<script type="text/javascript">
|
|
||||||
if(window.location.hash === "#refreshParent") {
|
|
||||||
window.location.hash = "";
|
|
||||||
window.parent.location.reload();
|
|
||||||
}
|
|
||||||
var li, siteiconurl, link, host;
|
|
||||||
ts.init(function(ts) {
|
|
||||||
host = ts.getHost(ts.user.name);
|
|
||||||
$(document.body).show();
|
|
||||||
window.location.hash = "#userpass-login";
|
|
||||||
if (ts.user.anon) {
|
|
||||||
$('.toggle-form').click(function(ev) {
|
|
||||||
$(this).closest('form').addClass('login-method-hide')
|
|
||||||
.siblings('form').removeClass('login-method-hide');
|
|
||||||
ev.preventDefault();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if ($(document.body).hasClass('ts-nonmember')) {
|
|
||||||
$('.write').remove();
|
|
||||||
}
|
|
||||||
if(!ts.user.anon) {
|
|
||||||
li = $('<li class="account" />').appendTo("#app-list")[0];
|
|
||||||
siteiconurl = host + '/bags/' + ts.user.name + '_public/tiddlers/SiteIcon';
|
|
||||||
link = $('<a target="_blank" />').attr("href", host + "/_account").
|
|
||||||
text("Your account").appendTo(li);
|
|
||||||
$('<img class="app-img">').attr("alt", 'SiteIcon for ' + ts.user.name).
|
|
||||||
attr("src", siteiconurl).prependTo(link);
|
|
||||||
}
|
|
||||||
}, {});
|
|
||||||
(function($) {
|
|
||||||
$(function() {
|
|
||||||
// send doc height to parent window
|
|
||||||
var totalHeight = $("html").height();
|
|
||||||
if(self !== top && !!window.postMessage) {
|
|
||||||
parent.postMessage(totalHeight, "*");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}(jQuery));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body></html>
|
|
||||||
|
|
@ -1,360 +0,0 @@
|
||||||
/***
|
|
||||||
Adds the app switcher to a TiddlySpace app.
|
|
||||||
|
|
||||||
Makes use of tw.Stylesheet
|
|
||||||
Triple licensed under the BSD, MIT and GPL licenses:
|
|
||||||
http://www.opensource.org/licenses/bsd-license.php
|
|
||||||
http://www.opensource.org/licenses/mit-license.php
|
|
||||||
http://www.gnu.org/licenses/gpl.html
|
|
||||||
***/
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
// Add or replace a style sheet
|
|
||||||
// css argument is a string of CSS rule sets
|
|
||||||
// options.id is an optional name identifying the style sheet
|
|
||||||
// options.doc is an optional document reference
|
|
||||||
// N.B.: Uses DOM methods instead of jQuery to ensure cross-browser comaptibility.
|
|
||||||
var twStylesheet = function(css, options) {
|
|
||||||
options = options || {};
|
|
||||||
var id = options.id || "backstageStyleSheet";
|
|
||||||
var doc = options.doc || document;
|
|
||||||
var el = doc.getElementById(id);
|
|
||||||
if(doc.createStyleSheet) { // IE-specific handling
|
|
||||||
if(el) {
|
|
||||||
el.parentNode.removeChild(el);
|
|
||||||
}
|
|
||||||
doc.getElementsByTagName("head")[0].insertAdjacentHTML("beforeEnd",
|
|
||||||
' <style id="' + id + '" type="text/css">' + css + '</style>'); // fails without
|
|
||||||
} else { // modern browsers
|
|
||||||
if(el) {
|
|
||||||
el.replaceChild(doc.createTextNode(css), el.firstChild);
|
|
||||||
} else {
|
|
||||||
el = doc.createElement("style");
|
|
||||||
el.type = "text/css";
|
|
||||||
el.id = id;
|
|
||||||
el.appendChild(doc.createTextNode(css));
|
|
||||||
doc.getElementsByTagName("head")[0].appendChild(el);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// detect background-size support
|
|
||||||
// in <IE9 need to fallback to msfilter property
|
|
||||||
function hasBgSizing() {
|
|
||||||
var supported,
|
|
||||||
elem = document.createElement('div');
|
|
||||||
|
|
||||||
document.body.appendChild(elem);
|
|
||||||
elem.style.cssText = "background-size: cover;";
|
|
||||||
supported = (elem.style.backgroundSize === undefined || elem.style.backgroundSize === null) ? false : true;
|
|
||||||
// clean up
|
|
||||||
elem.parentNode.removeChild(elem);
|
|
||||||
return supported;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ms filters as fix for not supporting background-size property
|
|
||||||
var msfilter_in = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/bags/tiddlyspace/tiddlers/privateAndPublicIcon', sizingMethod='scale')",
|
|
||||||
msfilter_out = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/bags/tiddlyspace/tiddlers/publicIcon', sizingMethod='scale')";
|
|
||||||
|
|
||||||
var stylesheet = ["#tsbackstage {",
|
|
||||||
" height: 256px; /* default value unless changed */",
|
|
||||||
" z-index: 1000;",
|
|
||||||
" position: relative;",
|
|
||||||
"}",
|
|
||||||
"",
|
|
||||||
"#app-picker {",
|
|
||||||
" cursor: pointer;",
|
|
||||||
" position: absolute;",
|
|
||||||
" right: 24px;",
|
|
||||||
" top: 0px;",
|
|
||||||
" width: 24px;",
|
|
||||||
" height: 24px;",
|
|
||||||
" background-size: 24px 24px;",
|
|
||||||
" text-indent: -999px;",
|
|
||||||
" overflow: hidden;",
|
|
||||||
" z-index: 2000;",
|
|
||||||
" border: none;",
|
|
||||||
" opacity: 0.5;",
|
|
||||||
"}",
|
|
||||||
"",
|
|
||||||
"#app-picker:hover {",
|
|
||||||
" background-color: none !important;",
|
|
||||||
" opacity: 1;",
|
|
||||||
"}",
|
|
||||||
"",
|
|
||||||
".bs-popup {",
|
|
||||||
" width: 100%;",
|
|
||||||
" position: absolute;",
|
|
||||||
" z-index: 1000;",
|
|
||||||
" right: 10px;",
|
|
||||||
" top: 36px;",
|
|
||||||
"}",
|
|
||||||
"",
|
|
||||||
".bubble .description {",
|
|
||||||
" margin-left: 70px;",
|
|
||||||
" margin-top: 2px;",
|
|
||||||
"}",
|
|
||||||
"",
|
|
||||||
".bubble {",
|
|
||||||
" float: right;",
|
|
||||||
" font-size: 0.9em;",
|
|
||||||
" font-family: Georgia;",
|
|
||||||
" position: relative;",
|
|
||||||
" width: 300px;",
|
|
||||||
" margin: 0px auto 0px auto;",
|
|
||||||
" margin: top right bottom left;",
|
|
||||||
" border: solid 1px rgb(200, 200, 200);",
|
|
||||||
" border-radius: 4px;",
|
|
||||||
" -webkit-box-shadow: 0px 0px 4px rgba(0,0,0,.2);",
|
|
||||||
" -moz-box-shadow: 0px 0px 4px rgba(0,0,0,.2);",
|
|
||||||
" -o-box-shadow: 0px 0px 4px rgba(0,0,0,.2);",
|
|
||||||
" -ms-box-shadow: 0px 0px 4px rgba(0,0,0,.2);",
|
|
||||||
" box-shadow: 0px 0px 4px rgba(0,0,0,.2);",
|
|
||||||
" background-color: #F0F4F8;",
|
|
||||||
"}",
|
|
||||||
"",
|
|
||||||
".ts-logout {",
|
|
||||||
" display: none;",
|
|
||||||
"}",
|
|
||||||
".ts-loggedin .ts-logout {",
|
|
||||||
" display: block;",
|
|
||||||
"}",
|
|
||||||
".arrow {",
|
|
||||||
" border-width: 0 10px 10px;",
|
|
||||||
" border-style: dashed dashed solid;",
|
|
||||||
" width: 0;",
|
|
||||||
" height: 0;",
|
|
||||||
" border-color: transparent;",
|
|
||||||
" display: inline-block;",
|
|
||||||
" position: absolute;",
|
|
||||||
" top: -10px;",
|
|
||||||
" right: 16px;",
|
|
||||||
" border-bottom-color: #fff;",
|
|
||||||
"}",
|
|
||||||
".bubble div.whitearrow {",
|
|
||||||
" top: -11px;",
|
|
||||||
" border-bottom-color: rgba(0,0,0,0.25);",
|
|
||||||
"}",
|
|
||||||
".ts-terms {",
|
|
||||||
" color: #999;",
|
|
||||||
" display: block;",
|
|
||||||
" font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Garuda, Verdana, Tahoma, sans-serif;",
|
|
||||||
" font-size: 12px;",
|
|
||||||
" font-style: normal;",
|
|
||||||
" font-variant: normal;",
|
|
||||||
" font-weight: normal;",
|
|
||||||
" height: 46px;",
|
|
||||||
" line-height: 16.7999992370605px;",
|
|
||||||
" z-index: 800;",
|
|
||||||
" background-color: rgb(218, 218, 218);",
|
|
||||||
" padding-right: 50px;",
|
|
||||||
" padding-top: 10px;",
|
|
||||||
" padding-left: 10px;",
|
|
||||||
" padding-bottom: 10px;",
|
|
||||||
"}",
|
|
||||||
".ts-terms a {",
|
|
||||||
" color: #333;",
|
|
||||||
"}",
|
|
||||||
".ts-service-update {",
|
|
||||||
" padding: 10px;",
|
|
||||||
" background-color: red;",
|
|
||||||
" font-family: Arial;",
|
|
||||||
" color: #ffffff;",
|
|
||||||
" font-size: 15px;",
|
|
||||||
" text-align: center;",
|
|
||||||
"}",
|
|
||||||
".ts-service-update a {",
|
|
||||||
" color: #ffffff;",
|
|
||||||
" font-weight: bold;",
|
|
||||||
" text-decoration: underline;",
|
|
||||||
"}",
|
|
||||||
".ts-service-update a:hover {",
|
|
||||||
" background-color: #cc0000;",
|
|
||||||
" text-decoration: none;",
|
|
||||||
"}"
|
|
||||||
].join("\n");
|
|
||||||
|
|
||||||
function addEventListener(node, event, handler, bubble) {
|
|
||||||
if (node.addEventListener){
|
|
||||||
node.addEventListener(event, handler, bubble);
|
|
||||||
} else if (node.attachEvent){
|
|
||||||
event = event == "click" ? "onclick" : event;
|
|
||||||
event = event == "load" ? "onload" : event;
|
|
||||||
node.attachEvent(event, handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setCookie(cname, cvalue, exdays) {
|
|
||||||
var d = new Date();
|
|
||||||
d.setTime(d.getTime() + (exdays*24*60*60*1000));
|
|
||||||
var expires = "expires="+d.toUTCString();
|
|
||||||
document.cookie = cname + "=" + cvalue + "; " + expires;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCookie(cname) {
|
|
||||||
var name = cname + "=";
|
|
||||||
var ca = document.cookie.split(';');
|
|
||||||
for(var i=0; i<ca.length; i++) {
|
|
||||||
var c = ca[i];
|
|
||||||
while (c.charAt(0)==' ') c = c.substring(1);
|
|
||||||
if (c.indexOf(name) != -1) return c.substring(name.length,c.length);
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
var loadEvent = function() {
|
|
||||||
var link = document.createElement("a");
|
|
||||||
link.setAttribute("id", "app-picker");
|
|
||||||
link.setAttribute("class", "app-picker");
|
|
||||||
link.setAttribute("title", "Click to navigate around tiddlyspace");
|
|
||||||
link.appendChild(document.createTextNode("tiddlyspace"));
|
|
||||||
var backgroundSizeSupported = hasBgSizing();
|
|
||||||
|
|
||||||
// Quite a hack. GUEST does not have a csrf token.
|
|
||||||
if (/csrf_token=\d+:\w+:\w+/.test(document.cookie)) {
|
|
||||||
if( backgroundSizeSupported ) {
|
|
||||||
link.style.backgroundImage = 'url(/bags/tiddlyspace/tiddlers/privateAndPublicIcon)';
|
|
||||||
} else {
|
|
||||||
link.style.filter = msfilter_in;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if( backgroundSizeSupported ) {
|
|
||||||
link.style.backgroundImage = 'url(/bags/tiddlyspace/tiddlers/publicIcon)';
|
|
||||||
} else {
|
|
||||||
link.style.filter = msfilter_out;
|
|
||||||
}
|
|
||||||
stylesheet = stylesheet.replace('height: 180px;', 'height: 156px;');
|
|
||||||
}
|
|
||||||
|
|
||||||
var body = document.getElementsByTagName("BODY")[0];
|
|
||||||
body.insertBefore(link, body.firstChild);
|
|
||||||
var html = [
|
|
||||||
'<div class="bubble">',
|
|
||||||
'<iframe src="/bags/common/tiddlers/backstage#userpass-login" name="tsbackstage" id="tsbackstage" width="auto" frameborder=0 border=0></iframe>',
|
|
||||||
'<div class="arrow whitearrow"></div>',
|
|
||||||
'<div class="arrow"></div>',
|
|
||||||
'</div>'].join("");
|
|
||||||
var bubble = document.createElement("div");
|
|
||||||
bubble.setAttribute("id", "bs-popup");
|
|
||||||
bubble.style.cssText = "visibility:hidden;";
|
|
||||||
bubble.className = "bs-popup";
|
|
||||||
bubble.innerHTML = html;
|
|
||||||
body.insertBefore(bubble, link);
|
|
||||||
|
|
||||||
//Terms and Conditions
|
|
||||||
if (document.getElementById("backstageButton")) {
|
|
||||||
//backstage area is displayed, so also check for terms acceptance;
|
|
||||||
var acceptedTermsVersion,
|
|
||||||
latestTermsVersion = 'v1.0-dec2014',
|
|
||||||
privacyPolicyOpen = false,
|
|
||||||
cookiePolicyOpen = false;
|
|
||||||
|
|
||||||
acceptedTermsVersion = getCookie('termsAccepted');
|
|
||||||
|
|
||||||
if (acceptedTermsVersion !== latestTermsVersion) {
|
|
||||||
html = 'The tiddlyspace service uses cookies. By using the service, you are agreeing to the <a href="http://osmo-terms.tiddlyspace.com/Cookies20141205" target="_blank">Cookie Policy</a>. We have updated tiddlyspace <a href="http://osmo-terms.tiddlyspace.com/TermsOfService20141205" target="_blank">Terms of Service</a>, effective as of 05 December 2014. By using the service you\'re agreeing to the updated terms. <a id="acceptTermsId" href="#">OK, got it</a>.';
|
|
||||||
var terms = document.createElement('div');
|
|
||||||
terms.setAttribute('id', 'bs-terms');
|
|
||||||
terms.className = 'ts-terms';
|
|
||||||
terms.innerHTML = html;
|
|
||||||
contentWrapper = document.getElementById('contentWrapper');
|
|
||||||
body.insertBefore(terms, contentWrapper);
|
|
||||||
|
|
||||||
addEventListener(document.getElementById("acceptTermsId"), "click", function(ev) {
|
|
||||||
setCookie('termsAccepted', latestTermsVersion, 365);
|
|
||||||
terms.style.cssText = "display:none;";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//Add Service Update Message
|
|
||||||
html = 'Service Update: <a href="http://osmo-service.tiddlyspace.com/ServiceUpdate20161205">***Please read this important Tiddlyspace service announcement December 5th 2016 ***</a>';
|
|
||||||
var serviceUpdate = document.createElement('div');
|
|
||||||
serviceUpdate.setAttribute('id', 'bs-serviceUpdate');
|
|
||||||
serviceUpdate.className = 'ts-service-update';
|
|
||||||
serviceUpdate.innerHTML = html;
|
|
||||||
contentWrapper = document.getElementById('contentWrapper');
|
|
||||||
body.insertBefore(serviceUpdate, contentWrapper);
|
|
||||||
//End of Service Update Message
|
|
||||||
|
|
||||||
}
|
|
||||||
//End of Terms and Conditions
|
|
||||||
|
|
||||||
twStylesheet(stylesheet);
|
|
||||||
|
|
||||||
var bubbleFadeInterval;
|
|
||||||
function fade(el, fadeIn) {
|
|
||||||
var opacity = fadeIn ? 0 : 1;
|
|
||||||
if(bubbleFadeInterval) {
|
|
||||||
clearInterval(bubbleFadeInterval);
|
|
||||||
}
|
|
||||||
bubbleFadeInterval = setInterval(function() {
|
|
||||||
// TODO: IE does not support opacity
|
|
||||||
el.style.cssText = "opacity:" + opacity;
|
|
||||||
opacity = fadeIn ? opacity + 0.1 : opacity - 0.1;
|
|
||||||
if(opacity < 0 || opacity > 1) {
|
|
||||||
clearInterval(bubbleFadeInterval);
|
|
||||||
el.style.cssText = fadeIn ? "" : "visibility:hidden;";
|
|
||||||
}
|
|
||||||
}, 25);
|
|
||||||
}
|
|
||||||
|
|
||||||
addEventListener(link, "mousedown", function(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
var bubbleOpen = false;
|
|
||||||
var toggleBubble = function(ev) {
|
|
||||||
if(ev.stopPropagation) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
} else {
|
|
||||||
ev.cancelBubble = false;
|
|
||||||
}
|
|
||||||
if(bubbleOpen) {
|
|
||||||
fade(bubble, false);
|
|
||||||
} else {
|
|
||||||
fade(bubble, true);
|
|
||||||
}
|
|
||||||
bubbleOpen = !bubbleOpen;
|
|
||||||
};
|
|
||||||
|
|
||||||
addEventListener(link, "click", toggleBubble);
|
|
||||||
|
|
||||||
addEventListener(window.document.body, "click",
|
|
||||||
function(ev) {
|
|
||||||
var targ,
|
|
||||||
ev = ev || window.event;
|
|
||||||
|
|
||||||
if (ev.target) targ = ev.target;
|
|
||||||
else if (ev.srcElement) targ = ev.srcElement;
|
|
||||||
if(targ == link) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(bubbleOpen) {
|
|
||||||
toggleBubble(ev);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
addEventListener(bubble, "click", function(ev) {
|
|
||||||
if(ev.stopPropagation) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
} else {
|
|
||||||
ev.cancelBubble = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
if(window.top == window) { // only add the backstage when NOT in an iframe (top window)
|
|
||||||
addEventListener(window, "load", loadEvent);
|
|
||||||
// check if postMessage is supported
|
|
||||||
// best test: https://github.com/ternarylabs/porthole/pull/10
|
|
||||||
if(!!window.postMessage) {
|
|
||||||
addEventListener(window, "message", function(e) {
|
|
||||||
var iframe = document.getElementById('tsbackstage');
|
|
||||||
if(e.data) {
|
|
||||||
iframe.style.height = e.data + "px";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
@ -1,373 +0,0 @@
|
||||||
/***
|
|
||||||
https://raw.github.com/tiddlyweb/chrjs/master/main.js
|
|
||||||
***/
|
|
||||||
//{{{
|
|
||||||
// TiddlyWeb adaptor
|
|
||||||
// v0.14.3
|
|
||||||
|
|
||||||
/*jslint vars: true, unparam: true, nomen: true, white: true */
|
|
||||||
/*global jQuery */
|
|
||||||
|
|
||||||
var tiddlyweb = (function($) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var tw = {
|
|
||||||
routes: {
|
|
||||||
// host is the TiddlyWeb instance's URI (including server_prefix)
|
|
||||||
// placeholders "_type" & "name" refer to the respective bag/recipe
|
|
||||||
root : "{host}/",
|
|
||||||
bags : "{host}/bags",
|
|
||||||
bag : "{host}/bags/{name}",
|
|
||||||
recipes : "{host}/recipes",
|
|
||||||
recipe : "{host}/recipes/{name}",
|
|
||||||
tiddlers : "{host}/{_type}s/{name}/tiddlers",
|
|
||||||
tiddler : "{host}/{_type}s/{name}/tiddlers/{title}",
|
|
||||||
revisions: "{host}/{_type}s/{name}/tiddlers/{title}/revisions",
|
|
||||||
revision : "{host}/{_type}s/{name}/tiddlers/{title}/revisions/{revision}",
|
|
||||||
search : "{host}/search?q={query}"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var convertTimestamp, supplant;
|
|
||||||
|
|
||||||
// host (optional) is the URI of the originating TiddlyWeb instance
|
|
||||||
tw.Resource = function(type, host) {
|
|
||||||
if(arguments.length) { // initialization
|
|
||||||
this._type = type;
|
|
||||||
if(host !== false) {
|
|
||||||
this.host = host !== undefined ? host.replace(/\/$/, "") : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
$.extend(tw.Resource.prototype, {
|
|
||||||
// retrieves resource from server
|
|
||||||
// callback is passed resource, status, XHR (cf. jQuery.ajax success)
|
|
||||||
// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
|
|
||||||
// filters is an optional filter string (e.g. "select=tag:foo;limit=5")
|
|
||||||
get: function(callback, errback, filters) {
|
|
||||||
var uri = this.route();
|
|
||||||
if(filters) {
|
|
||||||
var separator = uri.indexOf("?") === -1 ? "?" : ";";
|
|
||||||
uri += separator + filters;
|
|
||||||
}
|
|
||||||
var self = this;
|
|
||||||
return $.ajax({
|
|
||||||
url: uri,
|
|
||||||
type: "GET",
|
|
||||||
dataType: "json",
|
|
||||||
success: function(data, status, xhr) {
|
|
||||||
var resource = self.parse(data);
|
|
||||||
resource.etag = xhr.getResponseHeader("Etag");
|
|
||||||
callback(resource, status, xhr);
|
|
||||||
},
|
|
||||||
error: function(xhr, error, exc) {
|
|
||||||
errback(xhr, error, exc, self);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// sends resource to server
|
|
||||||
// callback is passed data, status, XHR (cf. jQuery.ajax success)
|
|
||||||
// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
|
|
||||||
put: function(callback, errback) {
|
|
||||||
var self = this;
|
|
||||||
var options = {
|
|
||||||
url: this.route(),
|
|
||||||
type: "PUT",
|
|
||||||
contentType: "application/json",
|
|
||||||
data: JSON.stringify(this.baseData()),
|
|
||||||
success: function(data, status, xhr) {
|
|
||||||
callback(self, status, xhr);
|
|
||||||
},
|
|
||||||
error: function(xhr, error, exc) {
|
|
||||||
errback(xhr, error, exc, self);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if(this.ajaxSetup) {
|
|
||||||
this.ajaxSetup(options);
|
|
||||||
}
|
|
||||||
return $.ajax(options);
|
|
||||||
},
|
|
||||||
// deletes resource on server
|
|
||||||
// callback is passed data, status, XHR (cf. jQuery.ajax success)
|
|
||||||
// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
|
|
||||||
"delete": function(callback, errback) {
|
|
||||||
var self = this;
|
|
||||||
var options = {
|
|
||||||
url: this.route(),
|
|
||||||
type: "DELETE",
|
|
||||||
success: function(data, status, xhr) {
|
|
||||||
callback(self, status, xhr);
|
|
||||||
},
|
|
||||||
error: function(xhr, error, exc) {
|
|
||||||
errback(xhr, error, exc, self);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if(this.ajaxSetup) {
|
|
||||||
this.ajaxSetup(options);
|
|
||||||
}
|
|
||||||
return $.ajax(options);
|
|
||||||
},
|
|
||||||
// returns an object carrying only the essential information of the resource
|
|
||||||
baseData: function() {
|
|
||||||
var data = {},
|
|
||||||
self = this;
|
|
||||||
$.each(this.data, function(i, item) {
|
|
||||||
var value = self[item];
|
|
||||||
if(value !== undefined) {
|
|
||||||
data[item] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return data;
|
|
||||||
},
|
|
||||||
// returns corresponding instance from a raw object (if applicable)
|
|
||||||
parse: function(data) {
|
|
||||||
return data;
|
|
||||||
},
|
|
||||||
// list of accepted keys in serialization
|
|
||||||
data: [],
|
|
||||||
// returns resource's URI
|
|
||||||
route: function() {
|
|
||||||
return supplant(tw.routes[this._type], this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var Container = function(type, name, host) {
|
|
||||||
if(arguments.length) { // initialization
|
|
||||||
tw.Resource.apply(this, [type, host]);
|
|
||||||
this.name = name;
|
|
||||||
this.desc = "";
|
|
||||||
this.policy = new tw.Policy({});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Container.prototype = new tw.Resource();
|
|
||||||
$.extend(Container.prototype, {
|
|
||||||
tiddlers: function() {
|
|
||||||
return new tw.TiddlerCollection(this);
|
|
||||||
},
|
|
||||||
parse: function(data) {
|
|
||||||
var type = tw._capitalize(this._type),
|
|
||||||
container = new tw[type](this.name, this.host);
|
|
||||||
data.policy = new tw.Policy(data.policy);
|
|
||||||
return $.extend(container, data);
|
|
||||||
},
|
|
||||||
data: ["desc", "policy"]
|
|
||||||
});
|
|
||||||
|
|
||||||
// attribs is an object whose members are merged into the instance (e.g. query)
|
|
||||||
tw.Collection = function(type, host, attribs) {
|
|
||||||
if(arguments.length) { // initialization
|
|
||||||
tw.Resource.apply(this, [type, host]);
|
|
||||||
$.extend(this, attribs);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
tw.Collection.prototype = new tw.Resource();
|
|
||||||
|
|
||||||
tw.TiddlerCollection = function(container, tiddler) {
|
|
||||||
if(arguments.length) { // initialization
|
|
||||||
tw.Collection.apply(this, [tiddler ? "revisions" : "tiddlers"]);
|
|
||||||
this.container = container || null;
|
|
||||||
this.tiddler = tiddler || null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
tw.TiddlerCollection.prototype = new tw.Collection();
|
|
||||||
$.extend(tw.TiddlerCollection.prototype, {
|
|
||||||
parse: function(data) {
|
|
||||||
var container = this.container;
|
|
||||||
return $.map(data, function(item, i) {
|
|
||||||
var tiddler = new tw.Tiddler(item.title, container),
|
|
||||||
bag = item.bag;
|
|
||||||
tiddler = tw.Tiddler.prototype.parse.apply(tiddler, [item]);
|
|
||||||
if(!tiddler.bag && bag) { // XXX: bag always present!?
|
|
||||||
tiddler.bag = new tw.Bag(bag, container.host);
|
|
||||||
}
|
|
||||||
if(!tiddler.recipe && item.recipe) {
|
|
||||||
tiddler.recipe = new tw.Recipe(item.recipe, container.host);
|
|
||||||
}
|
|
||||||
delete item.recipe;
|
|
||||||
return $.extend(tiddler, item);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
route: function() {
|
|
||||||
var params = this.container;
|
|
||||||
if(this.tiddler) {
|
|
||||||
var container = this.tiddler.bag || this.tiddler.recipe;
|
|
||||||
params = {
|
|
||||||
_type: container._type,
|
|
||||||
host: container.host,
|
|
||||||
name: container.name,
|
|
||||||
title: this.tiddler.title
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return supplant(tw.routes[this._type], params);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
tw.Search = function(query, host) {
|
|
||||||
tw.Collection.apply(this, ["search", host]);
|
|
||||||
this.query = query;
|
|
||||||
};
|
|
||||||
tw.Search.prototype = new tw.Collection();
|
|
||||||
$.extend(tw.Search.prototype, {
|
|
||||||
parse: function(data) {
|
|
||||||
this.container = { // XXX: hacky
|
|
||||||
_type: "bag",
|
|
||||||
host: this.host
|
|
||||||
};
|
|
||||||
var tiddlers = tw.TiddlerCollection.prototype.parse.apply(this, arguments);
|
|
||||||
delete this.container;
|
|
||||||
return tiddlers;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// title is the name of the tiddler
|
|
||||||
// container (optional) is an instance of either Bag or Recipe
|
|
||||||
// optionally accepts a single object representing tiddler attributes
|
|
||||||
tw.Tiddler = function(title, container) {
|
|
||||||
tw.Resource.apply(this, ["tiddler", false]);
|
|
||||||
this.title = title;
|
|
||||||
this.bag = container && container._type === "bag" ? container : null;
|
|
||||||
this.recipe = container && container._type === "recipe" ? container : null;
|
|
||||||
var self = this;
|
|
||||||
$.each(this.data, function(i, item) {
|
|
||||||
self[item] = undefined; // exposes list of standard attributes for inspectability
|
|
||||||
});
|
|
||||||
if(title && title.title) { // title is an object of tiddler attributes
|
|
||||||
$.extend(this, title);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
tw.Tiddler.prototype = new tw.Resource();
|
|
||||||
$.extend(tw.Tiddler.prototype, {
|
|
||||||
revisions: function() {
|
|
||||||
return new tw.TiddlerCollection(this.bag || this.recipe, this);
|
|
||||||
},
|
|
||||||
route: function() {
|
|
||||||
var container = this.bag || this.recipe;
|
|
||||||
var params = $.extend({}, this, {
|
|
||||||
host: container ? container.host : null,
|
|
||||||
_type: this.bag ? "bag" : (this.recipe ? "recipe" : null),
|
|
||||||
name: container ? container.name : null
|
|
||||||
});
|
|
||||||
return supplant(tw.routes[this._type], params);
|
|
||||||
},
|
|
||||||
parse: function(data) {
|
|
||||||
var tiddler = new tw.Tiddler(this.title),
|
|
||||||
container = this.bag || this.recipe;
|
|
||||||
if(data.bag) {
|
|
||||||
tiddler.bag = new tw.Bag(data.bag, container.host);
|
|
||||||
delete data.bag;
|
|
||||||
}
|
|
||||||
delete data.recipe;
|
|
||||||
tiddler.created = data.created ? convertTimestamp(data.created) : new Date();
|
|
||||||
delete data.created;
|
|
||||||
tiddler.modified = data.modified ? convertTimestamp(data.modified) : new Date();
|
|
||||||
delete data.modified;
|
|
||||||
if(this.recipe) {
|
|
||||||
tiddler.recipe = this.recipe;
|
|
||||||
}
|
|
||||||
return $.extend(tiddler, data);
|
|
||||||
},
|
|
||||||
data: ["created", "creator", "modifier", "modified", "tags", "type", "text",
|
|
||||||
"fields"],
|
|
||||||
ajaxSetup: function(options) {
|
|
||||||
var self = this;
|
|
||||||
if(this.etag && (options.type === "PUT" || options.type === "DELETE")) {
|
|
||||||
options.beforeSend = function(xhr) {
|
|
||||||
xhr.setRequestHeader("If-Match", self.etag);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if(options.type === "PUT") {
|
|
||||||
var callback = options.success;
|
|
||||||
options.success = function(data, status, xhr) {
|
|
||||||
var loc = xhr.getResponseHeader("Location"),
|
|
||||||
etag = xhr.getResponseHeader("Etag");
|
|
||||||
if(loc && etag) {
|
|
||||||
self.etag = etag;
|
|
||||||
if(!self.bag) {
|
|
||||||
var bag = loc.split("/bags/").pop().split("/")[0];
|
|
||||||
self.bag = new tw.Bag(bag, self.recipe.host);
|
|
||||||
}
|
|
||||||
callback(self, status, xhr);
|
|
||||||
} else { // IE
|
|
||||||
self.get(callback, options.error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
tw.Revision = function(id, tiddler) {
|
|
||||||
var container = tiddler.bag || tiddler.recipe;
|
|
||||||
tw.Tiddler.apply(this, [tiddler.title, container]);
|
|
||||||
this._type = "revision";
|
|
||||||
this.revision = id;
|
|
||||||
};
|
|
||||||
tw.Revision.prototype = new tw.Tiddler();
|
|
||||||
$.extend(tw.Revision.prototype, {
|
|
||||||
revisions: false,
|
|
||||||
data: false,
|
|
||||||
put: false,
|
|
||||||
"delete": false
|
|
||||||
});
|
|
||||||
|
|
||||||
tw.Bag = function(name, host) {
|
|
||||||
Container.apply(this, ["bag", name, host]);
|
|
||||||
};
|
|
||||||
tw.Bag.prototype = new Container();
|
|
||||||
|
|
||||||
tw.Recipe = function(name, host) {
|
|
||||||
Container.apply(this, ["recipe", name, host]);
|
|
||||||
this.recipe = [];
|
|
||||||
};
|
|
||||||
tw.Recipe.prototype = new Container();
|
|
||||||
$.extend(tw.Recipe.prototype, {
|
|
||||||
data: ["recipe"].concat(Container.prototype.data)
|
|
||||||
});
|
|
||||||
|
|
||||||
tw.Policy = function(constraints) { // TODO: validation?
|
|
||||||
var self = this;
|
|
||||||
$.each(this.constraints, function(i, item) {
|
|
||||||
self[item] = constraints[item];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
tw.Policy.prototype.constraints = ["read", "write", "create", "delete",
|
|
||||||
"manage", "accept", "owner"];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* utilities
|
|
||||||
*/
|
|
||||||
|
|
||||||
tw._capitalize = function(str) {
|
|
||||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
||||||
};
|
|
||||||
|
|
||||||
// convert YYYYMMDDhhmmss timestamp to Date instance
|
|
||||||
convertTimestamp = function(t) {
|
|
||||||
if (t.match(/^\d{12,17}$/)) {
|
|
||||||
return new Date(Date.UTC(
|
|
||||||
parseInt(t.substr(0, 4), 10),
|
|
||||||
parseInt(t.substr(4, 2), 10) - 1,
|
|
||||||
parseInt(t.substr(6, 2), 10),
|
|
||||||
parseInt(t.substr(8, 2), 10),
|
|
||||||
parseInt(t.substr(10, 2), 10),
|
|
||||||
parseInt(t.substr(12, 2) || "0", 10),
|
|
||||||
parseInt(t.substr(14, 3) || "0", 10)
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
return new Date(Date.parse(t));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// adapted from Crockford (http://javascript.crockford.com/remedial.html)
|
|
||||||
supplant = function(str, obj) {
|
|
||||||
return str.replace(/{([^{}]*)}/g, function (a, b) {
|
|
||||||
var r = obj[b];
|
|
||||||
r = typeof r === "string" || typeof r === "number" ? r : a;
|
|
||||||
return $.inArray(b, ["host", "query"]) !== -1 ? r : encodeURIComponent(r); // XXX: special-casing
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return tw;
|
|
||||||
|
|
||||||
}(jQuery));
|
|
||||||
//}}}
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
/***
|
|
||||||
TiddlySpace extensions for [[chrjs]]
|
|
||||||
|''Requires''|chrjs.users|
|
|
||||||
***/
|
|
||||||
//{{{
|
|
||||||
(function($) {
|
|
||||||
|
|
||||||
tiddlyweb.routes.identities = "{host}/users/{username}/identities";
|
|
||||||
var IdentitiesCollection = function(user) {
|
|
||||||
tiddlyweb.Collection.apply(this, ["identities", user.host, {
|
|
||||||
username: user.username
|
|
||||||
}]);
|
|
||||||
};
|
|
||||||
IdentitiesCollection.prototype = new tiddlyweb.Collection();
|
|
||||||
jQuery.extend(IdentitiesCollection.prototype, {
|
|
||||||
add: function(identity, callback, errback) {
|
|
||||||
var tiddler = new tiddlyweb.Tiddler(identity);
|
|
||||||
tiddler.bag = new tiddlyweb.Bag("MAPUSER", this.host);
|
|
||||||
tiddler.put(callback, errback);
|
|
||||||
},
|
|
||||||
get: function(callback, errback) {
|
|
||||||
var uri = this.route();
|
|
||||||
$.ajax({
|
|
||||||
type: "get",
|
|
||||||
dataType: "json",
|
|
||||||
url: uri,
|
|
||||||
success: function(uris, status, xhr) {
|
|
||||||
callback(uris, status, xhr);
|
|
||||||
},
|
|
||||||
error: function(xhr, error, exc) {
|
|
||||||
errback(xhr, error, exc, self);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
tiddlyweb.User.prototype.identities = function() {
|
|
||||||
return new IdentitiesCollection(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
})(jQuery);
|
|
||||||
//}}}
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
/***
|
|
||||||
TiddlySpace extensions for [[chrjs]]
|
|
||||||
***/
|
|
||||||
//{{{
|
|
||||||
(function($) {
|
|
||||||
|
|
||||||
tiddlyweb.routes.spaces = "{host}/spaces";
|
|
||||||
tiddlyweb.routes.space = "{host}/spaces/{name}";
|
|
||||||
tiddlyweb.routes.members = "{host}/spaces/{name}/members";
|
|
||||||
tiddlyweb.routes.member = "{host}/spaces/{name}/members/{username}";
|
|
||||||
|
|
||||||
tiddlyweb.Space = function(name, host) {
|
|
||||||
tiddlyweb.Resource.apply(this, ["space", host]);
|
|
||||||
this.name = name;
|
|
||||||
};
|
|
||||||
tiddlyweb.Space.prototype = new tiddlyweb.Resource();
|
|
||||||
$.extend(tiddlyweb.Space.prototype, {
|
|
||||||
create: function(callback, errback) { // API wrapper
|
|
||||||
this.put.apply(this, arguments);
|
|
||||||
},
|
|
||||||
members: function() {
|
|
||||||
return new MemberCollection(this);
|
|
||||||
},
|
|
||||||
includes: function() {
|
|
||||||
return new IncludesCollection(this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var Member = function(username, space) {
|
|
||||||
tiddlyweb.Resource.apply(this, ["member", space.host]);
|
|
||||||
this.name = space.name;
|
|
||||||
this.username = username;
|
|
||||||
};
|
|
||||||
Member.prototype = new tiddlyweb.Resource();
|
|
||||||
|
|
||||||
var MemberCollection = function(space) {
|
|
||||||
tiddlyweb.Collection.apply(this, ["members", space.host, {
|
|
||||||
name: space.name
|
|
||||||
}]);
|
|
||||||
};
|
|
||||||
MemberCollection.prototype = new tiddlyweb.Collection();
|
|
||||||
$.extend(MemberCollection.prototype, {
|
|
||||||
add: function(username, callback, errback) {
|
|
||||||
var member = new Member(username, this);
|
|
||||||
member.put(callback, errback);
|
|
||||||
},
|
|
||||||
remove: function(username, callback, errback) {
|
|
||||||
var member = new Member(username, this);
|
|
||||||
member["delete"](callback, errback);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var IncludesCollection = function(space) {
|
|
||||||
tiddlyweb.Collection.apply(this, ["space", space.host, {
|
|
||||||
name: space.name
|
|
||||||
}]);
|
|
||||||
};
|
|
||||||
IncludesCollection.prototype = new tiddlyweb.Collection();
|
|
||||||
$.extend(IncludesCollection.prototype, {
|
|
||||||
get: function(callback, errback) {
|
|
||||||
var self = this;
|
|
||||||
var recipe = new tiddlyweb.Recipe(this.name + "_public", this.host);
|
|
||||||
recipe.get(function(recipe, status, xhr) {
|
|
||||||
var inclusions = $.map(recipe.recipe, function(item, i) {
|
|
||||||
var arr = item[0].split("_public");
|
|
||||||
return (arr[0] != self.name && arr[1] === "") ? arr[0] : null;
|
|
||||||
});
|
|
||||||
callback(inclusions, status, xhr);
|
|
||||||
}, function(xhr, error, exc) {
|
|
||||||
errback(xhr, error, exc, self);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
add: function(name, callback, errback) {
|
|
||||||
var self = this;
|
|
||||||
var names = typeof(name) === "string" ? [ name ] : name;
|
|
||||||
$.ajax({
|
|
||||||
type: "post",
|
|
||||||
url: this.route(),
|
|
||||||
contentType: "json",
|
|
||||||
data: JSON.stringify({ "subscriptions": names }),
|
|
||||||
success: function(response, status, xhr) {
|
|
||||||
callback(self, status, xhr);
|
|
||||||
},
|
|
||||||
error: function(xhr, error, exc) {
|
|
||||||
errback(xhr, error, exc, self);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
remove: function(name, callback, errback) {
|
|
||||||
var self = this;
|
|
||||||
var names = typeof(name) === "string" ? [ name ] : name;
|
|
||||||
$.ajax({
|
|
||||||
type: "post",
|
|
||||||
contentType: "json",
|
|
||||||
url: this.route(),
|
|
||||||
data: JSON.stringify({ "unsubscriptions": names }),
|
|
||||||
success: function(response, status, xhr) {
|
|
||||||
callback(self, status, xhr);
|
|
||||||
},
|
|
||||||
error: function(xhr, error, exc) {
|
|
||||||
errback(xhr, error, exc, self);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
})(jQuery);
|
|
||||||
//}}}
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
/***
|
|
||||||
https://raw.github.com/tiddlyweb/chrjs/master/users.js
|
|
||||||
***/
|
|
||||||
//{{{
|
|
||||||
// chrjs users extension
|
|
||||||
// v0.5.0
|
|
||||||
//
|
|
||||||
// requires tiddlywebplugins.socialusers
|
|
||||||
// http://pypi.python.org/pypi/tiddlywebplugins.socialusers
|
|
||||||
|
|
||||||
/*jslint vars: true */
|
|
||||||
/*global jQuery, tiddlyweb */
|
|
||||||
|
|
||||||
(function($, tw) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
tw.routes.users = "{host}/users";
|
|
||||||
tw.routes.user = "{host}/users/{username}";
|
|
||||||
|
|
||||||
tw.User = function(username, password, host) {
|
|
||||||
tw.Resource.apply(this, ["user", host]);
|
|
||||||
this.username = username;
|
|
||||||
this.password = password;
|
|
||||||
};
|
|
||||||
tw.User.prototype = new tw.Resource();
|
|
||||||
$.extend(tw.User.prototype, {
|
|
||||||
create: function(callback, errback) {
|
|
||||||
var uri = this.route().split("/"); // XXX: hacky!?
|
|
||||||
uri.pop();
|
|
||||||
uri = uri.join("/");
|
|
||||||
var data = {
|
|
||||||
username: this.username,
|
|
||||||
password: this.password
|
|
||||||
};
|
|
||||||
var self = this;
|
|
||||||
return $.ajax({
|
|
||||||
url: uri,
|
|
||||||
type: "POST",
|
|
||||||
contentType: "application/json",
|
|
||||||
data: JSON.stringify(data),
|
|
||||||
success: callback,
|
|
||||||
error: function(xhr, error, exc) {
|
|
||||||
errback(xhr, error, exc, self);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
setPassword: function(newPass, callback, errback) {
|
|
||||||
this.old_password = this.password; // XXX: should not use underscore (consistency)
|
|
||||||
this.password = newPass;
|
|
||||||
return this.put(callback, errback);
|
|
||||||
},
|
|
||||||
data: ["password", "old_password"]
|
|
||||||
});
|
|
||||||
|
|
||||||
}(jQuery, tiddlyweb));
|
|
||||||
//}}}
|
|
||||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
|
@ -1,406 +0,0 @@
|
||||||
/*! normalize.css v2.1.3 | MIT License | git.io/normalize */
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
HTML5 display definitions
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Correct `block` display not defined in IE 8/9.
|
|
||||||
*/
|
|
||||||
|
|
||||||
article,
|
|
||||||
aside,
|
|
||||||
details,
|
|
||||||
figcaption,
|
|
||||||
figure,
|
|
||||||
footer,
|
|
||||||
header,
|
|
||||||
hgroup,
|
|
||||||
main,
|
|
||||||
nav,
|
|
||||||
section,
|
|
||||||
summary {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Correct `inline-block` display not defined in IE 8/9.
|
|
||||||
*/
|
|
||||||
|
|
||||||
audio,
|
|
||||||
canvas,
|
|
||||||
video {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevent modern browsers from displaying `audio` without controls.
|
|
||||||
* Remove excess height in iOS 5 devices.
|
|
||||||
*/
|
|
||||||
|
|
||||||
audio:not([controls]) {
|
|
||||||
display: none;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address `[hidden]` styling not present in IE 8/9.
|
|
||||||
* Hide the `template` element in IE, Safari, and Firefox < 22.
|
|
||||||
*/
|
|
||||||
|
|
||||||
[hidden],
|
|
||||||
template {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
Base
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. Set default font family to sans-serif.
|
|
||||||
* 2. Prevent iOS text size adjust after orientation change, without disabling
|
|
||||||
* user zoom.
|
|
||||||
*/
|
|
||||||
|
|
||||||
html {
|
|
||||||
font-family: sans-serif; /* 1 */
|
|
||||||
-ms-text-size-adjust: 100%; /* 2 */
|
|
||||||
-webkit-text-size-adjust: 100%; /* 2 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove default margin.
|
|
||||||
*/
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
Links
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the gray background color from active links in IE 10.
|
|
||||||
*/
|
|
||||||
|
|
||||||
a {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address `outline` inconsistency between Chrome and other browsers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
a:focus {
|
|
||||||
outline: thin dotted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Improve readability when focused and also mouse hovered in all browsers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
a:active,
|
|
||||||
a:hover {
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
Typography
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address variable `h1` font-size and margin within `section` and `article`
|
|
||||||
* contexts in Firefox 4+, Safari 5, and Chrome.
|
|
||||||
*/
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 2em;
|
|
||||||
margin: 0.67em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address styling not present in IE 8/9, Safari 5, and Chrome.
|
|
||||||
*/
|
|
||||||
|
|
||||||
abbr[title] {
|
|
||||||
border-bottom: 1px dotted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
|
|
||||||
*/
|
|
||||||
|
|
||||||
b,
|
|
||||||
strong {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address styling not present in Safari 5 and Chrome.
|
|
||||||
*/
|
|
||||||
|
|
||||||
dfn {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address differences between Firefox and other browsers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
hr {
|
|
||||||
-moz-box-sizing: content-box;
|
|
||||||
box-sizing: content-box;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address styling not present in IE 8/9.
|
|
||||||
*/
|
|
||||||
|
|
||||||
mark {
|
|
||||||
background: #ff0;
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Correct font family set oddly in Safari 5 and Chrome.
|
|
||||||
*/
|
|
||||||
|
|
||||||
code,
|
|
||||||
kbd,
|
|
||||||
pre,
|
|
||||||
samp {
|
|
||||||
font-family: monospace, serif;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Improve readability of pre-formatted text in all browsers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
pre {
|
|
||||||
white-space: pre-wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set consistent quote types.
|
|
||||||
*/
|
|
||||||
|
|
||||||
q {
|
|
||||||
quotes: "\201C" "\201D" "\2018" "\2019";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address inconsistent and variable font size in all browsers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
small {
|
|
||||||
font-size: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
sub,
|
|
||||||
sup {
|
|
||||||
font-size: 75%;
|
|
||||||
line-height: 0;
|
|
||||||
position: relative;
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
sup {
|
|
||||||
top: -0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub {
|
|
||||||
bottom: -0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
Embedded content
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove border when inside `a` element in IE 8/9.
|
|
||||||
*/
|
|
||||||
|
|
||||||
img {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Correct overflow displayed oddly in IE 9.
|
|
||||||
*/
|
|
||||||
|
|
||||||
svg:not(:root) {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
Figures
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address margin not present in IE 8/9 and Safari 5.
|
|
||||||
*/
|
|
||||||
|
|
||||||
figure {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
Forms
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define consistent border, margin, and padding.
|
|
||||||
*/
|
|
||||||
|
|
||||||
fieldset {
|
|
||||||
border: 1px solid #c0c0c0;
|
|
||||||
margin: 0 2px;
|
|
||||||
padding: 0.35em 0.625em 0.75em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. Correct `color` not being inherited in IE 8/9.
|
|
||||||
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
|
||||||
*/
|
|
||||||
|
|
||||||
legend {
|
|
||||||
border: 0; /* 1 */
|
|
||||||
padding: 0; /* 2 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. Correct font family not being inherited in all browsers.
|
|
||||||
* 2. Correct font size not being inherited in all browsers.
|
|
||||||
* 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
|
|
||||||
*/
|
|
||||||
|
|
||||||
button,
|
|
||||||
input,
|
|
||||||
select,
|
|
||||||
textarea {
|
|
||||||
font-family: inherit; /* 1 */
|
|
||||||
font-size: 100%; /* 2 */
|
|
||||||
margin: 0; /* 3 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address Firefox 4+ setting `line-height` on `input` using `!important` in
|
|
||||||
* the UA stylesheet.
|
|
||||||
*/
|
|
||||||
|
|
||||||
button,
|
|
||||||
input {
|
|
||||||
line-height: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Address inconsistent `text-transform` inheritance for `button` and `select`.
|
|
||||||
* All other form control elements do not inherit `text-transform` values.
|
|
||||||
* Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.
|
|
||||||
* Correct `select` style inheritance in Firefox 4+ and Opera.
|
|
||||||
*/
|
|
||||||
|
|
||||||
button,
|
|
||||||
select {
|
|
||||||
text-transform: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
|
||||||
* and `video` controls.
|
|
||||||
* 2. Correct inability to style clickable `input` types in iOS.
|
|
||||||
* 3. Improve usability and consistency of cursor style between image-type
|
|
||||||
* `input` and others.
|
|
||||||
*/
|
|
||||||
|
|
||||||
button,
|
|
||||||
html input[type="button"], /* 1 */
|
|
||||||
input[type="reset"],
|
|
||||||
input[type="submit"] {
|
|
||||||
-webkit-appearance: button; /* 2 */
|
|
||||||
cursor: pointer; /* 3 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Re-set default cursor for disabled elements.
|
|
||||||
*/
|
|
||||||
|
|
||||||
button[disabled],
|
|
||||||
html input[disabled] {
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. Address box sizing set to `content-box` in IE 8/9/10.
|
|
||||||
* 2. Remove excess padding in IE 8/9/10.
|
|
||||||
*/
|
|
||||||
|
|
||||||
input[type="checkbox"],
|
|
||||||
input[type="radio"] {
|
|
||||||
box-sizing: border-box; /* 1 */
|
|
||||||
padding: 0; /* 2 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
|
|
||||||
* 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
|
|
||||||
* (include `-moz` to future-proof).
|
|
||||||
*/
|
|
||||||
|
|
||||||
input[type="search"] {
|
|
||||||
-webkit-appearance: textfield; /* 1 */
|
|
||||||
-moz-box-sizing: content-box;
|
|
||||||
-webkit-box-sizing: content-box; /* 2 */
|
|
||||||
box-sizing: content-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove inner padding and search cancel button in Safari 5 and Chrome
|
|
||||||
* on OS X.
|
|
||||||
*/
|
|
||||||
|
|
||||||
input[type="search"]::-webkit-search-cancel-button,
|
|
||||||
input[type="search"]::-webkit-search-decoration {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove inner padding and border in Firefox 4+.
|
|
||||||
*/
|
|
||||||
|
|
||||||
button::-moz-focus-inner,
|
|
||||||
input::-moz-focus-inner {
|
|
||||||
border: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. Remove default vertical scrollbar in IE 8/9.
|
|
||||||
* 2. Improve readability and alignment in all browsers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
overflow: auto; /* 1 */
|
|
||||||
vertical-align: top; /* 2 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ==========================================================================
|
|
||||||
Tables
|
|
||||||
========================================================================== */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove most spacing between table cells.
|
|
||||||
*/
|
|
||||||
|
|
||||||
table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
border-spacing: 0;
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
|
|
@ -1,2 +0,0 @@
|
||||||
var tiddlyweb = tiddlyweb || {};
|
|
||||||
tiddlyweb.status = {"username": "jermolene", "tiddlyspace_version": "1.2.26", "space": {"recipe": "interview_private", "name": "interview"}, "challengers": ["tiddlywebplugins.tiddlyspace.cookie_form", "tiddlywebplugins.tiddlyspace.openid"], "server_host": {"host": "tiddlyspace.com", "scheme": "http", "port": "80"}, "version": "1.4.18"};
|
|
||||||
|
|
@ -1,766 +0,0 @@
|
||||||
/***
|
|
||||||
https://raw.github.com/TiddlySpace/ts.js/master/src/ts.js
|
|
||||||
***/
|
|
||||||
//{{{
|
|
||||||
/*jslint vars: true, browser: true */
|
|
||||||
/*global jQuery, tiddlyweb, confirm, prompt */
|
|
||||||
//
|
|
||||||
// version 0.5.12
|
|
||||||
(function($) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var getCSRFToken = function() {
|
|
||||||
// XXX: should not use RegEx - cf.
|
|
||||||
// http://www.quirksmode.org/js/cookies.html
|
|
||||||
// https://github.com/TiddlySpace/tiddlyspace/commit/5f4adbe009ed4bda3ce39058a3fb07de1420358d
|
|
||||||
var regex = /^(?:.*; )?csrf_token=([^(;|$)]*)(?:;|$)/;
|
|
||||||
var match = regex.exec(document.cookie);
|
|
||||||
var csrf_token = null;
|
|
||||||
if (match && (match.length === 2)) {
|
|
||||||
csrf_token = match[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return csrf_token;
|
|
||||||
};
|
|
||||||
|
|
||||||
$.ajaxSetup({
|
|
||||||
beforeSend: function(xhr) {
|
|
||||||
xhr.setRequestHeader("X-ControlView", "false");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
window.getCSRFToken = getCSRFToken;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add the members of spaceName to the current space.
|
|
||||||
*/
|
|
||||||
function addMembersfromSpace(ts, spaceName, callback, errback) {
|
|
||||||
new tiddlyweb.Space(spaceName, "/").members().get(function(members) {
|
|
||||||
var spaceMembers = new tiddlyweb.Space(ts.currentSpace, "/").
|
|
||||||
members(),
|
|
||||||
putMembers = function(members, callback, errback) {
|
|
||||||
var currentMember = members.shift();
|
|
||||||
if (currentMember) {
|
|
||||||
var next = function() {
|
|
||||||
putMembers(members, callback, errback);
|
|
||||||
};
|
|
||||||
spaceMembers.add(currentMember, next, errback);
|
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
putMembers(members, callback, errback);
|
|
||||||
}, errback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reset the message area associated with the provided form.
|
|
||||||
*/
|
|
||||||
function resetMessage(form) {
|
|
||||||
$(".annotation", form).removeClass("annotation");
|
|
||||||
$(".messageArea", form).removeClass("error").hide();
|
|
||||||
$(".inputArea", form).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Build message area element
|
|
||||||
*/
|
|
||||||
function buildMsgArea(form) {
|
|
||||||
var msgArea = $("<div class='messageArea' />");
|
|
||||||
msgArea
|
|
||||||
.append($("<button></button>")
|
|
||||||
.html("×")
|
|
||||||
.addClass("close-btn")
|
|
||||||
.attr("title", "close notification")
|
|
||||||
.data("parent-class", "messageArea")
|
|
||||||
.click( function() {
|
|
||||||
resetMessage(form);
|
|
||||||
return false;
|
|
||||||
} )
|
|
||||||
)
|
|
||||||
.append( $("<p></p>") );
|
|
||||||
|
|
||||||
var container = $("<div />").appendTo(msgArea)[0];
|
|
||||||
$("<a />").text("Try again?").click(function() {
|
|
||||||
$("input", form)[0].focus();
|
|
||||||
}).appendTo(container);
|
|
||||||
|
|
||||||
return msgArea;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Display a message aligned with the provided form.
|
|
||||||
*/
|
|
||||||
function displayMessage(form, msg, error, options) {
|
|
||||||
options = options || {};
|
|
||||||
if(options.hideForm) {
|
|
||||||
$(".inputArea", form).hide();
|
|
||||||
} else {
|
|
||||||
$(".inputArea", form).show();
|
|
||||||
}
|
|
||||||
var msgArea = $(".messageArea", form);
|
|
||||||
if(msgArea.length === 0) {
|
|
||||||
msgArea = buildMsgArea(form);
|
|
||||||
msgArea.prependTo(form);
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace error msg
|
|
||||||
msgArea
|
|
||||||
.find("p")
|
|
||||||
.empty()
|
|
||||||
.html(msg || ts.locale.error)
|
|
||||||
.end()
|
|
||||||
.show(100);
|
|
||||||
|
|
||||||
var errorDiv = msgArea.find("div");
|
|
||||||
if(error) {
|
|
||||||
msgArea.addClass("error annotation");
|
|
||||||
errorDiv.show();
|
|
||||||
} else {
|
|
||||||
msgArea.removeClass("error");
|
|
||||||
errorDiv.hide();
|
|
||||||
}
|
|
||||||
if(options.annotate) {
|
|
||||||
$(options.annotate, form).addClass("annotation");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do the default initialization behaviors.
|
|
||||||
*/
|
|
||||||
function defaultInit(ts, status, callback, options) {
|
|
||||||
options = options || {};
|
|
||||||
if (status.space && status.space.name &&
|
|
||||||
typeof options.space === "undefined") {
|
|
||||||
options.space = status.space.name;
|
|
||||||
}
|
|
||||||
ts.resolveCurrentSpaceName(options, status.server_host.host);
|
|
||||||
if(!ts.currentSpace) {
|
|
||||||
$(document.body).addClass("ts-unknown-space");
|
|
||||||
}
|
|
||||||
ts.loadStatus(status);
|
|
||||||
if(status.identity || ts.parameters.openid) {
|
|
||||||
ts.register_openid(status.identity);
|
|
||||||
} else if(status.username && ts.parameters.openid) {
|
|
||||||
// open id login occurred so redirect to homespace
|
|
||||||
window.location.href = ts.parameters.redirect ||
|
|
||||||
ts.getHost(status.username);
|
|
||||||
}
|
|
||||||
// do login status
|
|
||||||
ts.forms.password($("form.ts-password")[0]);
|
|
||||||
ts.loginStatus();
|
|
||||||
if(ts.currentSpace) {
|
|
||||||
ts.initForSpace(status);
|
|
||||||
}
|
|
||||||
if(callback) {
|
|
||||||
callback(ts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parse query parameters into a simple object.
|
|
||||||
*/
|
|
||||||
function parseParameters(queryString) {
|
|
||||||
var args = queryString.split(/[&;]/),
|
|
||||||
parameters = {},
|
|
||||||
i,
|
|
||||||
nameval;
|
|
||||||
for(i = 0; i < args.length; i += 1) {
|
|
||||||
nameval = args[i].split("=");
|
|
||||||
if(nameval.length === 2) {
|
|
||||||
parameters[nameval[0]] = nameval[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return parameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* add CSRF form fields to the provided form.
|
|
||||||
*/
|
|
||||||
function addCSRF(form) {
|
|
||||||
$("<input type='hidden' name='csrf_token' />").
|
|
||||||
val(getCSRFToken()).appendTo(form);
|
|
||||||
}
|
|
||||||
|
|
||||||
var ts = {
|
|
||||||
currentSpace: false,
|
|
||||||
locale: {
|
|
||||||
error: "An error occurred",
|
|
||||||
tryAgain: "Please try again",
|
|
||||||
success: "Clear this notification",
|
|
||||||
badLogin: "We are unable to log you in with those details.",
|
|
||||||
charError: "Username is invalid - must only contain lowercase " +
|
|
||||||
"letters, digits or hyphens",
|
|
||||||
spaceSuccess: "Successfully created space.",
|
|
||||||
userError: "Username is already taken, please choose another.",
|
|
||||||
passwordError: "Passwords do not match",
|
|
||||||
passwordLengthError: "Error: password must be at least 6 characters",
|
|
||||||
invalidSpaceError: ["error: invalid space name - must start with a ",
|
|
||||||
"letter, be at least two characters in length and only contain ",
|
|
||||||
"lowercase letters, digits or hyphens"].join("")
|
|
||||||
},
|
|
||||||
status: {},
|
|
||||||
user: {},
|
|
||||||
resolveCurrentSpaceName: function(options, host) {
|
|
||||||
if(options && typeof options.space !== "undefined") {
|
|
||||||
ts.currentSpace = options.space;
|
|
||||||
} else if(window.location.protocol !== "file:") {
|
|
||||||
var hostname = window.location.hostname;
|
|
||||||
if(host.split(".").length < hostname.split(".").length) {
|
|
||||||
ts.currentSpace = hostname.split(".")[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isValidSpaceName: function(name) {
|
|
||||||
return name.match(/^[a-z][0-9a-z\-]*[0-9a-z]$/) ? true : false;
|
|
||||||
},
|
|
||||||
init: function(callback, options) {
|
|
||||||
ts.parameters = parseParameters(window.location.search.substr(1));
|
|
||||||
var status = tiddlyweb.status;
|
|
||||||
if (status) {
|
|
||||||
defaultInit(ts, status, callback, options);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
initForSpace: function(status) {
|
|
||||||
if (/_private$/.test(status.space.recipe)) {
|
|
||||||
$(document.body).addClass("ts-member");
|
|
||||||
ts.forms.addInclude($("form.ts-includes")[0]);
|
|
||||||
ts.forms.addMember($("form.ts-members")[0]);
|
|
||||||
ts.forms.addSpace($("form.ts-spaces")[0]);
|
|
||||||
} else {
|
|
||||||
$(document.body).addClass("ts-nonmember");
|
|
||||||
}
|
|
||||||
ts.initLists();
|
|
||||||
},
|
|
||||||
getSpaces: function(callback) {
|
|
||||||
if(ts.spaces) {
|
|
||||||
callback(ts.spaces);
|
|
||||||
} else {
|
|
||||||
$.ajax({
|
|
||||||
url: "/spaces?mine=1",
|
|
||||||
dataType: "json",
|
|
||||||
success: function(spaces) {
|
|
||||||
ts.spaces = spaces;
|
|
||||||
callback(ts.spaces);
|
|
||||||
},
|
|
||||||
error: function() {
|
|
||||||
ts.spaces = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
initLists: function() {
|
|
||||||
ts.lists.identities();
|
|
||||||
ts.lists.members();
|
|
||||||
ts.lists.includes();
|
|
||||||
},
|
|
||||||
loadStatus: function(status) {
|
|
||||||
ts.status = status;
|
|
||||||
ts.user = {
|
|
||||||
name: status.username,
|
|
||||||
anon: status.username ? status.username === "GUEST" : true
|
|
||||||
};
|
|
||||||
},
|
|
||||||
getHost: function(subdomain) {
|
|
||||||
var s = ts.status;
|
|
||||||
var host = s.server_host;
|
|
||||||
subdomain = subdomain ? subdomain + "." : "";
|
|
||||||
var url = host.scheme + "://" + subdomain + host.host;
|
|
||||||
var port = host.port;
|
|
||||||
if(port && port !== "80" && port !== "443") {
|
|
||||||
url += ":" + port;
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
},
|
|
||||||
login: function(username, password, options) {
|
|
||||||
options = options || {};
|
|
||||||
var success = options.success || function() {
|
|
||||||
window.location = options.redirect || ts.getHost(username);
|
|
||||||
};
|
|
||||||
// XXX void errback?
|
|
||||||
var errback = options.errback || function() {};
|
|
||||||
var challenger = options.challenger = options.challenger ||
|
|
||||||
"/challenge/tiddlywebplugins.tiddlyspace.cookie_form";
|
|
||||||
$.ajax({
|
|
||||||
url: challenger,
|
|
||||||
type: "POST",
|
|
||||||
data: {
|
|
||||||
user: username,
|
|
||||||
password: password,
|
|
||||||
csrf_token: getCSRFToken(),
|
|
||||||
// workaround to marginalize automatic subsequent GET
|
|
||||||
tiddlyweb_redirect: "/status"
|
|
||||||
},
|
|
||||||
success: success,
|
|
||||||
error: errback
|
|
||||||
});
|
|
||||||
},
|
|
||||||
parameters: {},
|
|
||||||
register_openid_for_user: function(username, openid) {
|
|
||||||
var user = new tiddlyweb.User(username, null, "/");
|
|
||||||
user.identities().add(openid, function() {
|
|
||||||
window.location.href = window.location.pathname;
|
|
||||||
}, function() {
|
|
||||||
throw "failed to add identity to current user.";
|
|
||||||
});
|
|
||||||
},
|
|
||||||
register_openid: function(openid) {
|
|
||||||
var space = ts.parameters.space;
|
|
||||||
var username = ts.parameters.user;
|
|
||||||
if(!space && !username) {
|
|
||||||
var answer = confirm(
|
|
||||||
"Would you like to create a space with your openid: " +
|
|
||||||
openid + "?"
|
|
||||||
);
|
|
||||||
if(answer) {
|
|
||||||
space = prompt("What would you like to be your TiddlySpace username?");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(space && openid) {
|
|
||||||
var possible =
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
||||||
var password = "";
|
|
||||||
while(password.length < 16) {
|
|
||||||
password += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
||||||
}
|
|
||||||
// register user with username of space and random password
|
|
||||||
ts.register(space, password, null, {
|
|
||||||
errback: function() {
|
|
||||||
throw "failed at step 1/3";
|
|
||||||
},
|
|
||||||
success: function() {
|
|
||||||
// login as that newly created user
|
|
||||||
ts.login(space, password, {
|
|
||||||
success: function() {
|
|
||||||
ts.register_openid_for_user(space, openid);
|
|
||||||
},
|
|
||||||
errback: function() {
|
|
||||||
throw "failed at step 2/3";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if(username) {
|
|
||||||
ts.register_openid_for_user(username, ts.parameters.openid);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
register: function(username, password, form, options) {
|
|
||||||
options = options || {};
|
|
||||||
var spaceCallback = options.success || function() {
|
|
||||||
displayMessage(form, ts.locale.spaceSuccess, false);
|
|
||||||
window.location = options.redirect || ts.getHost(username);
|
|
||||||
};
|
|
||||||
var spaceErrback = function (xhr) {
|
|
||||||
// XXX: 409 unlikely to occur at this point
|
|
||||||
var msg = xhr.status === 409 ? ts.locale.userError : false;
|
|
||||||
displayMessage(form, msg, true, options);
|
|
||||||
};
|
|
||||||
var userCallback = function() {
|
|
||||||
ts.login(username, password, {
|
|
||||||
success: function() {
|
|
||||||
var space = new tiddlyweb.Space(username, "/");
|
|
||||||
space.create(spaceCallback, spaceErrback);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var userErrback = function(xhr) {
|
|
||||||
var msg = xhr.status === 409 ? ts.locale.userError : false;
|
|
||||||
displayMessage(form, msg, true, options);
|
|
||||||
};
|
|
||||||
var user = new tiddlyweb.User(username, password, "/");
|
|
||||||
user.create(userCallback, userErrback);
|
|
||||||
},
|
|
||||||
createSpace: function(form, spaceName, callback, errback) {
|
|
||||||
if(ts.isValidSpaceName(spaceName)) {
|
|
||||||
var space = new tiddlyweb.Space(spaceName, "/");
|
|
||||||
space.create(callback, errback);
|
|
||||||
} else {
|
|
||||||
displayMessage(form, ts.locale.invalidSpaceError, true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
changePassword: function(username, password, npassword, form) {
|
|
||||||
var pwCallback = function() {
|
|
||||||
var msg = "Successfully changed your password.";
|
|
||||||
displayMessage(form, msg);
|
|
||||||
};
|
|
||||||
var pwErrback = function() {
|
|
||||||
var msg = "Old password is incorrect.";
|
|
||||||
displayMessage(form, msg, true);
|
|
||||||
};
|
|
||||||
var user = new tiddlyweb.User(username, password, "/");
|
|
||||||
user.setPassword(npassword, pwCallback, pwErrback);
|
|
||||||
},
|
|
||||||
loginStatus: function() {
|
|
||||||
var register = $("form.ts-registration");
|
|
||||||
var login = $("form.ts-login");
|
|
||||||
var logout = $(".ts-logout");
|
|
||||||
|
|
||||||
var user = ts.user;
|
|
||||||
$("form.ts-openid").each(function(i, el) {
|
|
||||||
ts.forms.openid(el, { user: user });
|
|
||||||
});
|
|
||||||
if(!user.anon) {
|
|
||||||
$(document.body).addClass("ts-loggedin");
|
|
||||||
$([register, login]).remove();
|
|
||||||
logout.each(function(i, el) {
|
|
||||||
ts.forms.logout(el);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
if(register) {
|
|
||||||
ts.forms.register(register);
|
|
||||||
}
|
|
||||||
if(login) {
|
|
||||||
ts.forms.login(login);
|
|
||||||
}
|
|
||||||
logout.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ts.forms = {
|
|
||||||
password: function(form) {
|
|
||||||
$(form).submit(function(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
var oldPass = $("[name=password]").val();
|
|
||||||
var newPass = $("[name=new_password]").val();
|
|
||||||
var newPass2 = $("[name=new_password_confirm]").val();
|
|
||||||
if(newPass !== newPass2) {
|
|
||||||
var msg = "Passwords do not match";
|
|
||||||
displayMessage(form, msg, true);
|
|
||||||
} else if(newPass.length < 6) {
|
|
||||||
displayMessage(form, ts.locale.passwordLengthError, true);
|
|
||||||
} else {
|
|
||||||
ts.changePassword(ts.user.name, oldPass, newPass, form);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
addInclude: function(form) {
|
|
||||||
if(!form) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
addCSRF(form);
|
|
||||||
$(form).submit(function(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
var input = $("input[name=spacename]", form);
|
|
||||||
var space = input.val();
|
|
||||||
var callback = function() {
|
|
||||||
ts.lists.includes($("ul.ts-includes").empty()[0]);
|
|
||||||
input.val("");
|
|
||||||
var msg = space + " included";
|
|
||||||
displayMessage(form, msg, false);
|
|
||||||
};
|
|
||||||
var errback = function() {
|
|
||||||
var msg = "Unable to include space with that name.";
|
|
||||||
displayMessage(form, msg, true);
|
|
||||||
};
|
|
||||||
new tiddlyweb.Space(ts.currentSpace, "/").includes().
|
|
||||||
add(space, callback, errback);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
addMember: function(form) {
|
|
||||||
if(!form) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
addCSRF(form);
|
|
||||||
$(form).submit(function(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
var input = $("input[name=username]", form);
|
|
||||||
var username = input.val();
|
|
||||||
var spaceName = /^@/.test(username) ? username.slice(1) :
|
|
||||||
null;
|
|
||||||
var callback = function() {
|
|
||||||
ts.lists.members($("ul.ts-members").empty()[0]);
|
|
||||||
input.val("");
|
|
||||||
resetMessage(form);
|
|
||||||
};
|
|
||||||
var errback = function(xhr) {
|
|
||||||
if(xhr.status === 403) {
|
|
||||||
displayMessage(form,
|
|
||||||
"Unable to add members from a space you " +
|
|
||||||
"are not a member of",
|
|
||||||
true);
|
|
||||||
} else if (xhr.status === 409) {
|
|
||||||
displayMessage(form,
|
|
||||||
"Unknown username entered.",
|
|
||||||
true);
|
|
||||||
} else {
|
|
||||||
var msg = "Unknown error occurred.";
|
|
||||||
displayMessage(form, msg, true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (!spaceName) {
|
|
||||||
new tiddlyweb.Space(ts.currentSpace, "/").members().
|
|
||||||
add(username, callback, errback);
|
|
||||||
} else {
|
|
||||||
addMembersfromSpace(ts, spaceName, callback, errback);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
addSpace: function(form) {
|
|
||||||
if(!form) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var selector = "[name=spacename]";
|
|
||||||
addCSRF(form);
|
|
||||||
$(form).submit(function(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
var spaceName = $(selector, form).val() || "";
|
|
||||||
var callback = function() {
|
|
||||||
var host = ts.getHost(spaceName),
|
|
||||||
msg = "Successfully created <a href='" +
|
|
||||||
host + "'>" + host + "</a>.";
|
|
||||||
displayMessage(form, msg, false);
|
|
||||||
};
|
|
||||||
var errback = function() {
|
|
||||||
var msg = "Problem creating a space with that name.";
|
|
||||||
displayMessage(form, msg, true);
|
|
||||||
};
|
|
||||||
ts.createSpace(form, spaceName, callback, errback);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
register: function(form, options) {
|
|
||||||
options = options || {};
|
|
||||||
addCSRF(form);
|
|
||||||
$(form).submit(function(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
var username = $("[name=username]", form).val();
|
|
||||||
var password = $("[name=password]", form).val();
|
|
||||||
options.redirect = $("[name=redirect]", form).val();
|
|
||||||
var passwordConfirm = $("[name=password_confirm]",
|
|
||||||
form).val();
|
|
||||||
var validName = ts.isValidSpaceName(username);
|
|
||||||
var validLength = password.length >= 6;
|
|
||||||
if(validName && validLength && password &&
|
|
||||||
password === passwordConfirm) {
|
|
||||||
ts.register(username, password, ev.target, options);
|
|
||||||
} else {
|
|
||||||
var msg = validName ?
|
|
||||||
(!validLength ? ts.locale.passwordLengthError :
|
|
||||||
ts.locale.passwordError) :
|
|
||||||
ts.locale.charError;
|
|
||||||
options.annotate = validName ? "[type=password]" :
|
|
||||||
"[name=username]";
|
|
||||||
displayMessage(form, msg, true, options);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
openid: function(form, options) {
|
|
||||||
addCSRF(form);
|
|
||||||
$(form).attr("method", "post").
|
|
||||||
attr("action",
|
|
||||||
"/challenge/tiddlywebplugins.tiddlyspace.openid").
|
|
||||||
submit(function(ev) {
|
|
||||||
var identity = $("input[name=openid]", form).val(),
|
|
||||||
space = $("input[name=space]", form).val(),
|
|
||||||
user = options && options.user ?
|
|
||||||
options.user.name : null;
|
|
||||||
if(!identity) {
|
|
||||||
ev.preventDefault();
|
|
||||||
return displayMessage(form,
|
|
||||||
"Please provide an openid!");
|
|
||||||
}
|
|
||||||
var querystring = "?openid=" + identity;
|
|
||||||
if(space) {
|
|
||||||
querystring += "&space=" + space;
|
|
||||||
}
|
|
||||||
if(user) {
|
|
||||||
querystring += "&user=" + user;
|
|
||||||
}
|
|
||||||
var redirect = $("[name=redirect]", form).val();
|
|
||||||
if(redirect) {
|
|
||||||
querystring += "&redirect=" + redirect;
|
|
||||||
}
|
|
||||||
// IMPORTANT: #auth:OpenID=<openid> is read by the openid tiddlyweb plugin
|
|
||||||
// when present it keeps you logged in as your cookie username
|
|
||||||
$("<input name='tiddlyweb_redirect' type='hidden' />").
|
|
||||||
val(window.location.pathname + querystring +
|
|
||||||
"#auth:OpenID=" + identity).appendTo(form);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
logout: function(form_or_container) {
|
|
||||||
if(!form_or_container) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var tag = form_or_container.nodeName;
|
|
||||||
var form;
|
|
||||||
var isContainer = tag !== "FORM";
|
|
||||||
if(isContainer) {
|
|
||||||
var uri = ts.getHost(ts.user.name);
|
|
||||||
var link = $("<a />").attr({"href": uri,
|
|
||||||
"target": "_parent"}).text(ts.user.name)[0];
|
|
||||||
var msg = $("<span class='message' />").
|
|
||||||
text("Welcome back ").prependTo(form_or_container)[0];
|
|
||||||
$(msg).append(link);
|
|
||||||
$("<span />").text("!").appendTo(msg);
|
|
||||||
form = $("form", form_or_container)[0];
|
|
||||||
if(!form) {
|
|
||||||
form = $("<form />").appendTo(form_or_container)[0];
|
|
||||||
$("<input type='submit' class='button' value='Log out'>").appendTo(form);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
form = form_or_container;
|
|
||||||
}
|
|
||||||
$(form).attr("action", "/logout").attr("method", "post");
|
|
||||||
addCSRF(form);
|
|
||||||
},
|
|
||||||
login: function(form) {
|
|
||||||
// do login
|
|
||||||
addCSRF(form);
|
|
||||||
var options = {
|
|
||||||
errback: function(xhr) {
|
|
||||||
var code = xhr.status;
|
|
||||||
if(code === 401) {
|
|
||||||
displayMessage(form, ts.locale.badlogin, true);
|
|
||||||
} else {
|
|
||||||
displayMessage(form, ts.locale.tryAgain, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
function doLogin(ev) {
|
|
||||||
var user = $("input[name=username]", form).val();
|
|
||||||
var pass = $("input[name=password]", form).val();
|
|
||||||
if(!user) {
|
|
||||||
return displayMessage(form, "Please provide a username!");
|
|
||||||
}
|
|
||||||
if(!pass) {
|
|
||||||
return displayMessage(form, "Please provide a password!");
|
|
||||||
}
|
|
||||||
options.redirect = $("input[name=redirect]", form).val();
|
|
||||||
options.challenger = $(form).attr("action");
|
|
||||||
ts.login(user, pass, options);
|
|
||||||
ev.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
$(form).submit(function(ev) {
|
|
||||||
doLogin(ev);
|
|
||||||
});
|
|
||||||
|
|
||||||
$(form).keypress(function(ev) {
|
|
||||||
if(ev.keyCode === 13) {
|
|
||||||
doLogin(ev);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ts.lists = {
|
|
||||||
identities: function() {
|
|
||||||
var list = $("ul.ts-identities")[0];
|
|
||||||
if (list) {
|
|
||||||
$(list).addClass("ts-loading");
|
|
||||||
var user = new tiddlyweb.User(ts.user.name, null, "/");
|
|
||||||
user.identities().get(
|
|
||||||
function(identities) {
|
|
||||||
var i;
|
|
||||||
$(list).removeClass("ts-loading").empty();
|
|
||||||
for(i = 0; i < identities.length; i += 1) {
|
|
||||||
$("<li />").text(identities[i]).appendTo(list);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
function() {
|
|
||||||
$(list).removeClass("ts-loading").empty();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
includes: function() {
|
|
||||||
var space = new tiddlyweb.Space(ts.currentSpace, "/");
|
|
||||||
var removeInclusion = function(ev) {
|
|
||||||
var item = $(ev.target).parents("li")[0];
|
|
||||||
var target_space = $(ev.target).data("inclusion");
|
|
||||||
var callback = function() {
|
|
||||||
$(item).hide(200);
|
|
||||||
};
|
|
||||||
var errback = function() {};
|
|
||||||
space.includes().remove(target_space, callback, errback);
|
|
||||||
};
|
|
||||||
var list = $("ul.ts-includes").addClass("ts-loading")[0];
|
|
||||||
if(list) {
|
|
||||||
var callback = function(inclusions) {
|
|
||||||
var i, item;
|
|
||||||
$(list).removeClass("ts-loading").empty();
|
|
||||||
for(i = 0; i < inclusions.length; i += 1) {
|
|
||||||
item = $("<li />").appendTo(list)[0];
|
|
||||||
$("<a />")
|
|
||||||
.text(inclusions[i])
|
|
||||||
.attr("href", ts.getHost(inclusions[i]))
|
|
||||||
.attr("title", "visit icluded space")
|
|
||||||
.appendTo(item);
|
|
||||||
addDeleteBtn("inclusion", inclusions[i], item, removeInclusion);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var errback = function(xhr) {
|
|
||||||
$(list).removeClass("ts-loading").empty();
|
|
||||||
$("<li class='annotation' />").
|
|
||||||
text("Error requesting inclusions:" + xhr.status + " " + xhr.statusText).
|
|
||||||
prependTo(list);
|
|
||||||
};
|
|
||||||
space.includes().get(callback, errback);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
members: function() {
|
|
||||||
var space = new tiddlyweb.Space(ts.currentSpace, "/");
|
|
||||||
var removeMember = function(ev) {
|
|
||||||
var list = $(ev).parents("ul.members")[0];
|
|
||||||
var item = $(ev.target).parents("li")[0];
|
|
||||||
var member = $(ev.target).data("member");
|
|
||||||
var callback = function() {
|
|
||||||
$(item).hide(200, function() {
|
|
||||||
$(item).remove();
|
|
||||||
if($("ul.ts-members li:visible").length > 1) {
|
|
||||||
$("button.delete", list).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$("button.delete", list).hide();
|
|
||||||
};
|
|
||||||
var errback = function() {
|
|
||||||
// Um ought to be something here
|
|
||||||
};
|
|
||||||
space.members().remove(member, callback, errback);
|
|
||||||
};
|
|
||||||
var list = $("ul.ts-members").addClass("ts-loading")[0];
|
|
||||||
if(list) {
|
|
||||||
var callback = function(members) {
|
|
||||||
var i, item;
|
|
||||||
$(list).removeClass("ts-loading").empty();
|
|
||||||
members = members.sort();
|
|
||||||
for(i = 0; i < members.length; i += 1) {
|
|
||||||
item = $("<li />").appendTo(list)[0];
|
|
||||||
$("<a />")
|
|
||||||
.text(members[i])
|
|
||||||
.attr("href", ts.getHost(members[i]))
|
|
||||||
.attr("title", "visit member's home space")
|
|
||||||
.appendTo(item);
|
|
||||||
if(members.length > 1) {
|
|
||||||
addDeleteBtn("member", members[i], item, removeMember);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var errback = function() {
|
|
||||||
$(list).removeClass("ts-loading").empty();
|
|
||||||
$("<li class='annotation' />").
|
|
||||||
text("Only members can see other members.").
|
|
||||||
prependTo(list);
|
|
||||||
};
|
|
||||||
space.members().get(callback, errback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function addDeleteBtn(type, data, item, cb) {
|
|
||||||
$("<button />")
|
|
||||||
.addClass("delete")
|
|
||||||
.data(type, data)
|
|
||||||
.attr("title", "remove " + type)
|
|
||||||
.html("×")
|
|
||||||
.click(cb)
|
|
||||||
.appendTo(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
ts.parseParameters = parseParameters;
|
|
||||||
window.ts = {
|
|
||||||
init: ts.init
|
|
||||||
};
|
|
||||||
|
|
||||||
}(jQuery));
|
|
||||||
//}}}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
This folder contains the output of using "save HTML file" in the browser viewing the interview project on TiddlySpace. This is not a TiddlyWiki; it is a snapshot of the HTML generated by an instance of TiddlyWiki.
|
|
||||||
|
|
||||||
See the `./scripts` directory for the tools used to extract the data from this file.
|
|
||||||