28e946ce by Michael Richards

Merge branch 'feature/tests'

2 parents b5e51cfc f150b31d
1 .DS_Store 1 .DS_Store
2 *.swp
......
1 source :rubygems
2
3 gem 'coffee-script'
4 gem 'closure-compiler'
5 gem 'guard'
6 gem 'guard-coffeescript'
1 GEM
2 remote: http://rubygems.org/
3 specs:
4 closure-compiler (1.1.6)
5 coffee-script (2.2.0)
6 coffee-script-source
7 execjs
8 coffee-script-source (1.3.3)
9 execjs (1.4.0)
10 multi_json (~> 1.0)
11 ffi (1.0.11)
12 guard (1.0.2)
13 ffi (>= 0.5.0)
14 thor (~> 0.14.6)
15 guard-coffeescript (0.6.0)
16 coffee-script (>= 2.2.0)
17 guard (>= 0.8.3)
18 multi_json (1.3.6)
19 thor (0.14.6)
20
21 PLATFORMS
22 ruby
23
24 DEPENDENCIES
25 closure-compiler
26 coffee-script
27 guard
28 guard-coffeescript
1 # A sample Guardfile
2 # More info at https://github.com/guard/guard#readme
3
4 guard 'coffeescript', :input => 'src', :output => 'build'
1 require 'rubygems'
2
3 BUILD_DIRECTORY = 'lib'
4 SRC_DIRECTORY = 'src'
5
6 desc "build the toast-min.js files for distribution"
7 task :default => :clean do
8 FileUtils.mkdir_p(BUILD_DIRECTORY)
9 compile_js
10 end
11
12 task :build => :default
13
14 desc "removes the build directory"
15 task :clean do
16 print_action('Removing existing build directory') do
17 FileUtils.rm_rf(BUILD_DIRECTORY)
18 end
19 end
20
21 def compile_js()
22 require 'coffee-script'
23 require 'closure-compiler'
24
25 source = File.read(File.join(SRC_DIRECTORY, 'rivets.coffee'))
26 FileUtils.mkdir_p(BUILD_DIRECTORY)
27 output = File.join(BUILD_DIRECTORY, 'rivets.js')
28 minified_output = File.join(BUILD_DIRECTORY, 'rivets-min.js')
29
30 compiled = ''
31 print_action("Compiling CoffeeScript to '#{output}'") do
32 File.open(output, 'w+') do |file|
33 compiled = CoffeeScript.compile(source)
34 file.write(compiled)
35 end
36 end
37
38 print_action("Minifying Javascript to '#{minified_output}'") do
39 File.open(minified_output, 'w+') do |file|
40 file.write(Closure::Compiler.new.compress(compiled))
41 end
42 end
43 end
44
45 def print_action(action, &block)
46 print "#{action}... "
47 STDOUT.flush
48
49 if block.call()
50 puts 'done'
51 else
52 puts 'failed'
53 end
54 end
1 (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,
2 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));
3 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-/};
4 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=
5 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;
6 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,
7 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=
8 new k(a,b);c.bind();return c}};"undefined"!==typeof module&&null!==module?module.exports=j:this.rivets=j}).call(this);
1 // Generated by CoffeeScript 1.3.3
2 (function() { 1 (function() {
3 var Rivets, attributeBinding, bidirectionals, bindEvent, eventBinding, getInputValue, rivets, unbindEvent, 2 var Rivets, attributeBinding, bidirectionals, bindEvent, eventBinding, getInputValue, rivets, unbindEvent,
4 __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, 3 __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
...@@ -97,51 +96,43 @@ ...@@ -97,51 +96,43 @@
97 }; 96 };
98 97
99 View.prototype.build = function() { 98 View.prototype.build = function() {
100 var attribute, bindType, bindingRegExp, eventRegExp, keypath, model, node, path, pipe, pipes, type, _i, _len, _ref, _results; 99 var attribute, bindType, bindingRegExp, elements, eventRegExp, keypath, model, node, path, pipe, pipes, type, _i, _j, _len, _len1, _ref;
101 this.bindings = []; 100 this.bindings = [];
102 bindingRegExp = this.bindingRegExp(); 101 bindingRegExp = this.bindingRegExp();
103 eventRegExp = /^on-/; 102 eventRegExp = /^on-/;
104 _ref = this.el.getElementsByTagName('*'); 103 elements = [this.el];
105 _results = []; 104 elements.concat(Array.prototype.slice.call(this.el.getElementsByTagName('*')));
106 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 105 for (_i = 0, _len = elements.length; _i < _len; _i++) {
107 node = _ref[_i]; 106 node = elements[_i];
108 _results.push((function() { 107 _ref = node.attributes;
109 var _j, _len1, _ref1, _results1; 108 for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
110 _ref1 = node.attributes; 109 attribute = _ref[_j];
111 _results1 = []; 110 if (bindingRegExp.test(attribute.name)) {
112 for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { 111 bindType = "attribute";
113 attribute = _ref1[_j]; 112 type = attribute.name.replace(bindingRegExp, '');
114 if (bindingRegExp.test(attribute.name)) { 113 pipes = (function() {
115 bindType = "attribute"; 114 var _k, _len2, _ref1, _results;
116 type = attribute.name.replace(bindingRegExp, ''); 115 _ref1 = attribute.value.split('|');
117 pipes = (function() { 116 _results = [];
118 var _k, _len2, _ref2, _results2; 117 for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
119 _ref2 = attribute.value.split('|'); 118 pipe = _ref1[_k];
120 _results2 = []; 119 _results.push(pipe.trim());
121 for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
122 pipe = _ref2[_k];
123 _results2.push(pipe.trim());
124 }
125 return _results2;
126 })();
127 path = pipes.shift().split('.');
128 model = this.models[path.shift()];
129 keypath = path.join('.');
130 if (eventRegExp.test(type)) {
131 type = type.replace(eventRegExp, '');
132 bindType = "event";
133 } else if (__indexOf.call(bidirectionals, type) >= 0) {
134 bindType = "bidirectional";
135 } 120 }
136 _results1.push(this.bindings.push(new Rivets.Binding(node, type, bindType, model, keypath, pipes))); 121 return _results;
137 } else { 122 })();
138 _results1.push(void 0); 123 path = pipes.shift().split('.');
124 model = this.models[path.shift()];
125 keypath = path.join('.');
126 if (eventRegExp.test(type)) {
127 type = type.replace(eventRegExp, '');
128 bindType = "event";
129 } else if (__indexOf.call(bidirectionals, type) >= 0) {
130 bindType = "bidirectional";
139 } 131 }
132 this.bindings.push(new Rivets.Binding(node, type, bindType, model, keypath, pipes));
140 } 133 }
141 return _results1; 134 }
142 }).call(this));
143 } 135 }
144 return _results;
145 }; 136 };
146 137
147 View.prototype.bind = function() { 138 View.prototype.bind = function() {
......
1 beforeEach(function() {
2 this.addMatchers({
3 toHaveTheTextContent: function(expected) {
4 var el = this.actual;
5 actual = el.textContent || el.innerText;
6 this.message = function() {
7 return "Expected '" + actual + "' to be '" + expected + "'";
8 }
9 return actual === expected;
10 }
11 });
12 });
1 function Data(attributes) {
2 this.attributes = attributes || {};
3 this.change = {}
4 }
5
6 Data.prototype.on = function(key, callback) {
7 if(this.hasCallback(key, callback))
8 return;
9 var ref = this.change[key] || (this.change[key] = []);
10 this.change[key].push(callback);
11 }
12
13 Data.prototype.hasCallback = function(key, callback) {
14 return indexOf(this.change[key], callback) !== -1;
15 }
16
17 indexOf = function(array, value) {
18 array || (array = [])
19 if(array.indexOf)
20 return array.indexOf(value);
21
22 for(i in array || {}) {
23 if(array[i] === value)
24 return i;
25 }
26 return -1;
27 }
28
29 Data.prototype.off = function(key, callback) {
30 var index = indexOf(this.change[key], callback);
31 if(index !== -1)
32 this.change[key].splice(index, 1);
33 }
34
35 Data.prototype.set = function(attributes) {
36 var old, key;
37
38 for(key in attributes) {
39 old = this.attributes[key];
40 this.attributes[key] = attributes[key];
41 if(this.get(key) !== old)
42 this.alertCallbacks(key);
43 }
44 }
45
46 Data.prototype.get = function(key) {
47 return this.attributes[key];
48 }
49
50 Data.prototype.alertCallbacks = function(key) {
51 if(!this.change[key])
52 return;
53
54 var key, callbacks;
55 for(i in this.change[key]) {
56 this.change[key][i](this.get(key));
57 }
58 }
59
60 window.Data = Data;
1 describe('Rivets', function() {
2 var data, bindData, el, input;
3
4 beforeEach(function() {
5 data = new Data({foo: 'bar'});
6 bindData = {data: data};
7 el = document.createElement('div');
8 input = document.createElement('input');
9 input.setAttribute('type', 'text');
10
11 rivets.configure({
12 preloadData: true,
13 adapter: {
14 subscribe: function(obj, keypath, callback) {
15 obj.on(keypath, callback);
16 },
17 read: function(obj, keypath) {
18 return obj.get(keypath);
19 },
20 publish: function(obj, keypath, value) {
21 attributes = {};
22 attributes[keypath] = value;
23 obj.set(attributes);
24 }
25 }
26 });
27 });
28
29 describe('Adapter', function() {
30 it('should read the initial value', function() {
31 spyOn(data, 'get');
32 el.setAttribute('data-text', 'data.foo');
33 rivets.bind(el, bindData);
34 expect(data.get).toHaveBeenCalledWith('foo');
35 });
36
37 it('should read the initial value unless preloadData is false', function() {
38 rivets.configure({preloadData: false});
39 spyOn(data, 'get');
40 el.setAttribute('data-value', 'data.foo');
41 rivets.bind(el, bindData);
42 expect(data.get).not.toHaveBeenCalled();
43 });
44
45 it('should subscribe to updates', function() {
46 spyOn(data, 'on');
47 el.setAttribute('data-value', 'data.foo');
48 rivets.bind(el, bindData);
49 expect(data.on).toHaveBeenCalled();
50 });
51 });
52
53 describe('Binds', function() {
54 describe('Text', function() {
55 it('should set the text content of the element', function() {
56 el.setAttribute('data-text', 'data.foo');
57 rivets.bind(el, bindData);
58 expect(el.textContent || el.innerText).toBe(data.get('foo'));
59 });
60
61 it('should correctly handle HTML in the content', function() {
62 el.setAttribute('data-text', 'data.foo');
63 value = '<b>Fail</b>';
64 data.set({foo: value});
65 rivets.bind(el, bindData);
66 expect(el.textContent || el.innerText).toBe(value);
67 });
68 });
69
70 describe('HTML', function() {
71 it('should set the html content of the element', function() {
72 el.setAttribute('data-html', 'data.foo');
73 rivets.bind(el, bindData);
74 expect(el).toHaveTheTextContent(data.get('foo'));
75 });
76
77 it('should correctly handle HTML in the content', function() {
78 el.setAttribute('data-html', 'data.foo');
79 value = '<b>Fail</b>';
80 data.set({foo: value});
81 rivets.bind(el, bindData);
82 expect(el.innerHTML).toBe(value);
83 });
84 });
85
86 describe('Value', function() {
87 it('should set the value of the element', function() {
88 input.setAttribute('data-value', 'data.foo');
89 rivets.bind(input, bindData);
90 expect(input.value).toBe(data.get('foo'));
91 });
92 });
93 });
94
95 describe('Updates', function() {
96 it('should change the value', function() {
97 el.setAttribute('data-text', 'data.foo');
98 rivets.bind(el, bindData);
99 data.set({foo: 'some new value'});
100 expect(el).toHaveTheTextContent(data.get('foo'));
101 });
102 });
103
104 describe('Input', function() {
105 it('should update the model value', function() {
106 input.setAttribute('data-value', 'data.foo');
107 rivets.bind(input, bindData);
108 input.value = 'some new value';
109 var event = document.createEvent('HTMLEvents')
110 event.initEvent('change', true, true);
111 input.dispatchEvent(event);
112 expect(input.value).toBe(data.get('foo'));
113 });
114 });
115 });
...@@ -67,7 +67,9 @@ class Rivets.View ...@@ -67,7 +67,9 @@ class Rivets.View
67 @bindings = [] 67 @bindings = []
68 bindingRegExp = @bindingRegExp() 68 bindingRegExp = @bindingRegExp()
69 eventRegExp = /^on-/ 69 eventRegExp = /^on-/
70 for node in @el.getElementsByTagName '*' 70 elements = [@el]
71 elements.concat Array::slice.call @el.getElementsByTagName '*'
72 for node in elements
71 for attribute in node.attributes 73 for attribute in node.attributes
72 if bindingRegExp.test attribute.name 74 if bindingRegExp.test attribute.name
73 bindType = "attribute" 75 bindType = "attribute"
...@@ -80,11 +82,14 @@ class Rivets.View ...@@ -80,11 +82,14 @@ class Rivets.View
80 if eventRegExp.test type 82 if eventRegExp.test type
81 type = type.replace eventRegExp, '' 83 type = type.replace eventRegExp, ''
82 bindType = "event" 84 bindType = "event"
83 else if type in bidirectionals 85 else if type in bidirectionals
84 bindType = "bidirectional" 86 bindType = "bidirectional"
85 87
86 @bindings.push new Rivets.Binding node, type, bindType, model, keypath, pipes 88 @bindings.push new Rivets.Binding node, type, bindType, model, keypath, pipes
87 89
90 # To avoid returning the result of the loop
91 return
92
88 # Binds all of the current bindings for this view. 93 # Binds all of the current bindings for this view.
89 bind: => 94 bind: =>
90 binding.bind() for binding in @bindings 95 binding.bind() for binding in @bindings
......
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
3 <html>
4 <head>
5 <title>Rivets test suite</title>
6
7 <link rel="shortcut icon" type="image/png" href="vendor/jasmine-1.2.0/jasmine_favicon.png">
8 <link rel="stylesheet" type="text/css" href="vendor/jasmine-1.2.0/jasmine.css">
9 <script type="text/javascript" src="vendor/jasmine-1.2.0/jasmine.js"></script>
10 <script type="text/javascript" src="vendor/jasmine-1.2.0/jasmine-html.js"></script>
11
12 <script type="text/javascript" src="lib/rivets.js"></script>
13
14 <script type="text/javascript" src="spec/matchers.js"></script>
15 <script type="text/javascript" src="spec/mock.data.js"></script>
16 <script type="text/javascript" src="spec/rivets.js"></script>
17
18 <script type="text/javascript">
19 (function() {
20 var jasmineEnv = jasmine.getEnv();
21 jasmineEnv.updateInterval = 250;
22
23 var htmlReporter = new jasmine.HtmlReporter();
24
25 jasmineEnv.addReporter(htmlReporter);
26
27 jasmineEnv.specFilter = function(spec) {
28 return htmlReporter.specFilter(spec);
29 };
30
31 var currentWindowOnload = window.onload;
32
33 window.onload = function() {
34 if (currentWindowOnload) {
35 currentWindowOnload();
36 }
37 execJasmine();
38 };
39
40 function execJasmine() {
41 jasmineEnv.execute();
42 }
43
44 })();
45 </script>
46
47 </head>
48
49 <body>
50 </body>
51 </html>
1 Copyright (c) 2008-2011 Pivotal Labs
2
3 Permission is hereby granted, free of charge, to any person obtaining
4 a copy of this software and associated documentation files (the
5 "Software"), to deal in the Software without restriction, including
6 without limitation the rights to use, copy, modify, merge, publish,
7 distribute, sublicense, and/or sell copies of the Software, and to
8 permit persons to whom the Software is furnished to do so, subject to
9 the following conditions:
10
11 The above copyright notice and this permission notice shall be
12 included in all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
2
3 #HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
4 #HTMLReporter a { text-decoration: none; }
5 #HTMLReporter a:hover { text-decoration: underline; }
6 #HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
7 #HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
8 #HTMLReporter #jasmine_content { position: fixed; right: 100%; }
9 #HTMLReporter .version { color: #aaaaaa; }
10 #HTMLReporter .banner { margin-top: 14px; }
11 #HTMLReporter .duration { color: #aaaaaa; float: right; }
12 #HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
13 #HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
14 #HTMLReporter .symbolSummary li.passed { font-size: 14px; }
15 #HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
16 #HTMLReporter .symbolSummary li.failed { line-height: 9px; }
17 #HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
18 #HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
19 #HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
20 #HTMLReporter .symbolSummary li.pending { line-height: 11px; }
21 #HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
22 #HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
23 #HTMLReporter .runningAlert { background-color: #666666; }
24 #HTMLReporter .skippedAlert { background-color: #aaaaaa; }
25 #HTMLReporter .skippedAlert:first-child { background-color: #333333; }
26 #HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
27 #HTMLReporter .passingAlert { background-color: #a6b779; }
28 #HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
29 #HTMLReporter .failingAlert { background-color: #cf867e; }
30 #HTMLReporter .failingAlert:first-child { background-color: #b03911; }
31 #HTMLReporter .results { margin-top: 14px; }
32 #HTMLReporter #details { display: none; }
33 #HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
34 #HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
35 #HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
36 #HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
37 #HTMLReporter.showDetails .summary { display: none; }
38 #HTMLReporter.showDetails #details { display: block; }
39 #HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
40 #HTMLReporter .summary { margin-top: 14px; }
41 #HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
42 #HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
43 #HTMLReporter .summary .specSummary.failed a { color: #b03911; }
44 #HTMLReporter .description + .suite { margin-top: 0; }
45 #HTMLReporter .suite { margin-top: 14px; }
46 #HTMLReporter .suite a { color: #333333; }
47 #HTMLReporter #details .specDetail { margin-bottom: 28px; }
48 #HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
49 #HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
50 #HTMLReporter .resultMessage span.result { display: block; }
51 #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; }
52
53 #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;*/ /*}*/ }
54 #TrivialReporter a:visited, #TrivialReporter a { color: #303; }
55 #TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
56 #TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
57 #TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
58 #TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
59 #TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
60 #TrivialReporter .runner.running { background-color: yellow; }
61 #TrivialReporter .options { text-align: right; font-size: .8em; }
62 #TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
63 #TrivialReporter .suite .suite { margin: 5px; }
64 #TrivialReporter .suite.passed { background-color: #dfd; }
65 #TrivialReporter .suite.failed { background-color: #fdd; }
66 #TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
67 #TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
68 #TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
69 #TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
70 #TrivialReporter .spec.skipped { background-color: #bbb; }
71 #TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
72 #TrivialReporter .passed { background-color: #cfc; display: none; }
73 #TrivialReporter .failed { background-color: #fbb; }
74 #TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
75 #TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
76 #TrivialReporter .resultMessage .mismatch { color: black; }
77 #TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
78 #TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
79 #TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
80 #TrivialReporter #jasmine_content { position: fixed; right: 100%; }
81 #TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }