completely revamp JS client because JS sucks^W^W^W to feature AMD, require.js, promises and HTML.js. The comment listing is now more like Disqus and for now comment retrieval, comment creation and deletion works. Form validation is rudimentary implemented as well. replaced Mako with Jinja2 (because... I forgot.), admin interface will use Bootstrap™ but is not functional yet. features a progress indicator in case you're sqlite db performs *really* badpull/16/head
parent
7e6fa0438b
commit
f6271e5cf6
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2013, Martin Zimmermann <info@posativ.org>. All rights reserved.
|
||||
* License: BSD Style, 2 clauses. See isso/__init__.py.
|
||||
*/
|
||||
|
||||
define(["lib/q", "app/models"], function(Q, models) {
|
||||
|
||||
// http://stackoverflow.com/questions/17544965/unhandled-rejection-reasons-should-be-empty
|
||||
Q.stopUnhandledRejectionTracking();
|
||||
Q.longStackSupport = true;
|
||||
|
||||
var endpoint = null,
|
||||
location = window.location.pathname;
|
||||
|
||||
// guess Isso API location
|
||||
var js = document.getElementsByTagName("script");
|
||||
for (var i = 0; i < js.length; i++) {
|
||||
if (js[i].src.match("/client/require\\.js$")) {
|
||||
endpoint = js[i].src.substring(0, js[i].src.length - 18);
|
||||
break;
|
||||
}
|
||||
|
||||
throw "no Isso API location found";
|
||||
}
|
||||
|
||||
var curl = function(method, url, data) {
|
||||
|
||||
var request = new XMLHttpRequest();
|
||||
var response = Q.defer();
|
||||
|
||||
function onload() {
|
||||
response.resolve({status: request.status, body: request.responseText});
|
||||
}
|
||||
|
||||
try {
|
||||
request.open(method, url, true);
|
||||
request.overrideMimeType("application/javascript");
|
||||
|
||||
request.onreadystatechange = function () {
|
||||
if (request.readyState === 4) {
|
||||
onload();
|
||||
}
|
||||
};
|
||||
} catch (exception) {
|
||||
response.reject(exception.message);
|
||||
}
|
||||
|
||||
request.send(data);
|
||||
return response.promise;
|
||||
};
|
||||
|
||||
var qs = function(params) {
|
||||
rv = "";
|
||||
for (var key in params) {
|
||||
if (params.hasOwnProperty(key)) {
|
||||
rv += key + "=" + encodeURIComponent(params[key]) + "&";
|
||||
}
|
||||
}
|
||||
|
||||
return rv.substring(0, rv.length - 1) // chop off trailing "&"
|
||||
}
|
||||
|
||||
var create = function(data) {
|
||||
|
||||
return curl("POST", endpoint + "/new?" + qs({uri: location}), JSON.stringify(data))
|
||||
.then(function (rv) {
|
||||
if (rv.status == 201 || rv.status == 202) {
|
||||
return JSON.parse(rv.body);
|
||||
} else {
|
||||
msg = rv.body.match("<p>(.+)</p>")
|
||||
throw {status: rv.status, reason: (msg && msg[1]) || rv.body}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var modify = function(data) {
|
||||
// ...
|
||||
}
|
||||
|
||||
var remove = function(id) {
|
||||
return curl("DELETE", endpoint + "/?" + qs({uri: location, id: id}), null)
|
||||
.then(function(rv) {
|
||||
if (rv.status == 200) {
|
||||
return rv;
|
||||
} else {
|
||||
throw {status: rv.status, reason: rv.body}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var fetchall = function() {
|
||||
|
||||
return curl("GET", endpoint + "/?" + qs({uri: location}), null)
|
||||
.then(function (rv) {
|
||||
if (rv.status == 200) {
|
||||
return JSON.parse(rv.body)
|
||||
} else {
|
||||
msg = rv.body.match("<p>(.+)</p>")
|
||||
throw {status: rv.status, reason: (msg && msg[1]) || rv.body}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
endpoint: endpoint,
|
||||
create: create,
|
||||
remove: remove,
|
||||
fetchall: fetchall
|
||||
}
|
||||
|
||||
});
|
@ -0,0 +1,54 @@
|
||||
define(["lib/HTML", "./logging"], function(HTML, logging) {
|
||||
|
||||
var msgbox = function(defaults) {
|
||||
|
||||
var form = document.createElement("div")
|
||||
form.className = "isso-comment-box"
|
||||
HTML.ify(form);
|
||||
|
||||
var optional = form.add("ul.optional");
|
||||
optional.add("li>input[type=text name=author placeholder=Name ]").value = defaults.author || "";
|
||||
optional.add("li>input[type=email name=email placeholder=Email]").value = defaults.email || "";
|
||||
optional.add("li>input[type=url name=website placeholder=Website]").value = defaults.website || "";
|
||||
|
||||
var textarea = form.add("div>textarea[rows=2 name=text]");
|
||||
textarea.value = defaults.text || "";
|
||||
textarea.placeholder = "Kommentar hier eintippen (andere Felder sind optional)"
|
||||
textarea.onfocus = function() {
|
||||
textarea.rows = 10
|
||||
};
|
||||
textarea.onblur = function() { setTimeout(function() {
|
||||
if (textarea.value == "" && document.activeElement != textarea) {
|
||||
textarea.rows = 2
|
||||
}}, 500)};
|
||||
|
||||
form.add("input[type=submit]").value = "Kommentar hinzufügen";
|
||||
form.add("span");
|
||||
return form;
|
||||
|
||||
}
|
||||
|
||||
var validate = function(msgbox) {
|
||||
if (msgbox.query("textarea").value.length < 3) {
|
||||
msgbox.query("textarea").focus();
|
||||
msgbox.span.className = "isso-popup"
|
||||
msgbox.span.innerHTML = "Dein Kommentar sollte schon etwas länger sein.";
|
||||
msgbox.span.addEventListener("click", function(event) {
|
||||
msgbox.span.className = "";
|
||||
msgbox.span.innerHTML = "";
|
||||
})
|
||||
setTimeout(function() {
|
||||
msgbox.span.className = ""
|
||||
msgbox.span.innerHTML = ""
|
||||
}, 5000 )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return {
|
||||
msgbox: msgbox,
|
||||
validate: validate
|
||||
}
|
||||
});
|
@ -0,0 +1,9 @@
|
||||
define({
|
||||
error: function(err) {
|
||||
if ("status" in err && "reason" in err) {
|
||||
console.error("%i: %s", err.status, err.reason)
|
||||
} else {
|
||||
console.error(err.stack)
|
||||
}
|
||||
}
|
||||
})
|
@ -0,0 +1,10 @@
|
||||
define(function() {
|
||||
|
||||
function Comment(data) {
|
||||
this.text = data["text"];
|
||||
}
|
||||
|
||||
return {
|
||||
Comment: Comment
|
||||
}
|
||||
});
|
@ -0,0 +1,5 @@
|
||||
require(["lib/ready", "app/isso"], function(domready, isso) {
|
||||
domready(function() {
|
||||
isso.init();
|
||||
})
|
||||
});
|
@ -0,0 +1,81 @@
|
||||
/* Copyright 2013, Martin Zimmermann <info@posativ.org>. All rights reserved.
|
||||
* License: BSD Style, 2 clauses. See isso/__init__.py.
|
||||
*
|
||||
* utility functions
|
||||
*/
|
||||
|
||||
define({
|
||||
|
||||
// return `cookie` string if set
|
||||
read: function(cookie) {
|
||||
return (document.cookie.match('(^|; )' + cookie + '=([^;]*)') || 0)[2]
|
||||
},
|
||||
|
||||
ago: function(date) {
|
||||
/*!
|
||||
* JavaScript Pretty Date
|
||||
* Copyright (c) 2011 John Resig (ejohn.org)
|
||||
* Licensed under the MIT and GPL licenses.
|
||||
*/
|
||||
var diff = (((new Date()).getTime() - date.getTime()) / 1000),
|
||||
day_diff = Math.floor(diff / 86400);
|
||||
|
||||
if (isNaN(day_diff) || day_diff < 0 || day_diff >= 31)
|
||||
return;
|
||||
|
||||
return day_diff == 0 && (
|
||||
diff < 60 && "just now" ||
|
||||
diff < 120 && "1 minute ago" ||
|
||||
diff < 3600 && "vor " + Math.floor(diff / 60) + " Minuten" ||
|
||||
diff < 7200 && "vor einer Stunde" ||
|
||||
diff < 86400 && "vor " + Math.floor(diff / 3600) + " Stunden") ||
|
||||
day_diff == 1 && "Gestern" ||
|
||||
day_diff < 7 && "vor " + day_diff + " Tagen" ||
|
||||
day_diff < 31 && "vor " + Math.ceil(day_diff / 7) + " Wochen";
|
||||
},
|
||||
|
||||
heading: function() {
|
||||
/*
|
||||
* return first level heading that is probably the
|
||||
* blog title. If no h1 is found, "Untitled." is used.
|
||||
*/
|
||||
var el = document.getElementById("isso-thread");
|
||||
var visited = [];
|
||||
|
||||
var recurse = function(node) {
|
||||
for (var i = 0; i < node.childNodes.length; i++) {
|
||||
var child = node.childNodes[i];
|
||||
|
||||
if (child.nodeType != child.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.nodeName == "H1") {
|
||||
return child;
|
||||
}
|
||||
|
||||
if (visited.indexOf(child) == -1) {
|
||||
return recurse(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
|
||||
visited.push(el);
|
||||
|
||||
if (el == document.documentElement) {
|
||||
break
|
||||
}
|
||||
|
||||
var rv = recurse(el);
|
||||
if (rv) {
|
||||
return rv.textContent
|
||||
}
|
||||
|
||||
el = el.parentNode;
|
||||
}
|
||||
|
||||
return "Untitled."
|
||||
}
|
||||
});
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,55 @@
|
||||
/*!
|
||||
* domready (c) Dustin Diaz 2012 - License MIT
|
||||
*/
|
||||
!function (name, definition) {
|
||||
if (typeof module != 'undefined') module.exports = definition()
|
||||
else if (typeof define == 'function' && typeof define.amd == 'object') define(definition)
|
||||
else this[name] = definition()
|
||||
}('domready', function (ready) {
|
||||
|
||||
var fns = [], fn, f = false
|
||||
, doc = document
|
||||
, testEl = doc.documentElement
|
||||
, hack = testEl.doScroll
|
||||
, domContentLoaded = 'DOMContentLoaded'
|
||||
, addEventListener = 'addEventListener'
|
||||
, onreadystatechange = 'onreadystatechange'
|
||||
, readyState = 'readyState'
|
||||
, loadedRgx = hack ? /^loaded|^c/ : /^loaded|c/
|
||||
, loaded = loadedRgx.test(doc[readyState])
|
||||
|
||||
function flush(f) {
|
||||
loaded = 1
|
||||
while (f = fns.shift()) f()
|
||||
}
|
||||
|
||||
doc[addEventListener] && doc[addEventListener](domContentLoaded, fn = function () {
|
||||
doc.removeEventListener(domContentLoaded, fn, f)
|
||||
flush()
|
||||
}, f)
|
||||
|
||||
|
||||
hack && doc.attachEvent(onreadystatechange, fn = function () {
|
||||
if (/^c/.test(doc[readyState])) {
|
||||
doc.detachEvent(onreadystatechange, fn)
|
||||
flush()
|
||||
}
|
||||
})
|
||||
|
||||
return (ready = hack ?
|
||||
function (fn) {
|
||||
self != top ?
|
||||
loaded ? fn() : fns.push(fn) :
|
||||
function () {
|
||||
try {
|
||||
testEl.doScroll('left')
|
||||
} catch (e) {
|
||||
return setTimeout(function() { ready(fn) }, 50)
|
||||
}
|
||||
fn()
|
||||
}()
|
||||
} :
|
||||
function (fn) {
|
||||
loaded ? fn() : fns.push(fn)
|
||||
})
|
||||
})
|
@ -0,0 +1,6 @@
|
||||
require(["minified"], function(minified) {
|
||||
console.log(minified)
|
||||
minified.$.ready(function() {
|
||||
console.log(123);
|
||||
})
|
||||
});
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
RequireJS 2.1.8 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
|
||||
Available via the MIT or new BSD license.
|
||||
see: http://github.com/jrburke/requirejs for details
|
||||
*/
|
||||
var requirejs,require,define;
|
||||
(function(Z){function H(b){return"[object Function]"===L.call(b)}function I(b){return"[object Array]"===L.call(b)}function y(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function M(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function s(b,c){return ga.call(b,c)}function l(b,c){return s(b,c)&&b[c]}function F(b,c){for(var d in b)if(s(b,d)&&c(b[d],d))break}function Q(b,c,d,h){c&&F(c,function(c,j){if(d||!s(b,j))h&&"string"!==typeof c?(b[j]||(b[j]={}),Q(b[j],
|
||||
c,d,h)):b[j]=c});return b}function u(b,c){return function(){return c.apply(b,arguments)}}function aa(b){throw b;}function ba(b){if(!b)return b;var c=Z;y(b.split("."),function(b){c=c[b]});return c}function A(b,c,d,h){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=h;d&&(c.originalError=d);return c}function ha(b){function c(a,f,b){var e,m,c,g,d,h,j,i=f&&f.split("/");e=i;var n=k.map,p=n&&n["*"];if(a&&"."===a.charAt(0))if(f){e=l(k.pkgs,f)?i=[f]:i.slice(0,i.length-
|
||||
1);f=a=e.concat(a.split("/"));for(e=0;f[e];e+=1)if(m=f[e],"."===m)f.splice(e,1),e-=1;else if(".."===m)if(1===e&&(".."===f[2]||".."===f[0]))break;else 0<e&&(f.splice(e-1,2),e-=2);e=l(k.pkgs,f=a[0]);a=a.join("/");e&&a===f+"/"+e.main&&(a=f)}else 0===a.indexOf("./")&&(a=a.substring(2));if(b&&n&&(i||p)){f=a.split("/");for(e=f.length;0<e;e-=1){c=f.slice(0,e).join("/");if(i)for(m=i.length;0<m;m-=1)if(b=l(n,i.slice(0,m).join("/")))if(b=l(b,c)){g=b;d=e;break}if(g)break;!h&&(p&&l(p,c))&&(h=l(p,c),j=e)}!g&&
|
||||
h&&(g=h,d=j);g&&(f.splice(0,d,g),a=f.join("/"))}return a}function d(a){z&&y(document.getElementsByTagName("script"),function(f){if(f.getAttribute("data-requiremodule")===a&&f.getAttribute("data-requirecontext")===i.contextName)return f.parentNode.removeChild(f),!0})}function h(a){var f=l(k.paths,a);if(f&&I(f)&&1<f.length)return d(a),f.shift(),i.require.undef(a),i.require([a]),!0}function $(a){var f,b=a?a.indexOf("!"):-1;-1<b&&(f=a.substring(0,b),a=a.substring(b+1,a.length));return[f,a]}function n(a,
|
||||
f,b,e){var m,B,g=null,d=f?f.name:null,h=a,j=!0,k="";a||(j=!1,a="_@r"+(L+=1));a=$(a);g=a[0];a=a[1];g&&(g=c(g,d,e),B=l(r,g));a&&(g?k=B&&B.normalize?B.normalize(a,function(a){return c(a,d,e)}):c(a,d,e):(k=c(a,d,e),a=$(k),g=a[0],k=a[1],b=!0,m=i.nameToUrl(k)));b=g&&!B&&!b?"_unnormalized"+(M+=1):"";return{prefix:g,name:k,parentMap:f,unnormalized:!!b,url:m,originalName:h,isDefine:j,id:(g?g+"!"+k:k)+b}}function q(a){var f=a.id,b=l(p,f);b||(b=p[f]=new i.Module(a));return b}function t(a,f,b){var e=a.id,m=l(p,
|
||||
e);if(s(r,e)&&(!m||m.defineEmitComplete))"defined"===f&&b(r[e]);else if(m=q(a),m.error&&"error"===f)b(m.error);else m.on(f,b)}function v(a,f){var b=a.requireModules,e=!1;if(f)f(a);else if(y(b,function(f){if(f=l(p,f))f.error=a,f.events.error&&(e=!0,f.emit("error",a))}),!e)j.onError(a)}function w(){R.length&&(ia.apply(G,[G.length-1,0].concat(R)),R=[])}function x(a){delete p[a];delete T[a]}function E(a,f,b){var e=a.map.id;a.error?a.emit("error",a.error):(f[e]=!0,y(a.depMaps,function(e,c){var g=e.id,
|
||||
d=l(p,g);d&&(!a.depMatched[c]&&!b[g])&&(l(f,g)?(a.defineDep(c,r[g]),a.check()):E(d,f,b))}),b[e]=!0)}function C(){var a,f,b,e,m=(b=1E3*k.waitSeconds)&&i.startTime+b<(new Date).getTime(),c=[],g=[],j=!1,l=!0;if(!U){U=!0;F(T,function(b){a=b.map;f=a.id;if(b.enabled&&(a.isDefine||g.push(b),!b.error))if(!b.inited&&m)h(f)?j=e=!0:(c.push(f),d(f));else if(!b.inited&&(b.fetched&&a.isDefine)&&(j=!0,!a.prefix))return l=!1});if(m&&c.length)return b=A("timeout","Load timeout for modules: "+c,null,c),b.contextName=
|
||||
i.contextName,v(b);l&&y(g,function(a){E(a,{},{})});if((!m||e)&&j)if((z||da)&&!V)V=setTimeout(function(){V=0;C()},50);U=!1}}function D(a){s(r,a[0])||q(n(a[0],null,!0)).init(a[1],a[2])}function J(a){var a=a.currentTarget||a.srcElement,b=i.onScriptLoad;a.detachEvent&&!W?a.detachEvent("onreadystatechange",b):a.removeEventListener("load",b,!1);b=i.onScriptError;(!a.detachEvent||W)&&a.removeEventListener("error",b,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function K(){var a;for(w();G.length;){a=
|
||||
G.shift();if(null===a[0])return v(A("mismatch","Mismatched anonymous define() module: "+a[a.length-1]));D(a)}}var U,X,i,N,V,k={waitSeconds:7,baseUrl:"./",paths:{},pkgs:{},shim:{},config:{}},p={},T={},Y={},G=[],r={},S={},L=1,M=1;N={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?a.exports:a.exports=r[a.map.id]={}},module:function(a){return a.module?a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){var b=
|
||||
l(k.pkgs,a.map.id);return(b?l(k.config,a.map.id+"/"+b.main):l(k.config,a.map.id))||{}},exports:r[a.map.id]}}};X=function(a){this.events=l(Y,a.id)||{};this.map=a;this.shim=l(k.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};X.prototype={init:function(a,b,c,e){e=e||{};if(!this.inited){this.factory=b;if(c)this.on("error",c);else this.events.error&&(c=u(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback=c;this.inited=!0;
|
||||
this.ignore=e.ignore;e.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,b){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=b)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],u(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=
|
||||
this.map.url;S[a]||(S[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,b,c=this.map.id;b=this.depExports;var e=this.exports,m=this.factory;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(H(m)){if(this.events.error&&this.map.isDefine||j.onError!==aa)try{e=i.execCb(c,m,b,e)}catch(d){a=d}else e=i.execCb(c,m,b,e);this.map.isDefine&&((b=this.module)&&void 0!==b.exports&&b.exports!==
|
||||
this.exports?e=b.exports:void 0===e&&this.usingExports&&(e=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",v(this.error=a)}else e=m;this.exports=e;if(this.map.isDefine&&!this.ignore&&(r[c]=e,j.onResourceLoad))j.onResourceLoad(i,this.map,this.depMaps);x(c);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=
|
||||
!0)}}else this.fetch()}},callPlugin:function(){var a=this.map,b=a.id,d=n(a.prefix);this.depMaps.push(d);t(d,"defined",u(this,function(e){var m,d;d=this.map.name;var g=this.map.parentMap?this.map.parentMap.name:null,h=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(e.normalize&&(d=e.normalize(d,function(a){return c(a,g,!0)})||""),e=n(a.prefix+"!"+d,this.map.parentMap),t(e,"defined",u(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),
|
||||
d=l(p,e.id)){this.depMaps.push(e);if(this.events.error)d.on("error",u(this,function(a){this.emit("error",a)}));d.enable()}}else m=u(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),m.error=u(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];F(p,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&x(a.map.id)});v(a)}),m.fromText=u(this,function(e,c){var d=a.name,g=n(d),B=O;c&&(e=c);B&&(O=!1);q(g);s(k.config,b)&&(k.config[d]=k.config[b]);try{j.exec(e)}catch(ca){return v(A("fromtexteval",
|
||||
"fromText eval for "+b+" failed: "+ca,ca,[b]))}B&&(O=!0);this.depMaps.push(g);i.completeLoad(d);h([d],m)}),e.load(a.name,h,m,k)}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){T[this.map.id]=this;this.enabling=this.enabled=!0;y(this.depMaps,u(this,function(a,b){var c,e;if("string"===typeof a){a=n(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=l(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;t(a,"defined",u(this,function(a){this.defineDep(b,
|
||||
a);this.check()}));this.errback&&t(a,"error",u(this,this.errback))}c=a.id;e=p[c];!s(N,c)&&(e&&!e.enabled)&&i.enable(a,this)}));F(this.pluginMaps,u(this,function(a){var b=l(p,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){y(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:k,contextName:b,registry:p,defined:r,urlFetched:S,defQueue:G,Module:X,makeModuleMap:n,
|
||||
nextTick:j.nextTick,onError:v,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=k.pkgs,c=k.shim,e={paths:!0,config:!0,map:!0};F(a,function(a,b){e[b]?"map"===b?(k.map||(k.map={}),Q(k[b],a,!0,!0)):Q(k[b],a,!0):k[b]=a});a.shim&&(F(a.shim,function(a,b){I(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);c[b]=a}),k.shim=c);a.packages&&(y(a.packages,function(a){a="string"===typeof a?{name:a}:a;b[a.name]={name:a.name,
|
||||
location:a.location||a.name,main:(a.main||"main").replace(ja,"").replace(ea,"")}}),k.pkgs=b);F(p,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=n(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(Z,arguments));return b||a.exports&&ba(a.exports)}},makeRequire:function(a,f){function d(e,c,h){var g,k;f.enableBuildCallback&&(c&&H(c))&&(c.__requireJsBuild=!0);if("string"===typeof e){if(H(c))return v(A("requireargs",
|
||||
"Invalid require call"),h);if(a&&s(N,e))return N[e](p[a.id]);if(j.get)return j.get(i,e,a,d);g=n(e,a,!1,!0);g=g.id;return!s(r,g)?v(A("notloaded",'Module name "'+g+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):r[g]}K();i.nextTick(function(){K();k=q(n(null,a));k.skipMap=f.skipMap;k.init(e,c,h,{enabled:!0});C()});return d}f=f||{};Q(d,{isBrowser:z,toUrl:function(b){var d,f=b.lastIndexOf("."),g=b.split("/")[0];if(-1!==f&&(!("."===g||".."===g)||1<f))d=b.substring(f,b.length),b=
|
||||
b.substring(0,f);return i.nameToUrl(c(b,a&&a.id,!0),d,!0)},defined:function(b){return s(r,n(b,a,!1,!0).id)},specified:function(b){b=n(b,a,!1,!0).id;return s(r,b)||s(p,b)}});a||(d.undef=function(b){w();var c=n(b,a,!0),f=l(p,b);delete r[b];delete S[c.url];delete Y[b];f&&(f.events.defined&&(Y[b]=f.events),x(b))});return d},enable:function(a){l(p,a.id)&&q(a).enable()},completeLoad:function(a){var b,c,e=l(k.shim,a)||{},d=e.exports;for(w();G.length;){c=G.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===
|
||||
a&&(b=!0);D(c)}c=l(p,a);if(!b&&!s(r,a)&&c&&!c.inited){if(k.enforceDefine&&(!d||!ba(d)))return h(a)?void 0:v(A("nodefine","No define call for "+a,null,[a]));D([a,e.deps||[],e.exportsFn])}C()},nameToUrl:function(a,b,c){var e,d,h,g,i,n;if(j.jsExtRegExp.test(a))g=a+(b||"");else{e=k.paths;d=k.pkgs;g=a.split("/");for(i=g.length;0<i;i-=1)if(n=g.slice(0,i).join("/"),h=l(d,n),n=l(e,n)){I(n)&&(n=n[0]);g.splice(0,i,n);break}else if(h){a=a===h.name?h.location+"/"+h.main:h.location;g.splice(0,i,a);break}g=g.join("/");
|
||||
g+=b||(/\?/.test(g)||c?"":".js");g=("/"===g.charAt(0)||g.match(/^[\w\+\.\-]+:/)?"":k.baseUrl)+g}return k.urlArgs?g+((-1===g.indexOf("?")?"?":"&")+k.urlArgs):g},load:function(a,b){j.load(i,a,b)},execCb:function(a,b,c,e){return b.apply(e,c)},onScriptLoad:function(a){if("load"===a.type||ka.test((a.currentTarget||a.srcElement).readyState))P=null,a=J(a),i.completeLoad(a.id)},onScriptError:function(a){var b=J(a);if(!h(b.id))return v(A("scripterror","Script error for: "+b.id,a,[b.id]))}};i.require=i.makeRequire();
|
||||
return i}var j,w,x,C,J,D,P,K,q,fa,la=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ma=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,ea=/\.js$/,ja=/^\.\//;w=Object.prototype;var L=w.toString,ga=w.hasOwnProperty,ia=Array.prototype.splice,z=!!("undefined"!==typeof window&&navigator&&window.document),da=!z&&"undefined"!==typeof importScripts,ka=z&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,W="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),E={},t={},R=[],O=
|
||||
!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(H(requirejs))return;t=requirejs;requirejs=void 0}"undefined"!==typeof require&&!H(require)&&(t=require,require=void 0);j=requirejs=function(b,c,d,h){var q,n="_";!I(b)&&"string"!==typeof b&&(q=b,I(c)?(b=c,c=d,d=h):b=[]);q&&q.context&&(n=q.context);(h=l(E,n))||(h=E[n]=j.s.newContext(n));q&&h.configure(q);return h.require(b,c,d)};j.config=function(b){return j(b)};j.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,
|
||||
4)}:function(b){b()};require||(require=j);j.version="2.1.8";j.jsExtRegExp=/^\/|:|\?|\.js$/;j.isBrowser=z;w=j.s={contexts:E,newContext:ha};j({});y(["toUrl","undef","defined","specified"],function(b){j[b]=function(){var c=E._;return c.require[b].apply(c,arguments)}});if(z&&(x=w.head=document.getElementsByTagName("head")[0],C=document.getElementsByTagName("base")[0]))x=w.head=C.parentNode;j.onError=aa;j.createNode=function(b){var c=b.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):
|
||||
document.createElement("script");c.type=b.scriptType||"text/javascript";c.charset="utf-8";c.async=!0;return c};j.load=function(b,c,d){var h=b&&b.config||{};if(z)return h=j.createNode(h,c,d),h.setAttribute("data-requirecontext",b.contextName),h.setAttribute("data-requiremodule",c),h.attachEvent&&!(h.attachEvent.toString&&0>h.attachEvent.toString().indexOf("[native code"))&&!W?(O=!0,h.attachEvent("onreadystatechange",b.onScriptLoad)):(h.addEventListener("load",b.onScriptLoad,!1),h.addEventListener("error",
|
||||
b.onScriptError,!1)),h.src=d,K=h,C?x.insertBefore(h,C):x.appendChild(h),K=null,h;if(da)try{importScripts(d),b.completeLoad(c)}catch(l){b.onError(A("importscripts","importScripts failed for "+c+" at "+d,l,[c]))}};z&&M(document.getElementsByTagName("script"),function(b){x||(x=b.parentNode);if(J=b.getAttribute("data-main"))return q=J,t.baseUrl||(D=q.split("/"),q=D.pop(),fa=D.length?D.join("/")+"/":"./",t.baseUrl=fa),q=q.replace(ea,""),j.jsExtRegExp.test(q)&&(q=J),t.deps=t.deps?t.deps.concat(q):[q],!0});
|
||||
define=function(b,c,d){var h,j;"string"!==typeof b&&(d=c,c=b,b=null);I(c)||(d=c,c=null);!c&&H(d)&&(c=[],d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(O){if(!(h=K))P&&"interactive"===P.readyState||M(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),h=P;h&&(b||(b=h.getAttribute("data-requiremodule")),j=E[h.getAttribute("data-requirecontext")])}(j?j.defQueue:
|
||||
R).push([b,c,d])};define.amd={jQuery:!0};j.exec=function(b){return eval(b)};j(t)}})(this);
|
@ -1,65 +0,0 @@
|
||||
/* Copyright 2012, Martin Zimmermann <info@posativ.org>. All rights reserved.
|
||||
* License: BSD Style, 2 clauses. See isso/__init__.py.
|
||||
*
|
||||
* utility functions -- JS Y U SO STUPID?
|
||||
*
|
||||
* read(cookie): return `cookie` string if set
|
||||
* format(date): human-readable date formatting
|
||||
* brew(array): similar to DOMinate essentials
|
||||
*/
|
||||
|
||||
function read(cookie) {
|
||||
return (document.cookie.match('(^|; )' + cookie + '=([^;]*)') || 0)[2]
|
||||
};
|
||||
|
||||
|
||||
function format(date) {
|
||||
/*!
|
||||
* JavaScript Pretty Date
|
||||
* Copyright (c) 2011 John Resig (ejohn.org)
|
||||
* Licensed under the MIT and GPL licenses.
|
||||
*/
|
||||
var diff = (((new Date()).getTime() - date.getTime()) / 1000),
|
||||
day_diff = Math.floor(diff / 86400);
|
||||
|
||||
if (isNaN(day_diff) || day_diff < 0 || day_diff >= 31)
|
||||
return;
|
||||
|
||||
return day_diff == 0 && (
|
||||
diff < 60 && "just now" ||
|
||||
diff < 120 && "1 minute ago" ||
|
||||
diff < 3600 && Math.floor(diff / 60) + " minutes ago" ||
|
||||
diff < 7200 && "1 hour ago" ||
|
||||
diff < 86400 && Math.floor(diff / 3600) + " hours ago") ||
|
||||
day_diff == 1 && "Yesterday" ||
|
||||
day_diff < 7 && day_diff + " days ago" ||
|
||||
day_diff < 31 && Math.ceil(day_diff / 7) + " weeks ago";
|
||||
}
|
||||
|
||||
|
||||
function brew(arr) {
|
||||
/*
|
||||
* Element creation utility. Similar to DOMinate, but with a slightly different syntax:
|
||||
* brew([TAG, {any: attribute, ...}, 'Hello World', ' Foo Bar', ['TAG', 'Hello World'], ...])
|
||||
* --> <TAG any="attribute">Hello World Foo Bar<TAG>Hello World</TAG></TAG>
|
||||
*/
|
||||
|
||||
var rv = document.createElement(arr[0]);
|
||||
|
||||
for (var i = 1; i < arr.length; i++) {
|
||||
|
||||
if (arr[i] instanceof Array) {
|
||||
rv.appendChild(brew(arr[i]));
|
||||
} else if (typeof(arr[i]) == "string") {
|
||||
rv.appendChild(document.createTextNode(arr[i]));
|
||||
} else {
|
||||
attrs = arr[i] || {};
|
||||
for (var k in attrs) {
|
||||
if (!attrs.hasOwnProperty(k)) continue;
|
||||
rv.setAttribute(k, attrs[k]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return rv;
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
{% extends "base.j2" %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<div class="row">
|
||||
<div class="span4">
|
||||
|
||||
<h2>Overview</h1>
|
||||
|
||||
<ul>
|
||||
<li><b>N</b> approved</li>
|
||||
<li><b>N</b> pending</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li><b>N</b> Threads</li>
|
||||
</ul>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="span8">
|
||||
|
||||
<h2>Recent Comments</h1>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -1,123 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title><%block name="title" /></title>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" type="text/css" href="/static/style.css" />
|
||||
<script type="text/javascript" src="/js/interface.js"></script>
|
||||
<style>
|
||||
|
||||
/* ================ */
|
||||
/* = The 1Kb Grid = */ /* 12 columns, 60 pixels each, with 20 pixel gutter */
|
||||
/* ================ */
|
||||
|
||||
.grid_1 { width: 60px; }
|
||||
.grid_2 { width: 140px; }
|
||||
.grid_3 { width: 220px; }
|
||||
.grid_4 { width: 300px; }
|
||||
.grid_5 { width: 380px; }
|
||||
.grid_6 { width: 460px; }
|
||||
.grid_7 { width: 540px; }
|
||||
.grid_8 { width: 620px; }
|
||||
.grid_9 { width: 700px; }
|
||||
.grid_10 { width: 780px; }
|
||||
.grid_11 { width: 860px; }
|
||||
.grid_12 { width: 940px; }
|
||||
|
||||
.column {
|
||||
margin: 0 10px;
|
||||
overflow: hidden;
|
||||
float: left;
|
||||
display: inline;
|
||||
}
|
||||
.row {
|
||||
width: 960px;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
.row .row {
|
||||
margin: 0 -10px;
|
||||
width: auto;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 1em;
|
||||
line-height: 1.4;
|
||||
margin: 20px 0 0 0;
|
||||
}
|
||||
|
||||
body > h1 {
|
||||
text-align: center;
|
||||
padding: 8px 0 8px 0;
|
||||
background-color: yellowgreen;
|
||||
}
|
||||
|
||||
article {
|
||||
background-color: rgb(245, 245, 245);
|
||||
box-shadow: 0px 0px 4px 0px;
|
||||
/*border-radius: 2px;*/
|
||||
}
|
||||
|
||||
article header {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
article .options {
|
||||
margin: 8px;
|
||||
padding-bottom: 40px
|
||||
}
|
||||
|
||||
article .text, article header {
|
||||
padding: 8px 16px 8px 16px;
|
||||
}
|
||||
|
||||
.text p {
|
||||
margin-bottom: 10px;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.recent, .pending {
|
||||
padding: 10px 40px 10px 40px;
|
||||
box-shadow: 0px 0px 2px 0px;
|
||||
/*border-radius: 4px;*/
|
||||
margin: 2px auto 2px auto;
|
||||
}
|
||||
|
||||
.green {
|
||||
background-color: #B7D798;
|
||||
}
|
||||
|
||||
.red {
|
||||
background-color: #D79998;
|
||||
}
|
||||
|
||||
body > footer {
|
||||
border-top: 1px solid #AAA;
|
||||
padding-top: 8px;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.approve, .delete {
|
||||
padding-top: 10px;
|
||||
padding: 5px;
|
||||
border: 1px solid #666;
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
<%block name="style" />
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
${self.body()}
|
||||
</body>
|
@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Sign in · Isso</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="../static/css/bootstrap.css" rel="stylesheet">
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.form-signin {
|
||||
max-width: 300px;
|
||||
padding: 19px 29px 29px;
|
||||
margin: 0 auto 20px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #e5e5e5;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.05);
|
||||
-moz-box-shadow: 0 1px 2px rgba(0,0,0,.05);
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,.05);
|
||||
}
|
||||
.form-signin .form-signin-heading,
|
||||
.form-signin .checkbox {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.form-signin input[type="text"],
|
||||
.form-signin input[type="password"] {
|
||||
font-size: 16px;
|
||||
height: auto;
|
||||
margin-bottom: 15px;
|
||||
padding: 7px 9px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../assets/js/html5shiv.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<form class="form-signin" action="/admin/", method="post">
|
||||
<h2 class="form-signin-heading">Admin Interface</h2>
|
||||
<input type="password" class="input-block-level" placeholder="secret" name="password">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" value="remember-me"> Remember me
|
||||
</label>
|
||||
<button class="btn btn-large btn-primary" type="submit">Sign in</button>
|
||||
</form>
|
||||
|
||||
</div> <!-- /container -->
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in new issue