28e946ce by Michael Richards

Merge branch 'feature/tests'

2 parents b5e51cfc f150b31d
.DS_Store
*.swp
......
source :rubygems
gem 'coffee-script'
gem 'closure-compiler'
gem 'guard'
gem 'guard-coffeescript'
GEM
remote: http://rubygems.org/
specs:
closure-compiler (1.1.6)
coffee-script (2.2.0)
coffee-script-source
execjs
coffee-script-source (1.3.3)
execjs (1.4.0)
multi_json (~> 1.0)
ffi (1.0.11)
guard (1.0.2)
ffi (>= 0.5.0)
thor (~> 0.14.6)
guard-coffeescript (0.6.0)
coffee-script (>= 2.2.0)
guard (>= 0.8.3)
multi_json (1.3.6)
thor (0.14.6)
PLATFORMS
ruby
DEPENDENCIES
closure-compiler
coffee-script
guard
guard-coffeescript
# A sample Guardfile
# More info at https://github.com/guard/guard#readme
guard 'coffeescript', :input => 'src', :output => 'build'
require 'rubygems'
BUILD_DIRECTORY = 'lib'
SRC_DIRECTORY = 'src'
desc "build the toast-min.js files for distribution"
task :default => :clean do
FileUtils.mkdir_p(BUILD_DIRECTORY)
compile_js
end
task :build => :default
desc "removes the build directory"
task :clean do
print_action('Removing existing build directory') do
FileUtils.rm_rf(BUILD_DIRECTORY)
end
end
def compile_js()
require 'coffee-script'
require 'closure-compiler'
source = File.read(File.join(SRC_DIRECTORY, 'rivets.coffee'))
FileUtils.mkdir_p(BUILD_DIRECTORY)
output = File.join(BUILD_DIRECTORY, 'rivets.js')
minified_output = File.join(BUILD_DIRECTORY, 'rivets-min.js')
compiled = ''
print_action("Compiling CoffeeScript to '#{output}'") do
File.open(output, 'w+') do |file|
compiled = CoffeeScript.compile(source)
file.write(compiled)
end
end
print_action("Minifying Javascript to '#{minified_output}'") do
File.open(minified_output, 'w+') do |file|
file.write(Closure::Compiler.new.compress(compiled))
end
end
end
def print_action(action, &block)
print "#{action}... "
STDOUT.flush
if block.call()
puts 'done'
else
puts 'failed'
end
end
(function(){var p,h,c,k,r,s,l,t,u,j,v,e=function(a,b){return function(){return a.apply(b,arguments)}},x=[].indexOf||function(a){for(var b=0,w=this.length;b<w;b++)if(b in this&&this[b]===a)return b;return-1};k=c=h=p=void 0;String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")});p=function(){function a(b,a,d,i,f,g){this.el=b;this.type=a;this.bindType=d;this.model=i;this.keypath=f;this.formatters=g!=null?g:[];this.publish=e(this.publish,this);this.bind=e(this.bind,
this);this.set=e(this.set,this);this.routine=this.bindType==="event"?t(this.type):h[this.type]||r(this.type)}a.prototype.set=function(b){var a,d,i,f;f=this.formatters;d=0;for(i=f.length;d<i;d++){a=f[d];b=c.formatters[a](b)}if(this.bindType==="event"){this.routine(this.el,b,this.currentListener);return this.currentListener=b}return this.routine(this.el,b)};a.prototype.bind=function(){c.adapter.subscribe(this.model,this.keypath,this.set);c.preloadData&&this.set(c.adapter.read(this.model,this.keypath));
if(this.bindType==="bidirectional")return l(this.el,"change",this.publish)};a.prototype.publish=function(b){return c.adapter.publish(this.model,this.keypath,u(b.target||b.srcElement))};return a}();k=function(){function a(b,a){this.el=b;this.models=a;this.bind=e(this.bind,this);this.build=e(this.build,this);this.bindingRegExp=e(this.bindingRegExp,this);if(this.el.jquery)this.el=this.el.get(0);this.build()}a.prototype.bindingRegExp=function(){var b;return(b=c.prefix)?RegExp("^data-"+b+"-"):/^data-/};
a.prototype.build=function(){var b,a,d,i,f,g,c,e,m,n,h,o,k,l,j;this.bindings=[];d=this.bindingRegExp();f=/^on-/;i=[this.el];i.concat(Array.prototype.slice.call(this.el.getElementsByTagName("*")));h=0;for(k=i.length;h<k;h++){e=i[h];j=e.attributes;o=0;for(l=j.length;o<l;o++){b=j[o];if(d.test(b.name)){a="attribute";n=b.name.replace(d,"");var q=g=m=c=void 0;g=b.value.split("|");q=[];c=0;for(m=g.length;c<m;c++){b=g[c];q.push(b.trim())}m=q;g=m.shift().split(".");c=this.models[g.shift()];g=g.join(".");if(f.test(n)){n=
n.replace(f,"");a="event"}else x.call(s,n)>=0&&(a="bidirectional");this.bindings.push(new p(e,n,a,c,g,m))}}}};a.prototype.bind=function(){var b,a,d,c,f;c=this.bindings;f=[];a=0;for(d=c.length;a<d;a++){b=c[a];f.push(b.bind())}return f};return a}();l=function(a,b,c){return window.addEventListener?a.addEventListener(b,c):a.attachEvent(b,c)};v=function(a,b,c){return window.removeEventListener?a.removeEventListener(b,c):a.detachEvent(b,c)};u=function(a){switch(a.type){case "text":case "textarea":case "password":case "select-one":return a.value;
case "checkbox":case "radio":return a.checked}};t=function(a){return function(b,c,d){c&&l(b,a,c);if(d)return v(b,a,d)}};r=function(a){return function(b,c){return c?b.setAttribute(a,c):b.removeAttribute(a)}};s=["value","checked","unchecked","selected","unselected"];h={enabled:function(a,b){return a.disabled=!b},disabled:function(a,b){return a.disabled=!!b},checked:function(a,b){return a.checked=!!b},unchecked:function(a,b){return a.checked=!b},selected:function(a,b){return a.selected=!!b},unselected:function(a,
b){return a.selected=!b},show:function(a,b){return a.style.display=b?"":"none"},hide:function(a,b){return a.style.display=b?"none":""},html:function(a,b){return a.innerHTML=b||""},value:function(a,b){return a.value=b},text:function(a,b){return a.innerText!=null?a.innerText=b||"":a.textContent=b||""}};c={preloadData:!0};j={configure:function(a){var b,e,d;a==null&&(a={});d=[];for(b in a){e=a[b];d.push(c[b]=e)}return d},register:function(a,b){return h[a]=b},bind:function(a,b){var c;b==null&&(b={});c=
new k(a,b);c.bind();return c}};"undefined"!==typeof module&&null!==module?module.exports=j:this.rivets=j}).call(this);
// Generated by CoffeeScript 1.3.3
(function() {
var Rivets, attributeBinding, bidirectionals, bindEvent, eventBinding, getInputValue, rivets, unbindEvent,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
......@@ -97,51 +96,43 @@
};
View.prototype.build = function() {
var attribute, bindType, bindingRegExp, eventRegExp, keypath, model, node, path, pipe, pipes, type, _i, _len, _ref, _results;
var attribute, bindType, bindingRegExp, elements, eventRegExp, keypath, model, node, path, pipe, pipes, type, _i, _j, _len, _len1, _ref;
this.bindings = [];
bindingRegExp = this.bindingRegExp();
eventRegExp = /^on-/;
_ref = this.el.getElementsByTagName('*');
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
node = _ref[_i];
_results.push((function() {
var _j, _len1, _ref1, _results1;
_ref1 = node.attributes;
_results1 = [];
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
attribute = _ref1[_j];
if (bindingRegExp.test(attribute.name)) {
bindType = "attribute";
type = attribute.name.replace(bindingRegExp, '');
pipes = (function() {
var _k, _len2, _ref2, _results2;
_ref2 = attribute.value.split('|');
_results2 = [];
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
pipe = _ref2[_k];
_results2.push(pipe.trim());
}
return _results2;
})();
path = pipes.shift().split('.');
model = this.models[path.shift()];
keypath = path.join('.');
if (eventRegExp.test(type)) {
type = type.replace(eventRegExp, '');
bindType = "event";
} else if (__indexOf.call(bidirectionals, type) >= 0) {
bindType = "bidirectional";
elements = [this.el];
elements.concat(Array.prototype.slice.call(this.el.getElementsByTagName('*')));
for (_i = 0, _len = elements.length; _i < _len; _i++) {
node = elements[_i];
_ref = node.attributes;
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
attribute = _ref[_j];
if (bindingRegExp.test(attribute.name)) {
bindType = "attribute";
type = attribute.name.replace(bindingRegExp, '');
pipes = (function() {
var _k, _len2, _ref1, _results;
_ref1 = attribute.value.split('|');
_results = [];
for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
pipe = _ref1[_k];
_results.push(pipe.trim());
}
_results1.push(this.bindings.push(new Rivets.Binding(node, type, bindType, model, keypath, pipes)));
} else {
_results1.push(void 0);
return _results;
})();
path = pipes.shift().split('.');
model = this.models[path.shift()];
keypath = path.join('.');
if (eventRegExp.test(type)) {
type = type.replace(eventRegExp, '');
bindType = "event";
} else if (__indexOf.call(bidirectionals, type) >= 0) {
bindType = "bidirectional";
}
this.bindings.push(new Rivets.Binding(node, type, bindType, model, keypath, pipes));
}
return _results1;
}).call(this));
}
}
return _results;
};
View.prototype.bind = function() {
......
beforeEach(function() {
this.addMatchers({
toHaveTheTextContent: function(expected) {
var el = this.actual;
actual = el.textContent || el.innerText;
this.message = function() {
return "Expected '" + actual + "' to be '" + expected + "'";
}
return actual === expected;
}
});
});
function Data(attributes) {
this.attributes = attributes || {};
this.change = {}
}
Data.prototype.on = function(key, callback) {
if(this.hasCallback(key, callback))
return;
var ref = this.change[key] || (this.change[key] = []);
this.change[key].push(callback);
}
Data.prototype.hasCallback = function(key, callback) {
return indexOf(this.change[key], callback) !== -1;
}
indexOf = function(array, value) {
array || (array = [])
if(array.indexOf)
return array.indexOf(value);
for(i in array || {}) {
if(array[i] === value)
return i;
}
return -1;
}
Data.prototype.off = function(key, callback) {
var index = indexOf(this.change[key], callback);
if(index !== -1)
this.change[key].splice(index, 1);
}
Data.prototype.set = function(attributes) {
var old, key;
for(key in attributes) {
old = this.attributes[key];
this.attributes[key] = attributes[key];
if(this.get(key) !== old)
this.alertCallbacks(key);
}
}
Data.prototype.get = function(key) {
return this.attributes[key];
}
Data.prototype.alertCallbacks = function(key) {
if(!this.change[key])
return;
var key, callbacks;
for(i in this.change[key]) {
this.change[key][i](this.get(key));
}
}
window.Data = Data;
describe('Rivets', function() {
var data, bindData, el, input;
beforeEach(function() {
data = new Data({foo: 'bar'});
bindData = {data: data};
el = document.createElement('div');
input = document.createElement('input');
input.setAttribute('type', 'text');
rivets.configure({
preloadData: true,
adapter: {
subscribe: function(obj, keypath, callback) {
obj.on(keypath, callback);
},
read: function(obj, keypath) {
return obj.get(keypath);
},
publish: function(obj, keypath, value) {
attributes = {};
attributes[keypath] = value;
obj.set(attributes);
}
}
});
});
describe('Adapter', function() {
it('should read the initial value', function() {
spyOn(data, 'get');
el.setAttribute('data-text', 'data.foo');
rivets.bind(el, bindData);
expect(data.get).toHaveBeenCalledWith('foo');
});
it('should read the initial value unless preloadData is false', function() {
rivets.configure({preloadData: false});
spyOn(data, 'get');
el.setAttribute('data-value', 'data.foo');
rivets.bind(el, bindData);
expect(data.get).not.toHaveBeenCalled();
});
it('should subscribe to updates', function() {
spyOn(data, 'on');
el.setAttribute('data-value', 'data.foo');
rivets.bind(el, bindData);
expect(data.on).toHaveBeenCalled();
});
});
describe('Binds', function() {
describe('Text', function() {
it('should set the text content of the element', function() {
el.setAttribute('data-text', 'data.foo');
rivets.bind(el, bindData);
expect(el.textContent || el.innerText).toBe(data.get('foo'));
});
it('should correctly handle HTML in the content', function() {
el.setAttribute('data-text', 'data.foo');
value = '<b>Fail</b>';
data.set({foo: value});
rivets.bind(el, bindData);
expect(el.textContent || el.innerText).toBe(value);
});
});
describe('HTML', function() {
it('should set the html content of the element', function() {
el.setAttribute('data-html', 'data.foo');
rivets.bind(el, bindData);
expect(el).toHaveTheTextContent(data.get('foo'));
});
it('should correctly handle HTML in the content', function() {
el.setAttribute('data-html', 'data.foo');
value = '<b>Fail</b>';
data.set({foo: value});
rivets.bind(el, bindData);
expect(el.innerHTML).toBe(value);
});
});
describe('Value', function() {
it('should set the value of the element', function() {
input.setAttribute('data-value', 'data.foo');
rivets.bind(input, bindData);
expect(input.value).toBe(data.get('foo'));
});
});
});
describe('Updates', function() {
it('should change the value', function() {
el.setAttribute('data-text', 'data.foo');
rivets.bind(el, bindData);
data.set({foo: 'some new value'});
expect(el).toHaveTheTextContent(data.get('foo'));
});
});
describe('Input', function() {
it('should update the model value', function() {
input.setAttribute('data-value', 'data.foo');
rivets.bind(input, bindData);
input.value = 'some new value';
var event = document.createEvent('HTMLEvents')
event.initEvent('change', true, true);
input.dispatchEvent(event);
expect(input.value).toBe(data.get('foo'));
});
});
});
......@@ -67,7 +67,9 @@ class Rivets.View
@bindings = []
bindingRegExp = @bindingRegExp()
eventRegExp = /^on-/
for node in @el.getElementsByTagName '*'
elements = [@el]
elements.concat Array::slice.call @el.getElementsByTagName '*'
for node in elements
for attribute in node.attributes
if bindingRegExp.test attribute.name
bindType = "attribute"
......@@ -80,11 +82,14 @@ class Rivets.View
if eventRegExp.test type
type = type.replace eventRegExp, ''
bindType = "event"
else if type in bidirectionals
else if type in bidirectionals
bindType = "bidirectional"
@bindings.push new Rivets.Binding node, type, bindType, model, keypath, pipes
# To avoid returning the result of the loop
return
# Binds all of the current bindings for this view.
bind: =>
binding.bind() for binding in @bindings
......
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Rivets test suite</title>
<link rel="shortcut icon" type="image/png" href="vendor/jasmine-1.2.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="vendor/jasmine-1.2.0/jasmine.css">
<script type="text/javascript" src="vendor/jasmine-1.2.0/jasmine.js"></script>
<script type="text/javascript" src="vendor/jasmine-1.2.0/jasmine-html.js"></script>
<script type="text/javascript" src="lib/rivets.js"></script>
<script type="text/javascript" src="spec/matchers.js"></script>
<script type="text/javascript" src="spec/mock.data.js"></script>
<script type="text/javascript" src="spec/rivets.js"></script>
<script type="text/javascript">
(function() {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 250;
var htmlReporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(htmlReporter);
jasmineEnv.specFilter = function(spec) {
return htmlReporter.specFilter(spec);
};
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
execJasmine();
};
function execJasmine() {
jasmineEnv.execute();
}
})();
</script>
</head>
<body>
</body>
</html>
Copyright (c) 2008-2011 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
#HTMLReporter a { text-decoration: none; }
#HTMLReporter a:hover { text-decoration: underline; }
#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
#HTMLReporter .version { color: #aaaaaa; }
#HTMLReporter .banner { margin-top: 14px; }
#HTMLReporter .duration { color: #aaaaaa; float: right; }
#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
#HTMLReporter .symbolSummary li.passed { font-size: 14px; }
#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
#HTMLReporter .symbolSummary li.failed { line-height: 9px; }
#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
#HTMLReporter .symbolSummary li.pending { line-height: 11px; }
#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
#HTMLReporter .runningAlert { background-color: #666666; }
#HTMLReporter .skippedAlert { background-color: #aaaaaa; }
#HTMLReporter .skippedAlert:first-child { background-color: #333333; }
#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
#HTMLReporter .passingAlert { background-color: #a6b779; }
#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
#HTMLReporter .failingAlert { background-color: #cf867e; }
#HTMLReporter .failingAlert:first-child { background-color: #b03911; }
#HTMLReporter .results { margin-top: 14px; }
#HTMLReporter #details { display: none; }
#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter.showDetails .summary { display: none; }
#HTMLReporter.showDetails #details { display: block; }
#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter .summary { margin-top: 14px; }
#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
#HTMLReporter .summary .specSummary.failed a { color: #b03911; }
#HTMLReporter .description + .suite { margin-top: 0; }
#HTMLReporter .suite { margin-top: 14px; }
#HTMLReporter .suite a { color: #333333; }
#HTMLReporter #details .specDetail { margin-bottom: 28px; }
#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
#HTMLReporter .resultMessage span.result { display: block; }
#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
#TrivialReporter .runner.running { background-color: yellow; }
#TrivialReporter .options { text-align: right; font-size: .8em; }
#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
#TrivialReporter .suite .suite { margin: 5px; }
#TrivialReporter .suite.passed { background-color: #dfd; }
#TrivialReporter .suite.failed { background-color: #fdd; }
#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
#TrivialReporter .spec.skipped { background-color: #bbb; }
#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
#TrivialReporter .passed { background-color: #cfc; display: none; }
#TrivialReporter .failed { background-color: #fbb; }
#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
#TrivialReporter .resultMessage .mismatch { color: black; }
#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }