Added lawnchair to list of working utilities, and am adding the editor.
This commit is contained in:
parent
de33547e83
commit
f4090dd0d2
11
grunt.coffee
11
grunt.coffee
|
@ -91,12 +91,9 @@ module.exports = (grunt) ->
|
||||||
|
|
||||||
install:
|
install:
|
||||||
src: [
|
src: [
|
||||||
"src/index.html"
|
|
||||||
"src/priority.js"
|
|
||||||
"src/*_tmpl.js"
|
|
||||||
"src/style.css"
|
|
||||||
"libs/jquery/jquery-1.7.2.js"
|
"libs/jquery/jquery-1.7.2.js"
|
||||||
"libs/require.js"
|
"libs/require.js"
|
||||||
|
"libs/lawnchair/lawnchair.js"
|
||||||
]
|
]
|
||||||
dest: "dist"
|
dest: "dist"
|
||||||
|
|
||||||
|
@ -106,7 +103,7 @@ module.exports = (grunt) ->
|
||||||
uglify: {}
|
uglify: {}
|
||||||
|
|
||||||
|
|
||||||
grunt.registerTask "default", "coffee:dev recess:dev haml:dev hamltojs:dev"
|
grunt.registerTask "default", "coffee:dev recess:dev haml:dev hamltojs:dev install"
|
||||||
|
|
||||||
# _ _ _ __ __ _ _ _ _ _____ __ __ _
|
# _ _ _ __ __ _ _ _ _ _____ __ __ _
|
||||||
# | || | /_\ | \/ | | | |_ ___ | || |_ _| \/ | |
|
# | || | /_\ | \/ | | | |_ ___ | || |_ _| \/ | |
|
||||||
|
@ -143,7 +140,7 @@ module.exports = (grunt) ->
|
||||||
grunt.registerHelper "templatize", (src, dest, done) ->
|
grunt.registerHelper "templatize", (src, dest, done) ->
|
||||||
file = grunt.file.read(src)
|
file = grunt.file.read(src)
|
||||||
out = path.basename(src, ".html")
|
out = path.basename(src, ".html")
|
||||||
grunt.file.write path.join(dest, out + ".js"), "define(" + _und.template(file).source + ");"
|
grunt.file.write path.join(dest, out + ".js"), "define(function() { return " + _und.template(result.stdout).source + "});"
|
||||||
done()
|
done()
|
||||||
|
|
||||||
grunt.registerMultiTask "templatize", "Compile Underscored HTML to Javascript", ->
|
grunt.registerMultiTask "templatize", "Compile Underscored HTML to Javascript", ->
|
||||||
|
@ -169,7 +166,7 @@ module.exports = (grunt) ->
|
||||||
grunt.utils.spawn args, (err, result) ->
|
grunt.utils.spawn args, (err, result) ->
|
||||||
console.log err if err
|
console.log err if err
|
||||||
out = path.basename(src, ".haml")
|
out = path.basename(src, ".haml")
|
||||||
grunt.file.write path.join(dest, out + ".js"), "define(" + _und.template(result.stdout).source + ");"
|
grunt.file.write path.join(dest, out + ".js"), "define(function() { return " + _und.template(result.stdout).source + "});"
|
||||||
done()
|
done()
|
||||||
|
|
||||||
grunt.registerMultiTask "hamltojs", "Compile Underscored HAML to Javascript", ->
|
grunt.registerMultiTask "hamltojs", "Compile Underscored HAML to Javascript", ->
|
||||||
|
|
8
grunt.js
8
grunt.js
|
@ -111,7 +111,7 @@ module.exports = function(grunt) {
|
||||||
findNestedDependencies: true
|
findNestedDependencies: true
|
||||||
},
|
},
|
||||||
install: {
|
install: {
|
||||||
src: ["src/index.html", "src/priority.js", "src/*_tmpl.js", "src/style.css", "libs/jquery/jquery-1.7.2.js", "libs/require.js"],
|
src: ["libs/jquery/jquery-1.7.2.js", "libs/require.js", "libs/lawnchair/lawnchair.js"],
|
||||||
dest: "dist"
|
dest: "dist"
|
||||||
},
|
},
|
||||||
mocha: {
|
mocha: {
|
||||||
|
@ -119,7 +119,7 @@ module.exports = function(grunt) {
|
||||||
},
|
},
|
||||||
uglify: {}
|
uglify: {}
|
||||||
});
|
});
|
||||||
grunt.registerTask("default", "coffee:dev recess:dev haml:dev hamltojs:dev");
|
grunt.registerTask("default", "coffee:dev recess:dev haml:dev hamltojs:dev install");
|
||||||
grunt.registerHelper("haml", function(src, dest, done) {
|
grunt.registerHelper("haml", function(src, dest, done) {
|
||||||
var args;
|
var args;
|
||||||
args = {
|
args = {
|
||||||
|
@ -149,7 +149,7 @@ module.exports = function(grunt) {
|
||||||
var file, out;
|
var file, out;
|
||||||
file = grunt.file.read(src);
|
file = grunt.file.read(src);
|
||||||
out = path.basename(src, ".html");
|
out = path.basename(src, ".html");
|
||||||
grunt.file.write(path.join(dest, out + ".js"), "define(" + _und.template(file).source + ");");
|
grunt.file.write(path.join(dest, out + ".js"), "define(function() { return " + _und.template(result.stdout).source + "});");
|
||||||
return done();
|
return done();
|
||||||
});
|
});
|
||||||
grunt.registerMultiTask("templatize", "Compile Underscored HTML to Javascript", function() {
|
grunt.registerMultiTask("templatize", "Compile Underscored HTML to Javascript", function() {
|
||||||
|
@ -176,7 +176,7 @@ module.exports = function(grunt) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
out = path.basename(src, ".haml");
|
out = path.basename(src, ".haml");
|
||||||
grunt.file.write(path.join(dest, out + ".js"), "define(" + _und.template(result.stdout).source + ");");
|
grunt.file.write(path.join(dest, out + ".js"), "define(function() { return " + _und.template(result.stdout).source + "});");
|
||||||
return done();
|
return done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,438 @@
|
||||||
|
/**
|
||||||
|
* Lawnchair!
|
||||||
|
* ---
|
||||||
|
* clientside json store
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
var Lawnchair = function (options, callback) {
|
||||||
|
// ensure Lawnchair was called as a constructor
|
||||||
|
if (!(this instanceof Lawnchair)) return new Lawnchair(options, callback);
|
||||||
|
|
||||||
|
// lawnchair requires json
|
||||||
|
if (!JSON) throw 'JSON unavailable! Include http://www.json.org/json2.js to fix.'
|
||||||
|
// options are optional; callback is not
|
||||||
|
if (arguments.length <= 2 && arguments.length > 0) {
|
||||||
|
callback = (typeof arguments[0] === 'function') ? arguments[0] : arguments[1];
|
||||||
|
options = (typeof arguments[0] === 'function') ? {} : arguments[0];
|
||||||
|
} else {
|
||||||
|
throw 'Incorrect # of ctor args!'
|
||||||
|
}
|
||||||
|
// TODO perhaps allow for pub/sub instead?
|
||||||
|
if (typeof callback !== 'function') throw 'No callback was provided';
|
||||||
|
|
||||||
|
// default configuration
|
||||||
|
this.record = options.record || 'record' // default for records
|
||||||
|
this.name = options.name || 'records' // default name for underlying store
|
||||||
|
|
||||||
|
// mixin first valid adapter
|
||||||
|
var adapter
|
||||||
|
// if the adapter is passed in we try to load that only
|
||||||
|
if (options.adapter) {
|
||||||
|
for (var i = 0, l = Lawnchair.adapters.length; i < l; i++) {
|
||||||
|
if (Lawnchair.adapters[i].adapter === options.adapter) {
|
||||||
|
adapter = Lawnchair.adapters[i].valid() ? Lawnchair.adapters[i] : undefined;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// otherwise find the first valid adapter for this env
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (var i = 0, l = Lawnchair.adapters.length; i < l; i++) {
|
||||||
|
adapter = Lawnchair.adapters[i].valid() ? Lawnchair.adapters[i] : undefined
|
||||||
|
if (adapter) break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we have failed
|
||||||
|
if (!adapter) throw 'No valid adapter.'
|
||||||
|
|
||||||
|
// yay! mixin the adapter
|
||||||
|
for (var j in adapter)
|
||||||
|
this[j] = adapter[j]
|
||||||
|
|
||||||
|
// call init for each mixed in plugin
|
||||||
|
for (var i = 0, l = Lawnchair.plugins.length; i < l; i++)
|
||||||
|
Lawnchair.plugins[i].call(this)
|
||||||
|
|
||||||
|
// init the adapter
|
||||||
|
this.init(options, callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
Lawnchair.adapters = []
|
||||||
|
|
||||||
|
/**
|
||||||
|
* queues an adapter for mixin
|
||||||
|
* ===
|
||||||
|
* - ensures an adapter conforms to a specific interface
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Lawnchair.adapter = function (id, obj) {
|
||||||
|
// add the adapter id to the adapter obj
|
||||||
|
// ugly here for a cleaner dsl for implementing adapters
|
||||||
|
obj['adapter'] = id
|
||||||
|
// methods required to implement a lawnchair adapter
|
||||||
|
var implementing = 'adapter valid init keys save batch get exists all remove nuke'.split(' ')
|
||||||
|
, indexOf = this.prototype.indexOf
|
||||||
|
// mix in the adapter
|
||||||
|
for (var i in obj) {
|
||||||
|
if (indexOf(implementing, i) === -1) throw 'Invalid adapter! Nonstandard method: ' + i
|
||||||
|
}
|
||||||
|
// if we made it this far the adapter interface is valid
|
||||||
|
// insert the new adapter as the preferred adapter
|
||||||
|
Lawnchair.adapters.splice(0,0,obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
Lawnchair.plugins = []
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generic shallow extension for plugins
|
||||||
|
* ===
|
||||||
|
* - if an init method is found it registers it to be called when the lawnchair is inited
|
||||||
|
* - yes we could use hasOwnProp but nobody here is an asshole
|
||||||
|
*/
|
||||||
|
Lawnchair.plugin = function (obj) {
|
||||||
|
for (var i in obj)
|
||||||
|
i === 'init' ? Lawnchair.plugins.push(obj[i]) : this.prototype[i] = obj[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* helpers
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Lawnchair.prototype = {
|
||||||
|
|
||||||
|
isArray: Array.isArray || function(o) { return Object.prototype.toString.call(o) === '[object Array]' },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this code exists for ie8... for more background see:
|
||||||
|
* http://www.flickr.com/photos/westcoastlogic/5955365742/in/photostream
|
||||||
|
*/
|
||||||
|
indexOf: function(ary, item, i, l) {
|
||||||
|
if (ary.indexOf) return ary.indexOf(item)
|
||||||
|
for (i = 0, l = ary.length; i < l; i++) if (ary[i] === item) return i
|
||||||
|
return -1
|
||||||
|
},
|
||||||
|
|
||||||
|
// awesome shorthand callbacks as strings. this is shameless theft from dojo.
|
||||||
|
lambda: function (callback) {
|
||||||
|
return this.fn(this.record, callback)
|
||||||
|
},
|
||||||
|
|
||||||
|
// first stab at named parameters for terse callbacks; dojo: first != best // ;D
|
||||||
|
fn: function (name, callback) {
|
||||||
|
return typeof callback == 'string' ? new Function(name, callback) : callback
|
||||||
|
},
|
||||||
|
|
||||||
|
// returns a unique identifier (by way of Backbone.localStorage.js)
|
||||||
|
// TODO investigate smaller UUIDs to cut on storage cost
|
||||||
|
uuid: function () {
|
||||||
|
var S4 = function () {
|
||||||
|
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
|
||||||
|
}
|
||||||
|
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
|
||||||
|
},
|
||||||
|
|
||||||
|
// a classic iterator
|
||||||
|
each: function (callback) {
|
||||||
|
var cb = this.lambda(callback)
|
||||||
|
// iterate from chain
|
||||||
|
if (this.__results) {
|
||||||
|
for (var i = 0, l = this.__results.length; i < l; i++) cb.call(this, this.__results[i], i)
|
||||||
|
}
|
||||||
|
// otherwise iterate the entire collection
|
||||||
|
else {
|
||||||
|
this.all(function(r) {
|
||||||
|
for (var i = 0, l = r.length; i < l; i++) cb.call(this, r[i], i)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
// --
|
||||||
|
};
|
||||||
|
// window.name code courtesy Remy Sharp: http://24ways.org/2009/breaking-out-the-edges-of-the-browser
|
||||||
|
Lawnchair.adapter('window-name', (function(index, store) {
|
||||||
|
if (typeof window==='undefined') {
|
||||||
|
window = { top: { } }; // node/optimizer compatibility
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = window.top.name ? JSON.parse(window.top.name) : {}
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
valid: function () {
|
||||||
|
return typeof window.top.name != 'undefined'
|
||||||
|
},
|
||||||
|
|
||||||
|
init: function (options, callback) {
|
||||||
|
data[this.name] = data[this.name] || {index:[],store:{}}
|
||||||
|
index = data[this.name].index
|
||||||
|
store = data[this.name].store
|
||||||
|
this.fn(this.name, callback).call(this, this)
|
||||||
|
},
|
||||||
|
|
||||||
|
keys: function (callback) {
|
||||||
|
this.fn('keys', callback).call(this, index)
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
save: function (obj, cb) {
|
||||||
|
// data[key] = value + ''; // force to string
|
||||||
|
// window.top.name = JSON.stringify(data);
|
||||||
|
var key = obj.key || this.uuid()
|
||||||
|
this.exists(key, function(exists) {
|
||||||
|
if (!exists) {
|
||||||
|
if (obj.key) delete obj.key
|
||||||
|
index.push(key)
|
||||||
|
}
|
||||||
|
store[key] = obj
|
||||||
|
window.top.name = JSON.stringify(data) // TODO wow, this is the only diff from the memory adapter
|
||||||
|
if (cb) {
|
||||||
|
obj.key = key
|
||||||
|
this.lambda(cb).call(this, obj)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
batch: function (objs, cb) {
|
||||||
|
var r = []
|
||||||
|
for (var i = 0, l = objs.length; i < l; i++) {
|
||||||
|
this.save(objs[i], function(record) {
|
||||||
|
r.push(record)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (cb) this.lambda(cb).call(this, r)
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
get: function (keyOrArray, cb) {
|
||||||
|
var r;
|
||||||
|
if (this.isArray(keyOrArray)) {
|
||||||
|
r = []
|
||||||
|
for (var i = 0, l = keyOrArray.length; i < l; i++) {
|
||||||
|
r.push(store[keyOrArray[i]])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r = store[keyOrArray]
|
||||||
|
if (r) r.key = keyOrArray
|
||||||
|
}
|
||||||
|
if (cb) this.lambda(cb).call(this, r)
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
exists: function (key, cb) {
|
||||||
|
this.lambda(cb).call(this, !!(store[key]))
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
all: function (cb) {
|
||||||
|
var r = []
|
||||||
|
for (var i = 0, l = index.length; i < l; i++) {
|
||||||
|
var obj = store[index[i]]
|
||||||
|
obj.key = index[i]
|
||||||
|
r.push(obj)
|
||||||
|
}
|
||||||
|
this.fn(this.name, cb).call(this, r)
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
remove: function (keyOrArray, cb) {
|
||||||
|
var del = this.isArray(keyOrArray) ? keyOrArray : [keyOrArray]
|
||||||
|
for (var i = 0, l = del.length; i < l; i++) {
|
||||||
|
delete store[del[i]]
|
||||||
|
index.splice(this.indexOf(index, del[i]), 1)
|
||||||
|
}
|
||||||
|
window.top.name = JSON.stringify(data)
|
||||||
|
if (cb) this.lambda(cb).call(this)
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
nuke: function (cb) {
|
||||||
|
store = {}
|
||||||
|
index = []
|
||||||
|
window.top.name = JSON.stringify(data)
|
||||||
|
if (cb) this.lambda(cb).call(this)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/////
|
||||||
|
})())
|
||||||
|
/**
|
||||||
|
* dom storage adapter
|
||||||
|
* ===
|
||||||
|
* - originally authored by Joseph Pecoraro
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
//
|
||||||
|
// TODO does it make sense to be chainable all over the place?
|
||||||
|
// chainable: nuke, remove, all, get, save, all
|
||||||
|
// not chainable: valid, keys
|
||||||
|
//
|
||||||
|
Lawnchair.adapter('dom', (function() {
|
||||||
|
var storage = window.localStorage
|
||||||
|
// the indexer is an encapsulation of the helpers needed to keep an ordered index of the keys
|
||||||
|
var indexer = function(name) {
|
||||||
|
return {
|
||||||
|
// the key
|
||||||
|
key: name + '._index_',
|
||||||
|
// returns the index
|
||||||
|
all: function() {
|
||||||
|
var a = storage.getItem(this.key)
|
||||||
|
if (a) {
|
||||||
|
a = JSON.parse(a)
|
||||||
|
}
|
||||||
|
if (a === null) storage.setItem(this.key, JSON.stringify([])) // lazy init
|
||||||
|
return JSON.parse(storage.getItem(this.key))
|
||||||
|
},
|
||||||
|
// adds a key to the index
|
||||||
|
add: function (key) {
|
||||||
|
var a = this.all()
|
||||||
|
a.push(key)
|
||||||
|
storage.setItem(this.key, JSON.stringify(a))
|
||||||
|
},
|
||||||
|
// deletes a key from the index
|
||||||
|
del: function (key) {
|
||||||
|
var a = this.all(), r = []
|
||||||
|
// FIXME this is crazy inefficient but I'm in a strata meeting and half concentrating
|
||||||
|
for (var i = 0, l = a.length; i < l; i++) {
|
||||||
|
if (a[i] != key) r.push(a[i])
|
||||||
|
}
|
||||||
|
storage.setItem(this.key, JSON.stringify(r))
|
||||||
|
},
|
||||||
|
// returns index for a key
|
||||||
|
find: function (key) {
|
||||||
|
var a = this.all()
|
||||||
|
for (var i = 0, l = a.length; i < l; i++) {
|
||||||
|
if (key === a[i]) return i
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// adapter api
|
||||||
|
return {
|
||||||
|
|
||||||
|
// ensure we are in an env with localStorage
|
||||||
|
valid: function () {
|
||||||
|
return !!storage && function() {
|
||||||
|
// in mobile safari if safe browsing is enabled, window.storage
|
||||||
|
// is defined but setItem calls throw exceptions.
|
||||||
|
var success = true
|
||||||
|
var value = Math.random()
|
||||||
|
try {
|
||||||
|
storage.setItem(value, value)
|
||||||
|
} catch (e) {
|
||||||
|
success = false
|
||||||
|
}
|
||||||
|
storage.removeItem(value)
|
||||||
|
return success
|
||||||
|
}()
|
||||||
|
},
|
||||||
|
|
||||||
|
init: function (options, callback) {
|
||||||
|
this.indexer = indexer(this.name)
|
||||||
|
if (callback) this.fn(this.name, callback).call(this, this)
|
||||||
|
},
|
||||||
|
|
||||||
|
save: function (obj, callback) {
|
||||||
|
var key = obj.key ? this.name + '.' + obj.key : this.name + '.' + this.uuid()
|
||||||
|
// if the key is not in the index push it on
|
||||||
|
if (this.indexer.find(key) === false) this.indexer.add(key)
|
||||||
|
// now we kil the key and use it in the store colleciton
|
||||||
|
delete obj.key;
|
||||||
|
storage.setItem(key, JSON.stringify(obj))
|
||||||
|
obj.key = key.slice(this.name.length + 1)
|
||||||
|
if (callback) {
|
||||||
|
this.lambda(callback).call(this, obj)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
batch: function (ary, callback) {
|
||||||
|
var saved = []
|
||||||
|
// not particularily efficient but this is more for sqlite situations
|
||||||
|
for (var i = 0, l = ary.length; i < l; i++) {
|
||||||
|
this.save(ary[i], function(r){
|
||||||
|
saved.push(r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (callback) this.lambda(callback).call(this, saved)
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
// accepts [options], callback
|
||||||
|
keys: function(callback) {
|
||||||
|
if (callback) {
|
||||||
|
var name = this.name
|
||||||
|
, keys = this.indexer.all().map(function(r){ return r.replace(name + '.', '') })
|
||||||
|
this.fn('keys', callback).call(this, keys)
|
||||||
|
}
|
||||||
|
return this // TODO options for limit/offset, return promise
|
||||||
|
},
|
||||||
|
|
||||||
|
get: function (key, callback) {
|
||||||
|
if (this.isArray(key)) {
|
||||||
|
var r = []
|
||||||
|
for (var i = 0, l = key.length; i < l; i++) {
|
||||||
|
var k = this.name + '.' + key[i]
|
||||||
|
var obj = storage.getItem(k)
|
||||||
|
if (obj) {
|
||||||
|
obj = JSON.parse(obj)
|
||||||
|
obj.key = key[i]
|
||||||
|
r.push(obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (callback) this.lambda(callback).call(this, r)
|
||||||
|
} else {
|
||||||
|
var k = this.name + '.' + key
|
||||||
|
var obj = storage.getItem(k)
|
||||||
|
if (obj) {
|
||||||
|
obj = JSON.parse(obj)
|
||||||
|
obj.key = key
|
||||||
|
}
|
||||||
|
if (callback) this.lambda(callback).call(this, obj)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
exists: function (key, cb) {
|
||||||
|
var exists = this.indexer.find(this.name+'.'+key) === false ? false : true ;
|
||||||
|
this.lambda(cb).call(this, exists);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
// NOTE adapters cannot set this.__results but plugins do
|
||||||
|
// this probably should be reviewed
|
||||||
|
all: function (callback) {
|
||||||
|
var idx = this.indexer.all()
|
||||||
|
, r = []
|
||||||
|
, o
|
||||||
|
, k
|
||||||
|
for (var i = 0, l = idx.length; i < l; i++) {
|
||||||
|
k = idx[i] //v
|
||||||
|
o = JSON.parse(storage.getItem(k))
|
||||||
|
o.key = k.replace(this.name + '.', '')
|
||||||
|
r.push(o)
|
||||||
|
}
|
||||||
|
if (callback) this.fn(this.name, callback).call(this, r)
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
remove: function (keyOrObj, callback) {
|
||||||
|
var key = this.name + '.' + ((keyOrObj.key) ? keyOrObj.key : keyOrObj)
|
||||||
|
this.indexer.del(key)
|
||||||
|
storage.removeItem(key)
|
||||||
|
if (callback) this.lambda(callback).call(this)
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
|
||||||
|
nuke: function (callback) {
|
||||||
|
this.all(function(r) {
|
||||||
|
for (var i = 0, l = r.length; i < l; i++) {
|
||||||
|
this.remove(r[i]);
|
||||||
|
}
|
||||||
|
if (callback) this.lambda(callback).call(this)
|
||||||
|
})
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}})());
|
|
@ -0,0 +1,3 @@
|
||||||
|
.edit-priority
|
||||||
|
.input.edit-priority-field(type="text" value="<%= p.name %>" data-for="<%= p.pos %>")
|
||||||
|
.button.delete-priority-field(data-for="<%= p.pos %>")
|
|
@ -12,12 +12,14 @@
|
||||||
%title Priority / Ignore
|
%title Priority / Ignore
|
||||||
|
|
||||||
%body
|
%body
|
||||||
#content
|
#grid.container
|
||||||
#leftbrain.column
|
.flow
|
||||||
%h1.prioritize Today I Will Pay Attention To:
|
.row-fluid
|
||||||
|
#leftbrain.span6
|
||||||
|
%h1#prioritize(data-for="0") Today I Will Pay Attention To:
|
||||||
#priorities
|
#priorities
|
||||||
#rightbrain.column
|
#rightbrain.span6
|
||||||
%h1.prioritize Today I Will Ignore:
|
%h1#ignorize(data-for="0") Today I Will Ignore:
|
||||||
#ignorities
|
#ignorities
|
||||||
|
|
||||||
#message(style="display:none")
|
#message(style="display:none")
|
||||||
|
|
|
@ -2,47 +2,70 @@ require.config
|
||||||
paths:
|
paths:
|
||||||
'jquery': 'jquery-1.7.2'
|
'jquery': 'jquery-1.7.2'
|
||||||
|
|
||||||
require ['jquery', 'priority_tmpl'], ($, priority_template) ->
|
require ['jquery', 'priority_tmpl', 'lawnchair'], ($, priority_template) ->
|
||||||
|
|
||||||
class Prioritize
|
class Prioritize
|
||||||
|
|
||||||
constructor(@repo) ->
|
constructor: (@repo) ->
|
||||||
@repo.get 'priorities', (p) =>
|
@repo.get 'priorities', (p) =>
|
||||||
@priorities = if p? and p.priorities? then p.priorities else []
|
@priorities = if p? and p.priorities? then p.priorities else []
|
||||||
@render()
|
@render()
|
||||||
|
|
||||||
$('body').on 'click', @render
|
$('body').on 'click', @render
|
||||||
$('#thumbsup').on 'click', () => @newPriority('priority')
|
$('#prioritize').on 'click', (ev) => @editPriority(ev, 'priority')
|
||||||
$('#thumbsdn').on 'click', () => @newPriority('ignore')
|
$('#ignorize').on 'click', (ev) => @editPriority(ev, 'ignore')
|
||||||
|
|
||||||
|
|
||||||
|
editPriority: (ev, ty = 'parent') =>
|
||||||
|
|
||||||
|
|
||||||
|
newPriority: (ty, ev) =>
|
||||||
|
ev.stopPropagation()
|
||||||
|
return if $('.edit-priority').length > 0
|
||||||
|
target = if ty == 'priority' then $('#priorities') else $('#ignorities')
|
||||||
|
target.append(edit_priorities_template({fur: ty}))
|
||||||
|
input = $('input.edit-priority-field', target)
|
||||||
|
|
||||||
|
maybeNewPrioritySave = (ev) =>
|
||||||
|
prioritySave = =>
|
||||||
|
@priorities.push({cat: ty, name: input.val()})
|
||||||
|
@save()
|
||||||
|
|
||||||
|
code = if ev.keyCode then ev.keyCode else ev.which
|
||||||
|
return prioritySave() if code == 13
|
||||||
|
return @cleanAndRender() if code == 27
|
||||||
|
|
||||||
|
input.on 'keyup', maybeNewPrioritySave
|
||||||
|
$('.delete-priority-field', target).on 'click', @render
|
||||||
|
input.focus()
|
||||||
|
|
||||||
|
save: ->
|
||||||
|
@repo.save {key: 'priorities', 'priorities': @priorities}, () =>
|
||||||
|
@render()
|
||||||
|
|
||||||
|
clean: ->
|
||||||
|
@priorities = ({name: p.name, cat: p.cat} for p in @priorities when c.name.trim() != "")
|
||||||
|
|
||||||
|
cleanAndRender: ->
|
||||||
|
@clean()
|
||||||
|
@render()
|
||||||
|
|
||||||
save: ->
|
save: ->
|
||||||
@repo.save {key: 'priorities', 'priorities': @priorities}, =>
|
@repo.save {key: 'priorities', 'priorities': @priorities}, =>
|
||||||
@render()
|
@render()
|
||||||
|
|
||||||
render: =>
|
render: =>
|
||||||
priority_enumerate = (cat) ->
|
priority_enumerate = (cat) =>
|
||||||
(c for c in @priorities if c.cat == cat)
|
r = []
|
||||||
|
for i in [0...@priorities.length]
|
||||||
|
if @priorities[i].cat == cat
|
||||||
|
r.push({name: @priorities[i].name, cat: @priorities[i].cat, pos: i})
|
||||||
|
r
|
||||||
|
|
||||||
priority_render = (cat) ->
|
$('#priorities').html(priority_template({priorities: priority_enumerate('priority')}))
|
||||||
$('#priority_list').html(priority_template({priorities: priority_enumerate('priority')}))
|
$('#ignorities').html(priority_template({priorities: priority_enumerate('ignore')}))
|
||||||
$('#ignore_list').html(priority_template({priorities: priority_enumerate('ignore')}))
|
|
||||||
|
|
||||||
$ ->
|
$ ->
|
||||||
prioritize = new Lawnchair {name: 'Prioritize'}, ->
|
prioritize = new Lawnchair {name: 'Prioritize'}, ->
|
||||||
p = this
|
handler = new Prioritize(this)
|
||||||
p.save
|
handler.render()
|
||||||
key: 'priorities',
|
|
||||||
priorities: [
|
|
||||||
{cat: 'priority', name: 'Omaha, Stormy, Raeney'}
|
|
||||||
{cat: 'ignore', name: 'Politics'}
|
|
||||||
{cat: 'priority', name: 'Spiral Genetics'}
|
|
||||||
{cat: 'priority', name: 'Looking for Work'}
|
|
||||||
{cat: 'priority', name: 'Writing'}
|
|
||||||
{cat: 'priority', name: 'Productivity Core'}
|
|
||||||
{cat: 'priority', name: 'Story Core'}
|
|
||||||
{cat: 'ignore', name: 'Smut'}
|
|
||||||
{cat: 'ignore', name: 'Religious Arguments'}
|
|
||||||
{cat: 'ignore', name: 'PASWO'}
|
|
||||||
{cat: 'ignore', name: 'Twitter'}
|
|
||||||
], ->
|
|
||||||
handler = new Prioritize(p)
|
|
||||||
|
|
420
src/style.less
420
src/style.less
|
@ -55,43 +55,322 @@ input[type="search"]::-webkit-search-cancel-button {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
* {
|
|
||||||
border: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font: 13pt/190% Calibri,Georgia,"Lucida Bright",Lucidabright,"Bitstream Vera Serif",serif;
|
font: 13pt/190% Montserrat,Calibri,Georgia,"Lucida Bright",Lucidabright,"Bitstream Vera Serif",serif;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
.clearfix {
|
||||||
margin: .25in .75in .25in 1.5in;
|
*zoom: 1;
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
display: table;
|
||||||
|
content: "";
|
||||||
}
|
}
|
||||||
.clearoncolumn {
|
&:after {
|
||||||
clear: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (min-width: 480px) {
|
|
||||||
body {
|
|
||||||
margin: .25in .75in .25in 1.5in;
|
|
||||||
}
|
|
||||||
.clearoncolumn {
|
|
||||||
clear: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 479px) {
|
|
||||||
body {
|
|
||||||
margin: 2% 2% 0 6%;
|
|
||||||
}
|
|
||||||
.clearoncolumn {
|
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Block level inputs
|
||||||
|
.input-block-level {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 28px; // Make inputs at least the height of their button counterpart
|
||||||
|
.box-sizing(border-box); // Makes inputs behave like true block-level elements
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// GRID
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
// Default 940px grid
|
||||||
|
// -------------------------
|
||||||
|
@gridColumns: 12;
|
||||||
|
@gridColumnWidth: 60px;
|
||||||
|
@gridGutterWidth: 20px;
|
||||||
|
@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1));
|
||||||
|
|
||||||
|
// Fluid grid
|
||||||
|
// -------------------------
|
||||||
|
@fluidGridColumnWidth: 6.382978723%;
|
||||||
|
@fluidGridGutterWidth: 2.127659574%;
|
||||||
|
|
||||||
|
#grid {
|
||||||
|
|
||||||
|
.core (@gridColumnWidth, @gridGutterWidth) {
|
||||||
|
|
||||||
|
.spanX (@index) when (@index > 0) {
|
||||||
|
(~".span@{index}") { .span(@index); }
|
||||||
|
.spanX(@index - 1);
|
||||||
|
}
|
||||||
|
.spanX (0) {}
|
||||||
|
|
||||||
|
.offsetX (@index) when (@index > 0) {
|
||||||
|
(~".offset@{index}") { .offset(@index); }
|
||||||
|
.offsetX(@index - 1);
|
||||||
|
}
|
||||||
|
.offsetX (0) {}
|
||||||
|
|
||||||
|
.offset (@columns) {
|
||||||
|
margin-left: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.span (@columns) {
|
||||||
|
width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
margin-left: @gridGutterWidth * -1;
|
||||||
|
.clearfix();
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*="span"] {
|
||||||
|
float: left;
|
||||||
|
margin-left: @gridGutterWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the container width, and override it for fixed navbars in media queries
|
||||||
|
.container,
|
||||||
|
.navbar-fixed-top .container,
|
||||||
|
.navbar-fixed-bottom .container { .span(@gridColumns); }
|
||||||
|
|
||||||
|
// generate .spanX and .offsetX
|
||||||
|
.spanX (@gridColumns);
|
||||||
|
.offsetX (@gridColumns);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.fluid (@fluidGridColumnWidth, @fluidGridGutterWidth) {
|
||||||
|
|
||||||
|
.spanX (@index) when (@index > 0) {
|
||||||
|
(~".span@{index}") { .span(@index); }
|
||||||
|
.spanX(@index - 1);
|
||||||
|
}
|
||||||
|
.spanX (0) {}
|
||||||
|
|
||||||
|
.span (@columns) {
|
||||||
|
width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1));
|
||||||
|
*width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-fluid {
|
||||||
|
width: 100%;
|
||||||
|
.clearfix();
|
||||||
|
[class*="span"] {
|
||||||
|
.input-block-level();
|
||||||
|
float: left;
|
||||||
|
margin-left: @fluidGridGutterWidth;
|
||||||
|
*margin-left: @fluidGridGutterWidth - (.5 / @gridRowWidth * 100 * 1%);
|
||||||
|
}
|
||||||
|
[class*="span"]:first-child {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate .spanX
|
||||||
|
.spanX (@gridColumns);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.input(@gridColumnWidth, @gridGutterWidth) {
|
||||||
|
|
||||||
|
.spanX (@index) when (@index > 0) {
|
||||||
|
(~"input.span@{index}, textarea.span@{index}, .uneditable-input.span@{index}") { .span(@index); }
|
||||||
|
.spanX(@index - 1);
|
||||||
|
}
|
||||||
|
.spanX (0) {}
|
||||||
|
|
||||||
|
.span(@columns) {
|
||||||
|
width: ((@gridColumnWidth) * @columns) + (@gridGutterWidth * (@columns - 1)) - 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
textarea,
|
||||||
|
.uneditable-input {
|
||||||
|
margin-left: 0; // override margin-left from core grid system
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate .spanX
|
||||||
|
.spanX (@gridColumns);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) and (max-width: 979px) {
|
||||||
|
|
||||||
|
// Fixed grid
|
||||||
|
#grid > .core(42px, 20px);
|
||||||
|
|
||||||
|
// Fluid grid
|
||||||
|
#grid > .fluid(5.801104972%, 2.762430939%);
|
||||||
|
|
||||||
|
// Input grid
|
||||||
|
#grid > .input(42px, 20px);
|
||||||
|
|
||||||
|
// No need to reset .thumbnails here since it is the same @gridGutterWidth
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
|
||||||
|
// Fixed grid
|
||||||
|
#grid > .core(70px, 30px);
|
||||||
|
|
||||||
|
// Fluid grid
|
||||||
|
#grid > .fluid(5.982905983%, 2.564102564%);
|
||||||
|
|
||||||
|
// Input grid
|
||||||
|
#grid > .input(70px, 30px);
|
||||||
|
|
||||||
|
// Thumbnails
|
||||||
|
.thumbnails {
|
||||||
|
margin-left: -30px;
|
||||||
|
}
|
||||||
|
.thumbnails > li {
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
.row-fluid .thumbnails {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
|
||||||
|
// Smooth out the collapsing/expanding nav
|
||||||
|
.nav-collapse {
|
||||||
|
-webkit-transform: translate3d(0, 0, 0); // activate the GPU
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block level the page header small tag for readability
|
||||||
|
.page-header h1 small {
|
||||||
|
display: block;
|
||||||
|
line-height: @baseLineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update checkboxes for iOS
|
||||||
|
input[type="checkbox"],
|
||||||
|
input[type="radio"] {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the horizontal form styles
|
||||||
|
.form-horizontal .control-group > label {
|
||||||
|
float: none;
|
||||||
|
width: auto;
|
||||||
|
padding-top: 0;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header .close {
|
||||||
|
padding: 10px;
|
||||||
|
margin: -10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carousel
|
||||||
|
.carousel-caption {
|
||||||
|
position: static;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// LANDSCAPE PHONE TO SMALL DESKTOP & PORTRAIT TABLET
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
|
||||||
|
// Padding to set content in a bit
|
||||||
|
body {
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
// Negative indent the now static "fixed" navbar
|
||||||
|
.navbar-fixed-top,
|
||||||
|
.navbar-fixed-bottom {
|
||||||
|
margin-left: -20px;
|
||||||
|
margin-right: -20px;
|
||||||
|
}
|
||||||
|
// Remove padding on container given explicit padding set on body
|
||||||
|
.container-fluid {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TYPOGRAPHY
|
||||||
|
// ----------
|
||||||
|
// Reset horizontal dl
|
||||||
|
.dl-horizontal {
|
||||||
|
dt {
|
||||||
|
float: none;
|
||||||
|
clear: none;
|
||||||
|
width: auto;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
dd {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GRID & CONTAINERS
|
||||||
|
// -----------------
|
||||||
|
// Remove width from containers
|
||||||
|
.container {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
// Fluid rows
|
||||||
|
.row-fluid {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
// Undo negative margin on rows and thumbnails
|
||||||
|
.row,
|
||||||
|
.thumbnails {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
// Make all grid-sized elements block level again
|
||||||
|
[class*="span"],
|
||||||
|
.row-fluid [class*="span"] {
|
||||||
|
float: none;
|
||||||
|
display: block;
|
||||||
|
width: auto;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FORM FIELDS
|
||||||
|
// -----------
|
||||||
|
// Make span* classes full width
|
||||||
|
.input-large,
|
||||||
|
.input-xlarge,
|
||||||
|
.input-xxlarge,
|
||||||
|
input[class*="span"],
|
||||||
|
select[class*="span"],
|
||||||
|
textarea[class*="span"],
|
||||||
|
.uneditable-input {
|
||||||
|
.input-block-level();
|
||||||
|
}
|
||||||
|
// But don't let it screw up prepend/append inputs
|
||||||
|
.input-prepend input,
|
||||||
|
.input-append input,
|
||||||
|
.input-prepend input[class*="span"],
|
||||||
|
.input-append input[class*="span"] {
|
||||||
|
display: inline-block; // redeclare so they don't wrap to new lines
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@baseLineHeight: 18px;
|
||||||
|
|
||||||
|
// Box sizing
|
||||||
|
.box-sizing(@boxmodel) {
|
||||||
|
-webkit-box-sizing: @boxmodel;
|
||||||
|
-moz-box-sizing: @boxmodel;
|
||||||
|
-ms-box-sizing: @boxmodel;
|
||||||
|
box-sizing: @boxmodel;
|
||||||
|
}
|
||||||
|
|
||||||
p,li,ul {
|
p,li,ul {
|
||||||
color: #333333;
|
color: #333333;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -110,92 +389,23 @@ ul + p {
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#content {
|
#prioritize { background: url(thumbsup.png) top left no-repeat; }
|
||||||
max-width: 732px;
|
#ignorize { background: url(thumbsdown.png) top left no-repeat; }
|
||||||
}
|
|
||||||
|
|
||||||
#braindiv {
|
#grid {
|
||||||
#msg {
|
margin: 0 auto;
|
||||||
font-size: 24px;
|
|
||||||
color: #999;
|
|
||||||
|
|
||||||
p {
|
|
||||||
width: 7em;
|
|
||||||
font-size: 20px;
|
|
||||||
margin: -3px 0 -8px 0;
|
|
||||||
padding: 0 0 0 0;
|
|
||||||
.doing {
|
|
||||||
color: #c00;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#braindiv {
|
|
||||||
float: left;
|
|
||||||
width: 45%;
|
|
||||||
padding-right: 5%;
|
|
||||||
|
|
||||||
#img {
|
|
||||||
width: 164px;
|
|
||||||
height: 226px;
|
|
||||||
background: url(brain-in-a-jar.jpg) top right no-repeat;
|
|
||||||
padding: 0 0 1em 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (min-width: 480px) {
|
|
||||||
#braindiv {
|
|
||||||
float: left;
|
|
||||||
width: 45%;
|
|
||||||
padding-right: 5%;
|
|
||||||
|
|
||||||
#img {
|
|
||||||
width: 164px;
|
|
||||||
height: 226px;
|
|
||||||
background: url(brain-in-a-jar.jpg) top right no-repeat;
|
|
||||||
padding: 0 0 1em 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@media only screen and (max-width: 479px) {
|
|
||||||
#braindiv {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
#img {
|
|
||||||
float: left;
|
|
||||||
width: 37.5%;
|
|
||||||
min-width: 122px;
|
|
||||||
height: 165px;
|
|
||||||
background: url(brain-in-a-jar-sm.jpg) top right no-repeat;
|
|
||||||
padding: 0 0 1em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#msg {
|
|
||||||
float: right;
|
|
||||||
width: 60.353125%;
|
|
||||||
}
|
|
||||||
padding-bottom: 2em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#rightnow {
|
|
||||||
float: left;
|
|
||||||
width: 49.9%;
|
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
display: block;
|
display: block;
|
||||||
float: left;
|
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
|
min-height: 72px;
|
||||||
border: none;
|
border: none;
|
||||||
color: #333;
|
color: #333;
|
||||||
font-size: 20px;
|
font-size: 24px;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
|
padding-left: 80px;
|
||||||
|
padding-top: 18px;
|
||||||
strong {
|
strong {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue