Initial import
This commit is contained in:
commit
9f6fb1a2c5
32 changed files with 2330 additions and 0 deletions
66
2008.ie-valign.css
Normal file
66
2008.ie-valign.css
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* @group valignfix */
|
||||||
|
/* ***************************************
|
||||||
|
valignfix, by Anders Ytterström @ madr.se
|
||||||
|
**************************************** */
|
||||||
|
/*
|
||||||
|
HTML fixture:
|
||||||
|
.valign
|
||||||
|
%div
|
||||||
|
%div
|
||||||
|
%h1
|
||||||
|
%h2
|
||||||
|
%img
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* @group ie8, ff, opera, safari
|
||||||
|
===================================== */
|
||||||
|
body > div {
|
||||||
|
display:table;
|
||||||
|
}
|
||||||
|
*.valign {
|
||||||
|
display:table-row;
|
||||||
|
}
|
||||||
|
*.valign > * {
|
||||||
|
width:50%;
|
||||||
|
display:table-cell;
|
||||||
|
vertical-align:middle;
|
||||||
|
}
|
||||||
|
/* @end ie8, ff, opera, safari
|
||||||
|
===================================== */
|
||||||
|
|
||||||
|
/* @group ie6,ie7
|
||||||
|
===================================== */
|
||||||
|
/*
|
||||||
|
use this in CC file.
|
||||||
|
Works only in standards mode.
|
||||||
|
*/
|
||||||
|
* html *.valign,
|
||||||
|
*+html *.valign {
|
||||||
|
position:relative;
|
||||||
|
overflow:auto;
|
||||||
|
}
|
||||||
|
* html *.valign div,
|
||||||
|
*+html *.valign div {
|
||||||
|
position:absolute;
|
||||||
|
top:50%;
|
||||||
|
}
|
||||||
|
* html *.valign div div,
|
||||||
|
*+html *.valign div div {
|
||||||
|
position:relative;
|
||||||
|
top:-50%;
|
||||||
|
}
|
||||||
|
* html *.valign div div *,
|
||||||
|
*+html *.valign div div * {
|
||||||
|
position:static;
|
||||||
|
top:0;
|
||||||
|
}
|
||||||
|
* html *.valign img,
|
||||||
|
*+html *.valign img {
|
||||||
|
float:right;
|
||||||
|
}
|
||||||
|
/* @end ie6, ie7
|
||||||
|
===================================== */
|
||||||
|
/* ****************************************
|
||||||
|
/valignfix, by Anders Ytterström @ madr.se
|
||||||
|
**************************************** */
|
||||||
|
/* @end valignfix */
|
||||||
4
2011.fix-outlook-2011-utf8-decoded-mails.php
Normal file
4
2011.fix-outlook-2011-utf8-decoded-mails.php
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?php
|
||||||
|
$subject = "=?UTF-8?B?" . base64_encode($subject) . "?=";
|
||||||
|
|
||||||
|
// mail( ... )
|
||||||
67
2011.js.click-event-delegator.js
Normal file
67
2011.js.click-event-delegator.js
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*!
|
||||||
|
light-weight click listener, v 1.0
|
||||||
|
Copyright (c) 2010 by madr <http://madr.se>
|
||||||
|
Licensed under the MIT license: http://en.wikipedia.org/wiki/MIT_License
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
Usage:
|
||||||
|
Alter the below snippet for your needs and put the modified snippet in a js-file or a <script> and add it to your document. If your webapp depends on libraries or other resources to load, you better keep that in mind.
|
||||||
|
*/
|
||||||
|
(function(document, undefined) {
|
||||||
|
function investigate(elm){
|
||||||
|
/*
|
||||||
|
Change the content of this function
|
||||||
|
to suit your web application.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
EXAMPLE 0: do nothing until jQuery (or other libraries) is loaded.
|
||||||
|
if (typeof window.jQuery == 'undefined') { return false; }
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
EXAMPLE 1: look for element type
|
||||||
|
if (elm.nodeName == 'A') {
|
||||||
|
// do stuff ...
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
EXAMPLE 2: look for id or other property
|
||||||
|
if (elm.id == 'modal-window-opener') {
|
||||||
|
// do stuff ...
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
EXAMPLE 3: sniffing a classname
|
||||||
|
if (elm.className.match(/read-more/)) {
|
||||||
|
// do stuff ...
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return false; // default
|
||||||
|
}
|
||||||
|
|
||||||
|
function clicklistener(evt){
|
||||||
|
var event = evt || window.event,
|
||||||
|
elm = event.target || window.srcElement,
|
||||||
|
magic_did_happen = investigate(elm);
|
||||||
|
|
||||||
|
if (magic_did_happen) {
|
||||||
|
if (window.event) { window.eventReturnValue = false; }
|
||||||
|
else { evt.preventDefault(); }
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.attachEvent) {
|
||||||
|
document.attachEvent('onclick', clicklistener);
|
||||||
|
} else {
|
||||||
|
document.addEventListener('click', clicklistener, false);
|
||||||
|
}
|
||||||
|
})(document);
|
||||||
96
2011.js.frontcontroller-skeleton.js
Normal file
96
2011.js.frontcontroller-skeleton.js
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*jshint forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true, strict:true, undef:true, curly:true, browser:true, indent:2, maxerr:50 */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
front.js
|
||||||
|
(c) 2011 Anders Ytterström
|
||||||
|
front.js may be freely distributed under the MIT license.
|
||||||
|
TODO: pushState support
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
USAGE: A route is defined by a path (could be a simple string or a regexp) and a callback (a function).
|
||||||
|
|
||||||
|
// static routes
|
||||||
|
front("books", displayBooks);
|
||||||
|
front("talks", displayTalks);
|
||||||
|
front("comments", displayComments);
|
||||||
|
|
||||||
|
// dynamic routes
|
||||||
|
front(/book:[\d+]$/, displayBookDetail);
|
||||||
|
front(/talk:[\d+]$/, displayTalkDetail);
|
||||||
|
front(/comment:[\d]$/, displayCommentDetail);
|
||||||
|
|
||||||
|
The frontcontroller should be executed when all dependencies are in place and the routes are configured.
|
||||||
|
|
||||||
|
front.run(); // defaults to location.hash -> http://example.com
|
||||||
|
front.run("book:12"); // goto book 12 -> http://example.com#!book:12
|
||||||
|
|
||||||
|
location.hash is altered everytime front.run is executed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (global) {
|
||||||
|
"use strict";
|
||||||
|
var i, _regexps = [], _statics = [];
|
||||||
|
|
||||||
|
function addRoute(path, callback) {
|
||||||
|
if (typeof path !== "string") { // regexp
|
||||||
|
_regexps.push([ path, callback ]);
|
||||||
|
} else {
|
||||||
|
_statics.push([ path, callback ]);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispatch(path) {
|
||||||
|
// set path
|
||||||
|
if (typeof path === "undefined") {
|
||||||
|
path = location.hash || "";
|
||||||
|
path = path.replace(/^#/, '').replace(/^!/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// cleanup
|
||||||
|
var action, args;
|
||||||
|
|
||||||
|
// static routes lookup
|
||||||
|
i = _statics.length;
|
||||||
|
while (i--) {
|
||||||
|
if (_statics[i][0] === path) {
|
||||||
|
action = _statics[i][1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// regexp routes lookup unless a static action was defined.
|
||||||
|
if (typeof action !== "function") {
|
||||||
|
i = _regexps.length;
|
||||||
|
while (i--) {
|
||||||
|
args = args = path.match(_regexps[i][0]);
|
||||||
|
if (args) {
|
||||||
|
action = _regexps[i][1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute action and update hash unless the action is still undefined
|
||||||
|
if (typeof action === "function") {
|
||||||
|
if (args instanceof Array) {
|
||||||
|
args.shift();
|
||||||
|
if (args.length === 1) { args = args[0]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
action(args);
|
||||||
|
|
||||||
|
path = (path.length ? '#!': '') + path;
|
||||||
|
|
||||||
|
if (location.hash !== path) {
|
||||||
|
location.hash = path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // for click events.
|
||||||
|
}
|
||||||
|
|
||||||
|
global.front = addRoute;
|
||||||
|
global.front.run = dispatch;
|
||||||
|
})(this);
|
||||||
14
2011.js.hex2rgb.js
Normal file
14
2011.js.hex2rgb.js
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
function hex2rgb(hex, opacity) {
|
||||||
|
var rgb = hex.replace('#', '').match(/(.{2})/g);
|
||||||
|
|
||||||
|
var i = 3;
|
||||||
|
while (i--) {
|
||||||
|
rgb[i] = parseInt(rgb[i], 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof opacity == 'undefined') {
|
||||||
|
return 'rgb(' + rgb.join(', ') + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'rgba(' + rgb.join(', ') + ', ' + opacity + ')';
|
||||||
|
};
|
||||||
17
2011.js.rel-ymd-date-str.js
Normal file
17
2011.js.rel-ymd-date-str.js
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
function adate(daysFromNow) {
|
||||||
|
var date, datestr, mm, dd;
|
||||||
|
datestr = new Date().getTime();
|
||||||
|
if (!!daysFromNow) {
|
||||||
|
datestr += (1000 * 60 * 60 * 24 * daysFromNow);
|
||||||
|
}
|
||||||
|
date = new Date(datestr);
|
||||||
|
mm = date.getMonth() + '';
|
||||||
|
if (mm.length == 1) {
|
||||||
|
mm = '0' + mm;
|
||||||
|
}
|
||||||
|
dd = date.getDate() + '';
|
||||||
|
if (dd.length == 1) {
|
||||||
|
dd = '0' + dd;
|
||||||
|
}
|
||||||
|
return date.getFullYear() + '-' + mm + '-' + dd;
|
||||||
|
}
|
||||||
45
2011.rake-target-generate-favicons-apple-touch-icons.rb
Normal file
45
2011.rake-target-generate-favicons-apple-touch-icons.rb
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
# example use:
|
||||||
|
# rake favicons["../img/origin.png"]
|
||||||
|
#
|
||||||
|
# Output:
|
||||||
|
# ./apple-touch-icon-114x114-precomposed.png
|
||||||
|
# ./apple-touch-icon-114x114.png
|
||||||
|
# ./apple-touch-icon-57x57-precomposed.png
|
||||||
|
# ./apple-touch-icon-57x57.png
|
||||||
|
# ./apple-touch-icon-72x72-precomposed.png
|
||||||
|
# ./apple-touch-icon-72x72.png
|
||||||
|
# ./apple-touch-icon-precomposed.png
|
||||||
|
# ./apple-touch-icon.png
|
||||||
|
# ./favicon.ico
|
||||||
|
|
||||||
|
require "RMagick"
|
||||||
|
|
||||||
|
desc "Generates favicons and webapp icons"
|
||||||
|
task :favicons, :origin do |t, args|
|
||||||
|
name = "apple-touch-icon-%dx%d.png"
|
||||||
|
name_pre = "apple-touch-icon-%dx%d-precomposed.png"
|
||||||
|
|
||||||
|
FileList["*apple-touch-ico*.png"].each do |img|
|
||||||
|
File.delete img
|
||||||
|
end
|
||||||
|
|
||||||
|
FileList["*favicon.ico"].each do |img|
|
||||||
|
File.delete img
|
||||||
|
end
|
||||||
|
|
||||||
|
FileList[args.origin].each do |img|
|
||||||
|
puts "creating favicon.ico"
|
||||||
|
|
||||||
|
Magick::Image::read(img).first.resize(16, 16).write("favicon.ico")
|
||||||
|
|
||||||
|
[114, 57, 72].each do |size|
|
||||||
|
puts "creating %d * %d icons" % [size, size]
|
||||||
|
Magick::Image::read(img).first.resize(size, size).write(name % [size, size]).write(name_pre % [size, size])
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "creating backward-compatible icons"
|
||||||
|
|
||||||
|
cp name_pre % [57, 57], "apple-touch-icon.png"
|
||||||
|
cp name_pre % [57, 57], "apple-touch-icon-precomposed.png"
|
||||||
|
end
|
||||||
|
end
|
||||||
119
2011.ruby.posterous-weekly-links-simplified.rb
Normal file
119
2011.ruby.posterous-weekly-links-simplified.rb
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'net/https'
|
||||||
|
require "rexml/document"
|
||||||
|
require "date"
|
||||||
|
require 'net/smtp'
|
||||||
|
|
||||||
|
# delicious
|
||||||
|
@username = "YOU"
|
||||||
|
@password = "secr3t"
|
||||||
|
# smtp settings, asuming gmail
|
||||||
|
@smtp_server = 'smtp.gmail.com'
|
||||||
|
@smtp_port = 587
|
||||||
|
@smtp_user = "YOU@gmail.com"
|
||||||
|
@smtp_passwd = "secr3t"
|
||||||
|
# outgoing mail
|
||||||
|
@mail_from = "YOU@gmail.com"
|
||||||
|
@mail_from_alias = "YOU"
|
||||||
|
@mail_subject = "Värt att uppmärksamma, vecka #{(Date.today.cweek)} ((tags: läsvärt))"
|
||||||
|
# posterous
|
||||||
|
@posterous_email = "YOU@posterous.com"
|
||||||
|
|
||||||
|
#######
|
||||||
|
|
||||||
|
def get_description
|
||||||
|
description = gets.chomp
|
||||||
|
|
||||||
|
return description
|
||||||
|
end
|
||||||
|
|
||||||
|
# found at: http://blog.jerodsanto.net/2009/02/a-simple-ruby-method-to-send-emai/
|
||||||
|
def send_email(to, opts={})
|
||||||
|
opts[:server] ||= 'localhost'
|
||||||
|
opts[:from] ||= @mail_from
|
||||||
|
opts[:from_alias] ||= @mail_from_alias
|
||||||
|
opts[:subject] ||= @mail_subject
|
||||||
|
opts[:body] ||= "test"
|
||||||
|
|
||||||
|
msg = <<END_OF_MESSAGE
|
||||||
|
From: #{opts[:from_alias]} <#{opts[:from]}>
|
||||||
|
To: <#{to}>
|
||||||
|
Subject: #{opts[:subject]}
|
||||||
|
|
||||||
|
#{opts[:body]}
|
||||||
|
END_OF_MESSAGE
|
||||||
|
|
||||||
|
# found at: http://stackoverflow.com/questions/1183743/ruby-getting-netsmtp-working-with-gmail
|
||||||
|
smtp = Net::SMTP.new @smtp_server, @smtp_port
|
||||||
|
smtp.enable_starttls
|
||||||
|
smtp.start(@smtp_server, @smtp_user, @smtp_passwd, :login)
|
||||||
|
smtp.send_message(msg, to, to)
|
||||||
|
smtp.finish
|
||||||
|
end
|
||||||
|
|
||||||
|
#######
|
||||||
|
|
||||||
|
begin
|
||||||
|
resp = href = "";
|
||||||
|
|
||||||
|
puts "From date, YYYY-MM-DD"
|
||||||
|
from_date = gets.chomp
|
||||||
|
|
||||||
|
puts "To date, YYYY-MM-DD"
|
||||||
|
to_date = gets.chomp
|
||||||
|
|
||||||
|
puts " "
|
||||||
|
|
||||||
|
url = "/v1/posts/all?fromdt=#{from_date}T00:00:00Z&todt=#{to_date}T23:59:59Z"
|
||||||
|
descriptions = []
|
||||||
|
|
||||||
|
http = Net::HTTP.new("api.del.icio.us", 443)
|
||||||
|
|
||||||
|
http.use_ssl = true
|
||||||
|
http.start do |http|
|
||||||
|
req = Net::HTTP::Get.new(url, {"User-Agent" =>
|
||||||
|
"juretta.com RubyLicious 0.2"} )
|
||||||
|
req.basic_auth(@username, @password)
|
||||||
|
response = http.request(req)
|
||||||
|
resp = response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
# XML Document
|
||||||
|
doc = REXML::Document.new(resp)
|
||||||
|
|
||||||
|
#doc.root.elements.each do |elem|
|
||||||
|
# puts " \n"
|
||||||
|
# puts elem.attributes['description']
|
||||||
|
# puts "(" + elem.attributes['href'] + ")"
|
||||||
|
# puts " =>"
|
||||||
|
# descriptions.push(get_description)
|
||||||
|
#end
|
||||||
|
|
||||||
|
body_txt = "<markdown>\n"
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
doc.root.elements.each do |elem|
|
||||||
|
if elem.attributes['extended'] != ''
|
||||||
|
body_txt += "* [" + elem.attributes['description'] + "]("+ elem.attributes['href'] + ") \n " +
|
||||||
|
elem.attributes['extended'] + "\n" #descriptions[i] + "\n"
|
||||||
|
#i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
body_txt += "</markdown>\n#end"
|
||||||
|
|
||||||
|
puts "\n\n"
|
||||||
|
puts body_txt
|
||||||
|
puts "\n\n"
|
||||||
|
|
||||||
|
#puts "Sending to posterous ... "
|
||||||
|
#send_email @posterous_email, :body => body_txt
|
||||||
|
#puts "Done."
|
||||||
|
#puts " "
|
||||||
|
|
||||||
|
rescue SocketError
|
||||||
|
raise "Host " + host + " nicht erreichbar"
|
||||||
|
rescue REXML::ParseException => e
|
||||||
|
print "error parsing XML " + e.to_s
|
||||||
|
end
|
||||||
119
2011.ruby.posterous-weekly-links.rb
Normal file
119
2011.ruby.posterous-weekly-links.rb
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'net/https'
|
||||||
|
require "rexml/document"
|
||||||
|
require "date"
|
||||||
|
require 'net/smtp'
|
||||||
|
|
||||||
|
# delicious
|
||||||
|
@username = "YOU"
|
||||||
|
@password = "secr3t"
|
||||||
|
# smtp settings, asuming gmail
|
||||||
|
@smtp_server = 'smtp.gmail.com'
|
||||||
|
@smtp_port = 587
|
||||||
|
@smtp_user = "YOU@gmail.com"
|
||||||
|
@smtp_passwd = "s3cr3t"
|
||||||
|
# outgoing mail
|
||||||
|
@mail_from = "YOU@gmail.com"
|
||||||
|
@mail_from_alias = "Name Surname"
|
||||||
|
@mail_subject = "Värt att uppmärksamma, vecka #{(Date.today.cweek)-1}"
|
||||||
|
# posterous
|
||||||
|
@posterous_email = "YOU@posterous.com"
|
||||||
|
|
||||||
|
#######
|
||||||
|
|
||||||
|
def get_description
|
||||||
|
description = gets.chomp
|
||||||
|
|
||||||
|
return description
|
||||||
|
end
|
||||||
|
|
||||||
|
# found at: http://blog.jerodsanto.net/2009/02/a-simple-ruby-method-to-send-emai/
|
||||||
|
def send_email(to, opts={})
|
||||||
|
opts[:server] ||= 'localhost'
|
||||||
|
opts[:from] ||= @mail_from
|
||||||
|
opts[:from_alias] ||= @mail_from_alias
|
||||||
|
opts[:subject] ||= @mail_subject
|
||||||
|
opts[:body] ||= "test"
|
||||||
|
|
||||||
|
msg = <<END_OF_MESSAGE
|
||||||
|
From: #{opts[:from_alias]} <#{opts[:from]}>
|
||||||
|
To: <#{to}>
|
||||||
|
Subject: #{opts[:subject]}
|
||||||
|
|
||||||
|
#{opts[:body]}
|
||||||
|
END_OF_MESSAGE
|
||||||
|
|
||||||
|
# found at: http://stackoverflow.com/questions/1183743/ruby-getting-netsmtp-working-with-gmail
|
||||||
|
smtp = Net::SMTP.new @smtp_server, @smtp_port
|
||||||
|
smtp.enable_starttls
|
||||||
|
smtp.start(@smtp_server, @smtp_user, @smtp_passwd, :login)
|
||||||
|
smtp.send_message(msg, to, to)
|
||||||
|
smtp.finish
|
||||||
|
end
|
||||||
|
|
||||||
|
#######
|
||||||
|
|
||||||
|
begin
|
||||||
|
resp = href = "";
|
||||||
|
|
||||||
|
puts "From date, YYYY-MM-DD"
|
||||||
|
from_date = gets.chomp
|
||||||
|
|
||||||
|
puts "To date, YYYY-MM-DD"
|
||||||
|
to_date = gets.chomp
|
||||||
|
|
||||||
|
puts " "
|
||||||
|
|
||||||
|
url = "/v1/posts/all?fromdt=#{from_date}T00:00:00Z&todt=#{to_date}T23:59:59Z"
|
||||||
|
descriptions = []
|
||||||
|
|
||||||
|
http = Net::HTTP.new("api.del.icio.us", 443)
|
||||||
|
|
||||||
|
http.use_ssl = true
|
||||||
|
http.start do |http|
|
||||||
|
req = Net::HTTP::Get.new(url, {"User-Agent" =>
|
||||||
|
"juretta.com RubyLicious 0.2"} )
|
||||||
|
req.basic_auth(@username, @password)
|
||||||
|
response = http.request(req)
|
||||||
|
resp = response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
# XML Document
|
||||||
|
doc = REXML::Document.new(resp)
|
||||||
|
|
||||||
|
doc.root.elements.each do |elem|
|
||||||
|
puts " \n"
|
||||||
|
puts elem.attributes['description']
|
||||||
|
puts "(" + elem.attributes['href'] + ")"
|
||||||
|
puts " =>"
|
||||||
|
descriptions.push(get_description)
|
||||||
|
end
|
||||||
|
|
||||||
|
body_txt = "<markdown>\n"
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
doc.root.elements.each do |elem|
|
||||||
|
if elem.attributes['extended'] != ''
|
||||||
|
body_txt += "* [" + elem.attributes['description'] + "]("+ elem.attributes['href'] + ") \n " +
|
||||||
|
descriptions[i] + "\n" #elem.attributes['extended'] + "\n"
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
body_txt += "</markdown>\n#end"
|
||||||
|
|
||||||
|
puts "\n\n"
|
||||||
|
puts body_txt
|
||||||
|
puts "\n\n"
|
||||||
|
|
||||||
|
puts "Sending to posterous ... "
|
||||||
|
#send_email @posterous_email, :body => body_txt
|
||||||
|
puts "Done."
|
||||||
|
puts " "
|
||||||
|
|
||||||
|
rescue SocketError
|
||||||
|
raise "Host " + host + " nicht erreichbar"
|
||||||
|
rescue REXML::ParseException => e
|
||||||
|
print "error parsing XML " + e.to_s
|
||||||
|
end
|
||||||
291
2012.js.autocomplete.js
Normal file
291
2012.js.autocomplete.js
Normal file
|
|
@ -0,0 +1,291 @@
|
||||||
|
/*
|
||||||
|
By Anders Ytterström 2012.
|
||||||
|
|
||||||
|
Example use:
|
||||||
|
<script src="autocomplete.js"></script>
|
||||||
|
<script>
|
||||||
|
var values = ["Hansi", "Andre", "The Omen", "Marcus", "Prince Charles"],
|
||||||
|
callback = function (k) {
|
||||||
|
console.log(k);
|
||||||
|
};
|
||||||
|
|
||||||
|
autocomplete("bg", values, callback);
|
||||||
|
</script>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*jslint indent: 2, maxlen: 90, browser: true */
|
||||||
|
var autocomplete = function (id, values, callback) {
|
||||||
|
"use strict";
|
||||||
|
var autoCompleteTimer,
|
||||||
|
stopDefaultAction,
|
||||||
|
getPosition,
|
||||||
|
field,
|
||||||
|
initAutoComplete,
|
||||||
|
keydownAutoComplete,
|
||||||
|
generateDropdown,
|
||||||
|
autoComplete,
|
||||||
|
mouseoverDropdown,
|
||||||
|
mouseoutDropdown,
|
||||||
|
mousedownDropdown,
|
||||||
|
assignMouseListeners,
|
||||||
|
blurAutoComplete,
|
||||||
|
closeDropdown;
|
||||||
|
|
||||||
|
stopDefaultAction = function (event) {
|
||||||
|
event.returnValue = false;
|
||||||
|
if (typeof event.preventDefault !== "undefined") {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
getPosition = function (theElement) {
|
||||||
|
var positionX = 0,
|
||||||
|
positionY = 0;
|
||||||
|
while (theElement !== null) {
|
||||||
|
positionX += theElement.offsetLeft;
|
||||||
|
positionY += theElement.offsetTop;
|
||||||
|
theElement = theElement.offsetParent;
|
||||||
|
}
|
||||||
|
return [positionX, positionY];
|
||||||
|
};
|
||||||
|
|
||||||
|
initAutoComplete = function () {
|
||||||
|
field = document.getElementById(id);
|
||||||
|
field.setAttribute("autocomplete", "off");
|
||||||
|
if (window.attachEvent) {
|
||||||
|
field.attachEvent("onkeydown", keydownAutoComplete);
|
||||||
|
} else {
|
||||||
|
field.addEventListener("keydown", keydownAutoComplete);
|
||||||
|
}
|
||||||
|
field.onblur = function () {
|
||||||
|
blurAutoComplete();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
keydownAutoComplete = function (event) {
|
||||||
|
var target = event.target || event.srcElement,
|
||||||
|
autoCompleteDropdown,
|
||||||
|
childLis,
|
||||||
|
selected,
|
||||||
|
i,
|
||||||
|
max,
|
||||||
|
inputRanges;
|
||||||
|
if (typeof event === "undefined") {
|
||||||
|
event = window.event;
|
||||||
|
}
|
||||||
|
switch (event.keyCode) {
|
||||||
|
case 9: // tab
|
||||||
|
case 13: // enter
|
||||||
|
case 16: // shift
|
||||||
|
case 17: // ctrl
|
||||||
|
case 18: // alt
|
||||||
|
case 20: // caps lock
|
||||||
|
case 27: // esc
|
||||||
|
case 33: // page up
|
||||||
|
case 34: // page down
|
||||||
|
case 35: // end
|
||||||
|
case 36: // home
|
||||||
|
case 37: // left arrow
|
||||||
|
case 39: // right arrow
|
||||||
|
break;
|
||||||
|
case 38: // up arrow
|
||||||
|
autoCompleteDropdown = document.getElementById("autoCompleteDropdown");
|
||||||
|
if (autoCompleteDropdown !== null) {
|
||||||
|
childLis = autoCompleteDropdown.childNodes;
|
||||||
|
selected = false;
|
||||||
|
for (i = 0, max = childLis.length; i < max; i += 1) {
|
||||||
|
if (childLis[i].className === "hover") {
|
||||||
|
selected = true;
|
||||||
|
if (i > 0) {
|
||||||
|
childLis[i].className = "";
|
||||||
|
childLis[i - 1].className = "hover";
|
||||||
|
target.value = childLis[i - 1].firstChild.nodeValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!selected) {
|
||||||
|
childLis[0].className = "hover";
|
||||||
|
target.value = childLis[0].firstChild.nodeValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stopDefaultAction(event);
|
||||||
|
break;
|
||||||
|
case 40: // down arrow
|
||||||
|
autoCompleteDropdown = document.getElementById("autoCompleteDropdown");
|
||||||
|
if (autoCompleteDropdown !== null) {
|
||||||
|
childLis = autoCompleteDropdown.childNodes;
|
||||||
|
selected = false;
|
||||||
|
for (i = 0, max = childLis.length; i < max; i += 1) {
|
||||||
|
if (childLis[i].className === "hover") {
|
||||||
|
selected = true;
|
||||||
|
|
||||||
|
if (i < childLis.length - 1) {
|
||||||
|
childLis[i].className = "";
|
||||||
|
childLis[i + 1].className = "hover";
|
||||||
|
target.value = childLis[i + 1].firstChild.nodeValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!selected) {
|
||||||
|
childLis[0].className = "hover";
|
||||||
|
target.value = childLis[0].firstChild.nodeValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stopDefaultAction(event);
|
||||||
|
break;
|
||||||
|
case 8: // backspace
|
||||||
|
case 46: // delete
|
||||||
|
if (typeof autoCompleteTimer !== "undefined") {
|
||||||
|
clearTimeout(autoCompleteTimer);
|
||||||
|
}
|
||||||
|
autoCompleteTimer = setTimeout(function () {
|
||||||
|
generateDropdown(false);
|
||||||
|
}, 500);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (typeof autoCompleteTimer !== "undefined") {
|
||||||
|
clearTimeout(autoCompleteTimer);
|
||||||
|
}
|
||||||
|
target = event.target || event.srcElement;
|
||||||
|
inputRanges = "false";
|
||||||
|
if (typeof target.createTextRange !== "undefined"
|
||||||
|
|| typeof target.setSelectionRange !== "undefined") {
|
||||||
|
inputRanges = "true";
|
||||||
|
}
|
||||||
|
autoCompleteTimer = setTimeout(function () {
|
||||||
|
generateDropdown(inputRanges);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
assignMouseListeners = function (e) {
|
||||||
|
e.onmouseover = function () {
|
||||||
|
mouseoverDropdown(this);
|
||||||
|
};
|
||||||
|
e.mouseout = function () {
|
||||||
|
mouseoutDropdown(this);
|
||||||
|
};
|
||||||
|
e.mousedown = function () {
|
||||||
|
mousedownDropdown(this);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
generateDropdown = function (doAutoComplete) {
|
||||||
|
closeDropdown();
|
||||||
|
var input = document.getElementById(id),
|
||||||
|
newUl = document.createElement("div"),
|
||||||
|
newLi,
|
||||||
|
i,
|
||||||
|
max = values.length;
|
||||||
|
newUl.setAttribute("id", "autoCompleteDropdown");
|
||||||
|
newUl.autoCompleteInput = input;
|
||||||
|
newUl.style.position = "absolute";
|
||||||
|
newUl.style.left = getPosition(input)[0] + "px";
|
||||||
|
newUl.style.top = getPosition(input)[1] + input.offsetHeight - 2 + "px";
|
||||||
|
newUl.style.width = input.offsetWidth - 3 + "px";
|
||||||
|
for (i = 0; i < max; i += 1) {
|
||||||
|
if (values[i].indexOf(input.value) === 0) {
|
||||||
|
newLi = document.createElement("button");
|
||||||
|
newLi.innerHTML = values[i];
|
||||||
|
assignMouseListeners(newLi);
|
||||||
|
newUl.appendChild(newLi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newUl.firstChild !== null) {
|
||||||
|
document.getElementsByTagName("body")[0].appendChild(newUl);
|
||||||
|
}
|
||||||
|
if (typeof doAutoComplete !== "undefined" && doAutoComplete) {
|
||||||
|
autoComplete();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
autoComplete = function () {
|
||||||
|
var input = document.getElementById(id),
|
||||||
|
cursorMidway = false,
|
||||||
|
range,
|
||||||
|
originalValue,
|
||||||
|
autoCompleteDropdown;
|
||||||
|
if (typeof document.selection !== "undefined") {
|
||||||
|
range = document.selection.createRange();
|
||||||
|
if (range.move("character", 1) !== 0) {
|
||||||
|
cursorMidway = true;
|
||||||
|
}
|
||||||
|
} else if (typeof input.selectionStart !== "undefined"
|
||||||
|
&& input.selectionStart < input.value.length) {
|
||||||
|
cursorMidway = true;
|
||||||
|
}
|
||||||
|
originalValue = input.value;
|
||||||
|
autoCompleteDropdown = document.getElementById("autoCompleteDropdown");
|
||||||
|
if (autoCompleteDropdown !== null && !cursorMidway) {
|
||||||
|
autoCompleteDropdown.firstChild.className = "hover";
|
||||||
|
input.value = autoCompleteDropdown.firstChild.firstChild.nodeValue;
|
||||||
|
if (typeof input.createTextRange !== "undefined") {
|
||||||
|
range = input.createTextRange();
|
||||||
|
range.moveStart("character", originalValue.length);
|
||||||
|
range.select();
|
||||||
|
} else if (typeof input.setSelectionRange !== "undefined") {
|
||||||
|
input.setSelectionRange(originalValue.length, input.value.length);
|
||||||
|
}
|
||||||
|
if (autoCompleteDropdown.childNodes.length === 1) {
|
||||||
|
setTimeout(function () {
|
||||||
|
closeDropdown();
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
mouseoverDropdown = function (target) {
|
||||||
|
var childLis, i, max;
|
||||||
|
while (target.nodeName.toLowerCase() !== "button") {
|
||||||
|
target = target.parentNode;
|
||||||
|
}
|
||||||
|
childLis = target.parentNode.childNodes;
|
||||||
|
max = childLis.length;
|
||||||
|
for (i = 0; i < max; i += 1) {
|
||||||
|
childLis[i].className = "";
|
||||||
|
}
|
||||||
|
target.className = "hover";
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
mouseoutDropdown = function (target) {
|
||||||
|
while (target.nodeName.toLowerCase() !== "button") {
|
||||||
|
target = target.parentNode;
|
||||||
|
}
|
||||||
|
target.className = "";
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
mousedownDropdown = function (target) {
|
||||||
|
while (target.nodeName.toLowerCase() !== "button") {
|
||||||
|
target = target.parentNode;
|
||||||
|
}
|
||||||
|
target.parentNode.autoCompleteInput.value = target.firstChild.nodeValue;
|
||||||
|
closeDropdown();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
blurAutoComplete = function () {
|
||||||
|
if (typeof autoCompleteTimer !== "undefined") {
|
||||||
|
clearTimeout(autoCompleteTimer);
|
||||||
|
}
|
||||||
|
closeDropdown();
|
||||||
|
callback(field.value);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
closeDropdown = function () {
|
||||||
|
var autoCompleteDropdown = document.getElementById("autoCompleteDropdown");
|
||||||
|
if (autoCompleteDropdown !== null) {
|
||||||
|
autoCompleteDropdown.parentNode.removeChild(autoCompleteDropdown);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
initAutoComplete();
|
||||||
|
};
|
||||||
8
2012.js.get-week.js
Normal file
8
2012.js.get-week.js
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* getWeek function, return current week number from a `Date` object.
|
||||||
|
*/
|
||||||
|
getWeek = function (date) {
|
||||||
|
var onejan = new Date(date.getFullYear(), 0, 1);
|
||||||
|
return Math.ceil((((date - onejan) / 86400000)
|
||||||
|
+ onejan.getDay()) / 7);
|
||||||
|
};
|
||||||
97
2012.js.match-media-conditional-exec.js
Normal file
97
2012.js.match-media-conditional-exec.js
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*jslint devel:true, browser:true, indent:2, maxlen: 70 */
|
||||||
|
(function (window) {
|
||||||
|
"use strict";
|
||||||
|
var Condition, Listener, watcher;
|
||||||
|
|
||||||
|
// Requires window.matchMedia:
|
||||||
|
// https://developer.mozilla.org/en/DOM/window.matchMedia
|
||||||
|
if (typeof window.matchMedia === "undefined") { return; }
|
||||||
|
|
||||||
|
Condition = function (mq, callback) {
|
||||||
|
this.mq = window.matchMedia(mq);
|
||||||
|
this.callback = function () {
|
||||||
|
callback.call();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
Condition.prototype.matches = function () {
|
||||||
|
return this.mq.matches;
|
||||||
|
};
|
||||||
|
|
||||||
|
Listener = function () {
|
||||||
|
this.callbacks = [];
|
||||||
|
this.cbLen = 0;
|
||||||
|
this.runned = 0;
|
||||||
|
};
|
||||||
|
Listener.prototype.waitFor = function (condition) {
|
||||||
|
this.callbacks.push(condition);
|
||||||
|
this.cbLen += 1;
|
||||||
|
};
|
||||||
|
Listener.prototype.walk = function () {
|
||||||
|
var toRun = [],
|
||||||
|
i = this.cbLen,
|
||||||
|
cb = this.callbacks;
|
||||||
|
|
||||||
|
while (i) {
|
||||||
|
i -= 1;
|
||||||
|
if (cb[i]) {
|
||||||
|
if (cb[i].matches()) {
|
||||||
|
toRun.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return toRun;
|
||||||
|
};
|
||||||
|
Listener.prototype.execute = function (toRun) {
|
||||||
|
var i = toRun.length;
|
||||||
|
|
||||||
|
while (i) {
|
||||||
|
i -= 1;
|
||||||
|
this.callbacks[toRun[i]].callback.call();
|
||||||
|
this.callbacks[toRun[i]] = '';
|
||||||
|
this.runned += 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Listener.prototype.investigate = function () {
|
||||||
|
var toRun;
|
||||||
|
toRun = this.walk();
|
||||||
|
|
||||||
|
if (toRun.length) { this.execute(toRun); }
|
||||||
|
|
||||||
|
if (this.runned === this.cbLen) {
|
||||||
|
window.onresize = "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Listener.prototype.install = function () {
|
||||||
|
var callback, wait, that = this;
|
||||||
|
|
||||||
|
callback = function () {
|
||||||
|
that.investigate();
|
||||||
|
};
|
||||||
|
|
||||||
|
window.onresize = function () {
|
||||||
|
clearTimeout(wait);
|
||||||
|
wait = setTimeout(callback, 333);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.investigate();
|
||||||
|
};
|
||||||
|
|
||||||
|
watcher = new Listener();
|
||||||
|
|
||||||
|
watcher.waitFor(new Condition(
|
||||||
|
"all and (min-width: 801px)",
|
||||||
|
function () {
|
||||||
|
console.log("load delicicous bookmarks (we have room!)");
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
watcher.waitFor(new Condition(
|
||||||
|
"all and (min-width: 1281px)",
|
||||||
|
function () {
|
||||||
|
console.log("load heavy pictures (we are on desktop!)");
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
watcher.install();
|
||||||
|
}(window));
|
||||||
10
2012.js.sprintf.js
Normal file
10
2012.js.sprintf.js
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
/*
|
||||||
|
Thank you, almighty!
|
||||||
|
http://www.nczonline.net/blog/2011/10/11/simple-maintainable-templating-with-javascript/
|
||||||
|
*/
|
||||||
|
function sprintf(text){
|
||||||
|
var i=1, args=arguments;
|
||||||
|
return text.replace(/%s/g, function(pattern){
|
||||||
|
return (i < args.length) ? args[i++] : "";
|
||||||
|
});
|
||||||
|
}
|
||||||
50
2012.python.download-hmtl-page-behind-login.py
Normal file
50
2012.python.download-hmtl-page-behind-login.py
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
'''
|
||||||
|
Example htmldump_config.py:
|
||||||
|
|
||||||
|
url = "http://localhost:5000"
|
||||||
|
login = "admin@adeprimo.se"
|
||||||
|
password = "app161770"
|
||||||
|
|
||||||
|
def pages_to_validate():
|
||||||
|
pages = [
|
||||||
|
# event registration
|
||||||
|
('event-start', '/events/start/'),
|
||||||
|
('event-form', '/events/create'),
|
||||||
|
('events', '/events'),
|
||||||
|
('event-edit', '/events/view/'),
|
||||||
|
|
||||||
|
return pages
|
||||||
|
'''
|
||||||
|
import mechanize
|
||||||
|
import re
|
||||||
|
from htmldump_config import pages_to_validate, url, login, password
|
||||||
|
|
||||||
|
url = url + "%s"
|
||||||
|
filepattern = "../static/htmldumps/%s.html"
|
||||||
|
|
||||||
|
print "creating fake browser env"
|
||||||
|
br = mechanize.Browser()
|
||||||
|
print "--- done"
|
||||||
|
print "logging in as admin"
|
||||||
|
br.open(url % "/login")
|
||||||
|
br.select_form(nr=0)
|
||||||
|
br["email"] = login
|
||||||
|
br["password"] = password
|
||||||
|
br.submit()
|
||||||
|
print "--- now logged in as %s" % login
|
||||||
|
|
||||||
|
def htmldump(name, doc):
|
||||||
|
with open(filepattern % name, "w") as f:
|
||||||
|
f.write(doc)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
def begin_download(pages):
|
||||||
|
for filename, url_path in pages:
|
||||||
|
print "downloading: %s" % url_path
|
||||||
|
print " to: %s.html" % filename
|
||||||
|
response = br.open(url % url_path)
|
||||||
|
htmldump(filename, response.read())
|
||||||
|
|
||||||
|
pages = pages_to_validate()
|
||||||
|
|
||||||
|
begin_download(pages)
|
||||||
14
2012.scss.column-separator.scss
Normal file
14
2012.scss.column-separator.scss
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
/* vertical ruler using pseudo-elements */
|
||||||
|
@mixin columnseparator {
|
||||||
|
@extend .relative;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 3px;
|
||||||
|
background: #eee;
|
||||||
|
left: 681px;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
2012.scss.folded-corner.scss
Normal file
18
2012.scss.folded-corner.scss
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
// folded box
|
||||||
|
@mixin folded ($size: 10px, $y: 30px, $background: $grey4) {
|
||||||
|
line-height: $y;
|
||||||
|
height: $y;
|
||||||
|
margin-left: ($size * -1);
|
||||||
|
text-indent: $size;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
border-left: $size solid $pagebg;
|
||||||
|
border-top: $size solid darken($background, 80%);
|
||||||
|
float: left;
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: ($size * -1);
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
2013.bash.new-mamp-vhost.sh
Normal file
24
2013.bash.new-mamp-vhost.sh
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# usage: ./adp-new-vhost <name>
|
||||||
|
#
|
||||||
|
mampdir=/Applications/MAMP
|
||||||
|
confdir=$mampdir/conf/apache/extra/vhosts
|
||||||
|
codedir=~/Code
|
||||||
|
mampport=80
|
||||||
|
|
||||||
|
cat <<end > $confdir/$1.conf
|
||||||
|
<VirtualHost *:$mampport>
|
||||||
|
ServerName $1
|
||||||
|
DocumentRoot $codedir/$1
|
||||||
|
|
||||||
|
<Directory "$codedir/$1">
|
||||||
|
AllowOverride all
|
||||||
|
Options -Indexes
|
||||||
|
Order allow,deny
|
||||||
|
Allow from all
|
||||||
|
</Directory>
|
||||||
|
</VirtualHost>
|
||||||
|
end
|
||||||
|
|
||||||
|
echo <passwd> | sudo -- sh -c "echo '127.0.0.1 $1' >> /etc/hosts"
|
||||||
26
2013.python.embed-png-in-css-as-datauri.py
Normal file
26
2013.python.embed-png-in-css-as-datauri.py
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
import base64, re, argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='CSS-Embed PNG images as data-URIs')
|
||||||
|
parser.add_argument('files', metavar='file', nargs="+", type=str,
|
||||||
|
help='path to a css file')
|
||||||
|
|
||||||
|
img = re.compile("url\('?\"?(.*\.png)'?\"?\)")
|
||||||
|
repl = "url(data:image/png;base64,%s)"
|
||||||
|
|
||||||
|
cssfiles = parser.parse_args().files
|
||||||
|
|
||||||
|
if "swapcase" in dir(["a"]):
|
||||||
|
cssfiles = [cssfiles]
|
||||||
|
|
||||||
|
for cssfile in cssfiles:
|
||||||
|
css = open(cssfile, "r").read()
|
||||||
|
|
||||||
|
for image_path in img.findall(css):
|
||||||
|
data = base64.b64encode(open(image_path, "r").read())
|
||||||
|
pattern = "url\('?\"?%s'?\"?\)" % image_path
|
||||||
|
css = re.sub(re.compile(pattern), repl % data, css)
|
||||||
|
|
||||||
|
f = open(cssfile, "w")
|
||||||
|
f.write(css)
|
||||||
|
f.close()
|
||||||
100
2013.ruby.ftp-upload.rb
Normal file
100
2013.ruby.ftp-upload.rb
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
require "rubygems"
|
||||||
|
require 'net/ftp'
|
||||||
|
require 'stringio'
|
||||||
|
|
||||||
|
ftp = ""
|
||||||
|
username = ""
|
||||||
|
passwd = ""
|
||||||
|
root_dir = "../../../../"
|
||||||
|
current_rev_file = root_dir + "__CURRENT_VERSION__"
|
||||||
|
|
||||||
|
root_dir = ""
|
||||||
|
|
||||||
|
# new rev is either HEAD or a commit, set by ARGV
|
||||||
|
new_rev = ""
|
||||||
|
new_rev = ARGV.first unless ARGV.first != nil
|
||||||
|
cmd_newrev = "git show -s --format=\"%%h %%s (%%ar)\" %s" % new_rev
|
||||||
|
new_rev = `#{cmd_newrev}`
|
||||||
|
|
||||||
|
# old rev (current in production) are stored in a file.
|
||||||
|
old_rev = File.open(current_rev_file, "r").read
|
||||||
|
|
||||||
|
cmd = "git diff --name-status %s %s" % [old_rev.split(" ").first, new_rev.split(" ").first]
|
||||||
|
|
||||||
|
files = `#{cmd}`
|
||||||
|
|
||||||
|
# change to root
|
||||||
|
Dir.chdir root_dir
|
||||||
|
|
||||||
|
class Net::FTP
|
||||||
|
def puttextcontent(content, remotefile, &block)
|
||||||
|
f = StringIO.new(content)
|
||||||
|
begin
|
||||||
|
storlines("STOR " + remotefile, f, &block)
|
||||||
|
ensure
|
||||||
|
f.close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def chkdir(ftp, parents)
|
||||||
|
path = []
|
||||||
|
|
||||||
|
parents.each do |d|
|
||||||
|
parent_path = path.join("/")
|
||||||
|
path << d
|
||||||
|
unless ftp.list(parent_path).any? { |dir| dir.match(d) }
|
||||||
|
ftp.mkdir(path.join("/"))
|
||||||
|
puts "[chkdir] created dir: %s" % path.join("/")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def put_file(ftp, path)
|
||||||
|
parents = path.split("/")
|
||||||
|
parents.pop
|
||||||
|
|
||||||
|
chkdir ftp, parents
|
||||||
|
|
||||||
|
if path.match(".png")
|
||||||
|
ftp.putbinaryfile(path, path)
|
||||||
|
else
|
||||||
|
ftp.puttextfile(path, path)
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "[put_file] %s" % path
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "\nCurrent rev in Production: %s" % old_rev
|
||||||
|
puts " The new rev: %s\n" % new_rev
|
||||||
|
|
||||||
|
if old_rev == new_rev
|
||||||
|
puts "Everything is up to date, exiting"
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
|
||||||
|
# list files to be changed in ftp prod
|
||||||
|
puts "files changed:", files, ""
|
||||||
|
|
||||||
|
# connect to ftp server
|
||||||
|
ftp = Net::FTP.new(ftp)
|
||||||
|
ftp.login username, passwd
|
||||||
|
remote = ftp.chdir root_dir
|
||||||
|
|
||||||
|
# make changes
|
||||||
|
files.each_line do |file|
|
||||||
|
flag, file = file.split("\t")
|
||||||
|
file.strip!
|
||||||
|
|
||||||
|
if flag == "A" || flag == "M"
|
||||||
|
put_file ftp, file
|
||||||
|
end
|
||||||
|
|
||||||
|
if flag == "D"
|
||||||
|
ftp.delete file
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
File.open(current_rev_file, "w").write(new_rev)
|
||||||
|
|
||||||
|
ftp.close
|
||||||
40
2013.ruby.html-validator.rb
Normal file
40
2013.ruby.html-validator.rb
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
require "rubygems"
|
||||||
|
require 'living-validator'
|
||||||
|
require 'uri'
|
||||||
|
|
||||||
|
url = ARGV.first
|
||||||
|
files = ARGV.slice(1, 9999)
|
||||||
|
stop_at = files.length
|
||||||
|
i = 1
|
||||||
|
|
||||||
|
def colorize(text, color_code)
|
||||||
|
"\e[#{color_code}m#{text}\e[0m"
|
||||||
|
end
|
||||||
|
|
||||||
|
def red(text); colorize(text, 31); end
|
||||||
|
def green(text); colorize(text, 32); end
|
||||||
|
|
||||||
|
valid = true
|
||||||
|
|
||||||
|
files.each do |file|
|
||||||
|
puts '[%d/%d] %s%s:' % [i, stop_at, url, file]
|
||||||
|
i += 1
|
||||||
|
result = LivingValidator::Validator.check '%s%s' % [url, file]
|
||||||
|
unless result == false
|
||||||
|
if result.errorCount > 0
|
||||||
|
result.errors.each do |error|
|
||||||
|
puts red("%d:%d %s" % [error["lastLine"], error["lastColumn"], error["message"]])
|
||||||
|
end
|
||||||
|
|
||||||
|
valid = false
|
||||||
|
else
|
||||||
|
puts green "valid"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
puts red("FAILED")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
exit 1 unless valid == true
|
||||||
|
|
||||||
|
exit 0
|
||||||
94
2014.js.geolocation-pos2px.html
Normal file
94
2014.js.geolocation-pos2px.html
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<style>
|
||||||
|
body { margin: 0; }
|
||||||
|
div { position: absolute; width: 20px; height: 20px; border-radius: 50%; background: red; }
|
||||||
|
</style>
|
||||||
|
<img src="mupp2.png" alt="" width="2500" height="2500">
|
||||||
|
<div hidden></div>
|
||||||
|
<script>
|
||||||
|
/*jslint browser: true */
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
if (navigator.geolocation !== undefined) {
|
||||||
|
var Map,
|
||||||
|
map,
|
||||||
|
mapImg,
|
||||||
|
upperLeftBound = { lat: 63.184472, lng: 14.616544 },
|
||||||
|
lowerRightBound = { lat: 63.171043, lng: 14.646316 };
|
||||||
|
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
|
||||||
|
Map = function (x, y, upperLeftBounds, lowerRightBounds) {
|
||||||
|
this.dims = {x: x, y: y};
|
||||||
|
this.bounds = [upperLeftBounds, lowerRightBounds];
|
||||||
|
this.spot = document.getElementsByTagName("div")[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
Map.prototype.convert = function (lat, lng) {
|
||||||
|
var MAP_WIDTH, MAP_HEIGHT, e, w, n, s, nsspan, ewspan, nspix, ewpix, x, y;
|
||||||
|
|
||||||
|
MAP_WIDTH = this.dims.x;
|
||||||
|
MAP_HEIGHT = this.dims.y;
|
||||||
|
|
||||||
|
e = this.bounds[1].lat;
|
||||||
|
w = this.bounds[0].lat;
|
||||||
|
n = this.bounds[0].lng;
|
||||||
|
s = this.bounds[1].lng;
|
||||||
|
|
||||||
|
nsspan = Math.abs(n - s);
|
||||||
|
ewspan = Math.abs(w - e);
|
||||||
|
|
||||||
|
nspix = MAP_HEIGHT / nsspan;
|
||||||
|
ewpix = MAP_WIDTH / ewspan;
|
||||||
|
|
||||||
|
x = (Math.abs(w - lat)) * ewpix;
|
||||||
|
y = (Math.abs(n - lng)) * nspix;
|
||||||
|
|
||||||
|
return {
|
||||||
|
top: parseInt(x, 10),
|
||||||
|
left: parseInt(y, 10)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Map.prototype.center = function (lat, lng) {
|
||||||
|
var lt,
|
||||||
|
tl = this.convert(lat, lng),
|
||||||
|
w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0),
|
||||||
|
h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
|
||||||
|
|
||||||
|
lt = {
|
||||||
|
left: tl.left - (w / 2),
|
||||||
|
top: tl.top - (h / 2)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (lt.left < 0) { lt.left = 0; }
|
||||||
|
if (lt.top < 0) { lt.top = 0; }
|
||||||
|
|
||||||
|
window.scrollTo(lt.left, lt.top);
|
||||||
|
};
|
||||||
|
|
||||||
|
Map.prototype.showPos = function (lat, lng) {
|
||||||
|
var pos = this.convert(lat, lng);
|
||||||
|
this.spot.hidden = false;
|
||||||
|
this.spot.style.top = pos.top - 10 + "px";
|
||||||
|
this.spot.style.left = pos.left - 10 + "px";
|
||||||
|
};
|
||||||
|
|
||||||
|
mapImg = document.getElementsByTagName("img")[0];
|
||||||
|
|
||||||
|
map = new Map(mapImg.width, mapImg.height, upperLeftBound, lowerRightBound);
|
||||||
|
|
||||||
|
// initial scroll for the map
|
||||||
|
navigator.geolocation.getCurrentPosition(function (position) {
|
||||||
|
map.center(position.coords.latitude, position.coords.longitude);
|
||||||
|
});
|
||||||
|
|
||||||
|
// update position on map
|
||||||
|
var watchID = navigator.geolocation.watchPosition(function (position) {
|
||||||
|
map.showPos(position.coords.latitude, position.coords.longitude);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
</script>
|
||||||
143
2015.grunt.htmldev-checklist.js
Normal file
143
2015.grunt.htmldev-checklist.js
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
The Following folder structure is required:
|
||||||
|
|
||||||
|
./
|
||||||
|
./dist
|
||||||
|
app.js
|
||||||
|
app.min.js
|
||||||
|
app.min.zipped.js
|
||||||
|
design.css
|
||||||
|
design.min.css
|
||||||
|
design.min.zipped.css
|
||||||
|
./src
|
||||||
|
./src/js
|
||||||
|
.src/js/core
|
||||||
|
.src/js/modules
|
||||||
|
init.js
|
||||||
|
design.less
|
||||||
|
./styleguide
|
||||||
|
./styleguide/template
|
||||||
|
index.html
|
||||||
|
section-1.html
|
||||||
|
section-2.html
|
||||||
|
section-3.html
|
||||||
|
section-5.html
|
||||||
|
*/
|
||||||
|
module.exports = function(grunt) {
|
||||||
|
|
||||||
|
// Project configuration.
|
||||||
|
grunt.initConfig({
|
||||||
|
pkg: grunt.file.readJSON('package.json'),
|
||||||
|
csslint: {
|
||||||
|
strict: {
|
||||||
|
src: ['dist/design.css']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
compress: {
|
||||||
|
main: {
|
||||||
|
options: {
|
||||||
|
mode: 'gzip'
|
||||||
|
},
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
expand: true,
|
||||||
|
src: ['dist/app.min.js'],
|
||||||
|
dest: '',
|
||||||
|
ext: '.min.zipped.js'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expand: true,
|
||||||
|
src: ['dist/design.min.css'],
|
||||||
|
dest: '',
|
||||||
|
ext: '.min.zipped.css'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
concat: {
|
||||||
|
dist: {
|
||||||
|
src: ['src/js/core/*.js', 'src/js/modules/*.js', 'src/js/init.js'],
|
||||||
|
dest: 'dist/app.js',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
devserver: {
|
||||||
|
"options": {
|
||||||
|
"port": 8888
|
||||||
|
},
|
||||||
|
server: {}
|
||||||
|
},
|
||||||
|
htmllint: {
|
||||||
|
all: ["styleguide/*.html"]
|
||||||
|
},
|
||||||
|
jasmine: {
|
||||||
|
pivotal: {
|
||||||
|
src: ['src/js/*/*.js'],
|
||||||
|
options: {
|
||||||
|
specs: 'spec/*Spec.js',
|
||||||
|
helpers: 'spec/*Helper.js'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
jslint: {
|
||||||
|
client: {
|
||||||
|
src: [
|
||||||
|
'src/js/*/*.js',
|
||||||
|
'src/js/*.js'
|
||||||
|
],
|
||||||
|
exclude: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
kss: {
|
||||||
|
options: {
|
||||||
|
template: 'styleguide/template', // create this manually: `kss-node -i styleguide/template`
|
||||||
|
includeType: 'less'
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
src: ['src/less'],
|
||||||
|
dest: 'styleguide'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
less: {
|
||||||
|
development: {
|
||||||
|
files: {
|
||||||
|
"dist": "src/less"
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
"dist/design.css": "src/less/design.less"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
production: {
|
||||||
|
options: {
|
||||||
|
cleancss: true
|
||||||
|
},
|
||||||
|
files: {
|
||||||
|
"dist/design.min.css": "src/less/design.less"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uglify: {
|
||||||
|
options: {
|
||||||
|
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
src: 'dist/app.js',
|
||||||
|
dest: 'dist/app.min.js'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-compress');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-csslint');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-jasmine');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-less');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||||
|
grunt.loadNpmTasks('grunt-devserver');
|
||||||
|
grunt.loadNpmTasks('grunt-html');
|
||||||
|
grunt.loadNpmTasks('grunt-jslint');
|
||||||
|
grunt.loadNpmTasks('grunt-kss');
|
||||||
|
|
||||||
|
grunt.registerTask('deploy', ['less:production', 'less:development', 'concat', 'uglify', 'compress', 'kss']);
|
||||||
|
grunt.registerTask('test', ['htmllint', 'csslint', 'jslint', 'jasmine']);
|
||||||
|
grunt.registerTask('default', ['test']);
|
||||||
|
};
|
||||||
66
2015.js.infinite-scroll.js
Normal file
66
2015.js.infinite-scroll.js
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*jslint browser: true, indent: 4 */
|
||||||
|
/*
|
||||||
|
Example use of ScrollGuard: a simple, unobtrusive lazy loader.
|
||||||
|
|
||||||
|
Each time the user scrolled to the bottom of the page:
|
||||||
|
|
||||||
|
1. Look if there is content to load (lookForNextPage)
|
||||||
|
2. If new content, get content using Ajax (getNextPage)
|
||||||
|
3. Append the new content and do some polish (appencContent)
|
||||||
|
|
||||||
|
*/
|
||||||
|
(function (g) {
|
||||||
|
"use strict";
|
||||||
|
var lookForNextPage,
|
||||||
|
getNextPage,
|
||||||
|
appendContent;
|
||||||
|
|
||||||
|
if (g.ScrollGuard === undefined) {
|
||||||
|
throw new Error("scrollguard.js is required!");
|
||||||
|
}
|
||||||
|
|
||||||
|
appendContent = function (content) {
|
||||||
|
var body, rows, i, max, newContent, table;
|
||||||
|
|
||||||
|
body = document.createElement("div");
|
||||||
|
body.innerHTML = content;
|
||||||
|
|
||||||
|
newContent = document.createDocumentFragment();
|
||||||
|
rows = body.querySelectorAll(".main-c table tr");
|
||||||
|
|
||||||
|
for (i = 1, max = rows.length; i < max; i += 1) {
|
||||||
|
newContent.appendChild(rows[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
table = document.querySelector(".main-c table").tBodies[0];
|
||||||
|
table.replaceChild(newContent, table.querySelector("tr.pagination"));
|
||||||
|
};
|
||||||
|
|
||||||
|
lookForNextPage = function () {
|
||||||
|
var nextPage = document.getElementById("pager-next");
|
||||||
|
|
||||||
|
if (nextPage) {
|
||||||
|
getNextPage(nextPage.href);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getNextPage = function (href) {
|
||||||
|
var request = new XMLHttpRequest();
|
||||||
|
|
||||||
|
request.onreadystatechange = function () {
|
||||||
|
if (request.readyState === 4) {
|
||||||
|
if (request.status === 200 || request.status === 304) {
|
||||||
|
appendContent(request.responseText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
request.open("GET", href, true);
|
||||||
|
request.send(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (document.getElementById("pager-next")) {
|
||||||
|
g.ScrollGuard.add(lookForNextPage, -1);
|
||||||
|
g.ScrollGuard.start();
|
||||||
|
}
|
||||||
|
}(this));
|
||||||
25
2015.js.pirate-speech.js
Normal file
25
2015.js.pirate-speech.js
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
/* Kopiera och klistra in i Firebug eller Dev Tools, ändra sista raden. */
|
||||||
|
(function (str) {
|
||||||
|
"use strict";
|
||||||
|
var blacklist = ' aeiouyöäåAEIOUYÖÄÅ';
|
||||||
|
|
||||||
|
function ify(c) {
|
||||||
|
return c + "o" + c.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
function pirate(str) {
|
||||||
|
var chars = str.split(""),
|
||||||
|
i = chars.length;
|
||||||
|
|
||||||
|
while (i) {
|
||||||
|
i -= 1;
|
||||||
|
if (!blacklist.match(chars[i])) {
|
||||||
|
chars[i] = ify(chars[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return chars.join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
return pirate(str);
|
||||||
|
}("Det här ska jag säga"));
|
||||||
113
2015.js.responsive-loader.js
Normal file
113
2015.js.responsive-loader.js
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*jslint browser: true, indent: 4 */
|
||||||
|
/*global updateCanvas: true */
|
||||||
|
(function (g) {
|
||||||
|
"use strict";
|
||||||
|
var lookForNextPage,
|
||||||
|
getNextPage,
|
||||||
|
appendContent,
|
||||||
|
loadManually,
|
||||||
|
manual,
|
||||||
|
loader,
|
||||||
|
working;
|
||||||
|
|
||||||
|
if (g.ScrollGuard === undefined) {
|
||||||
|
throw new Error("scrollguard.js is required!");
|
||||||
|
}
|
||||||
|
|
||||||
|
appendContent = function (content) {
|
||||||
|
var body, rows, i, max, newContent, table;
|
||||||
|
body = document.createElement("div");
|
||||||
|
body.innerHTML = content;
|
||||||
|
|
||||||
|
newContent = document.createDocumentFragment();
|
||||||
|
rows = body.querySelectorAll(".main-c table tr");
|
||||||
|
|
||||||
|
for (i = 1, max = rows.length; i < max; i += 1) {
|
||||||
|
newContent.appendChild(rows[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
table = document.querySelector(".main-c table").tBodies[0];
|
||||||
|
table.replaceChild(newContent, table.querySelector("tr.pagination"));
|
||||||
|
|
||||||
|
if (typeof(updateCanvas) === "function") {
|
||||||
|
updateCanvas();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadManually();
|
||||||
|
};
|
||||||
|
|
||||||
|
loadManually = function () {
|
||||||
|
var button;
|
||||||
|
|
||||||
|
button = document.getElementById("load-manually");
|
||||||
|
|
||||||
|
if (button) {
|
||||||
|
if (!document.getElementById("pager-next")) {
|
||||||
|
button.parentNode.removeChild(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.onclick = function () {
|
||||||
|
var nextPage = document.getElementById("pager-next");
|
||||||
|
|
||||||
|
if (nextPage) {
|
||||||
|
getNextPage(nextPage.href);
|
||||||
|
button.parentNode.replaceChild(loader.cloneNode(), button);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
manual = function () {
|
||||||
|
var style, elm;
|
||||||
|
|
||||||
|
elm = document.getElementById("load-manually");
|
||||||
|
|
||||||
|
if (!elm) { return false; }
|
||||||
|
|
||||||
|
style = window.getComputedStyle(elm, null);
|
||||||
|
return style.getPropertyValue("display") !== "none";
|
||||||
|
};
|
||||||
|
|
||||||
|
lookForNextPage = function () {
|
||||||
|
if (!manual()) {
|
||||||
|
var nextPage = document.getElementById("pager-next");
|
||||||
|
|
||||||
|
if (nextPage) {
|
||||||
|
getNextPage(nextPage.href);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getNextPage = function (href) {
|
||||||
|
var request = new XMLHttpRequest();
|
||||||
|
|
||||||
|
if (working === true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
working = true;
|
||||||
|
|
||||||
|
request.onreadystatechange = function () {
|
||||||
|
if (request.readyState === 4) {
|
||||||
|
working = false;
|
||||||
|
if (request.status === 200 || request.status === 304) {
|
||||||
|
appendContent(request.responseText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
request.open("GET", href, true);
|
||||||
|
request.send(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
loadManually();
|
||||||
|
|
||||||
|
loader = document.createElement("img");
|
||||||
|
loader.style.paddingTop = "14px";
|
||||||
|
loader.src = "/templates/wide/css/images/loader.gif";
|
||||||
|
|
||||||
|
if (document.getElementById("pager-next")) {
|
||||||
|
g.ScrollGuard.add(lookForNextPage, -1);
|
||||||
|
g.ScrollGuard.start();
|
||||||
|
}
|
||||||
|
}(this));
|
||||||
116
2015.js.scrollguard.js
Normal file
116
2015.js.scrollguard.js
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*jslint browser: true, indent: 4 */
|
||||||
|
(function (g) {
|
||||||
|
"use strict";
|
||||||
|
var ScrollGuard,
|
||||||
|
started = false,
|
||||||
|
lock = false,
|
||||||
|
timer,
|
||||||
|
breakpoints = [],
|
||||||
|
getDocHeight,
|
||||||
|
getScrollTop;
|
||||||
|
|
||||||
|
// found at http://james.padolsey.com/javascript/
|
||||||
|
// get-document-height-cross-browser/
|
||||||
|
getDocHeight = function () {
|
||||||
|
return Math.max(
|
||||||
|
Math.max(document.body.scrollHeight,
|
||||||
|
document.documentElement.scrollHeight),
|
||||||
|
Math.max(document.body.offsetHeight,
|
||||||
|
document.documentElement.offsetHeight),
|
||||||
|
Math.max(document.body.clientHeight,
|
||||||
|
document.documentElement.clientHeight)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// found at http://stackoverflow.com/questions/871399/
|
||||||
|
// cross-browser-method-for-detecting-the-scrolltop-of-the-browser-g
|
||||||
|
getScrollTop = function () {
|
||||||
|
var b, d;
|
||||||
|
if (g.pageYOffset !== undefined) {
|
||||||
|
return g.pageYOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
b = document.body;
|
||||||
|
d = document.documentElement;
|
||||||
|
|
||||||
|
d = (d.clientHeight) ? d : b;
|
||||||
|
|
||||||
|
return d.scrollTop;
|
||||||
|
};
|
||||||
|
|
||||||
|
ScrollGuard = {
|
||||||
|
// from: a distance from top, given in pixels (required)
|
||||||
|
// to: a distance from top, given in pixels (optional)
|
||||||
|
//
|
||||||
|
// special cases:
|
||||||
|
// from = -1 will instead look if bottom of page
|
||||||
|
// is visible.
|
||||||
|
add: function (callback, from, to) {
|
||||||
|
var range;
|
||||||
|
|
||||||
|
if (from === -1) {
|
||||||
|
range = function (topPos) {
|
||||||
|
return getDocHeight() - topPos <= g.innerHeight;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
if (to === undefined) {
|
||||||
|
range = function (topPos) {
|
||||||
|
return topPos >= from;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
range = function (topPos) {
|
||||||
|
return topPos >= from && topPos <= to;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
breakpoints.push({
|
||||||
|
within: range,
|
||||||
|
callback: callback
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fire: function (pos) {
|
||||||
|
var max = breakpoints.length,
|
||||||
|
i,
|
||||||
|
bp;
|
||||||
|
|
||||||
|
lock = true;
|
||||||
|
|
||||||
|
for (i = 0; i < max; i += 1) {
|
||||||
|
bp = breakpoints[i];
|
||||||
|
|
||||||
|
if (bp.within(pos)) {
|
||||||
|
bp.callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lock = false;
|
||||||
|
},
|
||||||
|
start: function () {
|
||||||
|
if (started) { return; }
|
||||||
|
|
||||||
|
var callback = function () {
|
||||||
|
if (lock === false) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
|
||||||
|
timer = setTimeout(function () {
|
||||||
|
ScrollGuard.fire(getScrollTop());
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (g.attachEvent) {
|
||||||
|
g.attachEvent('onscroll', callback);
|
||||||
|
} else {
|
||||||
|
g.addEventListener('scroll', callback, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
started = true;
|
||||||
|
|
||||||
|
// initial call to catch initial scroll positions
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
g.ScrollGuard = ScrollGuard;
|
||||||
|
}(this));
|
||||||
61
2015.php.view-engine.php
Normal file
61
2015.php.view-engine.php
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* view.php
|
||||||
|
*
|
||||||
|
* simple view class, template-based.
|
||||||
|
* @todo indent markup using tidy?
|
||||||
|
*
|
||||||
|
* $Rev$
|
||||||
|
* $Author$
|
||||||
|
* $Date$
|
||||||
|
*/
|
||||||
|
class view
|
||||||
|
{
|
||||||
|
protected $hasLayout;
|
||||||
|
private $file;
|
||||||
|
|
||||||
|
public function __construct( $file_path ) {
|
||||||
|
if(!file_exists($file_path)) {
|
||||||
|
throw new Exception('file ' . $file_path . ' does not exist!', 666);
|
||||||
|
} else {
|
||||||
|
$this->file = $file_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compile the view
|
||||||
|
*
|
||||||
|
* @return $HTMLSource the compiled view
|
||||||
|
*/
|
||||||
|
public function compile($registry = false) {
|
||||||
|
if($registry === false){
|
||||||
|
$registry =& registry::getInstance();
|
||||||
|
}
|
||||||
|
$user =& user::getInstance();
|
||||||
|
foreach($registry as $k=>$v){
|
||||||
|
$$k = $v;
|
||||||
|
}
|
||||||
|
ob_start();
|
||||||
|
require $this->file;
|
||||||
|
$body = ob_get_clean();
|
||||||
|
|
||||||
|
(isset($contentType)) ? http_response::content($contentType) : http_response::content(CONTENT_TYPE);
|
||||||
|
|
||||||
|
$isFragment = isset($this->isFragment);
|
||||||
|
|
||||||
|
if(defined('LAYOUT') && !$isFragment){
|
||||||
|
ob_start();
|
||||||
|
require LAYOUT;
|
||||||
|
$body = ob_get_clean();
|
||||||
|
}
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isFragment() {
|
||||||
|
$this->isFragment = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function __toString() {
|
||||||
|
return __CLASS__;
|
||||||
|
}
|
||||||
|
}
|
||||||
19
2015.python.color-contrast-foreground-color.py
Normal file
19
2015.python.color-contrast-foreground-color.py
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
'''
|
||||||
|
based on: http://24ways.org/2010/calculating-color-contrast/
|
||||||
|
accepts hex colors with 3 or 6 chars. hash-char is optional.
|
||||||
|
'''
|
||||||
|
def get_contrast_yiq(hex_color):
|
||||||
|
hex_color = hex_color.replace("#", "")
|
||||||
|
|
||||||
|
if len(hex_color) == 3:
|
||||||
|
hex_color = "".join([c + c for c in hex_color])
|
||||||
|
|
||||||
|
r = int(hex_color[0:2], 16)
|
||||||
|
g = int(hex_color[2:4], 16)
|
||||||
|
b = int(hex_color[4:6], 16)
|
||||||
|
|
||||||
|
yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000
|
||||||
|
|
||||||
|
if yiq >= 128:
|
||||||
|
return 'black'
|
||||||
|
return 'white'
|
||||||
293
2016.less.boilerplate.less
Normal file
293
2016.less.boilerplate.less
Normal file
|
|
@ -0,0 +1,293 @@
|
||||||
|
/*csslint box-model: false, box-sizing: false, universal-selector: false */
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
All projects
|
||||||
|
should have nice
|
||||||
|
ASCII ART!
|
||||||
|
|
||||||
|
http://patorjk.com/software/taag/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
@bg: #fff;
|
||||||
|
@fg: #000;
|
||||||
|
|
||||||
|
.transform(@value) {
|
||||||
|
-webkit-transform: @value;
|
||||||
|
-moz-transform: @value;
|
||||||
|
-o-transform: @value;
|
||||||
|
-ms-transform: @value;
|
||||||
|
transform: @value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Base
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Base
|
||||||
|
|
||||||
|
Normalisering av HTML-element, t ex inmatningsfält, knappar och länkar. Detta
|
||||||
|
avsnitt bör innehålla element- och attributselektorer som är enkla att stila
|
||||||
|
med hjälp av klasser. Klasser ska undvikas.
|
||||||
|
|
||||||
|
Låna så mycket som möjligt från
|
||||||
|
[normalise.css](https://github.com/necolas/normalize.css/blob/master/normalize.css).
|
||||||
|
|
||||||
|
Bastypografin sätts till *large* (ca 24px) med 1.25 radhöjd. Fonten **Open Sans** bäddas in från Google Web Fonts.
|
||||||
|
Fonten ändras med hjälp av media queries (blir mindre på små viewports).
|
||||||
|
|
||||||
|
Markup:
|
||||||
|
Normaliserad text som fyller ut en hel rad genom att
|
||||||
|
fler ord fylls på i det här stycket, även <a href="http://madr.se">länk läggs in</a> för att visa hur den ser ut.
|
||||||
|
<br>Detta är ett hårt radbryt.
|
||||||
|
|
||||||
|
Styleguide 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
*, :before, :after {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
|
||||||
|
background: @bg;
|
||||||
|
color: @fg;
|
||||||
|
font: normal large/1.25 sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
body, ul, p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
legend {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[href]:not([class]) {
|
||||||
|
color: blue;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
em {
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
input[type=submit] {
|
||||||
|
.user-select(text);
|
||||||
|
|
||||||
|
border: 0;
|
||||||
|
font: inherit;
|
||||||
|
line-height: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button::-moz-focus-inner,
|
||||||
|
input[type=submit]::-moz-focus-inner {
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
border: 0;
|
||||||
|
background: #fff;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1;
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Template
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Mall
|
||||||
|
|
||||||
|
Innehåller kolumner, ett system för grids och containers fö övriga
|
||||||
|
designkomponenter. Detta avsnitt ska i strikt mening innehålla endast klasser.
|
||||||
|
|
||||||
|
Styleguide 2
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Float Helpers
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Layouthjälpare (floats)
|
||||||
|
|
||||||
|
Klasser som främst hanterar floats. Är i dagsläget ej anpassade till
|
||||||
|
följsam layout.
|
||||||
|
|
||||||
|
.pull-left - gör ett objekt float: left;
|
||||||
|
.pull-right - gör ett objekt float: right;
|
||||||
|
.line - får en behållare att rymma objekt med floats
|
||||||
|
.clear - får en behållare eller objekt att rensa floats
|
||||||
|
|
||||||
|
Markup:
|
||||||
|
<div class="line">
|
||||||
|
<div class="{$modifiers}">Text</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Styleguide 2.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
.pull-left, .unit {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pull-right {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line:after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Columns
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.page {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Grid
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Grid
|
||||||
|
|
||||||
|
Griden är baserad på YUI grids och är i skrivandets stund ej anpassad för
|
||||||
|
följsam layout.
|
||||||
|
|
||||||
|
Markup:
|
||||||
|
<div class="line">
|
||||||
|
<div class="unit size1of2">1/2</div>
|
||||||
|
<div class="unit size1of2">1/2</div>
|
||||||
|
</div>
|
||||||
|
<div class="line">
|
||||||
|
<div class="unit size1of3">1/3</div>
|
||||||
|
<div class="unit size2of2">2/3</div>
|
||||||
|
</div>
|
||||||
|
<div class="line">
|
||||||
|
<div class="unit size1of4">1/4</div>
|
||||||
|
<div class="unit size3of4">3/4</div>
|
||||||
|
</div>
|
||||||
|
<div class="line">
|
||||||
|
<div class="unit size1of5">1/5</div>
|
||||||
|
<div class="unit size4of5">4/5</div>
|
||||||
|
<div class="unit size3of5">3/5</div>
|
||||||
|
<div class="unit size2of5">2/5</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
Styleguide 2.2
|
||||||
|
*/
|
||||||
|
|
||||||
|
.unit {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size1of5 { width: 20% }
|
||||||
|
.size1of4 { width: 25% }
|
||||||
|
.size1of3 { width: 33.3333% }
|
||||||
|
.size2of5 { width: 40% }
|
||||||
|
.size1of2 { width: 50% }
|
||||||
|
.size3of5 { width: 60% }
|
||||||
|
.size2of3 { width: 66.6666% }
|
||||||
|
.size3of4 { width: 75% }
|
||||||
|
.size4of5 { width: 80% }
|
||||||
|
.size1of7 { width: 14.2857% }
|
||||||
|
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Core modules
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Kärnmoduler
|
||||||
|
|
||||||
|
Moduler som andra moduler är beroende av för att fungera korrekt, vilket gör
|
||||||
|
att dessa behöver komma först i The Cascade.
|
||||||
|
|
||||||
|
Detta avsnitt ska endast innehålla klasser och media queries, med få undantag.
|
||||||
|
|
||||||
|
Styleguide 3
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* nav pattern */
|
||||||
|
.nav { list-style: none; padding: 0;}
|
||||||
|
.nav a, .nav strong { display: block; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Headings
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Rubriker
|
||||||
|
|
||||||
|
Rubriker används för att skapa sektioner och avdelningar i designen.
|
||||||
|
|
||||||
|
.big - Överdrivet stor rubrik
|
||||||
|
.h1 - Dominant one-of-a-kind rubrik
|
||||||
|
.h2 - typisk sektionsrubrik
|
||||||
|
|
||||||
|
Markup:
|
||||||
|
<div class="{$modifiers}">En rubrik<br>med ett radbryt</div>
|
||||||
|
|
||||||
|
Styleguide 3.2
|
||||||
|
*/
|
||||||
|
|
||||||
|
h1, .h1 {
|
||||||
|
font-weight: normal;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.66em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Modules
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Moduler
|
||||||
|
|
||||||
|
Modulerna i detta asvnitt är isolerade och beror ej på andra moduler som ej är
|
||||||
|
kärnmoduler, detta för att enkelt kunna slå av och på CSS. Normalt sett så
|
||||||
|
är modulerna utökningar av kärnmoduler och behållare.
|
||||||
|
|
||||||
|
Avsnittet ska enbart innehålla klasser och media queries, med få undantag.
|
||||||
|
|
||||||
|
Styleguide 4
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
92
2019.python.podcast-downloader.py
Normal file
92
2019.python.podcast-downloader.py
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
"""
|
||||||
|
Podcast backup script
|
||||||
|
|
||||||
|
Parses an RSS feed from SOURCE_FILE and download all items to
|
||||||
|
DESTINATION_PATH. Downloads are done in parallel, for
|
||||||
|
PARALLEL_COUNT downloads at the time.
|
||||||
|
|
||||||
|
How to use
|
||||||
|
----------
|
||||||
|
|
||||||
|
1. Set DESTINATION_PATH. Make sure the folder exists on your
|
||||||
|
file system.
|
||||||
|
2. Save the source file (RSS or Atom) on your computer and
|
||||||
|
update SOURCE_FILE if needed.
|
||||||
|
3. Alter PARALLEL_COUNT for your needs. Higher number will
|
||||||
|
decrease total time for this script to be done, but will
|
||||||
|
increase net traffic.
|
||||||
|
4. Run script in a python intepreter, 3.7 is recommended.
|
||||||
|
|
||||||
|
This script was written by Anders Ytterström in October 2019.
|
||||||
|
If you find it useful, buy him a 🍺.
|
||||||
|
"""
|
||||||
|
import queue
|
||||||
|
import threading
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
from urllib.request import urlretrieve
|
||||||
|
|
||||||
|
DESTINATION_PATH = "D:\Asmodean\podcasts\inbox"
|
||||||
|
SOURCE_FILE = "D:\Kod\gists\src.xml"
|
||||||
|
PARALLEL_COUNT = 3
|
||||||
|
|
||||||
|
|
||||||
|
def download_file(url, target):
|
||||||
|
print(f"Downloading {target} <- {url}")
|
||||||
|
urlretrieve(url, f"{DESTINATION_PATH}\{target}.mp3")
|
||||||
|
|
||||||
|
|
||||||
|
def get_urls():
|
||||||
|
tree = ET.parse(SOURCE_FILE)
|
||||||
|
root = tree.getroot()
|
||||||
|
|
||||||
|
def f(item):
|
||||||
|
url = item.find("enclosure").attrib["url"]
|
||||||
|
filename = slugify(item.find("title").text)
|
||||||
|
return (url, filename)
|
||||||
|
|
||||||
|
return map(f, root.findall("./channel/item"))
|
||||||
|
|
||||||
|
|
||||||
|
def slugify(text):
|
||||||
|
return (
|
||||||
|
text.lower()
|
||||||
|
.replace(" ", "-")
|
||||||
|
.replace(":", "")
|
||||||
|
.replace("/", "-av-")
|
||||||
|
.replace("?", "")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def do_work(item):
|
||||||
|
download_file(*item)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
def worker():
|
||||||
|
while True:
|
||||||
|
item = q.get()
|
||||||
|
if item is None:
|
||||||
|
break
|
||||||
|
do_work(item)
|
||||||
|
q.task_done()
|
||||||
|
|
||||||
|
q = queue.Queue()
|
||||||
|
threads = []
|
||||||
|
for i in range(PARALLEL_COUNT):
|
||||||
|
t = threading.Thread(target=worker)
|
||||||
|
t.start()
|
||||||
|
threads.append(t)
|
||||||
|
|
||||||
|
source = get_urls()
|
||||||
|
for item in source:
|
||||||
|
q.put(item)
|
||||||
|
|
||||||
|
# block until all tasks are done
|
||||||
|
q.join()
|
||||||
|
|
||||||
|
# stop workers
|
||||||
|
for i in range(PARALLEL_COUNT):
|
||||||
|
q.put(None)
|
||||||
|
for t in threads:
|
||||||
|
t.join()
|
||||||
71
2020.css.shame.css
Normal file
71
2020.css.shame.css
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
acronym,
|
||||||
|
applet,
|
||||||
|
basefont,
|
||||||
|
big,
|
||||||
|
center,
|
||||||
|
dir,
|
||||||
|
font,
|
||||||
|
isindex,
|
||||||
|
menu,
|
||||||
|
noframes,
|
||||||
|
s,
|
||||||
|
strike,
|
||||||
|
tt,
|
||||||
|
u {
|
||||||
|
color: red !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[rev],
|
||||||
|
[charset],
|
||||||
|
[shape],
|
||||||
|
[coords],
|
||||||
|
[longdesc],
|
||||||
|
link[target]
|
||||||
|
[nohref]
|
||||||
|
img[name]
|
||||||
|
archive object
|
||||||
|
classid object
|
||||||
|
codebase object
|
||||||
|
codetype object
|
||||||
|
declare object
|
||||||
|
standby object
|
||||||
|
valuetype param
|
||||||
|
type param
|
||||||
|
axis td and t
|
||||||
|
abbr td and t
|
||||||
|
scope td
|
||||||
|
align caption, iframe, img, input, object, legend, table, hr, div, h1, h2, h3, h4, h5, h6, p, col, colgroup, tbody, td, tfoot, th, thead and tr.
|
||||||
|
alink body
|
||||||
|
link body
|
||||||
|
vlink body
|
||||||
|
text body
|
||||||
|
background body
|
||||||
|
bgcolor table, tr, td, th and body.
|
||||||
|
border table and object.
|
||||||
|
cellpadding table
|
||||||
|
cellspacing table
|
||||||
|
char col, colgroup, tbody, td, tfoot, th, thead and tr.
|
||||||
|
charoff col, colgroup, tbody, td, tfoot, th, thead and tr.
|
||||||
|
clear br
|
||||||
|
compact dl, menu, ol and ul.
|
||||||
|
frame table
|
||||||
|
compact dl, menu, ol and ul.
|
||||||
|
frame table
|
||||||
|
frameborder iframe
|
||||||
|
hspace img and object.
|
||||||
|
vspace img and object.
|
||||||
|
marginheight iframe
|
||||||
|
marginwidth iframe
|
||||||
|
noshade hr
|
||||||
|
nowrap td and th
|
||||||
|
rules table
|
||||||
|
scrolling iframe
|
||||||
|
size hr
|
||||||
|
type li, ol and ul.
|
||||||
|
valign col, colgroup, tbody, td, tfoot, th, thead and tr
|
||||||
|
width hr, table, td, th, col, colgroup and pre.
|
||||||
|
|
||||||
|
br + br {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
12
2021.spreadsheet.army-fat.txt
Normal file
12
2021.spreadsheet.army-fat.txt
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
# Males (B2: waist, C2: neck)
|
||||||
|
# Replace `height` with actual height
|
||||||
|
# for the imperial system, replace 30,3 with 36,76
|
||||||
|
=86,01 * Log10(B2 - C2) - 70,041 * log10(height) + 30,3
|
||||||
|
|
||||||
|
# Females (B2: waist, C2: neck, D2: hips)
|
||||||
|
# Replace `height` with actual height
|
||||||
|
# for the imperial system, replace 104,912 with 78,387
|
||||||
|
=163,205 * Log10(B2 + D2 - C2) - 97,684 * Log10(height) - 104,912
|
||||||
|
|
||||||
|
# ALL MEASUREMENTS SHOULD BE DONE IN METRIC, LIKE THE REST OF THE WORLD DOES IT.
|
||||||
|
# https://friendlybit.com/other/im-not-from-america/
|
||||||
Loading…
Add table
Reference in a new issue