COMMIT ALL THE THINGS
* refactor JS (a lot) * use a CSS framework (neat/bourbon), because CSS is hard * up/downvote comments * cleaner HTML * HTML inclusion in JS * SVG icons for reference, up and downvote * basic i18n: english and german supported ootb * lazy (because slow) client-side identicon generation (preview ability) * removed website input field for no particular reason * remove HTML.js in favour of a homebrew DOM manipulation tool
This commit is contained in:
parent
6d9792d22e
commit
b36e2fdb28
@ -54,7 +54,7 @@ from werkzeug.contrib.fixers import ProxyFix
|
|||||||
|
|
||||||
from jinja2 import Environment, FileSystemLoader
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
|
||||||
from isso import db, migrate, views, wsgi, notify, colors
|
from isso import db, migrate, views, wsgi, notify, colors, utils
|
||||||
from isso.views import comment, admin
|
from isso.views import comment, admin
|
||||||
|
|
||||||
url_map = Map([
|
url_map = Map([
|
||||||
@ -62,16 +62,20 @@ url_map = Map([
|
|||||||
|
|
||||||
Rule('/id/<int:id>', methods=['GET', 'PUT', 'DELETE'], endpoint=views.comment.single),
|
Rule('/id/<int:id>', methods=['GET', 'PUT', 'DELETE'], endpoint=views.comment.single),
|
||||||
Rule('/id/<int:id>/like', methods=['POST'], endpoint=views.comment.like),
|
Rule('/id/<int:id>/like', methods=['POST'], endpoint=views.comment.like),
|
||||||
|
Rule('/id/<int:id>/dislike', methods=['POST'], endpoint=views.comment.dislike),
|
||||||
|
|
||||||
Rule('/', methods=['GET'], endpoint=views.comment.fetch),
|
Rule('/', methods=['GET'], endpoint=views.comment.fetch),
|
||||||
Rule('/count', methods=['GET'], endpoint=views.comment.count),
|
Rule('/count', methods=['GET'], endpoint=views.comment.count),
|
||||||
Rule('/admin/', endpoint=views.admin.index)
|
Rule('/admin/', endpoint=views.admin.index),
|
||||||
|
|
||||||
|
Rule('/check-ip', endpoint=views.comment.checkip)
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
class Isso(object):
|
class Isso(object):
|
||||||
|
|
||||||
PRODUCTION = False
|
PRODUCTION = False
|
||||||
|
SALT = "Eech7co8Ohloopo9Ol6baimi"
|
||||||
|
|
||||||
def __init__(self, dbpath, secret, origin, max_age, passphrase, mailer):
|
def __init__(self, dbpath, secret, origin, max_age, passphrase, mailer):
|
||||||
|
|
||||||
|
89
isso/crypto.py
Normal file
89
isso/crypto.py
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright (c) Django Software Foundation and individual contributors.
|
||||||
|
# All rights reserved.
|
||||||
|
|
||||||
|
import hmac
|
||||||
|
import time
|
||||||
|
import struct
|
||||||
|
import base64
|
||||||
|
import hashlib
|
||||||
|
import binascii
|
||||||
|
import operator
|
||||||
|
|
||||||
|
|
||||||
|
def _bin_to_long(x):
|
||||||
|
"""
|
||||||
|
Convert a binary string into a long integer
|
||||||
|
|
||||||
|
This is a clever optimization for fast xor vector math
|
||||||
|
"""
|
||||||
|
return int(binascii.hexlify(x), 16)
|
||||||
|
|
||||||
|
|
||||||
|
def _long_to_bin(x, hex_format_string):
|
||||||
|
"""
|
||||||
|
Convert a long integer into a binary string.
|
||||||
|
hex_format_string is like "%020x" for padding 10 characters.
|
||||||
|
"""
|
||||||
|
return binascii.unhexlify((hex_format_string % x).encode('ascii'))
|
||||||
|
|
||||||
|
|
||||||
|
def _fast_hmac(key, msg, digest):
|
||||||
|
"""
|
||||||
|
A trimmed down version of Python's HMAC implementation.
|
||||||
|
|
||||||
|
This function operates on bytes.
|
||||||
|
"""
|
||||||
|
dig1, dig2 = digest(), digest()
|
||||||
|
if len(key) > dig1.block_size:
|
||||||
|
key = digest(key).digest()
|
||||||
|
key += b'\x00' * (dig1.block_size - len(key))
|
||||||
|
dig1.update(key.translate(hmac.trans_36))
|
||||||
|
dig1.update(msg)
|
||||||
|
dig2.update(key.translate(hmac.trans_5C))
|
||||||
|
dig2.update(dig1.digest())
|
||||||
|
return dig2
|
||||||
|
|
||||||
|
|
||||||
|
def _pbkdf2(password, salt, iterations, dklen=0, digest=None):
|
||||||
|
"""
|
||||||
|
Implements PBKDF2 as defined in RFC 2898, section 5.2
|
||||||
|
|
||||||
|
HMAC+SHA256 is used as the default pseudo random function.
|
||||||
|
|
||||||
|
Right now 10,000 iterations is the recommended default which takes
|
||||||
|
100ms on a 2.2Ghz Core 2 Duo. This is probably the bare minimum
|
||||||
|
for security given 1000 iterations was recommended in 2001. This
|
||||||
|
code is very well optimized for CPython and is only four times
|
||||||
|
slower than openssl's implementation.
|
||||||
|
"""
|
||||||
|
|
||||||
|
assert iterations > 0
|
||||||
|
if not digest:
|
||||||
|
digest = hashlib.sha1
|
||||||
|
password = b'' + password
|
||||||
|
salt = b'' + salt
|
||||||
|
hlen = digest().digest_size
|
||||||
|
if not dklen:
|
||||||
|
dklen = hlen
|
||||||
|
if dklen > (2 ** 32 - 1) * hlen:
|
||||||
|
raise OverflowError('dklen too big')
|
||||||
|
l = -(-dklen // hlen)
|
||||||
|
r = dklen - (l - 1) * hlen
|
||||||
|
|
||||||
|
hex_format_string = "%%0%ix" % (hlen * 2)
|
||||||
|
|
||||||
|
def F(i):
|
||||||
|
def U():
|
||||||
|
u = salt + struct.pack(b'>I', i)
|
||||||
|
for j in xrange(int(iterations)):
|
||||||
|
u = _fast_hmac(password, u, digest).digest()
|
||||||
|
yield _bin_to_long(u)
|
||||||
|
return _long_to_bin(reduce(operator.xor, U()), hex_format_string)
|
||||||
|
|
||||||
|
T = [F(x) for x in range(1, l + 1)]
|
||||||
|
return b''.join(T[:-1]) + T[-1][:r]
|
||||||
|
|
||||||
|
pbkdf2 = lambda text, salt, iterations, dklen: base64.b16encode(
|
||||||
|
_pbkdf2(text.encode('utf-8'), salt, iterations, dklen)).lower()
|
@ -141,7 +141,7 @@ class Comments:
|
|||||||
self._remove_stale()
|
self._remove_stale()
|
||||||
return self.get(id)
|
return self.get(id)
|
||||||
|
|
||||||
def like(self, id, remote_addr):
|
def vote(self, upvote, id, remote_addr):
|
||||||
"""+1 a given comment. Returns the new like count (may not change because
|
"""+1 a given comment. Returns the new like count (may not change because
|
||||||
the creater can't vote on his/her own comment and multiple votes from the
|
the creater can't vote on his/her own comment and multiple votes from the
|
||||||
same ip address are ignored as well)."""
|
same ip address are ignored as well)."""
|
||||||
@ -151,23 +151,26 @@ class Comments:
|
|||||||
.fetchone()
|
.fetchone()
|
||||||
|
|
||||||
if rv is None:
|
if rv is None:
|
||||||
return 0
|
return None
|
||||||
|
|
||||||
likes, dislikes, voters = rv
|
likes, dislikes, voters = rv
|
||||||
if likes + dislikes >= 142:
|
if likes + dislikes >= 142:
|
||||||
return likes
|
return {'likes': likes, 'dislikes': dislikes}
|
||||||
|
|
||||||
bf = Bloomfilter(bytearray(voters), likes + dislikes)
|
bf = Bloomfilter(bytearray(voters), likes + dislikes)
|
||||||
if remote_addr in bf:
|
if remote_addr in bf:
|
||||||
return likes
|
return {'likes': likes, 'dislikes': dislikes}
|
||||||
|
|
||||||
bf.add(remote_addr)
|
bf.add(remote_addr)
|
||||||
self.db.execute([
|
self.db.execute([
|
||||||
'UPDATE comments SET',
|
'UPDATE comments SET',
|
||||||
' likes = likes + 1, voters = ?',
|
' likes = likes + 1,' if upvote else 'dislikes = dislikes + 1,',
|
||||||
|
' voters = ?'
|
||||||
'WHERE id=?;'], (buffer(bf.array), id))
|
'WHERE id=?;'], (buffer(bf.array), id))
|
||||||
|
|
||||||
return likes + 1
|
if upvote:
|
||||||
|
return {'likes': likes + 1, 'dislikes': dislikes}
|
||||||
|
return {'likes': likes, 'dislikes': dislikes + 1}
|
||||||
|
|
||||||
def count(self, uri):
|
def count(self, uri):
|
||||||
"""
|
"""
|
||||||
|
@ -5,11 +5,14 @@
|
|||||||
|
|
||||||
define(["lib/q"], function(Q) {
|
define(["lib/q"], function(Q) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
// http://stackoverflow.com/questions/17544965/unhandled-rejection-reasons-should-be-empty
|
// http://stackoverflow.com/questions/17544965/unhandled-rejection-reasons-should-be-empty
|
||||||
Q.stopUnhandledRejectionTracking();
|
// Q.stopUnhandledRejectionTracking();
|
||||||
Q.longStackSupport = true;
|
Q.longStackSupport = true;
|
||||||
|
|
||||||
var endpoint = null,
|
var endpoint = null, remote_addr = null,
|
||||||
|
salt = "Eech7co8Ohloopo9Ol6baimi",
|
||||||
location = window.location.pathname;
|
location = window.location.pathname;
|
||||||
|
|
||||||
// guess Isso API location
|
// guess Isso API location
|
||||||
@ -34,20 +37,17 @@ define(["lib/q"], function(Q) {
|
|||||||
var response = Q.defer();
|
var response = Q.defer();
|
||||||
|
|
||||||
if (! ("withCredentials" in xhr)) {
|
if (! ("withCredentials" in xhr)) {
|
||||||
respone.reject("I won't support IE ≤ 10.")
|
respone.reject("I won't support IE ≤ 10.");
|
||||||
return response.promise;
|
return response.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
xhr.withCredentials = true;
|
|
||||||
|
|
||||||
function onload() {
|
function onload() {
|
||||||
response.resolve({status: xhr.status, body: xhr.responseText});
|
response.resolve({status: xhr.status, body: xhr.responseText});
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
xhr.open(method, url, true);
|
xhr.open(method, url, true);
|
||||||
xhr.overrideMimeType("application/javascript");
|
xhr.withCredentials = true; // fuck you, fuck you, fuck you IE
|
||||||
|
|
||||||
xhr.onreadystatechange = function () {
|
xhr.onreadystatechange = function () {
|
||||||
if (xhr.readyState === 4) {
|
if (xhr.readyState === 4) {
|
||||||
onload();
|
onload();
|
||||||
@ -62,56 +62,56 @@ define(["lib/q"], function(Q) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var qs = function(params) {
|
var qs = function(params) {
|
||||||
rv = "";
|
var rv = "";
|
||||||
for (var key in params) {
|
for (var key in params) {
|
||||||
if (params.hasOwnProperty(key)) {
|
if (params.hasOwnProperty(key)) {
|
||||||
rv += key + "=" + encodeURIComponent(params[key]) + "&";
|
rv += key + "=" + encodeURIComponent(params[key]) + "&";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv.substring(0, rv.length - 1) // chop off trailing "&"
|
return rv.substring(0, rv.length - 1); // chop off trailing "&"
|
||||||
}
|
}
|
||||||
|
|
||||||
var create = function(data) {
|
var create = function(data) {
|
||||||
|
|
||||||
return curl("POST", endpoint + "/new?" + qs({uri: location}), JSON.stringify(data))
|
return curl("POST", endpoint + "/new?" + qs({uri: location}), JSON.stringify(data))
|
||||||
.then(function (rv) {
|
.then(function (rv) {
|
||||||
if (rv.status == 201 || rv.status == 202) {
|
if (rv.status === 201 || rv.status === 202) {
|
||||||
return JSON.parse(rv.body);
|
return JSON.parse(rv.body);
|
||||||
} else {
|
} else {
|
||||||
msg = rv.body.match("<p>(.+)</p>")
|
var msg = rv.body.match("<p>(.+)</p>");
|
||||||
throw {status: rv.status, reason: (msg && msg[1]) || rv.body}
|
throw {status: rv.status, reason: (msg && msg[1]) || rv.body};
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
var modify = function(data) {
|
var modify = function(data) {
|
||||||
// ...
|
// ...
|
||||||
}
|
};
|
||||||
|
|
||||||
var remove = function(id) {
|
var remove = function(id) {
|
||||||
return curl("DELETE", endpoint + "/id/" + id, null)
|
return curl("DELETE", endpoint + "/id/" + id, null)
|
||||||
.then(function(rv) {
|
.then(function(rv) {
|
||||||
if (rv.status == 200) {
|
if (rv.status === 200) {
|
||||||
return JSON.parse(rv.body) == null;
|
return JSON.parse(rv.body) === null;
|
||||||
} else {
|
} else {
|
||||||
throw {status: rv.status, reason: rv.body}
|
throw {status: rv.status, reason: rv.body};
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
var fetchall = function() {
|
var fetch = function() {
|
||||||
|
|
||||||
return curl("GET", endpoint + "/?" + qs({uri: location}), null)
|
return curl("GET", endpoint + "/?" + qs({uri: location}), null)
|
||||||
.then(function (rv) {
|
.then(function (rv) {
|
||||||
if (rv.status == 200) {
|
if (rv.status === 200) {
|
||||||
return JSON.parse(rv.body)
|
return JSON.parse(rv.body);
|
||||||
} else {
|
} else {
|
||||||
msg = rv.body.match("<p>(.+)</p>")
|
var msg = rv.body.match("<p>(.+)</p>");
|
||||||
throw {status: rv.status, reason: (msg && msg[1]) || rv.body}
|
throw {status: rv.status, reason: (msg && msg[1]) || rv.body};
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
var count = function(uri) {
|
var count = function(uri) {
|
||||||
return curl("GET", endpoint + "/count?" + qs({uri: uri}), null)
|
return curl("GET", endpoint + "/count?" + qs({uri: uri}), null)
|
||||||
@ -123,12 +123,30 @@ define(["lib/q"], function(Q) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var like = function(id) {
|
||||||
|
return curl("POST", endpoint + "/id/" + id + "/like", null)
|
||||||
|
.then(function(rv) {
|
||||||
|
return JSON.parse(rv.body);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var dislike = function(id) {
|
||||||
|
return curl("POST", endpoint + "/id/" + id + "/dislike", null)
|
||||||
|
.then(function(rv) {
|
||||||
|
return JSON.parse(rv.body);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
remote_addr = curl("GET", endpoint + "/check-ip", null).then(function(rv) {return rv.body});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
endpoint: endpoint,
|
endpoint: endpoint, remote_addr: remote_addr, salt: salt,
|
||||||
create: create,
|
create: create,
|
||||||
remove: remove,
|
remove: remove,
|
||||||
fetchall: fetchall,
|
fetch: fetch,
|
||||||
count: count
|
count: count,
|
||||||
|
like: like,
|
||||||
|
dislike: dislike
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
@ -1,15 +1,15 @@
|
|||||||
define(["app/api", "lib/HTML"], function(api, HTML) {
|
define(["app/api", "app/dom", "app/markup"], function(api, $, Mark) {
|
||||||
return function() {
|
return function() {
|
||||||
HTML.query("a").each(function(el, i, all) {
|
$.each("a", function(el) {
|
||||||
if (! el.href.match("#isso-thread$")) {
|
if (! el.href.match("#isso-thread$")) {
|
||||||
return;
|
return;
|
||||||
};
|
}
|
||||||
|
|
||||||
var uri = el.href.match("^(.+)#isso-thread$")[1]
|
var uri = el.href.match("^(.+)#isso-thread$")[1]
|
||||||
.replace(/^.*\/\/[^\/]+/, '');
|
.replace(/^.*\/\/[^\/]+/, '');
|
||||||
api.count(uri).then(function(rv) {
|
api.count(uri).then(function(rv) {
|
||||||
el.textContent = rv + (rv > 1 ? " Kommentare" : " Kommentar");
|
el.textContent = Mark.up("{{ i18n-num-comments | pluralize : `n` }}", {n: rv});
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
});
|
});
|
82
isso/js/app/dom.js
Normal file
82
isso/js/app/dom.js
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
define(function() {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
window.Element.prototype.replace = function(el) {
|
||||||
|
var element = DOM.htmlify(el);
|
||||||
|
this.parentNode.replaceChild(element, this);
|
||||||
|
return element;
|
||||||
|
};
|
||||||
|
|
||||||
|
window.Element.prototype.prepend = function(el) {
|
||||||
|
var element = DOM.htmlify(el);
|
||||||
|
this.insertBefore(element, this.firstChild);
|
||||||
|
return element;
|
||||||
|
};
|
||||||
|
|
||||||
|
window.Element.prototype.append = function(el) {
|
||||||
|
var element = DOM.htmlify(el);
|
||||||
|
this.appendChild(element);
|
||||||
|
return element;
|
||||||
|
};
|
||||||
|
|
||||||
|
window.Element.prototype.insertAfter = function(el) {
|
||||||
|
var element = DOM.htmlify(el);
|
||||||
|
this.parentNode.insertBefore(element, this.nextSibling);
|
||||||
|
return element;
|
||||||
|
};
|
||||||
|
|
||||||
|
window.Element.prototype.on = function(type, listener, prevent) {
|
||||||
|
this.addEventListener(type, function(event) {
|
||||||
|
listener();
|
||||||
|
if (prevent === undefined || prevent) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
window.Element.prototype.remove = function() {
|
||||||
|
// Mimimi, I am IE and I am so retarded, mimimi.
|
||||||
|
this.parentNode.removeChild(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
var DOM = function(query, root) {
|
||||||
|
|
||||||
|
if (! root) {
|
||||||
|
root = window.document;
|
||||||
|
}
|
||||||
|
|
||||||
|
var elements = root.querySelectorAll(query);
|
||||||
|
|
||||||
|
if (elements.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elements.length === 1) {
|
||||||
|
return elements[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return elements;
|
||||||
|
};
|
||||||
|
|
||||||
|
DOM.htmlify = function(html) {
|
||||||
|
|
||||||
|
if (html instanceof window.Element) {
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
var wrapper = DOM.new("div");
|
||||||
|
wrapper.innerHTML = html;
|
||||||
|
return wrapper.firstChild;
|
||||||
|
};
|
||||||
|
|
||||||
|
DOM.new = function(tag) {
|
||||||
|
return document.createElement(tag);
|
||||||
|
};
|
||||||
|
|
||||||
|
DOM.each = function(tag, func) {
|
||||||
|
Array.prototype.forEach.call(document.getElementsByTagName(tag), func);
|
||||||
|
};
|
||||||
|
|
||||||
|
return DOM;
|
||||||
|
});
|
@ -1,51 +0,0 @@
|
|||||||
define(["lib/HTML"], function(HTML) {
|
|
||||||
|
|
||||||
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 = 8;
|
|
||||||
// scrollIntoView enhancement
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
});
|
|
70
isso/js/app/i18n.js
Normal file
70
isso/js/app/i18n.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
define(function() {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// pluralization functions for each language you support
|
||||||
|
var plurals = {
|
||||||
|
"en": function (msgs, n) {
|
||||||
|
return msgs[n === 1 ? 0 : 1];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
plurals["de"] = plurals["en"];
|
||||||
|
|
||||||
|
// the user's language. you can replace this with your own code
|
||||||
|
var lang = (navigator.language || navigator.userLanguage).split("-")[0];
|
||||||
|
|
||||||
|
// fall back to English
|
||||||
|
if (!plurals[lang]) {
|
||||||
|
lang = "en";
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
plurals: plurals,
|
||||||
|
lang: lang,
|
||||||
|
de: {
|
||||||
|
"postbox-text" : "Kommentar hier eintippen (mindestens 3 Zeichen)",
|
||||||
|
"postbox-author" : "Name (optional)",
|
||||||
|
"postbox-email" : "Email (optional)",
|
||||||
|
"postbox-submit": "Abschicken.",
|
||||||
|
|
||||||
|
"num-comments": "1 Kommentar\n{{ n }} Kommentare",
|
||||||
|
"no-comments": "Keine Kommentare bis jetzt",
|
||||||
|
|
||||||
|
"comment-reply": "Antworten",
|
||||||
|
"comment-delete": "Löschen",
|
||||||
|
"comment-confirm": "Bestätigen",
|
||||||
|
"comment-close": "Schließen",
|
||||||
|
|
||||||
|
"date-now": "eben jetzt",
|
||||||
|
"date-minute": "vor einer Minute\nvor {{ n }} Minuten",
|
||||||
|
"date-hour": "vor einer Stunde\nvor {{ n }} Stunden",
|
||||||
|
"date-day": "Gestern\nvor {{ n }} Tagen",
|
||||||
|
"date-week": "letzte Woche\nvor {{ n }} Wochen",
|
||||||
|
"date-month": "letzten Monat\nvor {{ n }} Monaten",
|
||||||
|
"date-year": "letztes Jahr\nvor {{ n }} Jahren"
|
||||||
|
},
|
||||||
|
en: {
|
||||||
|
"postbox-text": "Type Comment Here (at least 3 chars)",
|
||||||
|
"postbox-author": "Name (optional)",
|
||||||
|
"postbox-email": "E-mail (optional)",
|
||||||
|
"postbox-submit": "Post Comment.",
|
||||||
|
|
||||||
|
"num-comments": "One Comment\n{{ n }} Comments",
|
||||||
|
"no-comments": "No Comments Yet",
|
||||||
|
|
||||||
|
"comment-reply": "Reply",
|
||||||
|
"comment-delete": "Delete",
|
||||||
|
"comment-confirm": "Confirm",
|
||||||
|
"comment-close": "Close",
|
||||||
|
|
||||||
|
"date-now": "now",
|
||||||
|
"date-minute": "a minute ago\n{{ n }} minutes ago",
|
||||||
|
"date-hour": "an hour ago\n{{ n }} hours ago",
|
||||||
|
"date-day": "Yesterday\n{{ n }} days ago",
|
||||||
|
"date-week": "last week\n{{ n }} weeks ago",
|
||||||
|
"date-month": "last month\n{{ n }} months ago",
|
||||||
|
"date-year": "last year\n{{ n }} years ago"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
@ -5,172 +5,224 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
define(["lib/q", "lib/HTML", "helper/utils", "helper/identicons", "./api", "./forms"], function(Q, HTML, utils, identicons, api, forms) {
|
define(["lib/pbkdf2", "lib/identicons", "text/html", "./dom", "./utils", "./api", "./markup", "./i18n"],
|
||||||
|
function(pbkdf2, identicons, templates, $, utils, api, Mark, i18n) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var msgs = i18n[i18n.lang];
|
||||||
|
|
||||||
|
var toggle = function(el, on, off) {
|
||||||
|
if (el.classList.contains("off") || ! el.classList.contains("on")) {
|
||||||
|
el.classList.remove("off");
|
||||||
|
el.classList.add("on");
|
||||||
|
on(el);
|
||||||
|
} else {
|
||||||
|
el.classList.remove("on");
|
||||||
|
el.classList.add("off");
|
||||||
|
off(el);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var Postbox = function(parent) {
|
||||||
|
|
||||||
|
var el = $.htmlify(Mark.up(templates["postbox"]));
|
||||||
|
|
||||||
|
// add a blank identicon to not waste CPU cycles
|
||||||
|
// XXX show a space invader instead :>
|
||||||
|
$(".avatar > canvas", el).replace(identicons.blank(48, 48));
|
||||||
|
|
||||||
|
// on text area focus, generate identicon from IP address
|
||||||
|
$(".textarea-wrapper > textarea", el).on("focus", function() {
|
||||||
|
if ($(".avatar canvas", el).classList.contains("blank")) {
|
||||||
|
$(".avatar canvas", el).replace(
|
||||||
|
identicons.generate(pbkdf2(api.remote_addr, api.salt, 1000, 6), 48, 48));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// update identicon, when the user provices an email address
|
||||||
|
var active;
|
||||||
|
$(".input-wrapper > [type=email]", el).on("keyup", function() {
|
||||||
|
if (active) {
|
||||||
|
clearTimeout(active);
|
||||||
|
}
|
||||||
|
active = setTimeout(function() {
|
||||||
|
pbkdf2($(".input-wrapper > [type=email]", el).value || api.remote_addr, api.salt, 1000, 6)
|
||||||
|
.then(function(rv) {
|
||||||
|
$(".avatar canvas", el).replace(identicons.generate(rv, 48, 48));
|
||||||
|
});
|
||||||
|
}, 200);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
$(".input-wrapper > [type=email]", el).on("keydown", function() {
|
||||||
|
clearTimeout(active);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
el.validate = function() {
|
||||||
|
if ($("textarea", this).value.length < 3) {
|
||||||
|
$("textarea", this).focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
$("[type=submit]", el).on("click", function() {
|
||||||
|
if (! el.validate()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
api.create({
|
||||||
|
author: $("[name=author]", el).value || null,
|
||||||
|
email: $("[name=email]", el).value || null,
|
||||||
|
text: $("textarea", el).value,
|
||||||
|
parent: parent || null
|
||||||
|
}).then(function(comment) {
|
||||||
|
$("[name=author]", el).value = "";
|
||||||
|
$("[name=email]", el).value = "";
|
||||||
|
$("textarea", el).value = "";
|
||||||
|
$("textarea", el).rows = 2;
|
||||||
|
$("textarea", el).blur();
|
||||||
|
insert(comment, true);
|
||||||
|
|
||||||
|
if (parent !== null) {
|
||||||
|
el.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return el;
|
||||||
|
};
|
||||||
|
|
||||||
|
var map = {id: {}, name: {}};
|
||||||
|
|
||||||
var insert = function(comment, scrollIntoView) {
|
var insert = function(comment, scrollIntoView) {
|
||||||
/*
|
|
||||||
* insert a comment (JSON/object) into the #isso-thread or below a parent (#isso-N), renders some HTML and
|
|
||||||
* registers events to reply to, edit and remove a comment.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
map.name[comment.id] = comment.author;
|
||||||
if (comment.parent) {
|
if (comment.parent) {
|
||||||
entrypoint = HTML.query("#isso-" + comment.parent).add("div.isso-follow-up");
|
comment["replyto"] = map.name[comment.parent];
|
||||||
} else {
|
|
||||||
entrypoint = HTML.query("div#isso-root")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entrypoint.add("article.isso-comment#isso-" + comment.id)
|
var el = $.htmlify(Mark.up(templates["comment"], comment));
|
||||||
.add("header+span.avatar+div.text+footer")
|
|
||||||
var node = HTML.query("#isso-" + comment.id),
|
|
||||||
date = new Date(parseInt(comment.created) * 1000);
|
|
||||||
|
|
||||||
if (comment.mode == 2) {
|
|
||||||
node.header.add("span.note").textContent = 'Kommentar muss noch freigeschaltet werden';
|
|
||||||
} else if (comment.mode == 4) { // deleted
|
|
||||||
node.classList.add('deleted');
|
|
||||||
node.header.add("span.note").textContent = "Kommentar gelöscht."
|
|
||||||
}
|
|
||||||
|
|
||||||
if (comment.website) {
|
|
||||||
var el = node.header.add("a.author")
|
|
||||||
el.textContent= comment.author || 'Anonymous';
|
|
||||||
el.href = comment.website;
|
|
||||||
el.rel = "nofollow"
|
|
||||||
} else {
|
|
||||||
node.header.add("span.author").innerHTML = comment.author || 'Anonymous';
|
|
||||||
}
|
|
||||||
|
|
||||||
node.header.add("span.spacer").textContent = "•";
|
|
||||||
|
|
||||||
var permalink = node.header.add("a.permalink");
|
|
||||||
permalink.href = '#isso-' + comment.id;
|
|
||||||
permalink.add("date[datetime=" + date.getUTCFullYear() + "-" + date.getUTCMonth() + "-" + date.getUTCDay() + "]")
|
|
||||||
var refresh = function() {
|
var refresh = function() {
|
||||||
permalink.date.textContent = utils.ago(date);
|
$(".permalink > date", el).textContent = utils.ago(new Date(parseInt(comment.created, 10) * 1000));
|
||||||
setTimeout(refresh, 60*1000)
|
setTimeout(refresh, 60*1000);
|
||||||
}; refresh();
|
}; refresh();
|
||||||
|
|
||||||
var canvas = node.query("span.avatar").add("canvas[hash=" + comment.hash + "]");
|
$("div.avatar > canvas", el).replace(identicons.generate(comment.hash, 48, 48));
|
||||||
canvas.width = canvas.height = 48;
|
|
||||||
identicons.generate(canvas.getContext('2d'), comment.hash);
|
|
||||||
|
|
||||||
if (comment.mode == 4) {
|
var entrypoint;
|
||||||
node.query(".text").add("p").value = " "
|
if (comment.parent === null) {
|
||||||
|
entrypoint = $("#isso-root");
|
||||||
} else {
|
} else {
|
||||||
node.query(".text").innerHTML = comment.text;
|
var key = comment.parent;
|
||||||
|
while (key in map.id) {
|
||||||
|
key = map.id[key];
|
||||||
|
}
|
||||||
|
map.id[comment.id] = comment.parent;
|
||||||
|
entrypoint = $("#isso-" + key + " > .text-wrapper > .isso-follow-up");
|
||||||
}
|
}
|
||||||
|
|
||||||
node.footer.add("a.liek{Liek}").href = "#";
|
entrypoint.append(el);
|
||||||
node.footer.add("a.reply{Antworten}").href = "#";
|
|
||||||
|
|
||||||
if (scrollIntoView) {
|
if (scrollIntoView) {
|
||||||
node.scrollIntoView(false);
|
el.scrollIntoView();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utils.read(comment.id)) {
|
var footer = $("#isso-" + comment.id + " > .text-wrapper > footer"),
|
||||||
node.footer.add("a.delete{Löschen}").href = "#";
|
header = $("#isso-" + comment.id + " > .text-wrapper > header");
|
||||||
node.footer.add("a.edit{Bearbeiten}").href = "#";
|
|
||||||
|
|
||||||
var delbtn = node.query("a.delete"),
|
var form = new Postbox(comment.id);
|
||||||
editbtn = node.query("a.edit");
|
$("a.reply", footer).on("click", function() {
|
||||||
|
toggle(
|
||||||
delbtn.addEventListener("click", function(event) {
|
$("a.reply", footer),
|
||||||
if (delbtn.textContent == "Bestätigen") {
|
function(reply) {
|
||||||
api.remove(comment.id).then(function(rv) {
|
footer.insertAfter(form);
|
||||||
if (rv) {
|
reply.textContent = msgs["comment-close"];
|
||||||
node.remove();
|
},
|
||||||
} else {
|
function(reply) {
|
||||||
node.classList.add('deleted');
|
form.remove();
|
||||||
node.header.add("span.note").textContent = "Kommentar gelöscht.";
|
reply.textContent = msgs["comment-reply"];
|
||||||
HTML.query("#isso-" + comment.id + " > div.text").innerHTML = "<p> </p>"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
delbtn.textContent = "Bestätigen"
|
|
||||||
setTimeout(function() {delbtn.textContent = "Löschen"}, 1500)
|
|
||||||
}
|
}
|
||||||
event.preventDefault();
|
);
|
||||||
})
|
});
|
||||||
|
|
||||||
|
if (comment.parent !== null) {
|
||||||
|
$("a.parent", header).on("mouseover", function() {
|
||||||
|
$("#isso-" + comment.parent).classList.add("parent-highlight");
|
||||||
|
});
|
||||||
|
$("a.parent", header).on("mouseout", function() {
|
||||||
|
$("#isso-" + comment.parent).classList.remove("parent-highlight");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ability to answer directly to a comment
|
var votes = function (value) {
|
||||||
HTML.query("#isso-" + comment.id + " a.reply").addEventListener("click", function(event) {
|
var span = $("span.votes", footer);
|
||||||
|
if (span === null) {
|
||||||
// remove active form when clicked again or reply to another comment
|
if (value === 0) {
|
||||||
var active = HTML.query(".isso-active-msgbox"); // [] when empty, element if not
|
span.remove();
|
||||||
|
return;
|
||||||
if (! (active instanceof Array)) {
|
} else {
|
||||||
active.query("div.isso-comment-box").remove()
|
footer.prepend($.htmlify('<span class="votes">' + value + '</span>'));
|
||||||
active.classList.remove("isso-active-msgbox");
|
}
|
||||||
active.query("a.reply").textContent = "Antworten"
|
} else {
|
||||||
|
if (value === 0) {
|
||||||
if (active.id == "isso-" + comment.id) {
|
span.remove();
|
||||||
event.preventDefault();
|
} else {
|
||||||
return;
|
span.textContent = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var msgbox = forms.msgbox({})
|
$("a.upvote", footer).on("click", function() {
|
||||||
HTML.query("#isso-" + comment.id).footer.appendChild(msgbox);
|
api.like(comment.id).then(function(rv) {
|
||||||
HTML.query("#isso-" + comment.id).classList.add("isso-active-msgbox");
|
votes(rv.likes - rv.dislikes);
|
||||||
HTML.query("#isso-" + comment.id + " a.reply").textContent = "Schließen";
|
|
||||||
|
|
||||||
// msgbox.scrollIntoView(false);
|
|
||||||
msgbox.query("input[type=submit]").addEventListener("click", function(event) {
|
|
||||||
forms.validate(msgbox) && api.create({
|
|
||||||
author: msgbox.query("[name=author]").value || null,
|
|
||||||
email: msgbox.query("[name=email]").value || null,
|
|
||||||
website: msgbox.query("[name=website]").value || null,
|
|
||||||
text: msgbox.query("textarea").value,
|
|
||||||
parent: comment.id })
|
|
||||||
.then(function(rv) {
|
|
||||||
// remove box on submit
|
|
||||||
msgbox.parentNode.parentNode.classList.remove("isso-active-msgbox");
|
|
||||||
msgbox.parentNode.parentNode.query("a.reply").textContent = "Antworten"
|
|
||||||
msgbox.remove()
|
|
||||||
insert(rv, true);
|
|
||||||
})
|
|
||||||
event.preventDefault()
|
|
||||||
});
|
});
|
||||||
event.preventDefault();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var init = function() {
|
|
||||||
|
|
||||||
var rootmsgbox = forms.msgbox({});
|
|
||||||
var h4 = HTML.query("#isso-thread").add("h4")
|
|
||||||
HTML.query("#isso-thread").add("div#isso-root").add(rootmsgbox);
|
|
||||||
rootmsgbox.query("input[type=submit]").addEventListener("click", function(event) {
|
|
||||||
forms.validate(rootmsgbox) && api.create({
|
|
||||||
author: rootmsgbox.query("[name=author]").value || null,
|
|
||||||
email: rootmsgbox.query("[name=email]").value || null,
|
|
||||||
website: rootmsgbox.query("[name=website]").value || null,
|
|
||||||
text: rootmsgbox.query("textarea").value,
|
|
||||||
parent: null })
|
|
||||||
.then(function(rv) {
|
|
||||||
rootmsgbox.query("[name=author]").value = "";
|
|
||||||
rootmsgbox.query("[name=email]").value = "";
|
|
||||||
rootmsgbox.query("[name=website]").value = "";
|
|
||||||
rootmsgbox.query("textarea").value = "";
|
|
||||||
rootmsgbox.query("textarea").rows = 2;
|
|
||||||
rootmsgbox.query("textarea").blur();
|
|
||||||
insert(rv, true);
|
|
||||||
})
|
|
||||||
event.preventDefault()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
api.fetchall().then(function(comments) {
|
$("a.downvote", footer).on("click", function() {
|
||||||
h4.textContent = comments.length + " Kommentare zu \"" + utils.heading() + "\"";
|
api.dislike(comment.id).then(function(rv) {
|
||||||
for (var i in comments) {
|
votes(rv.likes - rv.dislikes);
|
||||||
insert(comments[i])
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (! utils.cookie(comment.id)) {
|
||||||
|
// $("a.edit", footer).remove();
|
||||||
|
$("a.delete", footer).remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("a.delete", footer).on("click", function() {
|
||||||
|
if ($("a.delete", footer).textContent === msgs["comment-confirm"]) {
|
||||||
|
api.remove(comment.id).then(function(rv) {
|
||||||
|
if (rv) {
|
||||||
|
el.remove();
|
||||||
|
} else {
|
||||||
|
$("span.note", el).textContent = "Kommentar gelöscht.";
|
||||||
|
$(".text", el).innerHTML = "<p> </p>";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$("a.delete", footer).textContent = msgs["comment-confirm"];
|
||||||
|
setTimeout(function() {
|
||||||
|
$("a.delete", footer).textContent = msgs["comment-delete"];
|
||||||
|
}, 1500);
|
||||||
}
|
}
|
||||||
}).fail(function(rv) {
|
});
|
||||||
h4.textContent = "Kommentiere \"" + utils.heading() + "\"";
|
|
||||||
})
|
return;
|
||||||
}
|
|
||||||
|
// var votes = node.footer.add("span.votes{" + (comment.likes - comment.dislikes) + "}");
|
||||||
|
// node.footer.add(forms.like(comment.id, function(rv) {
|
||||||
|
// votes.textContent = rv.likes - rv.dislikes;
|
||||||
|
// }))
|
||||||
|
// node.footer.add(forms.dislike(comment.id, function(rv) {
|
||||||
|
// votes.textContent = rv.likes - rv.dislikes;
|
||||||
|
// }))
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init: init
|
insert: insert,
|
||||||
}
|
Postbox: Postbox
|
||||||
|
};
|
||||||
});
|
});
|
58
isso/js/app/markup.js
Normal file
58
isso/js/app/markup.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
define(["lib/markup", "./i18n", "text/svg"], function(Mark, i18n, svg) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var pad = function(n, width, z) {
|
||||||
|
z = z || '0';
|
||||||
|
n = n + '';
|
||||||
|
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
|
||||||
|
};
|
||||||
|
|
||||||
|
// circumvent https://github.com/adammark/Markup.js/issues/22
|
||||||
|
function merge(obj) {
|
||||||
|
var result = {};
|
||||||
|
for (var prefix in obj) {
|
||||||
|
for (var attrname in obj[prefix]) {
|
||||||
|
result[prefix + "-" + attrname] = obj[prefix][attrname];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mark.delimiter = ":";
|
||||||
|
Mark.includes = merge({
|
||||||
|
i18n: i18n[i18n.lang],
|
||||||
|
svg: svg
|
||||||
|
});
|
||||||
|
|
||||||
|
Mark.pipes.datetime = function(date) {
|
||||||
|
if (typeof date !== "object") {
|
||||||
|
date = new Date(parseInt(date, 10) * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [date.getUTCFullYear(), pad(date.getUTCMonth(), 2), pad(date.getUTCDay(), 2)].join("-");
|
||||||
|
};
|
||||||
|
|
||||||
|
Mark.pipes.substract = function(a, b) {
|
||||||
|
return parseInt(a, 10) - parseInt(b, 10);
|
||||||
|
};
|
||||||
|
|
||||||
|
Mark.pipes.pluralize = function(str, n) {
|
||||||
|
return i18n.plurals[i18n.lang](str.split("\n"), +n).trim();
|
||||||
|
};
|
||||||
|
|
||||||
|
var strip = function(string) {
|
||||||
|
// allow whitespace between Markup.js delimiters such as
|
||||||
|
// {{ var | pipe : arg }} instead of {{var|pipe:arg}}
|
||||||
|
return string.replace(/\{\{\s*(.+?)\s*\}\}/g, function(match, val) {
|
||||||
|
return ("{{" + val + "}}").replace(/\s*\|\s*/g, "|")
|
||||||
|
.replace(/\s*\:\s*/g, ":");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
up: function(template, context) {
|
||||||
|
return Mark.up(strip(template), context);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
45
isso/js/app/utils.js
Normal file
45
isso/js/app/utils.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/* Copyright 2013, Martin Zimmermann <info@posativ.org>. All rights reserved.
|
||||||
|
* License: BSD Style, 2 clauses. See isso/__init__.py.
|
||||||
|
*
|
||||||
|
* utility functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
define(["./markup"], function(Mark) {
|
||||||
|
|
||||||
|
// return `cookie` string if set
|
||||||
|
var cookie = function(cookie) {
|
||||||
|
return (document.cookie.match('(^|; )' + cookie + '=([^;]*)') || 0)[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
var ago = function(date) {
|
||||||
|
|
||||||
|
var diff = (((new Date()).getTime() - date.getTime()) / 1000),
|
||||||
|
day_diff = Math.floor(diff / 86400);
|
||||||
|
|
||||||
|
if (isNaN(day_diff) || day_diff < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var i18n = function(msgid, n) {
|
||||||
|
if (! n) {
|
||||||
|
return Mark.up("{{ i18n-" + msgid + " }}");
|
||||||
|
} else {
|
||||||
|
return Mark.up("{{ i18n-" + msgid + " | pluralize : `n` }}", {n: n});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return day_diff === 0 && (
|
||||||
|
diff < 60 && i18n("date-now") ||
|
||||||
|
diff < 3600 && i18n("date-minute", Math.floor(diff / 60)) ||
|
||||||
|
diff < 86400 && i18n("date-hour", Math.floor(diff / 3600))) ||
|
||||||
|
day_diff === 1 && i18n("date-day", day_diff) ||
|
||||||
|
day_diff < 31 && i18n("date-week", Math.ceil(day_diff / 7)) ||
|
||||||
|
day_diff < 365 && i18n("date-month", Math.ceil(day_diff / 30)) ||
|
||||||
|
i18n("date-year", Math.ceil(day_diff / 365.25));
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
cookie: cookie,
|
||||||
|
ago: ago
|
||||||
|
};
|
||||||
|
});
|
@ -3,5 +3,7 @@
|
|||||||
name: "lib/almond",
|
name: "lib/almond",
|
||||||
include: ['embed'],
|
include: ['embed'],
|
||||||
out: "embed.min.js",
|
out: "embed.min.js",
|
||||||
|
|
||||||
|
optimizeAllPluginResources: true,
|
||||||
wrap: true
|
wrap: true
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,21 @@
|
|||||||
require(["lib/ready", "app/isso", "app/count"], function(domready, isso, count) {
|
require(["lib/ready", "app/api", "app/isso", "app/count", "app/dom", "app/markup"], function(domready, api, isso, count, $, Mark) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
domready(function() {
|
domready(function() {
|
||||||
count();
|
count();
|
||||||
isso.init();
|
|
||||||
})
|
$("#isso-thread").append($.new('h4'));
|
||||||
|
$("#isso-thread").append(new isso.Postbox(null));
|
||||||
|
$("#isso-thread").append('<div id="isso-root"></div>');
|
||||||
|
|
||||||
|
api.fetch().then(function(comments) {
|
||||||
|
$("#isso-thread > h4").textContent = Mark.up("{{ i18n-num-comments | pluralize : `n` }}", {n: comments.length});
|
||||||
|
for (var i=0; i < comments.length; i++) {
|
||||||
|
isso.insert(comments[i], false);
|
||||||
|
}
|
||||||
|
}).fail(function() {
|
||||||
|
$("#isso-thread > h4").textContent = Mark.up("{{ i18n-no-comments }}");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
@ -1,83 +0,0 @@
|
|||||||
/* 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)
|
|
||||||
return;
|
|
||||||
|
|
||||||
return day_diff == 0 && (
|
|
||||||
diff < 60 && "eben jetzt" ||
|
|
||||||
diff < 120 && "vor einer Minute" ||
|
|
||||||
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" ||
|
|
||||||
day_diff < 365 && "vor " + Math.ceil(day_diff / 30) + " Monaten" ||
|
|
||||||
"vor " + Math.ceil(day_diff / 365.25) + " Jahren";
|
|
||||||
},
|
|
||||||
|
|
||||||
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 (el != null) {
|
|
||||||
|
|
||||||
visited.push(el);
|
|
||||||
|
|
||||||
if (el == document.documentElement) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
var rv = recurse(el);
|
|
||||||
if (rv) {
|
|
||||||
return rv.textContent.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
el = el.parentNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Untitled."
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,7 +1,9 @@
|
|||||||
define(function() {
|
define(["lib/q"], function(Q) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
// JS Identicon generation via Gregory Schier (http://codepen.io/gschier/pen/GLvAy)
|
// JS Identicon generation via Gregory Schier (http://codepen.io/gschier/pen/GLvAy)
|
||||||
// modified to work with a given seed using Jenkins hashing.
|
// extended to produce the same identicon for a given hash
|
||||||
|
|
||||||
// Size of a grid square in pixels
|
// Size of a grid square in pixels
|
||||||
var SQUARE = 8;
|
var SQUARE = 8;
|
||||||
@ -10,28 +12,11 @@ define(function() {
|
|||||||
var GRID = 5;
|
var GRID = 5;
|
||||||
|
|
||||||
// Padding on the edge of the canvas in px
|
// Padding on the edge of the canvas in px
|
||||||
var PADDING = SQUARE/2;
|
var PADDING = 4;
|
||||||
|
|
||||||
/* Jenkins 18-bit hash */
|
|
||||||
var jenkins = function(key) {
|
|
||||||
var hash = 0;
|
|
||||||
|
|
||||||
for (var i=0; i<key.length; ++i) {
|
|
||||||
hash += key.charCodeAt(i);
|
|
||||||
hash += (hash << 10);
|
|
||||||
hash ^= (hash >> 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
hash += (hash << 3);
|
|
||||||
hash ^= (hash >> 11);
|
|
||||||
hash += (hash << 15);
|
|
||||||
|
|
||||||
return (hash >>> 0) % Math.pow(2, 18);
|
|
||||||
}
|
|
||||||
|
|
||||||
var pad = function(n, width) {
|
var pad = function(n, width) {
|
||||||
return n.length >= width ? n : new Array(width - n.length + 1).join("0") + n;
|
return n.length >= width ? n : new Array(width - n.length + 1).join("0") + n;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill in a square on the canvas.
|
* Fill in a square on the canvas.
|
||||||
@ -51,13 +36,31 @@ define(function() {
|
|||||||
/**
|
/**
|
||||||
* Pick random squares to fill in.
|
* Pick random squares to fill in.
|
||||||
*/
|
*/
|
||||||
var generateIdenticon = function(ctx, key) {
|
var generateIdenticon = function(key, height, width) {
|
||||||
|
|
||||||
var hash = pad(jenkins(key).toString(2), 18),
|
var canvas = document.createElement("canvas"),
|
||||||
index = 0, color = null;
|
ctx = canvas.getContext("2d");
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
|
||||||
// via http://colrd.com/palette/19308/
|
// FILL CANVAS BG
|
||||||
switch (hash.substring(hash.length - 3, hash.length)) {
|
ctx.beginPath();
|
||||||
|
ctx.rect(0, 0, height, width);
|
||||||
|
ctx.fillStyle = '#F0F0F0';
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
if (typeof key === null) {
|
||||||
|
return canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q.when(key, function(key) {
|
||||||
|
var hash = pad((parseInt(key, 16) % Math.pow(2, 18)).toString(2), 18),
|
||||||
|
index = 0, color = null;
|
||||||
|
|
||||||
|
canvas.setAttribute("data-hash", key);
|
||||||
|
|
||||||
|
// via http://colrd.com/palette/19308/
|
||||||
|
switch (hash.substring(hash.length - 3, hash.length)) {
|
||||||
case "000":
|
case "000":
|
||||||
color = "#9abf88";
|
color = "#9abf88";
|
||||||
break;
|
break;
|
||||||
@ -82,35 +85,36 @@ define(function() {
|
|||||||
case "111":
|
case "111":
|
||||||
color = "#447c69";
|
color = "#447c69";
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
// FILL CANVAS BG
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.rect(0, 0, 48, 48);
|
|
||||||
ctx.fillStyle = '#F0F0F0';
|
|
||||||
ctx.fill();
|
|
||||||
|
|
||||||
// FILL THE SQUARES
|
|
||||||
for (var x=0; x<Math.ceil(GRID/2); x++) {
|
|
||||||
for (var y=0; y<GRID; y++) {
|
|
||||||
|
|
||||||
if (hash.charAt(index) == "1") {
|
|
||||||
fillBlock(x, y, color, ctx);
|
|
||||||
|
|
||||||
// FILL RIGHT SIDE SYMMETRICALLY
|
|
||||||
if (x < Math.floor(GRID/2)) {
|
|
||||||
fillBlock((GRID-1) - x, y, color, ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return ctx;
|
// FILL THE SQUARES
|
||||||
|
for (var x=0; x<Math.ceil(GRID/2); x++) {
|
||||||
|
for (var y=0; y<GRID; y++) {
|
||||||
|
|
||||||
|
if (hash.charAt(index) === "1") {
|
||||||
|
fillBlock(x, y, color, ctx);
|
||||||
|
|
||||||
|
// FILL RIGHT SIDE SYMMETRICALLY
|
||||||
|
if (x < Math.floor(GRID/2)) {
|
||||||
|
fillBlock((GRID-1) - x, y, color, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return canvas;
|
||||||
|
};
|
||||||
|
|
||||||
|
var generateBlank = function(height, width) {
|
||||||
|
var el = generateIdenticon(null, height, width);
|
||||||
|
el.className = "blank";
|
||||||
|
return el;
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
generate: generateIdenticon,
|
generate: generateIdenticon,
|
||||||
hash: jenkins
|
blank: generateBlank
|
||||||
};
|
};
|
||||||
})
|
});
|
476
isso/js/lib/markup.js
Normal file
476
isso/js/lib/markup.js
Normal file
@ -0,0 +1,476 @@
|
|||||||
|
/*
|
||||||
|
Markup.js v1.5.16: http://github.com/adammark/Markup.js
|
||||||
|
MIT License
|
||||||
|
(c) 2011 - 2013 Adam Mark
|
||||||
|
*/
|
||||||
|
var Mark = {
|
||||||
|
// Templates to include, by name. A template is a string.
|
||||||
|
includes: {},
|
||||||
|
|
||||||
|
// Global variables, by name. Global variables take precedence over context variables.
|
||||||
|
globals: {},
|
||||||
|
|
||||||
|
// The delimiter to use in pipe expressions, e.g. {{if color|like>red}}.
|
||||||
|
delimiter: ">",
|
||||||
|
|
||||||
|
// Collapse white space between HTML elements in the resulting string.
|
||||||
|
compact: false,
|
||||||
|
|
||||||
|
// Shallow-copy an object.
|
||||||
|
_copy: function (a, b) {
|
||||||
|
b = b || [];
|
||||||
|
|
||||||
|
for (var i in a) {
|
||||||
|
b[i] = a[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return b;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Get the value of a number or size of an array. This is a helper function for several pipes.
|
||||||
|
_size: function (a) {
|
||||||
|
return a instanceof Array ? a.length : (a || 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
// This object represents an iteration. It has an index and length.
|
||||||
|
_iter: function (idx, size) {
|
||||||
|
this.idx = idx;
|
||||||
|
this.size = size;
|
||||||
|
this.length = size;
|
||||||
|
this.sign = "#";
|
||||||
|
|
||||||
|
// Print the index if "#" or the count if "##".
|
||||||
|
this.toString = function () {
|
||||||
|
return this.idx + this.sign.length - 1;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
// Pass a value through a series of pipe expressions, e.g. _pipe(123, ["add>10","times>5"]).
|
||||||
|
_pipe: function (val, expressions) {
|
||||||
|
var expression, parts, fn, result;
|
||||||
|
|
||||||
|
// If we have expressions, pull out the first one, e.g. "add>10".
|
||||||
|
if ((expression = expressions.shift())) {
|
||||||
|
|
||||||
|
// Split the expression into its component parts, e.g. ["add", "10"].
|
||||||
|
parts = expression.split(this.delimiter);
|
||||||
|
|
||||||
|
// Pull out the function name, e.g. "add".
|
||||||
|
fn = parts.shift().trim();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Run the function, e.g. add(123, 10) ...
|
||||||
|
result = Mark.pipes[fn].apply(null, [val].concat(parts));
|
||||||
|
|
||||||
|
// ... then pipe again with remaining expressions.
|
||||||
|
val = this._pipe(result, expressions);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the piped value.
|
||||||
|
return val;
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO doc
|
||||||
|
_eval: function (context, filters, child) {
|
||||||
|
var result = this._pipe(context, filters),
|
||||||
|
ctx = result,
|
||||||
|
i = -1,
|
||||||
|
j,
|
||||||
|
opts;
|
||||||
|
|
||||||
|
if (result instanceof Array) {
|
||||||
|
result = "";
|
||||||
|
j = ctx.length;
|
||||||
|
|
||||||
|
while (++i < j) {
|
||||||
|
opts = {
|
||||||
|
iter: new this._iter(i, j)
|
||||||
|
};
|
||||||
|
result += child ? Mark.up(child, ctx[i], opts) : ctx[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (result instanceof Object) {
|
||||||
|
result = Mark.up(child, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Process the contents of an IF or IF/ELSE block.
|
||||||
|
_test: function (bool, child, context, options) {
|
||||||
|
// Process the child string, then split it into the IF and ELSE parts.
|
||||||
|
var str = Mark.up(child, context, options).split(/\{\{\s*else\s*\}\}/);
|
||||||
|
|
||||||
|
// Return the IF or ELSE part. If no ELSE, return an empty string.
|
||||||
|
return (bool === false ? str[1] : str[0]) || "";
|
||||||
|
},
|
||||||
|
|
||||||
|
// Determine the extent of a block expression, e.g. "{{foo}}...{{/foo}}"
|
||||||
|
_bridge: function (tpl, tkn) {
|
||||||
|
var exp = "{{\\s*" + tkn + "([^/}]+\\w*)?}}|{{/" + tkn + "\\s*}}",
|
||||||
|
re = new RegExp(exp, "g"),
|
||||||
|
tags = tpl.match(re) || [],
|
||||||
|
t,
|
||||||
|
i,
|
||||||
|
a = 0,
|
||||||
|
b = 0,
|
||||||
|
c = -1,
|
||||||
|
d = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < tags.length; i++) {
|
||||||
|
t = i;
|
||||||
|
c = tpl.indexOf(tags[t], c + 1);
|
||||||
|
|
||||||
|
if (tags[t].indexOf("{{/") > -1) {
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a === b) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a = tpl.indexOf(tags[0]);
|
||||||
|
b = a + tags[0].length;
|
||||||
|
d = c + tags[t].length;
|
||||||
|
|
||||||
|
// Return the block, e.g. "{{foo}}bar{{/foo}}" and its child, e.g. "bar".
|
||||||
|
return [tpl.substring(a, d), tpl.substring(b, c)];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Inject a template string with contextual data and return a new string.
|
||||||
|
Mark.up = function (template, context, options) {
|
||||||
|
context = context || {};
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
// Match all tags like "{{...}}".
|
||||||
|
var re = /\{\{(.+?)\}\}/g,
|
||||||
|
// All tags in the template.
|
||||||
|
tags = template.match(re) || [],
|
||||||
|
// The tag being evaluated, e.g. "{{hamster|dance}}".
|
||||||
|
tag,
|
||||||
|
// The expression to evaluate inside the tag, e.g. "hamster|dance".
|
||||||
|
prop,
|
||||||
|
// The token itself, e.g. "hamster".
|
||||||
|
token,
|
||||||
|
// An array of pipe expressions, e.g. ["more>1", "less>2"].
|
||||||
|
filters = [],
|
||||||
|
// Does the tag close itself? e.g. "{{stuff/}}".
|
||||||
|
selfy,
|
||||||
|
// Is the tag an "if" statement?
|
||||||
|
testy,
|
||||||
|
// The contents of a block tag, e.g. "{{aa}}bb{{/aa}}" -> "bb".
|
||||||
|
child,
|
||||||
|
// The resulting string.
|
||||||
|
result,
|
||||||
|
// The global variable being evaluated, or undefined.
|
||||||
|
global,
|
||||||
|
// The included template being evaluated, or undefined.
|
||||||
|
include,
|
||||||
|
// A placeholder variable.
|
||||||
|
ctx,
|
||||||
|
// Iterators.
|
||||||
|
i = 0,
|
||||||
|
j = 0;
|
||||||
|
|
||||||
|
// Set custom pipes, if provided.
|
||||||
|
if (options.pipes) {
|
||||||
|
this._copy(options.pipes, this.pipes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set templates to include, if provided.
|
||||||
|
if (options.includes) {
|
||||||
|
this._copy(options.includes, this.includes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set global variables, if provided.
|
||||||
|
if (options.globals) {
|
||||||
|
this._copy(options.globals, this.globals);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optionally override the delimiter.
|
||||||
|
if (options.delimiter) {
|
||||||
|
this.delimiter = options.delimiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optionally collapse white space.
|
||||||
|
if (options.compact !== undefined) {
|
||||||
|
this.compact = options.compact;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through tags, e.g. {{a}}, {{b}}, {{c}}, {{/c}}.
|
||||||
|
while ((tag = tags[i++])) {
|
||||||
|
result = undefined;
|
||||||
|
child = "";
|
||||||
|
selfy = tag.indexOf("/}}") > -1;
|
||||||
|
prop = tag.substr(2, tag.length - (selfy ? 5 : 4));
|
||||||
|
prop = prop.replace(/`(.+?)`/g, function (s, p1) {
|
||||||
|
return Mark.up("{{" + p1 + "}}", context);
|
||||||
|
});
|
||||||
|
testy = prop.trim().indexOf("if ") === 0;
|
||||||
|
filters = prop.split("|");
|
||||||
|
filters.shift(); // instead of splice(1)
|
||||||
|
prop = prop.replace(/^\s*if/, "").split("|").shift().trim();
|
||||||
|
token = testy ? "if" : prop.split("|")[0];
|
||||||
|
ctx = context[prop];
|
||||||
|
|
||||||
|
// If an "if" statement without filters, assume "{{if foo|notempty}}"
|
||||||
|
if (testy && !filters.length) {
|
||||||
|
filters = ["notempty"];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does the tag have a corresponding closing tag? If so, find it and move the cursor.
|
||||||
|
if (!selfy && template.indexOf("{{/" + token) > -1) {
|
||||||
|
result = this._bridge(template, token);
|
||||||
|
tag = result[0];
|
||||||
|
child = result[1];
|
||||||
|
i += tag.match(re).length - 1; // fast forward
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip "else" tags. These are pulled out in _test().
|
||||||
|
if (/^\{\{\s*else\s*\}\}$/.test(tag)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluating a global variable.
|
||||||
|
else if ((global = this.globals[prop]) !== undefined) {
|
||||||
|
result = this._eval(global, filters, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluating an included template.
|
||||||
|
else if ((include = this.includes[prop])) {
|
||||||
|
if (include instanceof Function) {
|
||||||
|
include = include();
|
||||||
|
}
|
||||||
|
result = this._pipe(Mark.up(include, context), filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluating a loop counter ("#" or "##").
|
||||||
|
else if (prop.indexOf("#") > -1) {
|
||||||
|
options.iter.sign = prop;
|
||||||
|
result = this._pipe(options.iter, filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluating the current context.
|
||||||
|
else if (prop === ".") {
|
||||||
|
result = this._pipe(context, filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluating a variable with dot notation, e.g. "a.b.c"
|
||||||
|
else if (prop.indexOf(".") > -1) {
|
||||||
|
prop = prop.split(".");
|
||||||
|
ctx = Mark.globals[prop[0]];
|
||||||
|
|
||||||
|
if (ctx) {
|
||||||
|
j = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
j = 0;
|
||||||
|
ctx = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the actual context
|
||||||
|
while (ctx && j < prop.length) {
|
||||||
|
ctx = ctx[prop[j++]];
|
||||||
|
}
|
||||||
|
|
||||||
|
result = this._eval(ctx, filters, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluating an "if" statement.
|
||||||
|
else if (testy) {
|
||||||
|
result = this._pipe(ctx, filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluating an array, which might be a block expression.
|
||||||
|
else if (ctx instanceof Array) {
|
||||||
|
result = this._eval(ctx, filters, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluating a block expression.
|
||||||
|
else if (child) {
|
||||||
|
result = ctx ? Mark.up(child, ctx) : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluating anything else.
|
||||||
|
else if (context.hasOwnProperty(prop)) {
|
||||||
|
result = this._pipe(ctx, filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluating an "if" statement.
|
||||||
|
if (testy) {
|
||||||
|
result = this._test(result, child, context, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace the tag, e.g. "{{name}}", with the result, e.g. "Adam".
|
||||||
|
template = template.replace(tag, result === undefined ? "???" : result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.compact ? template.replace(/>\s+</g, "><") : template;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Freebie pipes. See usage in README.md
|
||||||
|
Mark.pipes = {
|
||||||
|
empty: function (obj) {
|
||||||
|
return !obj || (obj + "").trim().length === 0 ? obj : false;
|
||||||
|
},
|
||||||
|
notempty: function (obj) {
|
||||||
|
return obj && (obj + "").trim().length ? obj : false;
|
||||||
|
},
|
||||||
|
blank: function (str, val) {
|
||||||
|
return !!str || str === 0 ? str : val;
|
||||||
|
},
|
||||||
|
more: function (a, b) {
|
||||||
|
return Mark._size(a) > b ? a : false;
|
||||||
|
},
|
||||||
|
less: function (a, b) {
|
||||||
|
return Mark._size(a) < b ? a : false;
|
||||||
|
},
|
||||||
|
ormore: function (a, b) {
|
||||||
|
return Mark._size(a) >= b ? a : false;
|
||||||
|
},
|
||||||
|
orless: function (a, b) {
|
||||||
|
return Mark._size(a) <= b ? a : false;
|
||||||
|
},
|
||||||
|
between: function (a, b, c) {
|
||||||
|
a = Mark._size(a);
|
||||||
|
return a >= b && a <= c ? a : false;
|
||||||
|
},
|
||||||
|
equals: function (a, b) {
|
||||||
|
return a == b ? a : false;
|
||||||
|
},
|
||||||
|
notequals: function (a, b) {
|
||||||
|
return a != b ? a : false;
|
||||||
|
},
|
||||||
|
like: function (str, pattern) {
|
||||||
|
return new RegExp(pattern, "i").test(str) ? str : false;
|
||||||
|
},
|
||||||
|
notlike: function (str, pattern) {
|
||||||
|
return !Mark.pipes.like(str, pattern) ? str : false;
|
||||||
|
},
|
||||||
|
upcase: function (str) {
|
||||||
|
return String(str).toUpperCase();
|
||||||
|
},
|
||||||
|
downcase: function (str) {
|
||||||
|
return String(str).toLowerCase();
|
||||||
|
},
|
||||||
|
capcase: function (str) {
|
||||||
|
return str.replace(/\b\w/g, function (s) { return s.toUpperCase(); });
|
||||||
|
},
|
||||||
|
chop: function (str, n) {
|
||||||
|
return str.length > n ? str.substr(0, n) + "..." : str;
|
||||||
|
},
|
||||||
|
tease: function (str, n) {
|
||||||
|
var a = str.split(/\s+/);
|
||||||
|
return a.slice(0, n).join(" ") + (a.length > n ? "..." : "");
|
||||||
|
},
|
||||||
|
trim: function (str) {
|
||||||
|
return str.trim();
|
||||||
|
},
|
||||||
|
pack: function (str) {
|
||||||
|
return str.trim().replace(/\s{2,}/g, " ");
|
||||||
|
},
|
||||||
|
round: function (num) {
|
||||||
|
return Math.round(+num);
|
||||||
|
},
|
||||||
|
clean: function (str) {
|
||||||
|
return String(str).replace(/<\/?[^>]+>/gi, "");
|
||||||
|
},
|
||||||
|
size: function (obj) {
|
||||||
|
return obj.length;
|
||||||
|
},
|
||||||
|
length: function (obj) {
|
||||||
|
return obj.length;
|
||||||
|
},
|
||||||
|
reverse: function (arr) {
|
||||||
|
return Mark._copy(arr).reverse();
|
||||||
|
},
|
||||||
|
join: function (arr, separator) {
|
||||||
|
return arr.join(separator);
|
||||||
|
},
|
||||||
|
limit: function (arr, count, idx) {
|
||||||
|
return arr.slice(+idx || 0, +count + (+idx || 0));
|
||||||
|
},
|
||||||
|
split: function (str, separator) {
|
||||||
|
return str.split(separator || ",");
|
||||||
|
},
|
||||||
|
choose: function (bool, iffy, elsy) {
|
||||||
|
return !!bool ? iffy : (elsy || "");
|
||||||
|
},
|
||||||
|
toggle: function (obj, csv1, csv2, str) {
|
||||||
|
return csv2.split(",")[csv1.match(/\w+/g).indexOf(obj + "")] || str;
|
||||||
|
},
|
||||||
|
sort: function (arr, prop) {
|
||||||
|
var fn = function (a, b) {
|
||||||
|
return a[prop] > b[prop] ? 1 : -1;
|
||||||
|
};
|
||||||
|
return Mark._copy(arr).sort(prop ? fn : undefined);
|
||||||
|
},
|
||||||
|
fix: function (num, n) {
|
||||||
|
return (+num).toFixed(n);
|
||||||
|
},
|
||||||
|
mod: function (num, n) {
|
||||||
|
return (+num) % (+n);
|
||||||
|
},
|
||||||
|
divisible: function (num, n) {
|
||||||
|
return num && (+num % n) === 0 ? num : false;
|
||||||
|
},
|
||||||
|
even: function (num) {
|
||||||
|
return num && (+num & 1) === 0 ? num : false;
|
||||||
|
},
|
||||||
|
odd: function (num) {
|
||||||
|
return num && (+num & 1) === 1 ? num : false;
|
||||||
|
},
|
||||||
|
number: function (str) {
|
||||||
|
return parseFloat(str.replace(/[^\-\d\.]/g, ""));
|
||||||
|
},
|
||||||
|
url: function (str) {
|
||||||
|
return encodeURI(str);
|
||||||
|
},
|
||||||
|
bool: function (obj) {
|
||||||
|
return !!obj;
|
||||||
|
},
|
||||||
|
falsy: function (obj) {
|
||||||
|
return !obj;
|
||||||
|
},
|
||||||
|
first: function (iter) {
|
||||||
|
return iter.idx === 0;
|
||||||
|
},
|
||||||
|
last: function (iter) {
|
||||||
|
return iter.idx === iter.size - 1;
|
||||||
|
},
|
||||||
|
call: function (obj, fn) {
|
||||||
|
return obj[fn].apply(obj, [].slice.call(arguments, 2));
|
||||||
|
},
|
||||||
|
set: function (obj, key) {
|
||||||
|
Mark.globals[key] = obj; return "";
|
||||||
|
},
|
||||||
|
log: function (obj) {
|
||||||
|
console.log(obj);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Shim for IE.
|
||||||
|
if (typeof String.prototype.trim !== "function") {
|
||||||
|
String.prototype.trim = function() {
|
||||||
|
return this.replace(/^\s+|\s+$/g, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export for Node.js and AMD.
|
||||||
|
if (typeof module !== "undefined" && module.exports) {
|
||||||
|
module.exports = Mark;
|
||||||
|
}
|
||||||
|
else if (typeof define === "function" && define.amd) {
|
||||||
|
define(function() {
|
||||||
|
return Mark;
|
||||||
|
});
|
||||||
|
}
|
201
isso/js/lib/pbkdf2.js
Normal file
201
isso/js/lib/pbkdf2.js
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
define(["lib/q", "lib/sha1"], function(Q, sha1) {
|
||||||
|
/*
|
||||||
|
* JavaScript implementation of Password-Based Key Derivation Function 2
|
||||||
|
* (PBKDF2) as defined in RFC 2898.
|
||||||
|
* Version 1.5
|
||||||
|
* Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Parvez Anandam
|
||||||
|
* parvez@anandam.com
|
||||||
|
* http://anandam.com/pbkdf2
|
||||||
|
*
|
||||||
|
* Distributed under the BSD license
|
||||||
|
*
|
||||||
|
* Uses Paul Johnston's excellent SHA-1 JavaScript library sha1.js:
|
||||||
|
* http://pajhome.org.uk/crypt/md5/sha1.html
|
||||||
|
* (uses the binb_sha1(), rstr2binb(), binb2str(), rstr2hex() functions from that libary)
|
||||||
|
*
|
||||||
|
* Thanks to Felix Gartsman for pointing out a bug in version 1.0
|
||||||
|
* Thanks to Thijs Van der Schaeghe for pointing out a bug in version 1.1
|
||||||
|
* Thanks to Richard Gautier for asking to clarify dependencies in version 1.2
|
||||||
|
* Updated contact information from version 1.3
|
||||||
|
* Thanks to Stuart Heinrich for pointing out updates to PAJ's SHA-1 library in version 1.4
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The four arguments to the constructor of the PBKDF2 object are
|
||||||
|
* the password, salt, number of iterations and number of bytes in
|
||||||
|
* generated key. This follows the RFC 2898 definition: PBKDF2 (P, S, c, dkLen)
|
||||||
|
*
|
||||||
|
* The method deriveKey takes two parameters, both callback functions:
|
||||||
|
* the first is used to provide status on the computation, the second
|
||||||
|
* is called with the result of the computation (the generated key in hex).
|
||||||
|
*
|
||||||
|
* Example of use:
|
||||||
|
*
|
||||||
|
* <script src="sha1.js"></script>
|
||||||
|
* <script src="pbkdf2.js"></script>
|
||||||
|
* <script>
|
||||||
|
* var mypbkdf2 = new PBKDF2("mypassword", "saltines", 1000, 16);
|
||||||
|
* var status_callback = function(percent_done) {
|
||||||
|
* document.getElementById("status").innerHTML = "Computed " + percent_done + "%"};
|
||||||
|
* var result_callback = function(key) {
|
||||||
|
* document.getElementById("status").innerHTML = "The derived key is: " + key};
|
||||||
|
* mypbkdf2.deriveKey(status_callback, result_callback);
|
||||||
|
* </script>
|
||||||
|
* <div id="status"></div>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
var PBKDF2 = function(password, salt, num_iterations, num_bytes)
|
||||||
|
{
|
||||||
|
// Remember the password and salt
|
||||||
|
var m_bpassword = sha1.rstr2binb(password);
|
||||||
|
var m_salt = salt;
|
||||||
|
|
||||||
|
// Total number of iterations
|
||||||
|
var m_total_iterations = num_iterations;
|
||||||
|
|
||||||
|
// Run iterations in chunks instead of all at once, so as to not block.
|
||||||
|
// Define size of chunk here; adjust for slower or faster machines if necessary.
|
||||||
|
var m_iterations_in_chunk = 10;
|
||||||
|
|
||||||
|
// Iteration counter
|
||||||
|
var m_iterations_done = 0;
|
||||||
|
|
||||||
|
// Key length, as number of bytes
|
||||||
|
var m_key_length = num_bytes;
|
||||||
|
|
||||||
|
// The hash cache
|
||||||
|
var m_hash = null;
|
||||||
|
|
||||||
|
// The length (number of bytes) of the output of the pseudo-random function.
|
||||||
|
// Since HMAC-SHA1 is the standard, and what is used here, it's 20 bytes.
|
||||||
|
var m_hash_length = 20;
|
||||||
|
|
||||||
|
// Number of hash-sized blocks in the derived key (called 'l' in RFC2898)
|
||||||
|
var m_total_blocks = Math.ceil(m_key_length/m_hash_length);
|
||||||
|
|
||||||
|
// Start computation with the first block
|
||||||
|
var m_current_block = 1;
|
||||||
|
|
||||||
|
// Used in the HMAC-SHA1 computations
|
||||||
|
var m_ipad = new Array(16);
|
||||||
|
var m_opad = new Array(16);
|
||||||
|
|
||||||
|
// This is where the result of the iterations gets sotred
|
||||||
|
var m_buffer = new Array(0x0,0x0,0x0,0x0,0x0);
|
||||||
|
|
||||||
|
// The result
|
||||||
|
var m_key = "";
|
||||||
|
|
||||||
|
// This object
|
||||||
|
var m_this_object = this;
|
||||||
|
|
||||||
|
// The function to call with the result
|
||||||
|
var m_result_func;
|
||||||
|
|
||||||
|
// The function to call with status after computing every chunk
|
||||||
|
var m_status_func;
|
||||||
|
|
||||||
|
// Set up the HMAC-SHA1 computations
|
||||||
|
if (m_bpassword.length > 16) m_bpassword = sha1.binb_sha1(m_bpassword, password.length * chrsz);
|
||||||
|
for(var i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
m_ipad[i] = m_bpassword[i] ^ 0x36363636;
|
||||||
|
m_opad[i] = m_bpassword[i] ^ 0x5C5C5C5C;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Starts the computation
|
||||||
|
this.deriveKey = function(status_callback, result_callback)
|
||||||
|
{
|
||||||
|
m_status_func = status_callback;
|
||||||
|
m_result_func = result_callback;
|
||||||
|
setTimeout(function() { m_this_object.do_PBKDF2_iterations() }, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The workhorse
|
||||||
|
this.do_PBKDF2_iterations = function()
|
||||||
|
{
|
||||||
|
var iterations = m_iterations_in_chunk;
|
||||||
|
if (m_total_iterations - m_iterations_done < m_iterations_in_chunk)
|
||||||
|
iterations = m_total_iterations - m_iterations_done;
|
||||||
|
|
||||||
|
for(var i=0; i<iterations; ++i)
|
||||||
|
{
|
||||||
|
// compute HMAC-SHA1
|
||||||
|
if (m_iterations_done == 0)
|
||||||
|
{
|
||||||
|
var salt_block = m_salt +
|
||||||
|
String.fromCharCode(m_current_block >> 24 & 0xF) +
|
||||||
|
String.fromCharCode(m_current_block >> 16 & 0xF) +
|
||||||
|
String.fromCharCode(m_current_block >> 8 & 0xF) +
|
||||||
|
String.fromCharCode(m_current_block & 0xF);
|
||||||
|
|
||||||
|
m_hash = sha1.binb_sha1(m_ipad.concat(sha1.rstr2binb(salt_block)),
|
||||||
|
512 + salt_block.length * 8);
|
||||||
|
m_hash = sha1.binb_sha1(m_opad.concat(m_hash), 512 + 160);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_hash = sha1.binb_sha1(m_ipad.concat(m_hash),
|
||||||
|
512 + m_hash.length * 32);
|
||||||
|
m_hash = sha1.binb_sha1(m_opad.concat(m_hash), 512 + 160);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var j=0; j<m_hash.length; ++j)
|
||||||
|
m_buffer[j] ^= m_hash[j];
|
||||||
|
|
||||||
|
m_iterations_done++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the status callback function
|
||||||
|
m_status_func( (m_current_block - 1 + m_iterations_done/m_total_iterations) / m_total_blocks * 100);
|
||||||
|
|
||||||
|
if (m_iterations_done < m_total_iterations)
|
||||||
|
{
|
||||||
|
setTimeout(function() { m_this_object.do_PBKDF2_iterations() }, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_current_block < m_total_blocks)
|
||||||
|
{
|
||||||
|
// Compute the next block (T_i in RFC 2898)
|
||||||
|
|
||||||
|
m_key += sha1.rstr2hex(sha1.binb2rstr(m_buffer));
|
||||||
|
|
||||||
|
m_current_block++;
|
||||||
|
m_buffer = new Array(0x0,0x0,0x0,0x0,0x0);
|
||||||
|
m_iterations_done = 0;
|
||||||
|
|
||||||
|
setTimeout(function() { m_this_object.do_PBKDF2_iterations() }, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We've computed the final block T_l; we're done.
|
||||||
|
|
||||||
|
var tmp = sha1.rstr2hex(sha1.binb2rstr(m_buffer));
|
||||||
|
m_key += tmp.substr(0, (m_key_length - (m_total_blocks - 1) * m_hash_length) * 2 );
|
||||||
|
|
||||||
|
// Call the result callback function
|
||||||
|
m_result_func(m_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return function(text, salt, iterations, size) {
|
||||||
|
|
||||||
|
var deferred = Q.defer();
|
||||||
|
|
||||||
|
Q.when(text, function(text) {
|
||||||
|
var pbkdf2 = new PBKDF2(text, salt, iterations, size);
|
||||||
|
pbkdf2.deriveKey(function(bla) {}, function(rv) {
|
||||||
|
deferred.resolve(rv);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
})
|
337
isso/js/lib/sha1.js
Normal file
337
isso/js/lib/sha1.js
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
/*
|
||||||
|
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
|
||||||
|
* in FIPS 180-1
|
||||||
|
* Version 2.2 Copyright Paul Johnston 2000 - 2009.
|
||||||
|
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||||||
|
* Distributed under the BSD License
|
||||||
|
* See http://pajhome.org.uk/crypt/md5 for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
define(function() {
|
||||||
|
/*
|
||||||
|
* Configurable variables. You may need to tweak these to be compatible with
|
||||||
|
* the server-side, but the defaults work in most cases.
|
||||||
|
*/
|
||||||
|
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
|
||||||
|
var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are the functions you'll usually want to call
|
||||||
|
* They take string arguments and return either hex or base-64 encoded strings
|
||||||
|
*/
|
||||||
|
function hex_sha1(s) { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
|
||||||
|
function b64_sha1(s) { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
|
||||||
|
function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
|
||||||
|
function hex_hmac_sha1(k, d)
|
||||||
|
{ return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
|
||||||
|
function b64_hmac_sha1(k, d)
|
||||||
|
{ return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
|
||||||
|
function any_hmac_sha1(k, d, e)
|
||||||
|
{ return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform a simple self-test to see if the VM is working
|
||||||
|
*/
|
||||||
|
function sha1_vm_test()
|
||||||
|
{
|
||||||
|
return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the SHA1 of a raw string
|
||||||
|
*/
|
||||||
|
function rstr_sha1(s)
|
||||||
|
{
|
||||||
|
return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the HMAC-SHA1 of a key and some data (raw strings)
|
||||||
|
*/
|
||||||
|
function rstr_hmac_sha1(key, data)
|
||||||
|
{
|
||||||
|
var bkey = rstr2binb(key);
|
||||||
|
if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8);
|
||||||
|
|
||||||
|
var ipad = Array(16), opad = Array(16);
|
||||||
|
for(var i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
ipad[i] = bkey[i] ^ 0x36363636;
|
||||||
|
opad[i] = bkey[i] ^ 0x5C5C5C5C;
|
||||||
|
}
|
||||||
|
|
||||||
|
var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
|
||||||
|
return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a raw string to a hex string
|
||||||
|
*/
|
||||||
|
function rstr2hex(input)
|
||||||
|
{
|
||||||
|
try { hexcase } catch(e) { hexcase=0; }
|
||||||
|
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
|
||||||
|
var output = "";
|
||||||
|
var x;
|
||||||
|
for(var i = 0; i < input.length; i++)
|
||||||
|
{
|
||||||
|
x = input.charCodeAt(i);
|
||||||
|
output += hex_tab.charAt((x >>> 4) & 0x0F)
|
||||||
|
+ hex_tab.charAt( x & 0x0F);
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a raw string to a base-64 string
|
||||||
|
*/
|
||||||
|
function rstr2b64(input)
|
||||||
|
{
|
||||||
|
try { b64pad } catch(e) { b64pad=''; }
|
||||||
|
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
var output = "";
|
||||||
|
var len = input.length;
|
||||||
|
for(var i = 0; i < len; i += 3)
|
||||||
|
{
|
||||||
|
var triplet = (input.charCodeAt(i) << 16)
|
||||||
|
| (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
|
||||||
|
| (i + 2 < len ? input.charCodeAt(i+2) : 0);
|
||||||
|
for(var j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
if(i * 8 + j * 6 > input.length * 8) output += b64pad;
|
||||||
|
else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a raw string to an arbitrary string encoding
|
||||||
|
*/
|
||||||
|
function rstr2any(input, encoding)
|
||||||
|
{
|
||||||
|
var divisor = encoding.length;
|
||||||
|
var remainders = Array();
|
||||||
|
var i, q, x, quotient;
|
||||||
|
|
||||||
|
/* Convert to an array of 16-bit big-endian values, forming the dividend */
|
||||||
|
var dividend = Array(Math.ceil(input.length / 2));
|
||||||
|
for(i = 0; i < dividend.length; i++)
|
||||||
|
{
|
||||||
|
dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Repeatedly perform a long division. The binary array forms the dividend,
|
||||||
|
* the length of the encoding is the divisor. Once computed, the quotient
|
||||||
|
* forms the dividend for the next step. We stop when the dividend is zero.
|
||||||
|
* All remainders are stored for later use.
|
||||||
|
*/
|
||||||
|
while(dividend.length > 0)
|
||||||
|
{
|
||||||
|
quotient = Array();
|
||||||
|
x = 0;
|
||||||
|
for(i = 0; i < dividend.length; i++)
|
||||||
|
{
|
||||||
|
x = (x << 16) + dividend[i];
|
||||||
|
q = Math.floor(x / divisor);
|
||||||
|
x -= q * divisor;
|
||||||
|
if(quotient.length > 0 || q > 0)
|
||||||
|
quotient[quotient.length] = q;
|
||||||
|
}
|
||||||
|
remainders[remainders.length] = x;
|
||||||
|
dividend = quotient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert the remainders to the output string */
|
||||||
|
var output = "";
|
||||||
|
for(i = remainders.length - 1; i >= 0; i--)
|
||||||
|
output += encoding.charAt(remainders[i]);
|
||||||
|
|
||||||
|
/* Append leading zero equivalents */
|
||||||
|
var full_length = Math.ceil(input.length * 8 /
|
||||||
|
(Math.log(encoding.length) / Math.log(2)))
|
||||||
|
for(i = output.length; i < full_length; i++)
|
||||||
|
output = encoding[0] + output;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encode a string as utf-8.
|
||||||
|
* For efficiency, this assumes the input is valid utf-16.
|
||||||
|
*/
|
||||||
|
function str2rstr_utf8(input)
|
||||||
|
{
|
||||||
|
var output = "";
|
||||||
|
var i = -1;
|
||||||
|
var x, y;
|
||||||
|
|
||||||
|
while(++i < input.length)
|
||||||
|
{
|
||||||
|
/* Decode utf-16 surrogate pairs */
|
||||||
|
x = input.charCodeAt(i);
|
||||||
|
y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
|
||||||
|
if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
|
||||||
|
{
|
||||||
|
x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encode output as utf-8 */
|
||||||
|
if(x <= 0x7F)
|
||||||
|
output += String.fromCharCode(x);
|
||||||
|
else if(x <= 0x7FF)
|
||||||
|
output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
|
||||||
|
0x80 | ( x & 0x3F));
|
||||||
|
else if(x <= 0xFFFF)
|
||||||
|
output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
|
||||||
|
0x80 | ((x >>> 6 ) & 0x3F),
|
||||||
|
0x80 | ( x & 0x3F));
|
||||||
|
else if(x <= 0x1FFFFF)
|
||||||
|
output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
|
||||||
|
0x80 | ((x >>> 12) & 0x3F),
|
||||||
|
0x80 | ((x >>> 6 ) & 0x3F),
|
||||||
|
0x80 | ( x & 0x3F));
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encode a string as utf-16
|
||||||
|
*/
|
||||||
|
function str2rstr_utf16le(input)
|
||||||
|
{
|
||||||
|
var output = "";
|
||||||
|
for(var i = 0; i < input.length; i++)
|
||||||
|
output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
|
||||||
|
(input.charCodeAt(i) >>> 8) & 0xFF);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
function str2rstr_utf16be(input)
|
||||||
|
{
|
||||||
|
var output = "";
|
||||||
|
for(var i = 0; i < input.length; i++)
|
||||||
|
output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
|
||||||
|
input.charCodeAt(i) & 0xFF);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a raw string to an array of big-endian words
|
||||||
|
* Characters >255 have their high-byte silently ignored.
|
||||||
|
*/
|
||||||
|
function rstr2binb(input)
|
||||||
|
{
|
||||||
|
var output = Array(input.length >> 2);
|
||||||
|
for(var i = 0; i < output.length; i++)
|
||||||
|
output[i] = 0;
|
||||||
|
for(var i = 0; i < input.length * 8; i += 8)
|
||||||
|
output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert an array of big-endian words to a string
|
||||||
|
*/
|
||||||
|
function binb2rstr(input)
|
||||||
|
{
|
||||||
|
var output = "";
|
||||||
|
for(var i = 0; i < input.length * 32; i += 8)
|
||||||
|
output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the SHA-1 of an array of big-endian words, and a bit length
|
||||||
|
*/
|
||||||
|
function binb_sha1(x, len)
|
||||||
|
{
|
||||||
|
/* append padding */
|
||||||
|
x[len >> 5] |= 0x80 << (24 - len % 32);
|
||||||
|
x[((len + 64 >> 9) << 4) + 15] = len;
|
||||||
|
|
||||||
|
var w = Array(80);
|
||||||
|
var a = 1732584193;
|
||||||
|
var b = -271733879;
|
||||||
|
var c = -1732584194;
|
||||||
|
var d = 271733878;
|
||||||
|
var e = -1009589776;
|
||||||
|
|
||||||
|
for(var i = 0; i < x.length; i += 16)
|
||||||
|
{
|
||||||
|
var olda = a;
|
||||||
|
var oldb = b;
|
||||||
|
var oldc = c;
|
||||||
|
var oldd = d;
|
||||||
|
var olde = e;
|
||||||
|
|
||||||
|
for(var j = 0; j < 80; j++)
|
||||||
|
{
|
||||||
|
if(j < 16) w[j] = x[i + j];
|
||||||
|
else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
|
||||||
|
var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
|
||||||
|
safe_add(safe_add(e, w[j]), sha1_kt(j)));
|
||||||
|
e = d;
|
||||||
|
d = c;
|
||||||
|
c = bit_rol(b, 30);
|
||||||
|
b = a;
|
||||||
|
a = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = safe_add(a, olda);
|
||||||
|
b = safe_add(b, oldb);
|
||||||
|
c = safe_add(c, oldc);
|
||||||
|
d = safe_add(d, oldd);
|
||||||
|
e = safe_add(e, olde);
|
||||||
|
}
|
||||||
|
return Array(a, b, c, d, e);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform the appropriate triplet combination function for the current
|
||||||
|
* iteration
|
||||||
|
*/
|
||||||
|
function sha1_ft(t, b, c, d)
|
||||||
|
{
|
||||||
|
if(t < 20) return (b & c) | ((~b) & d);
|
||||||
|
if(t < 40) return b ^ c ^ d;
|
||||||
|
if(t < 60) return (b & c) | (b & d) | (c & d);
|
||||||
|
return b ^ c ^ d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine the appropriate additive constant for the current iteration
|
||||||
|
*/
|
||||||
|
function sha1_kt(t)
|
||||||
|
{
|
||||||
|
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
|
||||||
|
(t < 60) ? -1894007588 : -899497514;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
|
||||||
|
* to work around bugs in some JS interpreters.
|
||||||
|
*/
|
||||||
|
function safe_add(x, y)
|
||||||
|
{
|
||||||
|
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
|
||||||
|
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
||||||
|
return (msw << 16) | (lsw & 0xFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bitwise rotate a 32-bit number to the left.
|
||||||
|
*/
|
||||||
|
function bit_rol(num, cnt)
|
||||||
|
{
|
||||||
|
return (num << cnt) | (num >>> (32 - cnt));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
rstr2hex: rstr2hex, binb2rstr: binb2rstr,
|
||||||
|
binb_sha1: binb_sha1, rstr2binb: rstr2binb
|
||||||
|
}
|
||||||
|
})
|
386
isso/js/text.js
Normal file
386
isso/js/text.js
Normal file
@ -0,0 +1,386 @@
|
|||||||
|
/**
|
||||||
|
* @license RequireJS text 2.0.10 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
|
||||||
|
* Available via the MIT or new BSD license.
|
||||||
|
* see: http://github.com/requirejs/text for details
|
||||||
|
*/
|
||||||
|
/*jslint regexp: true */
|
||||||
|
/*global require, XMLHttpRequest, ActiveXObject,
|
||||||
|
define, window, process, Packages,
|
||||||
|
java, location, Components, FileUtils */
|
||||||
|
|
||||||
|
define(['module'], function (module) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var text, fs, Cc, Ci, xpcIsWindows,
|
||||||
|
progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
|
||||||
|
xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,
|
||||||
|
bodyRegExp = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,
|
||||||
|
hasLocation = typeof location !== 'undefined' && location.href,
|
||||||
|
defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''),
|
||||||
|
defaultHostName = hasLocation && location.hostname,
|
||||||
|
defaultPort = hasLocation && (location.port || undefined),
|
||||||
|
buildMap = {},
|
||||||
|
masterConfig = (module.config && module.config()) || {};
|
||||||
|
|
||||||
|
text = {
|
||||||
|
version: '2.0.10',
|
||||||
|
|
||||||
|
strip: function (content) {
|
||||||
|
//Strips <?xml ...?> declarations so that external SVG and XML
|
||||||
|
//documents can be added to a document without worry. Also, if the string
|
||||||
|
//is an HTML document, only the part inside the body tag is returned.
|
||||||
|
if (content) {
|
||||||
|
content = content.replace(xmlRegExp, "");
|
||||||
|
var matches = content.match(bodyRegExp);
|
||||||
|
if (matches) {
|
||||||
|
content = matches[1];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
content = "";
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
},
|
||||||
|
|
||||||
|
jsEscape: function (content) {
|
||||||
|
return content.replace(/(['\\])/g, '\\$1')
|
||||||
|
.replace(/[\f]/g, "\\f")
|
||||||
|
.replace(/[\b]/g, "\\b")
|
||||||
|
.replace(/[\n]/g, "\\n")
|
||||||
|
.replace(/[\t]/g, "\\t")
|
||||||
|
.replace(/[\r]/g, "\\r")
|
||||||
|
.replace(/[\u2028]/g, "\\u2028")
|
||||||
|
.replace(/[\u2029]/g, "\\u2029");
|
||||||
|
},
|
||||||
|
|
||||||
|
createXhr: masterConfig.createXhr || function () {
|
||||||
|
//Would love to dump the ActiveX crap in here. Need IE 6 to die first.
|
||||||
|
var xhr, i, progId;
|
||||||
|
if (typeof XMLHttpRequest !== "undefined") {
|
||||||
|
return new XMLHttpRequest();
|
||||||
|
} else if (typeof ActiveXObject !== "undefined") {
|
||||||
|
for (i = 0; i < 3; i += 1) {
|
||||||
|
progId = progIds[i];
|
||||||
|
try {
|
||||||
|
xhr = new ActiveXObject(progId);
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
if (xhr) {
|
||||||
|
progIds = [progId]; // so faster next time
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xhr;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a resource name into its component parts. Resource names
|
||||||
|
* look like: module/name.ext!strip, where the !strip part is
|
||||||
|
* optional.
|
||||||
|
* @param {String} name the resource name
|
||||||
|
* @returns {Object} with properties "moduleName", "ext" and "strip"
|
||||||
|
* where strip is a boolean.
|
||||||
|
*/
|
||||||
|
parseName: function (name) {
|
||||||
|
var modName, ext, temp,
|
||||||
|
strip = false,
|
||||||
|
index = name.indexOf("."),
|
||||||
|
isRelative = name.indexOf('./') === 0 ||
|
||||||
|
name.indexOf('../') === 0;
|
||||||
|
|
||||||
|
if (index !== -1 && (!isRelative || index > 1)) {
|
||||||
|
modName = name.substring(0, index);
|
||||||
|
ext = name.substring(index + 1, name.length);
|
||||||
|
} else {
|
||||||
|
modName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = ext || modName;
|
||||||
|
index = temp.indexOf("!");
|
||||||
|
if (index !== -1) {
|
||||||
|
//Pull off the strip arg.
|
||||||
|
strip = temp.substring(index + 1) === "strip";
|
||||||
|
temp = temp.substring(0, index);
|
||||||
|
if (ext) {
|
||||||
|
ext = temp;
|
||||||
|
} else {
|
||||||
|
modName = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
moduleName: modName,
|
||||||
|
ext: ext,
|
||||||
|
strip: strip
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is an URL on another domain. Only works for browser use, returns
|
||||||
|
* false in non-browser environments. Only used to know if an
|
||||||
|
* optimized .js version of a text resource should be loaded
|
||||||
|
* instead.
|
||||||
|
* @param {String} url
|
||||||
|
* @returns Boolean
|
||||||
|
*/
|
||||||
|
useXhr: function (url, protocol, hostname, port) {
|
||||||
|
var uProtocol, uHostName, uPort,
|
||||||
|
match = text.xdRegExp.exec(url);
|
||||||
|
if (!match) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
uProtocol = match[2];
|
||||||
|
uHostName = match[3];
|
||||||
|
|
||||||
|
uHostName = uHostName.split(':');
|
||||||
|
uPort = uHostName[1];
|
||||||
|
uHostName = uHostName[0];
|
||||||
|
|
||||||
|
return (!uProtocol || uProtocol === protocol) &&
|
||||||
|
(!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) &&
|
||||||
|
((!uPort && !uHostName) || uPort === port);
|
||||||
|
},
|
||||||
|
|
||||||
|
finishLoad: function (name, strip, content, onLoad) {
|
||||||
|
content = strip ? text.strip(content) : content;
|
||||||
|
if (masterConfig.isBuild) {
|
||||||
|
buildMap[name] = content;
|
||||||
|
}
|
||||||
|
onLoad(content);
|
||||||
|
},
|
||||||
|
|
||||||
|
load: function (name, req, onLoad, config) {
|
||||||
|
//Name has format: some.module.filext!strip
|
||||||
|
//The strip part is optional.
|
||||||
|
//if strip is present, then that means only get the string contents
|
||||||
|
//inside a body tag in an HTML string. For XML/SVG content it means
|
||||||
|
//removing the <?xml ...?> declarations so the content can be inserted
|
||||||
|
//into the current doc without problems.
|
||||||
|
|
||||||
|
// Do not bother with the work if a build and text will
|
||||||
|
// not be inlined.
|
||||||
|
if (config.isBuild && !config.inlineText) {
|
||||||
|
onLoad();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
masterConfig.isBuild = config.isBuild;
|
||||||
|
|
||||||
|
var parsed = text.parseName(name),
|
||||||
|
nonStripName = parsed.moduleName +
|
||||||
|
(parsed.ext ? '.' + parsed.ext : ''),
|
||||||
|
url = req.toUrl(nonStripName),
|
||||||
|
useXhr = (masterConfig.useXhr) ||
|
||||||
|
text.useXhr;
|
||||||
|
|
||||||
|
// Do not load if it is an empty: url
|
||||||
|
if (url.indexOf('empty:') === 0) {
|
||||||
|
onLoad();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Load the text. Use XHR if possible and in a browser.
|
||||||
|
if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) {
|
||||||
|
text.get(url, function (content) {
|
||||||
|
text.finishLoad(name, parsed.strip, content, onLoad);
|
||||||
|
}, function (err) {
|
||||||
|
if (onLoad.error) {
|
||||||
|
onLoad.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
//Need to fetch the resource across domains. Assume
|
||||||
|
//the resource has been optimized into a JS module. Fetch
|
||||||
|
//by the module name + extension, but do not include the
|
||||||
|
//!strip part to avoid file system issues.
|
||||||
|
req([nonStripName], function (content) {
|
||||||
|
text.finishLoad(parsed.moduleName + '.' + parsed.ext,
|
||||||
|
parsed.strip, content, onLoad);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
write: function (pluginName, moduleName, write, config) {
|
||||||
|
if (buildMap.hasOwnProperty(moduleName)) {
|
||||||
|
var content = text.jsEscape(buildMap[moduleName]);
|
||||||
|
write.asModule(pluginName + "!" + moduleName,
|
||||||
|
"define(function () { return '" +
|
||||||
|
content +
|
||||||
|
"';});\n");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
writeFile: function (pluginName, moduleName, req, write, config) {
|
||||||
|
var parsed = text.parseName(moduleName),
|
||||||
|
extPart = parsed.ext ? '.' + parsed.ext : '',
|
||||||
|
nonStripName = parsed.moduleName + extPart,
|
||||||
|
//Use a '.js' file name so that it indicates it is a
|
||||||
|
//script that can be loaded across domains.
|
||||||
|
fileName = req.toUrl(parsed.moduleName + extPart) + '.js';
|
||||||
|
|
||||||
|
//Leverage own load() method to load plugin value, but only
|
||||||
|
//write out values that do not have the strip argument,
|
||||||
|
//to avoid any potential issues with ! in file names.
|
||||||
|
text.load(nonStripName, req, function (value) {
|
||||||
|
//Use own write() method to construct full module value.
|
||||||
|
//But need to create shell that translates writeFile's
|
||||||
|
//write() to the right interface.
|
||||||
|
var textWrite = function (contents) {
|
||||||
|
return write(fileName, contents);
|
||||||
|
};
|
||||||
|
textWrite.asModule = function (moduleName, contents) {
|
||||||
|
return write.asModule(moduleName, fileName, contents);
|
||||||
|
};
|
||||||
|
|
||||||
|
text.write(pluginName, nonStripName, textWrite, config);
|
||||||
|
}, config);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (masterConfig.env === 'node' || (!masterConfig.env &&
|
||||||
|
typeof process !== "undefined" &&
|
||||||
|
process.versions &&
|
||||||
|
!!process.versions.node &&
|
||||||
|
!process.versions['node-webkit'])) {
|
||||||
|
//Using special require.nodeRequire, something added by r.js.
|
||||||
|
fs = require.nodeRequire('fs');
|
||||||
|
|
||||||
|
text.get = function (url, callback, errback) {
|
||||||
|
try {
|
||||||
|
var file = fs.readFileSync(url, 'utf8');
|
||||||
|
//Remove BOM (Byte Mark Order) from utf8 files if it is there.
|
||||||
|
if (file.indexOf('\uFEFF') === 0) {
|
||||||
|
file = file.substring(1);
|
||||||
|
}
|
||||||
|
callback(file);
|
||||||
|
} catch (e) {
|
||||||
|
errback(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else if (masterConfig.env === 'xhr' || (!masterConfig.env &&
|
||||||
|
text.createXhr())) {
|
||||||
|
text.get = function (url, callback, errback, headers) {
|
||||||
|
var xhr = text.createXhr(), header;
|
||||||
|
xhr.open('GET', url, true);
|
||||||
|
|
||||||
|
//Allow plugins direct access to xhr headers
|
||||||
|
if (headers) {
|
||||||
|
for (header in headers) {
|
||||||
|
if (headers.hasOwnProperty(header)) {
|
||||||
|
xhr.setRequestHeader(header.toLowerCase(), headers[header]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Allow overrides specified in config
|
||||||
|
if (masterConfig.onXhr) {
|
||||||
|
masterConfig.onXhr(xhr, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.onreadystatechange = function (evt) {
|
||||||
|
var status, err;
|
||||||
|
//Do not explicitly handle errors, those should be
|
||||||
|
//visible via console output in the browser.
|
||||||
|
if (xhr.readyState === 4) {
|
||||||
|
status = xhr.status;
|
||||||
|
if (status > 399 && status < 600) {
|
||||||
|
//An http 4xx or 5xx error. Signal an error.
|
||||||
|
err = new Error(url + ' HTTP status: ' + status);
|
||||||
|
err.xhr = xhr;
|
||||||
|
errback(err);
|
||||||
|
} else {
|
||||||
|
callback(xhr.responseText);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (masterConfig.onXhrComplete) {
|
||||||
|
masterConfig.onXhrComplete(xhr, url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send(null);
|
||||||
|
};
|
||||||
|
} else if (masterConfig.env === 'rhino' || (!masterConfig.env &&
|
||||||
|
typeof Packages !== 'undefined' && typeof java !== 'undefined')) {
|
||||||
|
//Why Java, why is this so awkward?
|
||||||
|
text.get = function (url, callback) {
|
||||||
|
var stringBuffer, line,
|
||||||
|
encoding = "utf-8",
|
||||||
|
file = new java.io.File(url),
|
||||||
|
lineSeparator = java.lang.System.getProperty("line.separator"),
|
||||||
|
input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)),
|
||||||
|
content = '';
|
||||||
|
try {
|
||||||
|
stringBuffer = new java.lang.StringBuffer();
|
||||||
|
line = input.readLine();
|
||||||
|
|
||||||
|
// Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
|
||||||
|
// http://www.unicode.org/faq/utf_bom.html
|
||||||
|
|
||||||
|
// Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK:
|
||||||
|
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
|
||||||
|
if (line && line.length() && line.charAt(0) === 0xfeff) {
|
||||||
|
// Eat the BOM, since we've already found the encoding on this file,
|
||||||
|
// and we plan to concatenating this buffer with others; the BOM should
|
||||||
|
// only appear at the top of a file.
|
||||||
|
line = line.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line !== null) {
|
||||||
|
stringBuffer.append(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((line = input.readLine()) !== null) {
|
||||||
|
stringBuffer.append(lineSeparator);
|
||||||
|
stringBuffer.append(line);
|
||||||
|
}
|
||||||
|
//Make sure we return a JavaScript string and not a Java string.
|
||||||
|
content = String(stringBuffer.toString()); //String
|
||||||
|
} finally {
|
||||||
|
input.close();
|
||||||
|
}
|
||||||
|
callback(content);
|
||||||
|
};
|
||||||
|
} else if (masterConfig.env === 'xpconnect' || (!masterConfig.env &&
|
||||||
|
typeof Components !== 'undefined' && Components.classes &&
|
||||||
|
Components.interfaces)) {
|
||||||
|
//Avert your gaze!
|
||||||
|
Cc = Components.classes,
|
||||||
|
Ci = Components.interfaces;
|
||||||
|
Components.utils['import']('resource://gre/modules/FileUtils.jsm');
|
||||||
|
xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc);
|
||||||
|
|
||||||
|
text.get = function (url, callback) {
|
||||||
|
var inStream, convertStream, fileObj,
|
||||||
|
readData = {};
|
||||||
|
|
||||||
|
if (xpcIsWindows) {
|
||||||
|
url = url.replace(/\//g, '\\');
|
||||||
|
}
|
||||||
|
|
||||||
|
fileObj = new FileUtils.File(url);
|
||||||
|
|
||||||
|
//XPCOM, you so crazy
|
||||||
|
try {
|
||||||
|
inStream = Cc['@mozilla.org/network/file-input-stream;1']
|
||||||
|
.createInstance(Ci.nsIFileInputStream);
|
||||||
|
inStream.init(fileObj, 1, 0, false);
|
||||||
|
|
||||||
|
convertStream = Cc['@mozilla.org/intl/converter-input-stream;1']
|
||||||
|
.createInstance(Ci.nsIConverterInputStream);
|
||||||
|
convertStream.init(inStream, "utf-8", inStream.available(),
|
||||||
|
Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
|
||||||
|
|
||||||
|
convertStream.readString(inStream.available(), readData);
|
||||||
|
convertStream.close();
|
||||||
|
inStream.close();
|
||||||
|
callback(readData.value);
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error((fileObj && fileObj.path || '') + ': ' + e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
});
|
6
isso/js/text/arrow-down.svg
Executable file
6
isso/js/text/arrow-down.svg
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
<!-- Generator: IcoMoon.io --><svg width="16" height="16" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="gray">
|
||||||
|
<g>
|
||||||
|
<path d="M 24.773,13.701c-0.651,0.669-7.512,7.205-7.512,7.205C 16.912,21.262, 16.456,21.44, 16,21.44c-0.458,0-0.914-0.178-1.261-0.534 c0,0-6.861-6.536-7.514-7.205c-0.651-0.669-0.696-1.87,0-2.586c 0.698-0.714, 1.669-0.77, 2.522,0L 16,17.112l 6.251-5.995 c 0.854-0.77, 1.827-0.714, 2.522,0C 25.47,11.83, 25.427,13.034, 24.773,13.701z">
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 539 B |
6
isso/js/text/arrow-up.svg
Executable file
6
isso/js/text/arrow-up.svg
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
<!-- Generator: IcoMoon.io --><svg width="16" height="16" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="gray">
|
||||||
|
<g>
|
||||||
|
<path d="M 24.773,18.299c-0.651-0.669-7.512-7.203-7.512-7.203C 16.912,10.739, 16.456,10.56, 16,10.56c-0.458,0-0.914,0.179-1.261,0.536 c0,0-6.861,6.534-7.514,7.203c-0.651,0.669-0.696,1.872,0,2.586c 0.698,0.712, 1.669,0.77, 2.522,0L 16,14.89l 6.251,5.995 c 0.854,0.77, 1.827,0.712, 2.522,0C 25.47,20.17, 25.427,18.966, 24.773,18.299z">
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 539 B |
61
isso/js/text/comment.html
Normal file
61
isso/js/text/comment.html
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<article class="isso-comment" id="isso-{{ id | blank }}">
|
||||||
|
<div class="avatar">
|
||||||
|
<canvas data-hash="{{ hash }}" height="48px" width="48px"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="text-wrapper">
|
||||||
|
<header>
|
||||||
|
{{ if bool(website) }}
|
||||||
|
<a class="author" href="{{ website }}" rel="nofollow">
|
||||||
|
{{ author | blank : Anonymous }}
|
||||||
|
</a>
|
||||||
|
{{ else }}
|
||||||
|
<span class="author">
|
||||||
|
{{ author | blank : Anonymous }}
|
||||||
|
</span>
|
||||||
|
{{ /if }}
|
||||||
|
|
||||||
|
{{ if parent }}
|
||||||
|
<span class="spacer">•</span>
|
||||||
|
<a class="parent" href="#isso-{{ parent }}"><i>{{ svg-forward }}</i>{{ replyto }}</a>
|
||||||
|
{{ /if }}
|
||||||
|
|
||||||
|
<span class="spacer">•</span>
|
||||||
|
|
||||||
|
<a class="permalink" href="#isso-{{ id }}">
|
||||||
|
<date datetime="{{ created | datetime }}"></date>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<span class="note">
|
||||||
|
{{ if mode | equals : 2 }}
|
||||||
|
Kommentar muss noch freigeschaltet werden.
|
||||||
|
{{ /if }}
|
||||||
|
{{ if mode | equals : 4 }}
|
||||||
|
Kommentar gelöscht.
|
||||||
|
{{ /if }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
|
||||||
|
</header>
|
||||||
|
<div class="text">
|
||||||
|
{{ if mode | equals : 4 }}
|
||||||
|
<p> </p>
|
||||||
|
{{ else }}
|
||||||
|
{{ text }}
|
||||||
|
{{ /if }}
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
{{ if likes | substract : `dislikes` | notequals : 0 }}
|
||||||
|
<span class="votes">{{ likes | substract : `dislikes` }}</span>
|
||||||
|
{{ /if }}
|
||||||
|
<a class="upvote" href="#"><i>{{ svg-arrow-up}}</i></a>
|
||||||
|
<span class="spacer">|</span>
|
||||||
|
<a class="downvote" href="#"><i>{{ svg-arrow-down}}</i></a>
|
||||||
|
|
||||||
|
<a class="reply" href="#">{{ i18n-comment-reply }}</a>
|
||||||
|
<!--<a class="edit" href="#">Bearbeiten</a>-->
|
||||||
|
<a class="delete" href="#">{{ i18n-comment-delete }}</a>
|
||||||
|
</footer>
|
||||||
|
<div class="isso-follow-up">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
6
isso/js/text/forward.svg
Executable file
6
isso/js/text/forward.svg
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
<!-- Generator: IcoMoon.io --><svg width="10" height="10" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="gray">
|
||||||
|
<g>
|
||||||
|
<path d="M 17.961,11.954L 17.961,2 L 32,16L 17.961,30L 17.961,19.958 C 10.826,19.958, 3.784,21.2,0,27.094 C 0.394,16.353, 8.43,13.796, 17.961,11.954z">
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 357 B |
6
isso/js/text/html.js
Normal file
6
isso/js/text/html.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
define(["text!./postbox.html", "text!./comment.html"], function (postbox, comment) {
|
||||||
|
return {
|
||||||
|
postbox: postbox,
|
||||||
|
comment: comment
|
||||||
|
};
|
||||||
|
});
|
21
isso/js/text/postbox.html
Normal file
21
isso/js/text/postbox.html
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<div class="postbox">
|
||||||
|
<div class="avatar">
|
||||||
|
<canvas class="placeholder" height="48px" width="48px"></canvas>
|
||||||
|
</div>
|
||||||
|
<div class="form-wrapper">
|
||||||
|
<div class="textarea-wrapper">
|
||||||
|
<textarea name="text" rows="3" placeholder="{{ i18n-postbox-text }}"></textarea>
|
||||||
|
</div>
|
||||||
|
<section class="auth-section">
|
||||||
|
<p class="input-wrapper">
|
||||||
|
<input type="text" name="author" placeholder="{{ i18n-postbox-author }}"/>
|
||||||
|
</p>
|
||||||
|
<p class="input-wrapper">
|
||||||
|
<input type="email" name="email" placeholder="{{ i18n-postbox-email }}"/>
|
||||||
|
</p>
|
||||||
|
<p class="post-action">
|
||||||
|
<input type="submit" value="{{ i18n-postbox-submit }}"/>
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
7
isso/js/text/svg.js
Normal file
7
isso/js/text/svg.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
define(["text!./forward.svg", "text!./arrow-down.svg", "text!./arrow-up.svg"], function (forward, arrdown, arrup) {
|
||||||
|
return {
|
||||||
|
"forward": forward,
|
||||||
|
"arrow-down": arrdown,
|
||||||
|
"arrow-up": arrup
|
||||||
|
};
|
||||||
|
});
|
@ -31,6 +31,10 @@
|
|||||||
text-shadow: #aaaaaa 0px 0px 1px;
|
text-shadow: #aaaaaa 0px 0px 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span.votes, a.like, a.dislike {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
.isso-comment > header, .isso-comment > footer {
|
.isso-comment > header, .isso-comment > footer {
|
||||||
font-family: "Helvetica", Arial, sans-serif;
|
font-family: "Helvetica", Arial, sans-serif;
|
||||||
font-size: 0.80em;
|
font-size: 0.80em;
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
|
|
||||||
<title>Hello World</title>
|
<title>Hello World</title>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="stylesheet" href="/static/isso.css" />
|
<link rel="stylesheet" type="text/css" href="/static/sass/new.css" />
|
||||||
<script data-main="/js/embed" src="/js/require.js"></script>
|
<!--<script src="/static/less.js"></script>-->
|
||||||
|
<script data-main="/isso/js/embed" src="/isso/js/require.js"></script>
|
||||||
|
<!--<script src="/isso/js/embed.min.js"></script>-->
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
13
isso/static/sass/bourbon/_bourbon-deprecated-upcoming.scss
vendored
Normal file
13
isso/static/sass/bourbon/_bourbon-deprecated-upcoming.scss
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//************************************************************************//
|
||||||
|
// These mixins/functions are deprecated
|
||||||
|
// They will be removed in the next MAJOR version release
|
||||||
|
//************************************************************************//
|
||||||
|
@mixin box-shadow ($shadows...) {
|
||||||
|
@include prefixer(box-shadow, $shadows, spec);
|
||||||
|
@warn "box-shadow is deprecated and will be removed in the next major version release";
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin background-size ($lengths...) {
|
||||||
|
@include prefixer(background-size, $lengths, spec);
|
||||||
|
@warn "background-size is deprecated and will be removed in the next major version release";
|
||||||
|
}
|
59
isso/static/sass/bourbon/_bourbon.scss
vendored
Normal file
59
isso/static/sass/bourbon/_bourbon.scss
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Custom Helpers
|
||||||
|
@import "helpers/deprecated-webkit-gradient";
|
||||||
|
@import "helpers/gradient-positions-parser";
|
||||||
|
@import "helpers/linear-positions-parser";
|
||||||
|
@import "helpers/radial-arg-parser";
|
||||||
|
@import "helpers/radial-positions-parser";
|
||||||
|
@import "helpers/render-gradients";
|
||||||
|
@import "helpers/shape-size-stripper";
|
||||||
|
|
||||||
|
// Custom Functions
|
||||||
|
@import "functions/compact";
|
||||||
|
@import "functions/flex-grid";
|
||||||
|
@import "functions/grid-width";
|
||||||
|
@import "functions/linear-gradient";
|
||||||
|
@import "functions/modular-scale";
|
||||||
|
@import "functions/px-to-em";
|
||||||
|
@import "functions/radial-gradient";
|
||||||
|
@import "functions/tint-shade";
|
||||||
|
@import "functions/transition-property-name";
|
||||||
|
|
||||||
|
// CSS3 Mixins
|
||||||
|
@import "css3/animation";
|
||||||
|
@import "css3/appearance";
|
||||||
|
@import "css3/backface-visibility";
|
||||||
|
@import "css3/background";
|
||||||
|
@import "css3/background-image";
|
||||||
|
@import "css3/border-image";
|
||||||
|
@import "css3/border-radius";
|
||||||
|
@import "css3/box-sizing";
|
||||||
|
@import "css3/columns";
|
||||||
|
@import "css3/flex-box";
|
||||||
|
@import "css3/font-face";
|
||||||
|
@import "css3/hidpi-media-query";
|
||||||
|
@import "css3/image-rendering";
|
||||||
|
@import "css3/inline-block";
|
||||||
|
@import "css3/keyframes";
|
||||||
|
@import "css3/linear-gradient";
|
||||||
|
@import "css3/perspective";
|
||||||
|
@import "css3/radial-gradient";
|
||||||
|
@import "css3/transform";
|
||||||
|
@import "css3/transition";
|
||||||
|
@import "css3/user-select";
|
||||||
|
@import "css3/placeholder";
|
||||||
|
|
||||||
|
// Addons & other mixins
|
||||||
|
@import "addons/button";
|
||||||
|
@import "addons/clearfix";
|
||||||
|
@import "addons/font-family";
|
||||||
|
@import "addons/hide-text";
|
||||||
|
@import "addons/html5-input-types";
|
||||||
|
@import "addons/position";
|
||||||
|
@import "addons/prefixer";
|
||||||
|
@import "addons/retina-image";
|
||||||
|
@import "addons/size";
|
||||||
|
@import "addons/timing-functions";
|
||||||
|
@import "addons/triangle";
|
||||||
|
|
||||||
|
// Soon to be deprecated Mixins
|
||||||
|
@import "bourbon-deprecated-upcoming";
|
273
isso/static/sass/bourbon/addons/_button.scss
vendored
Normal file
273
isso/static/sass/bourbon/addons/_button.scss
vendored
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
@mixin button ($style: simple, $base-color: #4294f0) {
|
||||||
|
|
||||||
|
@if type-of($style) == color {
|
||||||
|
$base-color: $style;
|
||||||
|
$style: simple;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grayscale button
|
||||||
|
@if $base-color == grayscale($base-color) {
|
||||||
|
@if $style == simple {
|
||||||
|
@include simple($base-color, $grayscale: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $style == shiny {
|
||||||
|
@include shiny($base-color, $grayscale: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $style == pill {
|
||||||
|
@include pill($base-color, $grayscale: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Colored button
|
||||||
|
@else {
|
||||||
|
@if $style == simple {
|
||||||
|
@include simple($base-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $style == shiny {
|
||||||
|
@include shiny($base-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $style == pill {
|
||||||
|
@include pill($base-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Simple Button
|
||||||
|
//************************************************************************//
|
||||||
|
@mixin simple($base-color, $grayscale: false) {
|
||||||
|
$color: hsl(0, 0, 100%);
|
||||||
|
$border: adjust-color($base-color, $saturation: 9%, $lightness: -14%);
|
||||||
|
$inset-shadow: adjust-color($base-color, $saturation: -8%, $lightness: 15%);
|
||||||
|
$stop-gradient: adjust-color($base-color, $saturation: 9%, $lightness: -11%);
|
||||||
|
$text-shadow: adjust-color($base-color, $saturation: 15%, $lightness: -18%);
|
||||||
|
|
||||||
|
@if lightness($base-color) > 70% {
|
||||||
|
$color: hsl(0, 0, 20%);
|
||||||
|
$text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$border: grayscale($border);
|
||||||
|
$inset-shadow: grayscale($inset-shadow);
|
||||||
|
$stop-gradient: grayscale($stop-gradient);
|
||||||
|
$text-shadow: grayscale($text-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
border: 1px solid $border;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: inset 0 1px 0 0 $inset-shadow;
|
||||||
|
color: $color;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: bold;
|
||||||
|
@include linear-gradient ($base-color, $stop-gradient);
|
||||||
|
padding: 7px 18px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-shadow: 0 1px 0 $text-shadow;
|
||||||
|
background-clip: padding-box;
|
||||||
|
|
||||||
|
&:hover:not(:disabled) {
|
||||||
|
$base-color-hover: adjust-color($base-color, $saturation: -4%, $lightness: -5%);
|
||||||
|
$inset-shadow-hover: adjust-color($base-color, $saturation: -7%, $lightness: 5%);
|
||||||
|
$stop-gradient-hover: adjust-color($base-color, $saturation: 8%, $lightness: -14%);
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$base-color-hover: grayscale($base-color-hover);
|
||||||
|
$inset-shadow-hover: grayscale($inset-shadow-hover);
|
||||||
|
$stop-gradient-hover: grayscale($stop-gradient-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
box-shadow: inset 0 1px 0 0 $inset-shadow-hover;
|
||||||
|
cursor: pointer;
|
||||||
|
@include linear-gradient ($base-color-hover, $stop-gradient-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active:not(:disabled) {
|
||||||
|
$border-active: adjust-color($base-color, $saturation: 9%, $lightness: -14%);
|
||||||
|
$inset-shadow-active: adjust-color($base-color, $saturation: 7%, $lightness: -17%);
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$border-active: grayscale($border-active);
|
||||||
|
$inset-shadow-active: grayscale($inset-shadow-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
border: 1px solid $border-active;
|
||||||
|
box-shadow: inset 0 0 8px 4px $inset-shadow-active, inset 0 0 8px 4px $inset-shadow-active, 0 1px 1px 0 #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Shiny Button
|
||||||
|
//************************************************************************//
|
||||||
|
@mixin shiny($base-color, $grayscale: false) {
|
||||||
|
$color: hsl(0, 0, 100%);
|
||||||
|
$border: adjust-color($base-color, $red: -117, $green: -111, $blue: -81);
|
||||||
|
$border-bottom: adjust-color($base-color, $red: -126, $green: -127, $blue: -122);
|
||||||
|
$fourth-stop: adjust-color($base-color, $red: -79, $green: -70, $blue: -46);
|
||||||
|
$inset-shadow: adjust-color($base-color, $red: 37, $green: 29, $blue: 12);
|
||||||
|
$second-stop: adjust-color($base-color, $red: -56, $green: -50, $blue: -33);
|
||||||
|
$text-shadow: adjust-color($base-color, $red: -140, $green: -141, $blue: -114);
|
||||||
|
$third-stop: adjust-color($base-color, $red: -86, $green: -75, $blue: -48);
|
||||||
|
|
||||||
|
@if lightness($base-color) > 70% {
|
||||||
|
$color: hsl(0, 0, 20%);
|
||||||
|
$text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$border: grayscale($border);
|
||||||
|
$border-bottom: grayscale($border-bottom);
|
||||||
|
$fourth-stop: grayscale($fourth-stop);
|
||||||
|
$inset-shadow: grayscale($inset-shadow);
|
||||||
|
$second-stop: grayscale($second-stop);
|
||||||
|
$text-shadow: grayscale($text-shadow);
|
||||||
|
$third-stop: grayscale($third-stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
border: 1px solid $border;
|
||||||
|
border-bottom: 1px solid $border-bottom;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: inset 0 1px 0 0 $inset-shadow;
|
||||||
|
color: $color;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
@include linear-gradient(top, $base-color 0%, $second-stop 50%, $third-stop 50%, $fourth-stop 100%);
|
||||||
|
padding: 8px 20px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
text-shadow: 0 -1px 1px $text-shadow;
|
||||||
|
|
||||||
|
&:hover:not(:disabled) {
|
||||||
|
$first-stop-hover: adjust-color($base-color, $red: -13, $green: -15, $blue: -18);
|
||||||
|
$second-stop-hover: adjust-color($base-color, $red: -66, $green: -62, $blue: -51);
|
||||||
|
$third-stop-hover: adjust-color($base-color, $red: -93, $green: -85, $blue: -66);
|
||||||
|
$fourth-stop-hover: adjust-color($base-color, $red: -86, $green: -80, $blue: -63);
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$first-stop-hover: grayscale($first-stop-hover);
|
||||||
|
$second-stop-hover: grayscale($second-stop-hover);
|
||||||
|
$third-stop-hover: grayscale($third-stop-hover);
|
||||||
|
$fourth-stop-hover: grayscale($fourth-stop-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
@include linear-gradient(top, $first-stop-hover 0%,
|
||||||
|
$second-stop-hover 50%,
|
||||||
|
$third-stop-hover 50%,
|
||||||
|
$fourth-stop-hover 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active:not(:disabled) {
|
||||||
|
$inset-shadow-active: adjust-color($base-color, $red: -111, $green: -116, $blue: -122);
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$inset-shadow-active: grayscale($inset-shadow-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
box-shadow: inset 0 0 20px 0 $inset-shadow-active, 0 1px 0 #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Pill Button
|
||||||
|
//************************************************************************//
|
||||||
|
@mixin pill($base-color, $grayscale: false) {
|
||||||
|
$color: hsl(0, 0, 100%);
|
||||||
|
$border-bottom: adjust-color($base-color, $hue: 8, $saturation: -11%, $lightness: -26%);
|
||||||
|
$border-sides: adjust-color($base-color, $hue: 4, $saturation: -21%, $lightness: -21%);
|
||||||
|
$border-top: adjust-color($base-color, $hue: -1, $saturation: -30%, $lightness: -15%);
|
||||||
|
$inset-shadow: adjust-color($base-color, $hue: -1, $saturation: -1%, $lightness: 7%);
|
||||||
|
$stop-gradient: adjust-color($base-color, $hue: 8, $saturation: 14%, $lightness: -10%);
|
||||||
|
$text-shadow: adjust-color($base-color, $hue: 5, $saturation: -19%, $lightness: -15%);
|
||||||
|
|
||||||
|
@if lightness($base-color) > 70% {
|
||||||
|
$color: hsl(0, 0, 20%);
|
||||||
|
$text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$border-bottom: grayscale($border-bottom);
|
||||||
|
$border-sides: grayscale($border-sides);
|
||||||
|
$border-top: grayscale($border-top);
|
||||||
|
$inset-shadow: grayscale($inset-shadow);
|
||||||
|
$stop-gradient: grayscale($stop-gradient);
|
||||||
|
$text-shadow: grayscale($text-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
border: 1px solid $border-top;
|
||||||
|
border-color: $border-top $border-sides $border-bottom;
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: inset 0 1px 0 0 $inset-shadow, 0 1px 2px 0 #b3b3b3;
|
||||||
|
color: $color;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 1;
|
||||||
|
@include linear-gradient ($base-color, $stop-gradient);
|
||||||
|
padding: 5px 16px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
text-shadow: 0 -1px 1px $text-shadow;
|
||||||
|
background-clip: padding-box;
|
||||||
|
|
||||||
|
&:hover:not(:disabled) {
|
||||||
|
$base-color-hover: adjust-color($base-color, $lightness: -4.5%);
|
||||||
|
$border-bottom: adjust-color($base-color, $hue: 8, $saturation: 13.5%, $lightness: -32%);
|
||||||
|
$border-sides: adjust-color($base-color, $hue: 4, $saturation: -2%, $lightness: -27%);
|
||||||
|
$border-top: adjust-color($base-color, $hue: -1, $saturation: -17%, $lightness: -21%);
|
||||||
|
$inset-shadow-hover: adjust-color($base-color, $saturation: -1%, $lightness: 3%);
|
||||||
|
$stop-gradient-hover: adjust-color($base-color, $hue: 8, $saturation: -4%, $lightness: -15.5%);
|
||||||
|
$text-shadow-hover: adjust-color($base-color, $hue: 5, $saturation: -5%, $lightness: -22%);
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$base-color-hover: grayscale($base-color-hover);
|
||||||
|
$border-bottom: grayscale($border-bottom);
|
||||||
|
$border-sides: grayscale($border-sides);
|
||||||
|
$border-top: grayscale($border-top);
|
||||||
|
$inset-shadow-hover: grayscale($inset-shadow-hover);
|
||||||
|
$stop-gradient-hover: grayscale($stop-gradient-hover);
|
||||||
|
$text-shadow-hover: grayscale($text-shadow-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
border: 1px solid $border-top;
|
||||||
|
border-color: $border-top $border-sides $border-bottom;
|
||||||
|
box-shadow: inset 0 1px 0 0 $inset-shadow-hover;
|
||||||
|
cursor: pointer;
|
||||||
|
@include linear-gradient ($base-color-hover, $stop-gradient-hover);
|
||||||
|
text-shadow: 0 -1px 1px $text-shadow-hover;
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active:not(:disabled) {
|
||||||
|
$active-color: adjust-color($base-color, $hue: 4, $saturation: -12%, $lightness: -10%);
|
||||||
|
$border-active: adjust-color($base-color, $hue: 6, $saturation: -2.5%, $lightness: -30%);
|
||||||
|
$border-bottom-active: adjust-color($base-color, $hue: 11, $saturation: 6%, $lightness: -31%);
|
||||||
|
$inset-shadow-active: adjust-color($base-color, $hue: 9, $saturation: 2%, $lightness: -21.5%);
|
||||||
|
$text-shadow-active: adjust-color($base-color, $hue: 5, $saturation: -12%, $lightness: -21.5%);
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$active-color: grayscale($active-color);
|
||||||
|
$border-active: grayscale($border-active);
|
||||||
|
$border-bottom-active: grayscale($border-bottom-active);
|
||||||
|
$inset-shadow-active: grayscale($inset-shadow-active);
|
||||||
|
$text-shadow-active: grayscale($text-shadow-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
background: $active-color;
|
||||||
|
border: 1px solid $border-active;
|
||||||
|
border-bottom: 1px solid $border-bottom-active;
|
||||||
|
box-shadow: inset 0 0 6px 3px $inset-shadow-active, 0 1px 0 0 #fff;
|
||||||
|
text-shadow: 0 -1px 1px $text-shadow-active;
|
||||||
|
}
|
||||||
|
}
|
29
isso/static/sass/bourbon/addons/_clearfix.scss
vendored
Normal file
29
isso/static/sass/bourbon/addons/_clearfix.scss
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Micro clearfix provides an easy way to contain floats without adding additional markup
|
||||||
|
//
|
||||||
|
// Example usage:
|
||||||
|
//
|
||||||
|
// // Contain all floats within .wrapper
|
||||||
|
// .wrapper {
|
||||||
|
// @include clearfix;
|
||||||
|
// .content,
|
||||||
|
// .sidebar {
|
||||||
|
// float : left;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
@mixin clearfix {
|
||||||
|
*zoom: 1;
|
||||||
|
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
content: " ";
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Acknowledgements
|
||||||
|
// Micro clearfix: [Nicolas Gallagher](http://nicolasgallagher.com/micro-clearfix-hack/)
|
5
isso/static/sass/bourbon/addons/_font-family.scss
vendored
Normal file
5
isso/static/sass/bourbon/addons/_font-family.scss
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
$georgia: Georgia, Cambria, "Times New Roman", Times, serif;
|
||||||
|
$helvetica: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
$lucida-grande: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif;
|
||||||
|
$monospace: "Bitstream Vera Sans Mono", Consolas, Courier, monospace;
|
||||||
|
$verdana: Verdana, Geneva, sans-serif;
|
5
isso/static/sass/bourbon/addons/_hide-text.scss
vendored
Normal file
5
isso/static/sass/bourbon/addons/_hide-text.scss
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@mixin hide-text {
|
||||||
|
color: transparent;
|
||||||
|
font: 0/0 a;
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
56
isso/static/sass/bourbon/addons/_html5-input-types.scss
vendored
Normal file
56
isso/static/sass/bourbon/addons/_html5-input-types.scss
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//************************************************************************//
|
||||||
|
// Generate a variable ($all-text-inputs) with a list of all html5
|
||||||
|
// input types that have a text-based input, excluding textarea.
|
||||||
|
// http://diveintohtml5.org/forms.html
|
||||||
|
//************************************************************************//
|
||||||
|
$inputs-list: 'input[type="email"]',
|
||||||
|
'input[type="number"]',
|
||||||
|
'input[type="password"]',
|
||||||
|
'input[type="search"]',
|
||||||
|
'input[type="tel"]',
|
||||||
|
'input[type="text"]',
|
||||||
|
'input[type="url"]',
|
||||||
|
|
||||||
|
// Webkit & Gecko may change the display of these in the future
|
||||||
|
'input[type="color"]',
|
||||||
|
'input[type="date"]',
|
||||||
|
'input[type="datetime"]',
|
||||||
|
'input[type="datetime-local"]',
|
||||||
|
'input[type="month"]',
|
||||||
|
'input[type="time"]',
|
||||||
|
'input[type="week"]';
|
||||||
|
|
||||||
|
$unquoted-inputs-list: ();
|
||||||
|
@each $input-type in $inputs-list {
|
||||||
|
$unquoted-inputs-list: append($unquoted-inputs-list, unquote($input-type), comma);
|
||||||
|
}
|
||||||
|
|
||||||
|
$all-text-inputs: $unquoted-inputs-list;
|
||||||
|
|
||||||
|
|
||||||
|
// Hover Pseudo-class
|
||||||
|
//************************************************************************//
|
||||||
|
$all-text-inputs-hover: ();
|
||||||
|
@each $input-type in $unquoted-inputs-list {
|
||||||
|
$input-type-hover: $input-type + ":hover";
|
||||||
|
$all-text-inputs-hover: append($all-text-inputs-hover, $input-type-hover, comma);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Focus Pseudo-class
|
||||||
|
//************************************************************************//
|
||||||
|
$all-text-inputs-focus: ();
|
||||||
|
@each $input-type in $unquoted-inputs-list {
|
||||||
|
$input-type-focus: $input-type + ":focus";
|
||||||
|
$all-text-inputs-focus: append($all-text-inputs-focus, $input-type-focus, comma);
|
||||||
|
}
|
||||||
|
|
||||||
|
// You must use interpolation on the variable:
|
||||||
|
// #{$all-text-inputs}
|
||||||
|
// #{$all-text-inputs-hover}
|
||||||
|
// #{$all-text-inputs-focus}
|
||||||
|
|
||||||
|
// Example
|
||||||
|
//************************************************************************//
|
||||||
|
// #{$all-text-inputs}, textarea {
|
||||||
|
// border: 1px solid red;
|
||||||
|
// }
|
42
isso/static/sass/bourbon/addons/_position.scss
vendored
Normal file
42
isso/static/sass/bourbon/addons/_position.scss
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
@mixin position ($position: relative, $coordinates: 0 0 0 0) {
|
||||||
|
|
||||||
|
@if type-of($position) == list {
|
||||||
|
$coordinates: $position;
|
||||||
|
$position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
$top: nth($coordinates, 1);
|
||||||
|
$right: nth($coordinates, 2);
|
||||||
|
$bottom: nth($coordinates, 3);
|
||||||
|
$left: nth($coordinates, 4);
|
||||||
|
|
||||||
|
position: $position;
|
||||||
|
|
||||||
|
@if $top == auto {
|
||||||
|
top: $top;
|
||||||
|
}
|
||||||
|
@else if not(unitless($top)) {
|
||||||
|
top: $top;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $right == auto {
|
||||||
|
right: $right;
|
||||||
|
}
|
||||||
|
@else if not(unitless($right)) {
|
||||||
|
right: $right;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $bottom == auto {
|
||||||
|
bottom: $bottom;
|
||||||
|
}
|
||||||
|
@else if not(unitless($bottom)) {
|
||||||
|
bottom: $bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $left == auto {
|
||||||
|
left: $left;
|
||||||
|
}
|
||||||
|
@else if not(unitless($left)) {
|
||||||
|
left: $left;
|
||||||
|
}
|
||||||
|
}
|
49
isso/static/sass/bourbon/addons/_prefixer.scss
vendored
Normal file
49
isso/static/sass/bourbon/addons/_prefixer.scss
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//************************************************************************//
|
||||||
|
// Example: @include prefixer(border-radius, $radii, webkit ms spec);
|
||||||
|
//************************************************************************//
|
||||||
|
$prefix-for-webkit: true !default;
|
||||||
|
$prefix-for-mozilla: true !default;
|
||||||
|
$prefix-for-microsoft: true !default;
|
||||||
|
$prefix-for-opera: true !default;
|
||||||
|
$prefix-for-spec: true !default; // required for keyframe mixin
|
||||||
|
|
||||||
|
@mixin prefixer ($property, $value, $prefixes) {
|
||||||
|
@each $prefix in $prefixes {
|
||||||
|
@if $prefix == webkit {
|
||||||
|
@if $prefix-for-webkit {
|
||||||
|
-webkit-#{$property}: $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@else if $prefix == moz {
|
||||||
|
@if $prefix-for-mozilla {
|
||||||
|
-moz-#{$property}: $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@else if $prefix == ms {
|
||||||
|
@if $prefix-for-microsoft {
|
||||||
|
-ms-#{$property}: $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@else if $prefix == o {
|
||||||
|
@if $prefix-for-opera {
|
||||||
|
-o-#{$property}: $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@else if $prefix == spec {
|
||||||
|
@if $prefix-for-spec {
|
||||||
|
#{$property}: $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@else {
|
||||||
|
@warn "Unrecognized prefix: #{$prefix}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin disable-prefix-for-all() {
|
||||||
|
$prefix-for-webkit: false;
|
||||||
|
$prefix-for-mozilla: false;
|
||||||
|
$prefix-for-microsoft: false;
|
||||||
|
$prefix-for-opera: false;
|
||||||
|
$prefix-for-spec: false;
|
||||||
|
}
|
32
isso/static/sass/bourbon/addons/_retina-image.scss
vendored
Normal file
32
isso/static/sass/bourbon/addons/_retina-image.scss
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
@mixin retina-image($filename, $background-size, $extension: png, $retina-filename: null, $asset-pipeline: false) {
|
||||||
|
@if $asset-pipeline {
|
||||||
|
background-image: image-url("#{$filename}.#{$extension}");
|
||||||
|
}
|
||||||
|
@else {
|
||||||
|
background-image: url("#{$filename}.#{$extension}");
|
||||||
|
}
|
||||||
|
|
||||||
|
@include hidpi {
|
||||||
|
|
||||||
|
@if $asset-pipeline {
|
||||||
|
@if $retina-filename {
|
||||||
|
background-image: image-url("#{$retina-filename}.#{$extension}");
|
||||||
|
}
|
||||||
|
@else {
|
||||||
|
background-image: image-url("#{$filename}@2x.#{$extension}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
@if $retina-filename {
|
||||||
|
background-image: url("#{$retina-filename}.#{$extension}");
|
||||||
|
}
|
||||||
|
@else {
|
||||||
|
background-image: url("#{$filename}@2x.#{$extension}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background-size: $background-size;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
44
isso/static/sass/bourbon/addons/_size.scss
vendored
Normal file
44
isso/static/sass/bourbon/addons/_size.scss
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
@mixin size($size) {
|
||||||
|
@if length($size) == 1 {
|
||||||
|
@if $size == auto {
|
||||||
|
width: $size;
|
||||||
|
height: $size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if unitless($size) {
|
||||||
|
width: $size + px;
|
||||||
|
height: $size + px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if not(unitless($size)) {
|
||||||
|
width: $size;
|
||||||
|
height: $size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Width x Height
|
||||||
|
@if length($size) == 2 {
|
||||||
|
$width: nth($size, 1);
|
||||||
|
$height: nth($size, 2);
|
||||||
|
|
||||||
|
@if $width == auto {
|
||||||
|
width: $width;
|
||||||
|
}
|
||||||
|
@else if not(unitless($width)) {
|
||||||
|
width: $width;
|
||||||
|
}
|
||||||
|
@else if unitless($width) {
|
||||||
|
width: $width + px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $height == auto {
|
||||||
|
height: $height;
|
||||||
|
}
|
||||||
|
@else if not(unitless($height)) {
|
||||||
|
height: $height;
|
||||||
|
}
|
||||||
|
@else if unitless($height) {
|
||||||
|
height: $height + px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
isso/static/sass/bourbon/addons/_timing-functions.scss
vendored
Normal file
32
isso/static/sass/bourbon/addons/_timing-functions.scss
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// CSS cubic-bezier timing functions. Timing functions courtesy of jquery.easie (github.com/jaukia/easie)
|
||||||
|
// Timing functions are the same as demo'ed here: http://jqueryui.com/demos/effect/easing.html
|
||||||
|
|
||||||
|
// EASE IN
|
||||||
|
$ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530);
|
||||||
|
$ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190);
|
||||||
|
$ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220);
|
||||||
|
$ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||||
|
$ease-in-sine: cubic-bezier(0.470, 0.000, 0.745, 0.715);
|
||||||
|
$ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035);
|
||||||
|
$ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335);
|
||||||
|
$ease-in-back: cubic-bezier(0.600, -0.280, 0.735, 0.045);
|
||||||
|
|
||||||
|
// EASE OUT
|
||||||
|
$ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940);
|
||||||
|
$ease-out-cubic: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||||
|
$ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1.000);
|
||||||
|
$ease-out-quint: cubic-bezier(0.230, 1.000, 0.320, 1.000);
|
||||||
|
$ease-out-sine: cubic-bezier(0.390, 0.575, 0.565, 1.000);
|
||||||
|
$ease-out-expo: cubic-bezier(0.190, 1.000, 0.220, 1.000);
|
||||||
|
$ease-out-circ: cubic-bezier(0.075, 0.820, 0.165, 1.000);
|
||||||
|
$ease-out-back: cubic-bezier(0.175, 0.885, 0.320, 1.275);
|
||||||
|
|
||||||
|
// EASE IN OUT
|
||||||
|
$ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955);
|
||||||
|
$ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1.000);
|
||||||
|
$ease-in-out-quart: cubic-bezier(0.770, 0.000, 0.175, 1.000);
|
||||||
|
$ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000);
|
||||||
|
$ease-in-out-sine: cubic-bezier(0.445, 0.050, 0.550, 0.950);
|
||||||
|
$ease-in-out-expo: cubic-bezier(1.000, 0.000, 0.000, 1.000);
|
||||||
|
$ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.150, 0.860);
|
||||||
|
$ease-in-out-back: cubic-bezier(0.680, -0.550, 0.265, 1.550);
|
45
isso/static/sass/bourbon/addons/_triangle.scss
vendored
Normal file
45
isso/static/sass/bourbon/addons/_triangle.scss
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
@mixin triangle ($size, $color, $direction) {
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
|
||||||
|
@if ($direction == up) or ($direction == down) or ($direction == right) or ($direction == left) {
|
||||||
|
border-color: transparent;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: $size / 2;
|
||||||
|
|
||||||
|
@if $direction == up {
|
||||||
|
border-bottom-color: $color;
|
||||||
|
|
||||||
|
} @else if $direction == right {
|
||||||
|
border-left-color: $color;
|
||||||
|
|
||||||
|
} @else if $direction == down {
|
||||||
|
border-top-color: $color;
|
||||||
|
|
||||||
|
} @else if $direction == left {
|
||||||
|
border-right-color: $color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if ($direction == up-right) or ($direction == up-left) {
|
||||||
|
border-top: $size solid $color;
|
||||||
|
|
||||||
|
@if $direction == up-right {
|
||||||
|
border-left: $size solid transparent;
|
||||||
|
|
||||||
|
} @else if $direction == up-left {
|
||||||
|
border-right: $size solid transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if ($direction == down-right) or ($direction == down-left) {
|
||||||
|
border-bottom: $size solid $color;
|
||||||
|
|
||||||
|
@if $direction == down-right {
|
||||||
|
border-left: $size solid transparent;
|
||||||
|
|
||||||
|
} @else if $direction == down-left {
|
||||||
|
border-right: $size solid transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
52
isso/static/sass/bourbon/css3/_animation.scss
vendored
Normal file
52
isso/static/sass/bourbon/css3/_animation.scss
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// http://www.w3.org/TR/css3-animations/#the-animation-name-property-
|
||||||
|
// Each of these mixins support comma separated lists of values, which allows different transitions for individual properties to be described in a single style rule. Each value in the list corresponds to the value at that same position in the other properties.
|
||||||
|
|
||||||
|
// Official animation shorthand property.
|
||||||
|
@mixin animation ($animations...) {
|
||||||
|
@include prefixer(animation, $animations, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Individual Animation Properties
|
||||||
|
@mixin animation-name ($names...) {
|
||||||
|
@include prefixer(animation-name, $names, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@mixin animation-duration ($times...) {
|
||||||
|
@include prefixer(animation-duration, $times, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@mixin animation-timing-function ($motions...) {
|
||||||
|
// ease | linear | ease-in | ease-out | ease-in-out
|
||||||
|
@include prefixer(animation-timing-function, $motions, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@mixin animation-iteration-count ($values...) {
|
||||||
|
// infinite | <number>
|
||||||
|
@include prefixer(animation-iteration-count, $values, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@mixin animation-direction ($directions...) {
|
||||||
|
// normal | alternate
|
||||||
|
@include prefixer(animation-direction, $directions, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@mixin animation-play-state ($states...) {
|
||||||
|
// running | paused
|
||||||
|
@include prefixer(animation-play-state, $states, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@mixin animation-delay ($times...) {
|
||||||
|
@include prefixer(animation-delay, $times, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@mixin animation-fill-mode ($modes...) {
|
||||||
|
// none | forwards | backwards | both
|
||||||
|
@include prefixer(animation-fill-mode, $modes, webkit moz spec);
|
||||||
|
}
|
3
isso/static/sass/bourbon/css3/_appearance.scss
vendored
Normal file
3
isso/static/sass/bourbon/css3/_appearance.scss
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
@mixin appearance ($value) {
|
||||||
|
@include prefixer(appearance, $value, webkit moz ms o spec);
|
||||||
|
}
|
6
isso/static/sass/bourbon/css3/_backface-visibility.scss
vendored
Normal file
6
isso/static/sass/bourbon/css3/_backface-visibility.scss
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
//************************************************************************//
|
||||||
|
// Backface-visibility mixin
|
||||||
|
//************************************************************************//
|
||||||
|
@mixin backface-visibility($visibility) {
|
||||||
|
@include prefixer(backface-visibility, $visibility, webkit spec);
|
||||||
|
}
|
48
isso/static/sass/bourbon/css3/_background-image.scss
vendored
Normal file
48
isso/static/sass/bourbon/css3/_background-image.scss
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//************************************************************************//
|
||||||
|
// Background-image property for adding multiple background images with
|
||||||
|
// gradients, or for stringing multiple gradients together.
|
||||||
|
//************************************************************************//
|
||||||
|
|
||||||
|
@mixin background-image($images...) {
|
||||||
|
background-image: _add-prefix($images, webkit);
|
||||||
|
background-image: _add-prefix($images);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function _add-prefix($images, $vendor: false) {
|
||||||
|
$images-prefixed: ();
|
||||||
|
$gradient-positions: false;
|
||||||
|
@for $i from 1 through length($images) {
|
||||||
|
$type: type-of(nth($images, $i)); // Get type of variable - List or String
|
||||||
|
|
||||||
|
// If variable is a list - Gradient
|
||||||
|
@if $type == list {
|
||||||
|
$gradient-type: nth(nth($images, $i), 1); // linear or radial
|
||||||
|
$gradient-pos: null;
|
||||||
|
$gradient-args: null;
|
||||||
|
|
||||||
|
@if ($gradient-type == linear) or ($gradient-type == radial) {
|
||||||
|
$gradient-pos: nth(nth($images, $i), 2); // Get gradient position
|
||||||
|
$gradient-args: nth(nth($images, $i), 3); // Get actual gradient (red, blue)
|
||||||
|
}
|
||||||
|
@else {
|
||||||
|
$gradient-args: nth(nth($images, $i), 2); // Get actual gradient (red, blue)
|
||||||
|
}
|
||||||
|
|
||||||
|
$gradient-positions: _gradient-positions-parser($gradient-type, $gradient-pos);
|
||||||
|
$gradient: _render-gradients($gradient-positions, $gradient-args, $gradient-type, $vendor);
|
||||||
|
$images-prefixed: append($images-prefixed, $gradient, comma);
|
||||||
|
}
|
||||||
|
// If variable is a string - Image
|
||||||
|
@else if $type == string {
|
||||||
|
$images-prefixed: join($images-prefixed, nth($images, $i), comma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@return $images-prefixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Examples:
|
||||||
|
//@include background-image(linear-gradient(top, orange, red));
|
||||||
|
//@include background-image(radial-gradient(50% 50%, cover circle, orange, red));
|
||||||
|
//@include background-image(url("/images/a.png"), linear-gradient(orange, red));
|
||||||
|
//@include background-image(url("image.png"), linear-gradient(orange, red), url("image.png"));
|
||||||
|
//@include background-image(linear-gradient(hsla(0, 100%, 100%, 0.25) 0%, hsla(0, 100%, 100%, 0.08) 50%, transparent 50%), linear-gradient(orange, red));
|
103
isso/static/sass/bourbon/css3/_background.scss
vendored
Normal file
103
isso/static/sass/bourbon/css3/_background.scss
vendored
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
//************************************************************************//
|
||||||
|
// Background property for adding multiple backgrounds using shorthand
|
||||||
|
// notation.
|
||||||
|
//************************************************************************//
|
||||||
|
|
||||||
|
@mixin background(
|
||||||
|
$background-1 , $background-2: false,
|
||||||
|
$background-3: false, $background-4: false,
|
||||||
|
$background-5: false, $background-6: false,
|
||||||
|
$background-7: false, $background-8: false,
|
||||||
|
$background-9: false, $background-10: false,
|
||||||
|
$fallback: false
|
||||||
|
) {
|
||||||
|
$backgrounds: compact($background-1, $background-2,
|
||||||
|
$background-3, $background-4,
|
||||||
|
$background-5, $background-6,
|
||||||
|
$background-7, $background-8,
|
||||||
|
$background-9, $background-10);
|
||||||
|
|
||||||
|
$fallback-color: false;
|
||||||
|
@if (type-of($fallback) == color) or ($fallback == "transparent") {
|
||||||
|
$fallback-color: $fallback;
|
||||||
|
}
|
||||||
|
@else {
|
||||||
|
$fallback-color: _extract-background-color($backgrounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $fallback-color {
|
||||||
|
background-color: $fallback-color;
|
||||||
|
}
|
||||||
|
background: _background-add-prefix($backgrounds, webkit);
|
||||||
|
background: _background-add-prefix($backgrounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function _extract-background-color($backgrounds) {
|
||||||
|
$final-bg-layer: nth($backgrounds, length($backgrounds));
|
||||||
|
@if type-of($final-bg-layer) == list {
|
||||||
|
@for $i from 1 through length($final-bg-layer) {
|
||||||
|
$value: nth($final-bg-layer, $i);
|
||||||
|
@if type-of($value) == color {
|
||||||
|
@return $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@function _background-add-prefix($backgrounds, $vendor: false) {
|
||||||
|
$backgrounds-prefixed: ();
|
||||||
|
|
||||||
|
@for $i from 1 through length($backgrounds) {
|
||||||
|
$shorthand: nth($backgrounds, $i); // Get member for current index
|
||||||
|
$type: type-of($shorthand); // Get type of variable - List (gradient) or String (image)
|
||||||
|
|
||||||
|
// If shorthand is a list (gradient)
|
||||||
|
@if $type == list {
|
||||||
|
$first-member: nth($shorthand, 1); // Get first member of shorthand
|
||||||
|
|
||||||
|
// Linear Gradient
|
||||||
|
@if index(linear radial, nth($first-member, 1)) {
|
||||||
|
$gradient-type: nth($first-member, 1); // linear || radial
|
||||||
|
$gradient-args: false;
|
||||||
|
$gradient-positions: false;
|
||||||
|
$shorthand-start: false;
|
||||||
|
@if type-of($first-member) == list { // Linear gradient plus additional shorthand values - lg(red,orange)repeat,...
|
||||||
|
$gradient-positions: nth($first-member, 2);
|
||||||
|
$gradient-args: nth($first-member, 3);
|
||||||
|
$shorthand-start: 2;
|
||||||
|
}
|
||||||
|
@else { // Linear gradient only - lg(red,orange),...
|
||||||
|
$gradient-positions: nth($shorthand, 2);
|
||||||
|
$gradient-args: nth($shorthand, 3); // Get gradient (red, blue)
|
||||||
|
}
|
||||||
|
|
||||||
|
$gradient-positions: _gradient-positions-parser($gradient-type, $gradient-positions);
|
||||||
|
$gradient: _render-gradients($gradient-positions, $gradient-args, $gradient-type, $vendor);
|
||||||
|
|
||||||
|
// Append any additional shorthand args to gradient
|
||||||
|
@if $shorthand-start {
|
||||||
|
@for $j from $shorthand-start through length($shorthand) {
|
||||||
|
$gradient: join($gradient, nth($shorthand, $j), space);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$backgrounds-prefixed: append($backgrounds-prefixed, $gradient, comma);
|
||||||
|
}
|
||||||
|
// Image with additional properties
|
||||||
|
@else {
|
||||||
|
$backgrounds-prefixed: append($backgrounds-prefixed, $shorthand, comma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If shorthand is a simple string (color or image)
|
||||||
|
@else if $type == string {
|
||||||
|
$backgrounds-prefixed: join($backgrounds-prefixed, $shorthand, comma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@return $backgrounds-prefixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Examples:
|
||||||
|
//@include background(linear-gradient(top, orange, red));
|
||||||
|
//@include background(radial-gradient(circle at 40% 40%, orange, red));
|
||||||
|
//@include background(url("/images/a.png") no-repeat, linear-gradient(orange, red));
|
||||||
|
//@include background(url("image.png") center center, linear-gradient(orange, red), url("image.png"));
|
55
isso/static/sass/bourbon/css3/_border-image.scss
vendored
Normal file
55
isso/static/sass/bourbon/css3/_border-image.scss
vendored
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
@mixin border-image($images) {
|
||||||
|
-webkit-border-image: _border-add-prefix($images, webkit);
|
||||||
|
-moz-border-image: _border-add-prefix($images, moz);
|
||||||
|
-o-border-image: _border-add-prefix($images, o);
|
||||||
|
border-image: _border-add-prefix($images);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function _border-add-prefix($images, $vendor: false) {
|
||||||
|
$border-image: null;
|
||||||
|
$images-type: type-of(nth($images, 1));
|
||||||
|
$first-var: nth(nth($images, 1), 1); // Get type of Gradient (Linear || radial)
|
||||||
|
|
||||||
|
// If input is a gradient
|
||||||
|
@if $images-type == string {
|
||||||
|
@if ($first-var == "linear") or ($first-var == "radial") {
|
||||||
|
$gradient-type: nth($images, 1); // Get type of gradient (linear || radial)
|
||||||
|
$gradient-pos: nth($images, 2); // Get gradient position
|
||||||
|
$gradient-args: nth($images, 3); // Get actual gradient (red, blue)
|
||||||
|
$gradient-positions: _gradient-positions-parser($gradient-type, $gradient-pos);
|
||||||
|
$border-image: _render-gradients($gradient-positions, $gradient-args, $gradient-type, $vendor);
|
||||||
|
}
|
||||||
|
// If input is a URL
|
||||||
|
@else {
|
||||||
|
$border-image: $images;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If input is gradient or url + additional args
|
||||||
|
@else if $images-type == list {
|
||||||
|
$type: type-of(nth($images, 1)); // Get type of variable - List or String
|
||||||
|
|
||||||
|
// If variable is a list - Gradient
|
||||||
|
@if $type == list {
|
||||||
|
$gradient: nth($images, 1);
|
||||||
|
$gradient-type: nth($gradient, 1); // Get type of gradient (linear || radial)
|
||||||
|
$gradient-pos: nth($gradient, 2); // Get gradient position
|
||||||
|
$gradient-args: nth($gradient, 3); // Get actual gradient (red, blue)
|
||||||
|
$gradient-positions: _gradient-positions-parser($gradient-type, $gradient-pos);
|
||||||
|
$border-image: _render-gradients($gradient-positions, $gradient-args, $gradient-type, $vendor);
|
||||||
|
|
||||||
|
@for $i from 2 through length($images) {
|
||||||
|
$border-image: append($border-image, nth($images, $i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@return $border-image;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Examples:
|
||||||
|
// @include border-image(url("image.png"));
|
||||||
|
// @include border-image(url("image.png") 20 stretch);
|
||||||
|
// @include border-image(linear-gradient(45deg, orange, yellow));
|
||||||
|
// @include border-image(linear-gradient(45deg, orange, yellow) stretch);
|
||||||
|
// @include border-image(linear-gradient(45deg, orange, yellow) 20 30 40 50 stretch round);
|
||||||
|
// @include border-image(radial-gradient(top, cover, orange, yellow, orange));
|
||||||
|
|
22
isso/static/sass/bourbon/css3/_border-radius.scss
vendored
Normal file
22
isso/static/sass/bourbon/css3/_border-radius.scss
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
//************************************************************************//
|
||||||
|
// Shorthand Border-radius mixins
|
||||||
|
//************************************************************************//
|
||||||
|
@mixin border-top-radius($radii) {
|
||||||
|
@include prefixer(border-top-left-radius, $radii, spec);
|
||||||
|
@include prefixer(border-top-right-radius, $radii, spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin border-bottom-radius($radii) {
|
||||||
|
@include prefixer(border-bottom-left-radius, $radii, spec);
|
||||||
|
@include prefixer(border-bottom-right-radius, $radii, spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin border-left-radius($radii) {
|
||||||
|
@include prefixer(border-top-left-radius, $radii, spec);
|
||||||
|
@include prefixer(border-bottom-left-radius, $radii, spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin border-right-radius($radii) {
|
||||||
|
@include prefixer(border-top-right-radius, $radii, spec);
|
||||||
|
@include prefixer(border-bottom-right-radius, $radii, spec);
|
||||||
|
}
|
4
isso/static/sass/bourbon/css3/_box-sizing.scss
vendored
Normal file
4
isso/static/sass/bourbon/css3/_box-sizing.scss
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
@mixin box-sizing ($box) {
|
||||||
|
// content-box | border-box | inherit
|
||||||
|
@include prefixer(box-sizing, $box, webkit moz spec);
|
||||||
|
}
|
47
isso/static/sass/bourbon/css3/_columns.scss
vendored
Normal file
47
isso/static/sass/bourbon/css3/_columns.scss
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
@mixin columns($arg: auto) {
|
||||||
|
// <column-count> || <column-width>
|
||||||
|
@include prefixer(columns, $arg, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-count($int: auto) {
|
||||||
|
// auto || integer
|
||||||
|
@include prefixer(column-count, $int, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-gap($length: normal) {
|
||||||
|
// normal || length
|
||||||
|
@include prefixer(column-gap, $length, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-fill($arg: auto) {
|
||||||
|
// auto || length
|
||||||
|
@include prefixer(columns-fill, $arg, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-rule($arg) {
|
||||||
|
// <border-width> || <border-style> || <color>
|
||||||
|
@include prefixer(column-rule, $arg, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-rule-color($color) {
|
||||||
|
@include prefixer(column-rule-color, $color, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-rule-style($style: none) {
|
||||||
|
// none | hidden | dashed | dotted | double | groove | inset | inset | outset | ridge | solid
|
||||||
|
@include prefixer(column-rule-style, $style, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-rule-width ($width: none) {
|
||||||
|
@include prefixer(column-rule-width, $width, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-span($arg: none) {
|
||||||
|
// none || all
|
||||||
|
@include prefixer(column-span, $arg, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-width($length: auto) {
|
||||||
|
// auto || length
|
||||||
|
@include prefixer(column-width, $length, webkit moz spec);
|
||||||
|
}
|
52
isso/static/sass/bourbon/css3/_flex-box.scss
vendored
Normal file
52
isso/static/sass/bourbon/css3/_flex-box.scss
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// CSS3 Flexible Box Model and property defaults
|
||||||
|
|
||||||
|
// Custom shorthand notation for flexbox
|
||||||
|
@mixin box($orient: inline-axis, $pack: start, $align: stretch) {
|
||||||
|
@include display-box;
|
||||||
|
@include box-orient($orient);
|
||||||
|
@include box-pack($pack);
|
||||||
|
@include box-align($align);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin display-box {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -moz-box;
|
||||||
|
display: box;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-orient($orient: inline-axis) {
|
||||||
|
// horizontal|vertical|inline-axis|block-axis|inherit
|
||||||
|
@include prefixer(box-orient, $orient, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-pack($pack: start) {
|
||||||
|
// start|end|center|justify
|
||||||
|
@include prefixer(box-pack, $pack, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-align($align: stretch) {
|
||||||
|
// start|end|center|baseline|stretch
|
||||||
|
@include prefixer(box-align, $align, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-direction($direction: normal) {
|
||||||
|
// normal|reverse|inherit
|
||||||
|
@include prefixer(box-direction, $direction, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-lines($lines: single) {
|
||||||
|
// single|multiple
|
||||||
|
@include prefixer(box-lines, $lines, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-ordinal-group($int: 1) {
|
||||||
|
@include prefixer(box-ordinal-group, $int, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-flex($value: 0.0) {
|
||||||
|
@include prefixer(box-flex, $value, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-flex-group($int: 1) {
|
||||||
|
@include prefixer(box-flex-group, $int, webkit moz spec);
|
||||||
|
}
|
23
isso/static/sass/bourbon/css3/_font-face.scss
vendored
Normal file
23
isso/static/sass/bourbon/css3/_font-face.scss
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Order of the includes matters, and it is: normal, bold, italic, bold+italic.
|
||||||
|
|
||||||
|
@mixin font-face($font-family, $file-path, $weight: normal, $style: normal, $asset-pipeline: false ) {
|
||||||
|
@font-face {
|
||||||
|
font-family: $font-family;
|
||||||
|
font-weight: $weight;
|
||||||
|
font-style: $style;
|
||||||
|
|
||||||
|
@if $asset-pipeline == true {
|
||||||
|
src: font-url('#{$file-path}.eot');
|
||||||
|
src: font-url('#{$file-path}.eot?#iefix') format('embedded-opentype'),
|
||||||
|
font-url('#{$file-path}.woff') format('woff'),
|
||||||
|
font-url('#{$file-path}.ttf') format('truetype'),
|
||||||
|
font-url('#{$file-path}.svg##{$font-family}') format('svg');
|
||||||
|
} @else {
|
||||||
|
src: url('#{$file-path}.eot');
|
||||||
|
src: url('#{$file-path}.eot?#iefix') format('embedded-opentype'),
|
||||||
|
url('#{$file-path}.woff') format('woff'),
|
||||||
|
url('#{$file-path}.ttf') format('truetype'),
|
||||||
|
url('#{$file-path}.svg##{$font-family}') format('svg');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
isso/static/sass/bourbon/css3/_hidpi-media-query.scss
vendored
Normal file
10
isso/static/sass/bourbon/css3/_hidpi-media-query.scss
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// HiDPI mixin. Default value set to 1.3 to target Google Nexus 7 (http://bjango.com/articles/min-device-pixel-ratio/)
|
||||||
|
@mixin hidpi($ratio: 1.3) {
|
||||||
|
@media only screen and (-webkit-min-device-pixel-ratio: $ratio),
|
||||||
|
only screen and (min--moz-device-pixel-ratio: $ratio),
|
||||||
|
only screen and (-o-min-device-pixel-ratio: #{$ratio}/1),
|
||||||
|
only screen and (min-resolution: #{round($ratio*96)}dpi),
|
||||||
|
only screen and (min-resolution: #{$ratio}dppx) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
13
isso/static/sass/bourbon/css3/_image-rendering.scss
vendored
Normal file
13
isso/static/sass/bourbon/css3/_image-rendering.scss
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
@mixin image-rendering ($mode:optimizeQuality) {
|
||||||
|
|
||||||
|
@if ($mode == optimize-contrast) {
|
||||||
|
image-rendering: -moz-crisp-edges;
|
||||||
|
image-rendering: -o-crisp-edges;
|
||||||
|
image-rendering: -webkit-optimize-contrast;
|
||||||
|
image-rendering: optimize-contrast;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
image-rendering: $mode;
|
||||||
|
}
|
||||||
|
}
|
8
isso/static/sass/bourbon/css3/_inline-block.scss
vendored
Normal file
8
isso/static/sass/bourbon/css3/_inline-block.scss
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Legacy support for inline-block in IE7 (maybe IE6)
|
||||||
|
@mixin inline-block {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: baseline;
|
||||||
|
zoom: 1;
|
||||||
|
*display: inline;
|
||||||
|
*vertical-align: auto;
|
||||||
|
}
|
43
isso/static/sass/bourbon/css3/_keyframes.scss
vendored
Normal file
43
isso/static/sass/bourbon/css3/_keyframes.scss
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Adds keyframes blocks for supported prefixes, removing redundant prefixes in the block's content
|
||||||
|
@mixin keyframes($name) {
|
||||||
|
$original-prefix-for-webkit: $prefix-for-webkit;
|
||||||
|
$original-prefix-for-mozilla: $prefix-for-mozilla;
|
||||||
|
$original-prefix-for-microsoft: $prefix-for-microsoft;
|
||||||
|
$original-prefix-for-opera: $prefix-for-opera;
|
||||||
|
$original-prefix-for-spec: $prefix-for-spec;
|
||||||
|
|
||||||
|
@if $original-prefix-for-webkit {
|
||||||
|
@include disable-prefix-for-all();
|
||||||
|
$prefix-for-webkit: true;
|
||||||
|
@-webkit-keyframes #{$name} {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@if $original-prefix-for-mozilla {
|
||||||
|
@include disable-prefix-for-all();
|
||||||
|
$prefix-for-mozilla: true;
|
||||||
|
@-moz-keyframes #{$name} {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@if $original-prefix-for-opera {
|
||||||
|
@include disable-prefix-for-all();
|
||||||
|
$prefix-for-opera: true;
|
||||||
|
@-o-keyframes #{$name} {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@if $original-prefix-for-spec {
|
||||||
|
@include disable-prefix-for-all();
|
||||||
|
$prefix-for-spec: true;
|
||||||
|
@keyframes #{$name} {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$prefix-for-webkit: $original-prefix-for-webkit;
|
||||||
|
$prefix-for-mozilla: $original-prefix-for-mozilla;
|
||||||
|
$prefix-for-microsoft: $original-prefix-for-microsoft;
|
||||||
|
$prefix-for-opera: $original-prefix-for-opera;
|
||||||
|
$prefix-for-spec: $original-prefix-for-spec;
|
||||||
|
}
|
41
isso/static/sass/bourbon/css3/_linear-gradient.scss
vendored
Normal file
41
isso/static/sass/bourbon/css3/_linear-gradient.scss
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
@mixin linear-gradient($pos, $G1, $G2: false,
|
||||||
|
$G3: false, $G4: false,
|
||||||
|
$G5: false, $G6: false,
|
||||||
|
$G7: false, $G8: false,
|
||||||
|
$G9: false, $G10: false,
|
||||||
|
$deprecated-pos1: left top,
|
||||||
|
$deprecated-pos2: left bottom,
|
||||||
|
$fallback: false) {
|
||||||
|
// Detect what type of value exists in $pos
|
||||||
|
$pos-type: type-of(nth($pos, 1));
|
||||||
|
$pos-spec: null;
|
||||||
|
$pos-degree: null;
|
||||||
|
|
||||||
|
// If $pos is missing from mixin, reassign vars and add default position
|
||||||
|
@if ($pos-type == color) or (nth($pos, 1) == "transparent") {
|
||||||
|
$G10: $G9; $G9: $G8; $G8: $G7; $G7: $G6; $G6: $G5;
|
||||||
|
$G5: $G4; $G4: $G3; $G3: $G2; $G2: $G1; $G1: $pos;
|
||||||
|
$pos: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $pos {
|
||||||
|
$positions: _linear-positions-parser($pos);
|
||||||
|
$pos-degree: nth($positions, 1);
|
||||||
|
$pos-spec: nth($positions, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
$full: compact($G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10);
|
||||||
|
|
||||||
|
// Set $G1 as the default fallback color
|
||||||
|
$fallback-color: nth($G1, 1);
|
||||||
|
|
||||||
|
// If $fallback is a color use that color as the fallback color
|
||||||
|
@if (type-of($fallback) == color) or ($fallback == "transparent") {
|
||||||
|
$fallback-color: $fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
background-color: $fallback-color;
|
||||||
|
background-image: _deprecated-webkit-gradient(linear, $deprecated-pos1, $deprecated-pos2, $full); // Safari <= 5.0
|
||||||
|
background-image: -webkit-linear-gradient($pos-degree $full); // Safari 5.1+, Chrome
|
||||||
|
background-image: unquote("linear-gradient(#{$pos-spec}#{$full})");
|
||||||
|
}
|
8
isso/static/sass/bourbon/css3/_perspective.scss
vendored
Normal file
8
isso/static/sass/bourbon/css3/_perspective.scss
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
@mixin perspective($depth: none) {
|
||||||
|
// none | <length>
|
||||||
|
@include prefixer(perspective, $depth, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin perspective-origin($value: 50% 50%) {
|
||||||
|
@include prefixer(perspective-origin, $value, webkit moz spec);
|
||||||
|
}
|
29
isso/static/sass/bourbon/css3/_placeholder.scss
vendored
Normal file
29
isso/static/sass/bourbon/css3/_placeholder.scss
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
$placeholders: '-webkit-input-placeholder',
|
||||||
|
'-moz-placeholder',
|
||||||
|
'-ms-input-placeholder';
|
||||||
|
|
||||||
|
@mixin placeholder {
|
||||||
|
@each $placeholder in $placeholders {
|
||||||
|
@if $placeholder == "-webkit-input-placeholder" {
|
||||||
|
&::#{$placeholder} {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@else if $placeholder == "-moz-placeholder" {
|
||||||
|
// FF 18-
|
||||||
|
&:#{$placeholder} {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FF 19+
|
||||||
|
&::#{$placeholder} {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@else {
|
||||||
|
&:#{$placeholder} {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
isso/static/sass/bourbon/css3/_radial-gradient.scss
vendored
Normal file
44
isso/static/sass/bourbon/css3/_radial-gradient.scss
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Requires Sass 3.1+
|
||||||
|
@mixin radial-gradient($G1, $G2,
|
||||||
|
$G3: false, $G4: false,
|
||||||
|
$G5: false, $G6: false,
|
||||||
|
$G7: false, $G8: false,
|
||||||
|
$G9: false, $G10: false,
|
||||||
|
$pos: null,
|
||||||
|
$shape-size: null,
|
||||||
|
$deprecated-pos1: center center,
|
||||||
|
$deprecated-pos2: center center,
|
||||||
|
$deprecated-radius1: 0,
|
||||||
|
$deprecated-radius2: 460,
|
||||||
|
$fallback: false) {
|
||||||
|
|
||||||
|
$data: _radial-arg-parser($G1, $G2, $pos, $shape-size);
|
||||||
|
$G1: nth($data, 1);
|
||||||
|
$G2: nth($data, 2);
|
||||||
|
$pos: nth($data, 3);
|
||||||
|
$shape-size: nth($data, 4);
|
||||||
|
|
||||||
|
$full: compact($G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10);
|
||||||
|
|
||||||
|
// Strip deprecated cover/contain for spec
|
||||||
|
$shape-size-spec: _shape-size-stripper($shape-size);
|
||||||
|
|
||||||
|
// Set $G1 as the default fallback color
|
||||||
|
$first-color: nth($full, 1);
|
||||||
|
$fallback-color: nth($first-color, 1);
|
||||||
|
|
||||||
|
@if (type-of($fallback) == color) or ($fallback == "transparent") {
|
||||||
|
$fallback-color: $fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add Commas and spaces
|
||||||
|
$shape-size: if($shape-size, '#{$shape-size}, ', null);
|
||||||
|
$pos: if($pos, '#{$pos}, ', null);
|
||||||
|
$pos-spec: if($pos, 'at #{$pos}', null);
|
||||||
|
$shape-size-spec: if(($shape-size-spec != ' ') and ($pos == null), '#{$shape-size-spec}, ', '#{$shape-size-spec} ');
|
||||||
|
|
||||||
|
background-color: $fallback-color;
|
||||||
|
background-image: _deprecated-webkit-gradient(radial, $deprecated-pos1, $deprecated-pos2, $full, $deprecated-radius1, $deprecated-radius2); // Safari <= 5.0 && IOS 4
|
||||||
|
background-image: -webkit-radial-gradient(unquote(#{$pos}#{$shape-size}#{$full}));
|
||||||
|
background-image: unquote("radial-gradient(#{$shape-size-spec}#{$pos-spec}#{$full})");
|
||||||
|
}
|
15
isso/static/sass/bourbon/css3/_transform.scss
vendored
Normal file
15
isso/static/sass/bourbon/css3/_transform.scss
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
@mixin transform($property: none) {
|
||||||
|
// none | <transform-function>
|
||||||
|
@include prefixer(transform, $property, webkit moz ms o spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin transform-origin($axes: 50%) {
|
||||||
|
// x-axis - left | center | right | length | %
|
||||||
|
// y-axis - top | center | bottom | length | %
|
||||||
|
// z-axis - length
|
||||||
|
@include prefixer(transform-origin, $axes, webkit moz ms o spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin transform-style ($style: flat) {
|
||||||
|
@include prefixer(transform-style, $style, webkit moz ms o spec);
|
||||||
|
}
|
34
isso/static/sass/bourbon/css3/_transition.scss
vendored
Normal file
34
isso/static/sass/bourbon/css3/_transition.scss
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Shorthand mixin. Supports multiple parentheses-deliminated values for each variable.
|
||||||
|
// Example: @include transition (all, 2.0s, ease-in-out);
|
||||||
|
// @include transition ((opacity, width), (1.0s, 2.0s), ease-in, (0, 2s));
|
||||||
|
// @include transition ($property:(opacity, width), $delay: (1.5s, 2.5s));
|
||||||
|
|
||||||
|
@mixin transition ($properties...) {
|
||||||
|
@if length($properties) >= 1 {
|
||||||
|
@include prefixer(transition, $properties, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
$properties: all 0.15s ease-out 0;
|
||||||
|
@include prefixer(transition, $properties, webkit moz spec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin transition-property ($properties...) {
|
||||||
|
-webkit-transition-property: transition-property-names($properties, 'webkit');
|
||||||
|
-moz-transition-property: transition-property-names($properties, 'moz');
|
||||||
|
transition-property: transition-property-names($properties, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin transition-duration ($times...) {
|
||||||
|
@include prefixer(transition-duration, $times, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin transition-timing-function ($motions...) {
|
||||||
|
// ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier()
|
||||||
|
@include prefixer(transition-timing-function, $motions, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin transition-delay ($times...) {
|
||||||
|
@include prefixer(transition-delay, $times, webkit moz spec);
|
||||||
|
}
|
3
isso/static/sass/bourbon/css3/_user-select.scss
vendored
Normal file
3
isso/static/sass/bourbon/css3/_user-select.scss
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
@mixin user-select($arg: none) {
|
||||||
|
@include prefixer(user-select, $arg, webkit moz ms spec);
|
||||||
|
}
|
11
isso/static/sass/bourbon/functions/_compact.scss
vendored
Normal file
11
isso/static/sass/bourbon/functions/_compact.scss
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Remove `false` values from a list
|
||||||
|
|
||||||
|
@function compact($vars...) {
|
||||||
|
$list: ();
|
||||||
|
@each $var in $vars {
|
||||||
|
@if $var {
|
||||||
|
$list: append($list, $var, comma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@return $list;
|
||||||
|
}
|
39
isso/static/sass/bourbon/functions/_flex-grid.scss
vendored
Normal file
39
isso/static/sass/bourbon/functions/_flex-grid.scss
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Flexible grid
|
||||||
|
@function flex-grid($columns, $container-columns: $fg-max-columns) {
|
||||||
|
$width: $columns * $fg-column + ($columns - 1) * $fg-gutter;
|
||||||
|
$container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
|
||||||
|
@return percentage($width / $container-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flexible gutter
|
||||||
|
@function flex-gutter($container-columns: $fg-max-columns, $gutter: $fg-gutter) {
|
||||||
|
$container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
|
||||||
|
@return percentage($gutter / $container-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The $fg-column, $fg-gutter and $fg-max-columns variables must be defined in your base stylesheet to properly use the flex-grid function.
|
||||||
|
// This function takes the fluid grid equation (target / context = result) and uses columns to help define each.
|
||||||
|
//
|
||||||
|
// The calculation presumes that your column structure will be missing the last gutter:
|
||||||
|
//
|
||||||
|
// -- column -- gutter -- column -- gutter -- column
|
||||||
|
//
|
||||||
|
// $fg-column: 60px; // Column Width
|
||||||
|
// $fg-gutter: 25px; // Gutter Width
|
||||||
|
// $fg-max-columns: 12; // Total Columns For Main Container
|
||||||
|
//
|
||||||
|
// div {
|
||||||
|
// width: flex-grid(4); // returns (315px / 995px) = 31.65829%;
|
||||||
|
// margin-left: flex-gutter(); // returns (25px / 995px) = 2.51256%;
|
||||||
|
//
|
||||||
|
// p {
|
||||||
|
// width: flex-grid(2, 4); // returns (145px / 315px) = 46.031746%;
|
||||||
|
// float: left;
|
||||||
|
// margin: flex-gutter(4); // returns (25px / 315px) = 7.936508%;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// blockquote {
|
||||||
|
// float: left;
|
||||||
|
// width: flex-grid(2, 4); // returns (145px / 315px) = 46.031746%;
|
||||||
|
// }
|
||||||
|
// }
|
13
isso/static/sass/bourbon/functions/_grid-width.scss
vendored
Normal file
13
isso/static/sass/bourbon/functions/_grid-width.scss
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
@function grid-width($n) {
|
||||||
|
@return $n * $gw-column + ($n - 1) * $gw-gutter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The $gw-column and $gw-gutter variables must be defined in your base stylesheet to properly use the grid-width function.
|
||||||
|
//
|
||||||
|
// $gw-column: 100px; // Column Width
|
||||||
|
// $gw-gutter: 40px; // Gutter Width
|
||||||
|
//
|
||||||
|
// div {
|
||||||
|
// width: grid-width(4); // returns 520px;
|
||||||
|
// margin-left: $gw-gutter; // returns 40px;
|
||||||
|
// }
|
13
isso/static/sass/bourbon/functions/_linear-gradient.scss
vendored
Normal file
13
isso/static/sass/bourbon/functions/_linear-gradient.scss
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
@function linear-gradient($pos, $gradients...) {
|
||||||
|
$type: linear;
|
||||||
|
$pos-type: type-of(nth($pos, 1));
|
||||||
|
|
||||||
|
// if $pos doesn't exist, fix $gradient
|
||||||
|
@if ($pos-type == color) or (nth($pos, 1) == "transparent") {
|
||||||
|
$gradients: zip($pos $gradients);
|
||||||
|
$pos: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$type-gradient: $type, $pos, $gradients;
|
||||||
|
@return $type-gradient;
|
||||||
|
}
|
40
isso/static/sass/bourbon/functions/_modular-scale.scss
vendored
Normal file
40
isso/static/sass/bourbon/functions/_modular-scale.scss
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
@function modular-scale($value, $increment, $ratio) {
|
||||||
|
@if $increment > 0 {
|
||||||
|
@for $i from 1 through $increment {
|
||||||
|
$value: ($value * $ratio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $increment < 0 {
|
||||||
|
$increment: abs($increment);
|
||||||
|
@for $i from 1 through $increment {
|
||||||
|
$value: ($value / $ratio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// div {
|
||||||
|
// Increment Up GR with positive value
|
||||||
|
// font-size: modular-scale(14px, 1, 1.618); // returns: 22.652px
|
||||||
|
//
|
||||||
|
// Increment Down GR with negative value
|
||||||
|
// font-size: modular-scale(14px, -1, 1.618); // returns: 8.653px
|
||||||
|
//
|
||||||
|
// Can be used with ceil(round up) or floor(round down)
|
||||||
|
// font-size: floor( modular-scale(14px, 1, 1.618) ); // returns: 22px
|
||||||
|
// font-size: ceil( modular-scale(14px, 1, 1.618) ); // returns: 23px
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// modularscale.com
|
||||||
|
|
||||||
|
@function golden-ratio($value, $increment) {
|
||||||
|
@return modular-scale($value, $increment, 1.618)
|
||||||
|
}
|
||||||
|
|
||||||
|
// div {
|
||||||
|
// font-size: golden-ratio(14px, 1); // returns: 22.652px
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// goldenratiocalculator.com
|
8
isso/static/sass/bourbon/functions/_px-to-em.scss
vendored
Normal file
8
isso/static/sass/bourbon/functions/_px-to-em.scss
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Convert pixels to ems
|
||||||
|
// eg. for a relational value of 12px write em(12) when the parent is 16px
|
||||||
|
// if the parent is another value say 24px write em(12, 24)
|
||||||
|
|
||||||
|
@function em($pxval, $base: 16) {
|
||||||
|
@return ($pxval / $base) * 1em;
|
||||||
|
}
|
||||||
|
|
23
isso/static/sass/bourbon/functions/_radial-gradient.scss
vendored
Normal file
23
isso/static/sass/bourbon/functions/_radial-gradient.scss
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// This function is required and used by the background-image mixin.
|
||||||
|
@function radial-gradient($G1, $G2,
|
||||||
|
$G3: false, $G4: false,
|
||||||
|
$G5: false, $G6: false,
|
||||||
|
$G7: false, $G8: false,
|
||||||
|
$G9: false, $G10: false,
|
||||||
|
$pos: null,
|
||||||
|
$shape-size: null) {
|
||||||
|
|
||||||
|
$data: _radial-arg-parser($G1, $G2, $pos, $shape-size);
|
||||||
|
$G1: nth($data, 1);
|
||||||
|
$G2: nth($data, 2);
|
||||||
|
$pos: nth($data, 3);
|
||||||
|
$shape-size: nth($data, 4);
|
||||||
|
|
||||||
|
$type: radial;
|
||||||
|
$gradient: compact($G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10);
|
||||||
|
|
||||||
|
$type-gradient: $type, $shape-size $pos, $gradient;
|
||||||
|
@return $type-gradient;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
9
isso/static/sass/bourbon/functions/_tint-shade.scss
vendored
Normal file
9
isso/static/sass/bourbon/functions/_tint-shade.scss
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Add percentage of white to a color
|
||||||
|
@function tint($color, $percent){
|
||||||
|
@return mix(white, $color, $percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add percentage of black to a color
|
||||||
|
@function shade($color, $percent){
|
||||||
|
@return mix(black, $color, $percent);
|
||||||
|
}
|
22
isso/static/sass/bourbon/functions/_transition-property-name.scss
vendored
Normal file
22
isso/static/sass/bourbon/functions/_transition-property-name.scss
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Return vendor-prefixed property names if appropriate
|
||||||
|
// Example: transition-property-names((transform, color, background), moz) -> -moz-transform, color, background
|
||||||
|
//************************************************************************//
|
||||||
|
@function transition-property-names($props, $vendor: false) {
|
||||||
|
$new-props: ();
|
||||||
|
|
||||||
|
@each $prop in $props {
|
||||||
|
$new-props: append($new-props, transition-property-name($prop, $vendor), comma);
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $new-props;
|
||||||
|
}
|
||||||
|
|
||||||
|
@function transition-property-name($prop, $vendor: false) {
|
||||||
|
// put other properties that need to be prefixed here aswell
|
||||||
|
@if $vendor and $prop == transform {
|
||||||
|
@return unquote('-'+$vendor+'-'+$prop);
|
||||||
|
}
|
||||||
|
@else {
|
||||||
|
@return $prop;
|
||||||
|
}
|
||||||
|
}
|
39
isso/static/sass/bourbon/helpers/_deprecated-webkit-gradient.scss
vendored
Normal file
39
isso/static/sass/bourbon/helpers/_deprecated-webkit-gradient.scss
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Render Deprecated Webkit Gradient - Linear || Radial
|
||||||
|
//************************************************************************//
|
||||||
|
@function _deprecated-webkit-gradient($type,
|
||||||
|
$deprecated-pos1, $deprecated-pos2,
|
||||||
|
$full,
|
||||||
|
$deprecated-radius1: false, $deprecated-radius2: false) {
|
||||||
|
$gradient-list: ();
|
||||||
|
$gradient: false;
|
||||||
|
$full-length: length($full);
|
||||||
|
$percentage: false;
|
||||||
|
$gradient-type: $type;
|
||||||
|
|
||||||
|
@for $i from 1 through $full-length {
|
||||||
|
$gradient: nth($full, $i);
|
||||||
|
|
||||||
|
@if length($gradient) == 2 {
|
||||||
|
$color-stop: color-stop(nth($gradient, 2), nth($gradient, 1));
|
||||||
|
$gradient-list: join($gradient-list, $color-stop, comma);
|
||||||
|
}
|
||||||
|
@else if $gradient != null {
|
||||||
|
@if $i == $full-length {
|
||||||
|
$percentage: 100%;
|
||||||
|
}
|
||||||
|
@else {
|
||||||
|
$percentage: ($i - 1) * (100 / ($full-length - 1)) + "%";
|
||||||
|
}
|
||||||
|
$color-stop: color-stop(unquote($percentage), $gradient);
|
||||||
|
$gradient-list: join($gradient-list, $color-stop, comma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $type == radial {
|
||||||
|
$gradient: -webkit-gradient(radial, $deprecated-pos1, $deprecated-radius1, $deprecated-pos2, $deprecated-radius2, $gradient-list);
|
||||||
|
}
|
||||||
|
@else if $type == linear {
|
||||||
|
$gradient: -webkit-gradient(linear, $deprecated-pos1, $deprecated-pos2, $gradient-list);
|
||||||
|
}
|
||||||
|
@return $gradient;
|
||||||
|
}
|
13
isso/static/sass/bourbon/helpers/_gradient-positions-parser.scss
vendored
Normal file
13
isso/static/sass/bourbon/helpers/_gradient-positions-parser.scss
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
@function _gradient-positions-parser($gradient-type, $gradient-positions) {
|
||||||
|
@if $gradient-positions
|
||||||
|
and ($gradient-type == linear)
|
||||||
|
and (type-of($gradient-positions) != color) {
|
||||||
|
$gradient-positions: _linear-positions-parser($gradient-positions);
|
||||||
|
}
|
||||||
|
@else if $gradient-positions
|
||||||
|
and ($gradient-type == radial)
|
||||||
|
and (type-of($gradient-positions) != color) {
|
||||||
|
$gradient-positions: _radial-positions-parser($gradient-positions);
|
||||||
|
}
|
||||||
|
@return $gradient-positions;
|
||||||
|
}
|
61
isso/static/sass/bourbon/helpers/_linear-positions-parser.scss
vendored
Normal file
61
isso/static/sass/bourbon/helpers/_linear-positions-parser.scss
vendored
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
@function _linear-positions-parser($pos) {
|
||||||
|
$type: type-of(nth($pos, 1));
|
||||||
|
$spec: null;
|
||||||
|
$degree: null;
|
||||||
|
$side: null;
|
||||||
|
$corner: null;
|
||||||
|
$length: length($pos);
|
||||||
|
// Parse Side and corner positions
|
||||||
|
@if ($length > 1) {
|
||||||
|
@if nth($pos, 1) == "to" { // Newer syntax
|
||||||
|
$side: nth($pos, 2);
|
||||||
|
|
||||||
|
@if $length == 2 { // eg. to top
|
||||||
|
// Swap for backwards compatability
|
||||||
|
$degree: _position-flipper(nth($pos, 2));
|
||||||
|
}
|
||||||
|
@else if $length == 3 { // eg. to top left
|
||||||
|
$corner: nth($pos, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@else if $length == 2 { // Older syntax ("top left")
|
||||||
|
$side: _position-flipper(nth($pos, 1));
|
||||||
|
$corner: _position-flipper(nth($pos, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@if ("#{$side} #{$corner}" == "left top") or ("#{$side} #{$corner}" == "top left") {
|
||||||
|
$degree: _position-flipper(#{$side}) _position-flipper(#{$corner});
|
||||||
|
}
|
||||||
|
@else if ("#{$side} #{$corner}" == "right top") or ("#{$side} #{$corner}" == "top right") {
|
||||||
|
$degree: _position-flipper(#{$side}) _position-flipper(#{$corner});
|
||||||
|
}
|
||||||
|
@else if ("#{$side} #{$corner}" == "right bottom") or ("#{$side} #{$corner}" == "bottom right") {
|
||||||
|
$degree: _position-flipper(#{$side}) _position-flipper(#{$corner});
|
||||||
|
}
|
||||||
|
@else if ("#{$side} #{$corner}" == "left bottom") or ("#{$side} #{$corner}" == "bottom left") {
|
||||||
|
$degree: _position-flipper(#{$side}) _position-flipper(#{$corner});
|
||||||
|
}
|
||||||
|
$spec: to $side $corner;
|
||||||
|
}
|
||||||
|
@else if $length == 1 {
|
||||||
|
// Swap for backwards compatability
|
||||||
|
@if $type == string {
|
||||||
|
$degree: $pos;
|
||||||
|
$spec: to _position-flipper($pos);
|
||||||
|
}
|
||||||
|
@else {
|
||||||
|
$degree: -270 - $pos; //rotate the gradient opposite from spec
|
||||||
|
$spec: $pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$degree: unquote($degree + ",");
|
||||||
|
$spec: unquote($spec + ",");
|
||||||
|
@return $degree $spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
@function _position-flipper($pos) {
|
||||||
|
@return if($pos == left, right, null)
|
||||||
|
if($pos == right, left, null)
|
||||||
|
if($pos == top, bottom, null)
|
||||||
|
if($pos == bottom, top, null);
|
||||||
|
}
|
69
isso/static/sass/bourbon/helpers/_radial-arg-parser.scss
vendored
Normal file
69
isso/static/sass/bourbon/helpers/_radial-arg-parser.scss
vendored
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
@function _radial-arg-parser($G1, $G2, $pos, $shape-size) {
|
||||||
|
@each $value in $G1, $G2 {
|
||||||
|
$first-val: nth($value, 1);
|
||||||
|
$pos-type: type-of($first-val);
|
||||||
|
$spec-at-index: null;
|
||||||
|
|
||||||
|
// Determine if spec was passed to mixin
|
||||||
|
@if type-of($value) == list {
|
||||||
|
$spec-at-index: if(index($value, at), index($value, at), false);
|
||||||
|
}
|
||||||
|
@if $spec-at-index {
|
||||||
|
@if $spec-at-index > 1 {
|
||||||
|
@for $i from 1 through ($spec-at-index - 1) {
|
||||||
|
$shape-size: $shape-size nth($value, $i);
|
||||||
|
}
|
||||||
|
@for $i from ($spec-at-index + 1) through length($value) {
|
||||||
|
$pos: $pos nth($value, $i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@else if $spec-at-index == 1 {
|
||||||
|
@for $i from ($spec-at-index + 1) through length($value) {
|
||||||
|
$pos: $pos nth($value, $i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$G1: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not spec calculate correct values
|
||||||
|
@else {
|
||||||
|
@if ($pos-type != color) or ($first-val != "transparent") {
|
||||||
|
@if ($pos-type == number)
|
||||||
|
or ($first-val == "center")
|
||||||
|
or ($first-val == "top")
|
||||||
|
or ($first-val == "right")
|
||||||
|
or ($first-val == "bottom")
|
||||||
|
or ($first-val == "left") {
|
||||||
|
|
||||||
|
$pos: $value;
|
||||||
|
|
||||||
|
@if $pos == $G1 {
|
||||||
|
$G1: false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if
|
||||||
|
($first-val == "ellipse")
|
||||||
|
or ($first-val == "circle")
|
||||||
|
or ($first-val == "closest-side")
|
||||||
|
or ($first-val == "closest-corner")
|
||||||
|
or ($first-val == "farthest-side")
|
||||||
|
or ($first-val == "farthest-corner")
|
||||||
|
or ($first-val == "contain")
|
||||||
|
or ($first-val == "cover") {
|
||||||
|
|
||||||
|
$shape-size: $value;
|
||||||
|
|
||||||
|
@if $value == $G1 {
|
||||||
|
$G1: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $value == $G2 {
|
||||||
|
$G2: false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@return $G1, $G2, $pos, $shape-size;
|
||||||
|
}
|
18
isso/static/sass/bourbon/helpers/_radial-positions-parser.scss
vendored
Normal file
18
isso/static/sass/bourbon/helpers/_radial-positions-parser.scss
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
@function _radial-positions-parser($gradient-pos) {
|
||||||
|
$shape-size: nth($gradient-pos, 1);
|
||||||
|
$pos: nth($gradient-pos, 2);
|
||||||
|
$shape-size-spec: _shape-size-stripper($shape-size);
|
||||||
|
|
||||||
|
$pre-spec: unquote(if($pos, "#{$pos}, ", null))
|
||||||
|
unquote(if($shape-size, "#{$shape-size},", null));
|
||||||
|
$pos-spec: if($pos, "at #{$pos}", null);
|
||||||
|
|
||||||
|
$spec: "#{$shape-size-spec} #{$pos-spec}";
|
||||||
|
|
||||||
|
// Add comma
|
||||||
|
@if ($spec != ' ') {
|
||||||
|
$spec: "#{$spec},"
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $pre-spec $spec;
|
||||||
|
}
|
26
isso/static/sass/bourbon/helpers/_render-gradients.scss
vendored
Normal file
26
isso/static/sass/bourbon/helpers/_render-gradients.scss
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// User for linear and radial gradients within background-image or border-image properties
|
||||||
|
|
||||||
|
@function _render-gradients($gradient-positions, $gradients, $gradient-type, $vendor: false) {
|
||||||
|
$pre-spec: null;
|
||||||
|
$spec: null;
|
||||||
|
$vendor-gradients: null;
|
||||||
|
@if $gradient-type == linear {
|
||||||
|
@if $gradient-positions {
|
||||||
|
$pre-spec: nth($gradient-positions, 1);
|
||||||
|
$spec: nth($gradient-positions, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@else if $gradient-type == radial {
|
||||||
|
$pre-spec: nth($gradient-positions, 1);
|
||||||
|
$spec: nth($gradient-positions, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $vendor {
|
||||||
|
$vendor-gradients: -#{$vendor}-#{$gradient-type}-gradient(#{$pre-spec} $gradients);
|
||||||
|
}
|
||||||
|
@else if $vendor == false {
|
||||||
|
$vendor-gradients: "#{$gradient-type}-gradient(#{$spec} #{$gradients})";
|
||||||
|
$vendor-gradients: unquote($vendor-gradients);
|
||||||
|
}
|
||||||
|
@return $vendor-gradients;
|
||||||
|
}
|
10
isso/static/sass/bourbon/helpers/_shape-size-stripper.scss
vendored
Normal file
10
isso/static/sass/bourbon/helpers/_shape-size-stripper.scss
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
@function _shape-size-stripper($shape-size) {
|
||||||
|
$shape-size-spec: null;
|
||||||
|
@each $value in $shape-size {
|
||||||
|
@if ($value == "cover") or ($value == "contain") {
|
||||||
|
$value: null;
|
||||||
|
}
|
||||||
|
$shape-size-spec: "#{$shape-size-spec} #{$value}";
|
||||||
|
}
|
||||||
|
@return $shape-size-spec;
|
||||||
|
}
|
8
isso/static/sass/neat/_neat-helpers.scss
Normal file
8
isso/static/sass/neat/_neat-helpers.scss
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Functions
|
||||||
|
@import "functions/private";
|
||||||
|
@import "functions/new-breakpoint";
|
||||||
|
@import "functions/px-to-em";
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
@import "settings/grid";
|
||||||
|
@import "settings/visual-grid";
|
21
isso/static/sass/neat/_neat.scss
Normal file
21
isso/static/sass/neat/_neat.scss
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Bourbon Neat
|
||||||
|
// MIT Licensed
|
||||||
|
// Copyright (c) 2012-2013 thoughtbot, inc.
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
@import "neat-helpers";
|
||||||
|
|
||||||
|
// Grid
|
||||||
|
@import "grid/private";
|
||||||
|
@import "grid/reset";
|
||||||
|
@import "grid/grid";
|
||||||
|
@import "grid/omega";
|
||||||
|
@import "grid/outer-container";
|
||||||
|
@import "grid/span-columns";
|
||||||
|
@import "grid/row";
|
||||||
|
@import "grid/shift";
|
||||||
|
@import "grid/pad";
|
||||||
|
@import "grid/fill-parent";
|
||||||
|
@import "grid/media";
|
||||||
|
@import "grid/to-deprecate";
|
||||||
|
@import "grid/visual-grid";
|
16
isso/static/sass/neat/functions/_new-breakpoint.scss
Normal file
16
isso/static/sass/neat/functions/_new-breakpoint.scss
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
@function new-breakpoint($query:$feature $value $columns, $total-columns: $grid-columns) {
|
||||||
|
|
||||||
|
@if length($query) == 1 {
|
||||||
|
$query: $default-feature nth($query, 1) $total-columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if length($query) == 2 or length($query) == 4 {
|
||||||
|
$query: append($query, $total-columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if not belongs-to($query, $visual-grid-breakpoints) {
|
||||||
|
$visual-grid-breakpoints: append($visual-grid-breakpoints, $query, comma);
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $query;
|
||||||
|
}
|
107
isso/static/sass/neat/functions/_private.scss
Normal file
107
isso/static/sass/neat/functions/_private.scss
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
// Checks if a number is even
|
||||||
|
@function is-even($int) {
|
||||||
|
@if $int%2 == 0 {
|
||||||
|
@return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if an element belongs to a list
|
||||||
|
@function belongs-to($tested-item, $list) {
|
||||||
|
@each $item in $list {
|
||||||
|
@if $item == $tested-item {
|
||||||
|
@return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contains display value
|
||||||
|
@function contains-display-value($query) {
|
||||||
|
@if belongs-to(table, $query) or belongs-to(block, $query) or belongs-to(inline-block, $query) or belongs-to(inline, $query) {
|
||||||
|
@return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses the first argument of span-columns()
|
||||||
|
@function container-span($span: $span) {
|
||||||
|
@if length($span) == 3 {
|
||||||
|
$container-columns: nth($span, 3);
|
||||||
|
@return $container-columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if length($span) == 2 {
|
||||||
|
$container-columns: nth($span, 2);
|
||||||
|
@return $container-columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
@return $grid-columns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a striped background
|
||||||
|
@function gradient-stops($grid-columns, $color: $visual-grid-color) {
|
||||||
|
$transparent: rgba(0,0,0,0);
|
||||||
|
|
||||||
|
$column-width: flex-grid(1, $grid-columns);
|
||||||
|
$gutter-width: flex-gutter($grid-columns);
|
||||||
|
$column-offset: $column-width;
|
||||||
|
|
||||||
|
$values: ($transparent 0, $color 0);
|
||||||
|
|
||||||
|
@for $i from 1 to $grid-columns*2 {
|
||||||
|
@if is-even($i) {
|
||||||
|
$values: append($values, $transparent $column-offset, comma);
|
||||||
|
$values: append($values, $color $column-offset, comma);
|
||||||
|
$column-offset: $column-offset + $column-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
$values: append($values, $color $column-offset, comma);
|
||||||
|
$values: append($values, $transparent $column-offset, comma);
|
||||||
|
$column-offset: $column-offset + $gutter-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $values;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layout direction
|
||||||
|
@function get-direction($layout, $default) {
|
||||||
|
$direction: nil;
|
||||||
|
|
||||||
|
@if $layout == LTR or $layout == RTL {
|
||||||
|
$direction: direction-from-layout($layout);
|
||||||
|
} @else {
|
||||||
|
$direction: direction-from-layout($default);
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@function direction-from-layout($layout) {
|
||||||
|
$direction: nil;
|
||||||
|
|
||||||
|
@if $layout == LTR {
|
||||||
|
$direction: right;
|
||||||
|
} @else {
|
||||||
|
$direction: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@function get-opposite-direction($direction) {
|
||||||
|
$opposite-direction: left;
|
||||||
|
|
||||||
|
@if $direction == left {
|
||||||
|
$opposite-direction: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $opposite-direction;
|
||||||
|
}
|
3
isso/static/sass/neat/functions/_px-to-em.scss
Normal file
3
isso/static/sass/neat/functions/_px-to-em.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
@function em($pxval, $base: 16) {
|
||||||
|
@return ($pxval / $base) * 1em;
|
||||||
|
}
|
7
isso/static/sass/neat/grid/_fill-parent.scss
Normal file
7
isso/static/sass/neat/grid/_fill-parent.scss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
@mixin fill-parent() {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
@if $border-box-sizing == false {
|
||||||
|
@include box-sizing(border-box);
|
||||||
|
}
|
||||||
|
}
|
5
isso/static/sass/neat/grid/_grid.scss
Normal file
5
isso/static/sass/neat/grid/_grid.scss
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@if $border-box-sizing == true {
|
||||||
|
* {
|
||||||
|
@include box-sizing(border-box);
|
||||||
|
}
|
||||||
|
}
|
51
isso/static/sass/neat/grid/_media.scss
Normal file
51
isso/static/sass/neat/grid/_media.scss
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
@mixin media($query:$feature $value $columns, $total-columns: $grid-columns) {
|
||||||
|
|
||||||
|
@if length($query) == 1 {
|
||||||
|
@media screen and ($default-feature: nth($query, 1)) {
|
||||||
|
$default-grid-columns: $grid-columns;
|
||||||
|
$grid-columns: $total-columns;
|
||||||
|
@content;
|
||||||
|
$grid-columns: $default-grid-columns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if length($query) == 2 {
|
||||||
|
@media screen and (nth($query, 1): nth($query, 2)) {
|
||||||
|
$default-grid-columns: $grid-columns;
|
||||||
|
$grid-columns: $total-columns;
|
||||||
|
@content;
|
||||||
|
$grid-columns: $default-grid-columns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if length($query) == 3 {
|
||||||
|
@media screen and (nth($query, 1): nth($query, 2)) {
|
||||||
|
$default-grid-columns: $grid-columns;
|
||||||
|
$grid-columns: nth($query, 3);
|
||||||
|
@content;
|
||||||
|
$grid-columns: $default-grid-columns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if length($query) == 4 {
|
||||||
|
@media screen and (nth($query, 1): nth($query, 2)) and (nth($query, 3): nth($query, 4)) {
|
||||||
|
$default-grid-columns: $grid-columns;
|
||||||
|
$grid-columns: $total-columns;
|
||||||
|
@content;
|
||||||
|
$grid-columns: $default-grid-columns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if length($query) == 5 {
|
||||||
|
@media screen and (nth($query, 1): nth($query, 2)) and (nth($query, 3): nth($query, 4)) {
|
||||||
|
$default-grid-columns: $grid-columns;
|
||||||
|
$grid-columns: nth($query, 5);
|
||||||
|
@content;
|
||||||
|
$grid-columns: $default-grid-columns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
@warn "Wrong number of arguments for breakpoint(). Read the documentation for more details.";
|
||||||
|
}
|
||||||
|
}
|
79
isso/static/sass/neat/grid/_omega.scss
Normal file
79
isso/static/sass/neat/grid/_omega.scss
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// Remove last element gutter
|
||||||
|
@mixin omega($query: block, $direction: default) {
|
||||||
|
$table: if(belongs-to(table, $query), true, false);
|
||||||
|
$auto: if(belongs-to(auto, $query), true, false);
|
||||||
|
|
||||||
|
@if $direction != default {
|
||||||
|
@warn "The omega mixin will no longer take a $direction argument. To change the layout direction, use row($direction) or set $default-layout-direction instead."
|
||||||
|
} @else {
|
||||||
|
$direction: get-direction($layout-direction, $default-layout-direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if length($query) == 1 {
|
||||||
|
@if $auto {
|
||||||
|
&:last-child {
|
||||||
|
margin-#{$direction}: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if contains-display-value($query) {
|
||||||
|
@if $table {
|
||||||
|
padding-#{$direction}: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
margin-#{$direction}: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
@include nth-child($query, $direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if length($query) == 2 {
|
||||||
|
@if $table {
|
||||||
|
@if $auto {
|
||||||
|
&:last-child {
|
||||||
|
padding-#{$direction}: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
&:nth-child(#{nth($query, 1)}) {
|
||||||
|
padding-#{$direction}: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
@if $auto {
|
||||||
|
&:last-child {
|
||||||
|
margin-#{$direction}: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
@include nth-child(nth($query, 1), $direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
@warn "Too many arguments passed to the omega() mixin."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin nth-child($query, $direction) {
|
||||||
|
$opposite-direction: get-opposite-direction($direction);
|
||||||
|
|
||||||
|
&:nth-child(#{$query}) {
|
||||||
|
margin-#{$direction}: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if type-of($query) == number {
|
||||||
|
&:nth-child(#{$query}+1) {
|
||||||
|
clear: $opposite-direction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
isso/static/sass/neat/grid/_outer-container.scss
Normal file
8
isso/static/sass/neat/grid/_outer-container.scss
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
@mixin outer-container {
|
||||||
|
@include clearfix;
|
||||||
|
max-width: $max-width;
|
||||||
|
margin: {
|
||||||
|
left: auto;
|
||||||
|
right: auto;
|
||||||
|
}
|
||||||
|
}
|
8
isso/static/sass/neat/grid/_pad.scss
Normal file
8
isso/static/sass/neat/grid/_pad.scss
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
@mixin pad($padding: flex-gutter()) {
|
||||||
|
$padding-list: null;
|
||||||
|
@each $value in $padding {
|
||||||
|
$value: if($value == 'default', flex-gutter(), $value);
|
||||||
|
$padding-list: join($padding-list, $value);
|
||||||
|
}
|
||||||
|
padding: $padding-list;
|
||||||
|
}
|
50
isso/static/sass/neat/grid/_private.scss
Normal file
50
isso/static/sass/neat/grid/_private.scss
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
$parent-columns: $grid-columns !default;
|
||||||
|
$fg-column: $column;
|
||||||
|
$fg-gutter: $gutter;
|
||||||
|
$fg-max-columns: $grid-columns;
|
||||||
|
$container-display-table: false !default;
|
||||||
|
$layout-direction: nil !default;
|
||||||
|
|
||||||
|
@function flex-grid($columns, $container-columns: $fg-max-columns) {
|
||||||
|
$width: $columns * $fg-column + ($columns - 1) * $fg-gutter;
|
||||||
|
$container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
|
||||||
|
@return percentage($width / $container-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function flex-gutter($container-columns: $fg-max-columns, $gutter: $fg-gutter) {
|
||||||
|
$container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
|
||||||
|
@return percentage($gutter / $container-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function grid-width($n) {
|
||||||
|
@return $n * $gw-column + ($n - 1) * $gw-gutter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@function get-parent-columns($columns) {
|
||||||
|
@if $columns != $grid-columns {
|
||||||
|
$parent-columns: $columns;
|
||||||
|
} @else {
|
||||||
|
$parent-columns: $grid-columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $parent-columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
@function is-display-table($container-is-display-table, $display) {
|
||||||
|
$display-table: false;
|
||||||
|
|
||||||
|
@if $container-is-display-table == true {
|
||||||
|
$display-table: true;
|
||||||
|
} @else if $display == table {
|
||||||
|
$display-table: true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $display-table;
|
||||||
|
}
|
||||||
|
|
||||||
|
@function get-padding-for-table-layout($columns, $total-columns) {
|
||||||
|
$total-padding: flex-gutter($total-columns) * ($columns - 1);
|
||||||
|
$padding: $total-padding / $columns;
|
||||||
|
|
||||||
|
@return $padding;
|
||||||
|
}
|
12
isso/static/sass/neat/grid/_reset.scss
Normal file
12
isso/static/sass/neat/grid/_reset.scss
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
@mixin reset-display {
|
||||||
|
$container-display-table: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin reset-layout-direction {
|
||||||
|
$layout-direction: $default-layout-direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin reset-all {
|
||||||
|
@include reset-display;
|
||||||
|
@include reset-layout-direction;
|
||||||
|
}
|
17
isso/static/sass/neat/grid/_row.scss
Normal file
17
isso/static/sass/neat/grid/_row.scss
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
@mixin row($display: block, $direction: $default-layout-direction) {
|
||||||
|
@include clearfix;
|
||||||
|
$layout-direction: $direction;
|
||||||
|
|
||||||
|
@if $display == table {
|
||||||
|
display: table;
|
||||||
|
@include fill-parent;
|
||||||
|
table-layout: fixed;
|
||||||
|
$container-display-table: true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
display: block;
|
||||||
|
$container-display-table: false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
9
isso/static/sass/neat/grid/_shift.scss
Normal file
9
isso/static/sass/neat/grid/_shift.scss
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
@mixin shift($n-columns: 1) {
|
||||||
|
$direction: get-direction($layout-direction, $default-layout-direction);
|
||||||
|
$opposite-direction: get-opposite-direction($direction);
|
||||||
|
|
||||||
|
margin-#{$opposite-direction}: $n-columns * flex-grid(1, $parent-columns) + $n-columns * flex-gutter($parent-columns);
|
||||||
|
|
||||||
|
// Reset nesting context
|
||||||
|
$parent-columns: $grid-columns;
|
||||||
|
}
|
38
isso/static/sass/neat/grid/_span-columns.scss
Normal file
38
isso/static/sass/neat/grid/_span-columns.scss
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
@mixin span-columns($span: $columns of $container-columns, $display: block) {
|
||||||
|
$columns: nth($span, 1);
|
||||||
|
$container-columns: container-span($span);
|
||||||
|
|
||||||
|
// Set nesting context (used by shift())
|
||||||
|
$parent-columns: get-parent-columns($container-columns);
|
||||||
|
|
||||||
|
$direction: get-direction($layout-direction, $default-layout-direction);
|
||||||
|
$opposite-direction: get-opposite-direction($direction);
|
||||||
|
|
||||||
|
$display-table: is-display-table($container-display-table, $display);
|
||||||
|
|
||||||
|
@if $display-table {
|
||||||
|
$padding: get-padding-for-table-layout($columns, $container-columns);
|
||||||
|
display: table-cell;
|
||||||
|
padding-#{$direction}: $padding;
|
||||||
|
width: flex-grid($columns, $container-columns) + $padding;
|
||||||
|
} @else {
|
||||||
|
display: block;
|
||||||
|
float: #{$opposite-direction};
|
||||||
|
|
||||||
|
@if $display == collapse {
|
||||||
|
width: flex-grid($columns, $container-columns) + flex-gutter($container-columns);
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
width: flex-grid($columns, $container-columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
} @else {
|
||||||
|
margin-#{$direction}: flex-gutter($container-columns);
|
||||||
|
width: flex-grid($columns, $container-columns);
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-#{$direction}: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
isso/static/sass/neat/grid/_to-deprecate.scss
Normal file
57
isso/static/sass/neat/grid/_to-deprecate.scss
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
@mixin breakpoint($query:$feature $value $columns, $total-columns: $grid-columns) {
|
||||||
|
@warn "The breakpoint() mixin was renamed to media() in Neat 1.0. Please update your project with the new syntax before the next version bump.";
|
||||||
|
|
||||||
|
@if length($query) == 1 {
|
||||||
|
@media screen and ($default-feature: nth($query, 1)) {
|
||||||
|
$default-grid-columns: $grid-columns;
|
||||||
|
$grid-columns: $total-columns;
|
||||||
|
@content;
|
||||||
|
$grid-columns: $default-grid-columns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if length($query) == 2 {
|
||||||
|
@media screen and (nth($query, 1): nth($query, 2)) {
|
||||||
|
$default-grid-columns: $grid-columns;
|
||||||
|
$grid-columns: $total-columns;
|
||||||
|
@content;
|
||||||
|
$grid-columns: $default-grid-columns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if length($query) == 3 {
|
||||||
|
@media screen and (nth($query, 1): nth($query, 2)) {
|
||||||
|
$default-grid-columns: $grid-columns;
|
||||||
|
$grid-columns: nth($query, 3);
|
||||||
|
@content;
|
||||||
|
$grid-columns: $default-grid-columns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if length($query) == 4 {
|
||||||
|
@media screen and (nth($query, 1): nth($query, 2)) and (nth($query, 3): nth($query, 4)) {
|
||||||
|
$default-grid-columns: $grid-columns;
|
||||||
|
$grid-columns: $total-columns;
|
||||||
|
@content;
|
||||||
|
$grid-columns: $default-grid-columns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if length($query) == 5 {
|
||||||
|
@media screen and (nth($query, 1): nth($query, 2)) and (nth($query, 3): nth($query, 4)) {
|
||||||
|
$default-grid-columns: $grid-columns;
|
||||||
|
$grid-columns: nth($query, 5);
|
||||||
|
@content;
|
||||||
|
$grid-columns: $default-grid-columns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
@warn "Wrong number of arguments for breakpoint(). Read the documentation for more details.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin nth-omega($nth, $display: block, $direction: default) {
|
||||||
|
@warn "The nth-omega() mixin is deprecated. Please use omega() instead.";
|
||||||
|
@include omega($nth $display, $direction);
|
||||||
|
}
|
41
isso/static/sass/neat/grid/_visual-grid.scss
Normal file
41
isso/static/sass/neat/grid/_visual-grid.scss
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
@mixin grid-column-gradient($values...) {
|
||||||
|
background-image: deprecated-webkit-gradient(linear, left top, left bottom, $values);
|
||||||
|
background-image: -webkit-linear-gradient(left, $values);
|
||||||
|
background-image: -moz-linear-gradient(left, $values);
|
||||||
|
background-image: -ms-linear-gradient(left, $values);
|
||||||
|
background-image: -o-linear-gradient(left, $values);
|
||||||
|
background-image: unquote("linear-gradient(left, #{$values})");
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $visual-grid == true or $visual-grid == yes {
|
||||||
|
body:before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
@include grid-column-gradient(gradient-stops($grid-columns));
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: $max-width;
|
||||||
|
opacity: $visual-grid-opacity;
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
width: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
@if $visual-grid-index == back {
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $visual-grid-index == front {
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $breakpoint in $visual-grid-breakpoints {
|
||||||
|
@if $breakpoint != nil {
|
||||||
|
@include media($breakpoint) {
|
||||||
|
@include grid-column-gradient(gradient-stops($grid-columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
isso/static/sass/neat/settings/_grid.scss
Normal file
7
isso/static/sass/neat/settings/_grid.scss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
$column: golden-ratio(1em, 3) !default; // Column width
|
||||||
|
$gutter: golden-ratio(1em, 1) !default; // Gutter between each two columns
|
||||||
|
$grid-columns: 12 !default; // Total number of columns in the grid
|
||||||
|
$max-width: em(1088) !default; // Max-width of the outer container
|
||||||
|
$border-box-sizing: true !default; // Makes all elements have a border-box layout
|
||||||
|
$default-feature: min-width; // Default @media feature for the breakpoint() mixin
|
||||||
|
$default-layout-direction: LTR !default;
|
5
isso/static/sass/neat/settings/_visual-grid.scss
Normal file
5
isso/static/sass/neat/settings/_visual-grid.scss
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
$visual-grid: false !default; // Display the base grid
|
||||||
|
$visual-grid-color: #EEE !default;
|
||||||
|
$visual-grid-index: back !default; // Show grid behind content (back) or overlay it over the content (front)
|
||||||
|
$visual-grid-opacity: 0.4 !default;
|
||||||
|
$visual-grid-breakpoints: () !default;
|
200
isso/static/sass/new.scss
Normal file
200
isso/static/sass/new.scss
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
@import "bourbon/bourbon";
|
||||||
|
@import "neat/neat";
|
||||||
|
|
||||||
|
$avatar-bg-color: #F0F0F0;
|
||||||
|
|
||||||
|
@mixin isso-shadow {
|
||||||
|
border: 1px solid $avatar-bg-color;
|
||||||
|
border-radius: 2px;
|
||||||
|
box-shadow: 0px 0px 2px #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin reset {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.isso-popup {
|
||||||
|
font-family: Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 0.8em;
|
||||||
|
padding: 6px 8px;
|
||||||
|
margin-left: 20px;
|
||||||
|
border: 1px solid rgb(242, 122, 122);
|
||||||
|
border-radius: 2px;
|
||||||
|
background-color: rgb(242, 222, 222);
|
||||||
|
z-index: 9002;
|
||||||
|
}
|
||||||
|
|
||||||
|
#isso-thread {
|
||||||
|
|
||||||
|
@include reset;
|
||||||
|
|
||||||
|
> h4 {
|
||||||
|
color: #555;
|
||||||
|
font-weight: bold;
|
||||||
|
font-family: "Helvetica", Arial, sans-serif;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.parent-highlight {
|
||||||
|
background-color: #EFEFEF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.isso-comment {
|
||||||
|
@include outer-container;
|
||||||
|
|
||||||
|
margin: 0.95em 0px;
|
||||||
|
|
||||||
|
> div.avatar {
|
||||||
|
@include span-columns(1 of 11);
|
||||||
|
|
||||||
|
> canvas {
|
||||||
|
@include isso-shadow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> div.text-wrapper {
|
||||||
|
@include span-columns(10 of 11);
|
||||||
|
|
||||||
|
> header, > footer {
|
||||||
|
font-size: 0.95em;
|
||||||
|
}
|
||||||
|
|
||||||
|
> header {
|
||||||
|
font-family: "Helvetica", Arial, sans-serif;
|
||||||
|
font-size: 0.85em;
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
padding-left: 6px;
|
||||||
|
padding-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer, a.permalink, .note, a.parent {
|
||||||
|
color: gray !important;
|
||||||
|
font-weight: normal;
|
||||||
|
|
||||||
|
text-shadow: none !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #606060 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.note { float: right }
|
||||||
|
|
||||||
|
.author {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> div.text {
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: 0.2em;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> footer {
|
||||||
|
|
||||||
|
font-family: "Helvetica", Arial, sans-serif;
|
||||||
|
font-size: 0.80em;
|
||||||
|
|
||||||
|
color: gray !important;
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration: none;
|
||||||
|
&:hover {
|
||||||
|
color: #111111 !important;
|
||||||
|
text-shadow: #aaaaaa 0px 0px 1px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.reply, a.delete {
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.votes {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upvote svg, .downvote svg {
|
||||||
|
margin-bottom: -0.2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.postbox {
|
||||||
|
margin-top: 0.8em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.postbox {
|
||||||
|
@include outer-container;
|
||||||
|
|
||||||
|
> .avatar {
|
||||||
|
@include span-columns(1 of 11);
|
||||||
|
|
||||||
|
> canvas {
|
||||||
|
@include isso-shadow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .form-wrapper {
|
||||||
|
@include span-columns(10 of 11);
|
||||||
|
|
||||||
|
> .auth-section {
|
||||||
|
@include outer-container;
|
||||||
|
|
||||||
|
.input-wrapper {
|
||||||
|
@include span-columns(2 of 5);
|
||||||
|
|
||||||
|
margin-top: 0.1em;
|
||||||
|
|
||||||
|
input {
|
||||||
|
@include fill-parent;
|
||||||
|
@include isso-shadow;
|
||||||
|
@include pad(0.4em);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-action {
|
||||||
|
@include span-columns(1 of 5);
|
||||||
|
margin-top: 0.1em;
|
||||||
|
|
||||||
|
> input {
|
||||||
|
padding: 0.4em 1em;
|
||||||
|
|
||||||
|
border-radius: 2px;
|
||||||
|
border: #CCC solid 1px;
|
||||||
|
|
||||||
|
background-color: #DDD;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #CCC;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: #BBB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
@include fill-parent;
|
||||||
|
@include isso-shadow;
|
||||||
|
min-height: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user