ninjs 0.13.8 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. data/VERSION +1 -1
  2. data/bin/ninjs +2 -1
  3. data/lib/ninjs/command.rb +1 -1
  4. data/lib/ninjs/generator.rb +14 -10
  5. data/lib/ninjs/project.rb +7 -4
  6. data/ninjs.gemspec +20 -7
  7. data/repository/ninjs/core/application.js +24 -43
  8. data/repository/ninjs/core/dom.js +139 -0
  9. data/repository/ninjs/core/existence.js +121 -277
  10. data/repository/ninjs/core/extend.js +35 -77
  11. data/repository/ninjs/core/module.js +101 -116
  12. data/repository/ninjs/core/nin.js +7 -4
  13. data/repository/ninjs/tests/application.test.js +24 -0
  14. data/repository/ninjs/tests/array.utilities.test.js +55 -0
  15. data/repository/ninjs/tests/existence.test.js +64 -0
  16. data/repository/ninjs/tests/extension.test.js +38 -0
  17. data/repository/ninjs/tests/index.html +11 -5
  18. data/repository/ninjs/tests/module.test.js +75 -0
  19. data/repository/ninjs/tests/qspec.js +26 -0
  20. data/repository/ninjs/tests/{ninjs.utilities.test.js → string.utilities.test.js} +14 -66
  21. data/spec/cli_spec.rb +159 -0
  22. data/spec/command_spec.rb +226 -2
  23. data/spec/fixtures/compressed.myapp.js +40 -20
  24. data/spec/fixtures/myapp.initial.js +383 -488
  25. data/spec/fixtures/myapp.js +379 -484
  26. data/spec/fixtures/mymodule.alias.module.js +10 -0
  27. data/spec/fixtures/mymodule.dependencies.module.js +13 -0
  28. data/spec/fixtures/mymodule.elements.js +5 -0
  29. data/spec/fixtures/mymodule.model.js +3 -0
  30. data/spec/fixtures/mymodule.module.js +10 -0
  31. data/spec/fixtures/nin.js +428 -0
  32. data/spec/generator_spec.rb +58 -10
  33. data/spec/project_spec.rb +11 -7
  34. metadata +59 -9
  35. data/repository/ninjs/tests/ninjs.test.js +0 -188
  36. data/repository/ninjs/tests/qunit/qunit.css +0 -197
  37. data/repository/ninjs/tests/qunit/qunit.js +0 -1415
data/spec/command_spec.rb CHANGED
@@ -2,8 +2,232 @@ require "spec_helper"
2
2
 
3
3
  describe Ninjs::Command do
4
4
 
5
- it 'should have a watch method' do
6
- Ninjs::Command.watch.should_not be_nil
5
+ context 'API' do
6
+ before :each do
7
+ suppress_output do
8
+ @project = Ninjs::Project.new 'myapp'
9
+ @project.create
10
+ end
11
+ end
12
+
13
+ after :each do
14
+ FileUtils.rm_rf 'application'
15
+ FileUtils.rm_rf 'modules'
16
+ FileUtils.rm_rf 'elements'
17
+ FileUtils.rm_rf 'models'
18
+ FileUtils.rm_rf 'lib'
19
+ FileUtils.rm_rf 'plugins'
20
+ FileUtils.rm_rf 'tests'
21
+ FileUtils.rm_rf 'ninjs.conf'
22
+ end
23
+
24
+ it 'should have a watch command' do
25
+ Ninjs::Command.should respond_to :watch
26
+ end
27
+
28
+ it 'should have a compile command' do
29
+ Ninjs::Command.should respond_to :compile
30
+ end
31
+
32
+ it 'should have a generate command' do
33
+ Ninjs::Command.should respond_to :generate
34
+ end
35
+
36
+ it 'should have a create command' do
37
+ Ninjs::Command.should respond_to :create
38
+ end
39
+
40
+ it 'should have an update command' do
41
+ Ninjs::Command.should respond_to :update
42
+ end
7
43
  end
8
44
 
45
+ context 'Usage' do
46
+ after :each do
47
+ FileUtils.rm_rf 'application'
48
+ FileUtils.rm_rf 'modules'
49
+ FileUtils.rm_rf 'elements'
50
+ FileUtils.rm_rf 'models'
51
+ FileUtils.rm_rf 'lib'
52
+ FileUtils.rm_rf 'plugins'
53
+ FileUtils.rm_rf 'tests'
54
+ FileUtils.rm_rf 'ninjs.conf'
55
+ FileUtils.rm_rf 'js' if File.exists? 'js'
56
+ end
57
+
58
+ it 'should create a new application' do
59
+ suppress_output { Ninjs::Command.create({ :name => 'myapp' }) }
60
+
61
+ 'ninjs.conf'.should be_same_file_as 'fixtures/ninjs.conf'
62
+
63
+ File.directory?("application").should be_true
64
+ File.directory?("elements").should be_true
65
+ File.directory?("lib").should be_true
66
+ File.directory?("models").should be_true
67
+ File.directory?("modules").should be_true
68
+ File.directory?("plugins").should be_true
69
+ File.directory?("tests").should be_true
70
+
71
+ File.exists?(File.expand_path("lib/nin.js")).should be_true
72
+ File.exists?(File.expand_path("lib/utilities.js")).should be_true
73
+
74
+ File.exists?(File.expand_path("application/myapp.js")).should be_true
75
+ application_file_content = File.open("application/myapp.js").readlines
76
+ application_file_content.shift
77
+ application_file_content.join('').should == File.open('fixtures/myapp.initial.js').readlines.join('')
78
+
79
+ File.exists?(File.expand_path("tests")).should be_true
80
+ File.exists?(File.expand_path("tests/index.html")).should be_true
81
+ File.exists?(File.expand_path("tests/application.test.js")).should be_true
82
+ File.exists?(File.expand_path("tests/array.utilities.test.js")).should be_true
83
+ File.exists?(File.expand_path("tests/existence.test.js")).should be_true
84
+ File.exists?(File.expand_path("tests/extension.test.js")).should be_true
85
+ File.exists?(File.expand_path("tests/module.test.js")).should be_true
86
+ File.exists?(File.expand_path("tests/qspec.js")).should be_true
87
+ File.exists?(File.expand_path("tests/string.utilities.test.js")).should be_true
88
+ end
89
+
90
+ it 'should create a new application in a subdirectory' do
91
+ suppress_output { Ninjs::Command.create({ :name => 'myapp', :directory => 'js' }) }
92
+
93
+ 'js/ninjs.conf'.should be_same_file_as 'fixtures/ninjs.conf'
94
+
95
+ File.directory?("js/application").should be_true
96
+ File.directory?("js/elements").should be_true
97
+ File.directory?("js/lib").should be_true
98
+ File.directory?("js/models").should be_true
99
+ File.directory?("js/modules").should be_true
100
+ File.directory?("js/plugins").should be_true
101
+ File.directory?("js/tests").should be_true
102
+
103
+ File.exists?(File.expand_path("js/lib/nin.js")).should be_true
104
+ File.exists?(File.expand_path("js/lib/utilities.js")).should be_true
105
+
106
+ File.exists?(File.expand_path("js/application/myapp.js")).should be_true
107
+ application_file_content = File.open("js/application/myapp.js").readlines
108
+ application_file_content.shift
109
+ application_file_content.join('').should == File.open('fixtures/myapp.initial.js').readlines.join('')
110
+
111
+ File.exists?(File.expand_path("js/tests")).should be_true
112
+ File.exists?(File.expand_path("js/tests/index.html")).should be_true
113
+ File.exists?(File.expand_path("js/tests/application.test.js")).should be_true
114
+ File.exists?(File.expand_path("js/tests/array.utilities.test.js")).should be_true
115
+ File.exists?(File.expand_path("js/tests/existence.test.js")).should be_true
116
+ File.exists?(File.expand_path("js/tests/extension.test.js")).should be_true
117
+ File.exists?(File.expand_path("js/tests/module.test.js")).should be_true
118
+ File.exists?(File.expand_path("js/tests/qspec.js")).should be_true
119
+ File.exists?(File.expand_path("js/tests/string.utilities.test.js")).should be_true
120
+ end
121
+
122
+ it 'should compile the application' do
123
+ suppress_output { Ninjs::Command.create({ :name => 'myapp' }) }
124
+
125
+ FileUtils.cp 'fixtures/hello.module.js', File.expand_path('modules')
126
+ FileUtils.cp 'fixtures/hello.elements.js', File.expand_path('elements')
127
+ FileUtils.cp 'fixtures/hello.model.js', File.expand_path('models')
128
+ FileUtils.cp 'fixtures/foo.module.js', File.expand_path('modules')
129
+ FileUtils.cp 'fixtures/foo.elements.js', File.expand_path('elements')
130
+ FileUtils.cp 'fixtures/foo.model.js', File.expand_path('models')
131
+
132
+ suppress_output { Ninjs::Command.compile }
133
+
134
+ File.exists?('application/hello.js').should be_true
135
+ File.exists?('application/foo.js').should be_true
136
+ end
137
+
138
+ it 'should update the application' do
139
+ suppress_output { Ninjs::Command.create({ :name => 'myapp' }) }
140
+
141
+ File.open('lib/nin.js', 'w+') do |file|
142
+ file << 'changed'
143
+ end
144
+
145
+ suppress_output { Ninjs::Command.update }
146
+
147
+ 'lib/nin.js'.should be_same_file_as 'fixtures/nin.js'
148
+ end
149
+
150
+ it 'should generate a module file' do
151
+ suppress_output do
152
+ Ninjs::Command.create({ :name => 'myapp' })
153
+ Ninjs::Command.generate({
154
+ :project => Ninjs::Project.new,
155
+ :type => 'module',
156
+ :name => 'mymodule',
157
+ :alias => nil,
158
+ :dest => nil,
159
+ :dependencies => nil
160
+ })
161
+ end
162
+
163
+ 'modules/mymodule.module.js'.should be_same_file_as 'fixtures/mymodule.module.js'
164
+ end
165
+
166
+ it 'should generate a module file with an alias' do
167
+ suppress_output do
168
+ Ninjs::Command.create({ :name => 'myapp' })
169
+ Ninjs::Command.generate({
170
+ :project => Ninjs::Project.new,
171
+ :type => 'module',
172
+ :name => 'mymodule',
173
+ :alias => 'app',
174
+ :dest => nil,
175
+ :dependencies => nil
176
+ })
177
+ end
178
+
179
+ 'modules/mymodule.module.js'.should be_same_file_as 'fixtures/mymodule.alias.module.js'
180
+ end
181
+
182
+ it 'should generate an elements file' do
183
+ suppress_output do
184
+ Ninjs::Command.create({ :name => 'myapp' })
185
+ Ninjs::Command.generate({
186
+ :project => Ninjs::Project.new,
187
+ :type => 'elements',
188
+ :name => 'mymodule',
189
+ :alias => nil,
190
+ :dest => nil,
191
+ :dependencies => nil
192
+ })
193
+ end
194
+
195
+ 'elements/mymodule.elements.js'.should be_same_file_as 'fixtures/mymodule.elements.js'
196
+ end
197
+
198
+ it 'should generate a model file' do
199
+ suppress_output do
200
+ Ninjs::Command.create({ :name => 'myapp' })
201
+ Ninjs::Command.generate({
202
+ :project => Ninjs::Project.new,
203
+ :type => 'model',
204
+ :name => 'mymodule',
205
+ :alias => nil,
206
+ :dest => nil,
207
+ :dependencies => nil
208
+ })
209
+ end
210
+
211
+ 'models/mymodule.model.js'.should be_same_file_as 'fixtures/mymodule.model.js'
212
+ end
213
+
214
+ it 'should generate a module file with dependencies' do
215
+ suppress_output do
216
+ Ninjs::Command.create({ :name => 'myapp' })
217
+ Ninjs::Command.generate({
218
+ :project => Ninjs::Project.new,
219
+ :type => 'module',
220
+ :name => 'mymodule',
221
+ :alias => nil,
222
+ :dest => nil,
223
+ :dependencies => { :elements => true, :model => true }
224
+ })
225
+ end
226
+
227
+ 'modules/mymodule.module.js'.should be_same_file_as 'fixtures/mymodule.dependencies.module.js'
228
+ 'elements/mymodule.elements.js'.should be_same_file_as 'fixtures/mymodule.elements.js'
229
+ 'models/mymodule.model.js'.should be_same_file_as 'fixtures/mymodule.model.js'
230
+ end
231
+ end
232
+ # Usage
9
233
  end
@@ -1,39 +1,59 @@
1
1
 
2
- if(is_defined===undefined){var is_defined=function(suspect){return((suspect===undefined)||(suspect===null))?false:true;};}
3
- if(!is_defined(is_undefined)){var is_undefined=function(suspect){return(suspect===undefined)?true:false;};}
4
- if(is_undefined(is_typeof)){var is_typeof=function(type,suspect){if(is_undefined(type)){throw new SyntaxError("is_typeof(Type, suspect): type is undefined");}
2
+ (function(){if(window.is_defined===undefined){window.is_defined=function(suspect){return((suspect===undefined)||(suspect===null))?false:true;};}
3
+ if(!is_defined(window.is_undefined)){window.is_undefined=function(suspect){return(suspect===undefined)?true:false;};}
4
+ if(is_undefined(window.is_typeof)){window.is_typeof=function(type,suspect){if(is_undefined(type)){throw new SyntaxError("is_typeof(Type, suspect): type is undefined");}
5
5
  if(is_undefined(suspect)){throw new SyntaxError("is_typeof(Type, suspect): suspect is undefined");}
6
6
  return(suspect.constructor==type)?true:false;};}
7
- if(is_undefined(is_numeric)){var is_numeric=function(suspect){if(is_typeof(Number,suspect)){return true;}
7
+ if(is_undefined(window.is_numeric)){window.is_numeric=function(suspect){if(is_typeof(Number,suspect)){return true;}
8
8
  else{var pattern=/^-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?$/i;return pattern.test(suspect);}};}
9
- if(is_undefined(is_string)){var is_string=function(suspect){return is_typeof(String,suspect);};}
10
- if(is_undefined(is_array)){var is_array=function(suspect){return is_typeof(Array,suspect);};}
11
- if(is_undefined(is_number)){var is_number=function(suspect){return is_typeof(Number,suspect);};}
12
- if(is_undefined(is_date)){var is_date=function(suspect){return is_typeof(Date,suspect);};}
13
- if(is_undefined(is_bool)){var is_bool=function(suspect){return is_typeof(Boolean,suspect);};}
14
- if(is_undefined(is_regex)){var is_regex=function(suspect){return is_typeof(RegExp,suspect);};}
15
- if(is_undefined(is_empty)){var is_empty=function(suspect){return suspect.length===0;};}
16
- if(is_undefined(is_not_empty)){var is_not_empty=function(suspect){return suspect.length>=1;};}
9
+ if(is_undefined(window.is_string)){window.is_string=function(suspect){return is_typeof(String,suspect);};}
10
+ if(is_undefined(window.is_array)){window.is_array=function(suspect){return is_typeof(Array,suspect);};}
11
+ if(is_undefined(window.is_number)){window.is_number=function(suspect){return is_typeof(Number,suspect);};}
12
+ if(is_undefined(window.is_date)){window.is_date=function(suspect){return is_typeof(Date,suspect);};}
13
+ if(is_undefined(window.is_bool)){window.is_bool=function(suspect){return is_typeof(Boolean,suspect);};}
14
+ if(is_undefined(window.is_regex)){window.is_regex=function(suspect){return is_typeof(RegExp,suspect);};}
15
+ if(is_undefined(window.is_empty)){window.is_empty=function(suspect){return suspect.length===0;};}
16
+ if(is_undefined(window.is_not_empty)){window.is_not_empty=function(suspect){return suspect.length>=1;};}
17
17
  if(is_undefined(Function.prototype['method'])){Function.prototype.method=function(name,func){if(is_undefined(name)){throw new SyntaxError("Object.method(name, func): name is undefined");}
18
18
  if(is_undefined(func)){throw new SyntaxError("Object.method(name, func): func is undefined");}
19
19
  if(is_undefined(this.prototype[name])){this.prototype[name]=func;return this;}};}
20
- if(is_undefined(unless)){var unless=function(expression,callback,fallback){if(is_undefined(expression)){throw new SyntaxError("unless(expression, callback[, fallback]): expression is undefined");}
20
+ if(is_undefined(window.unless)){window.unless=function(expression,callback,fallback){if(is_undefined(expression)){throw new SyntaxError("unless(expression, callback[, fallback]): expression is undefined");}
21
21
  if(is_undefined(callback)){throw new SyntaxError("unless(expression, callback[, fallback]): callback is undefined");}
22
22
  if(!expression){callback.call(this);}
23
23
  else if(is_defined(fallback)){fallback.call(this);}};}
24
- var NinjsModule=function(name){this.dom={};this.data={};this.name=name;this.run_tests=false;this.tests=[];};NinjsModule.method('actions',function(){});NinjsModule.method('run',function(){this.call_on_ready(this.execute);});NinjsModule.method('call_on_ready',function(callback){var timer;var module=this;function check_ready(){timer=setInterval(is_ready,13);}
25
- function is_ready(){if(document&&document.getElementsByTagName&&document.getElementById&&document.body){clearInterval(timer);timer=null;callback.call(module);}}
26
- check_ready();});NinjsModule.method('execute',function(){if(this.run_tests){this._run_tests();}
24
+ if(is_undefined(Function.prototype['method'])){Function.prototype.method=function(name,func){if(is_undefined(name)){throw new SyntaxError("Object.method(name, func): name is undefined");}
25
+ if(is_undefined(func)){throw new SyntaxError("Object.method(name, func): func is undefined");}
26
+ if(is_undefined(this.prototype[name])){this.prototype[name]=func;return this;}};}
27
+ if(is_undefined(window.unless)){window.unless=function(expression,callback,fallback){if(is_undefined(expression)){throw new SyntaxError("unless(expression, callback[, fallback]): expression is undefined");}
28
+ if(is_undefined(callback)){throw new SyntaxError("unless(expression, callback[, fallback]): callback is undefined");}
29
+ if(!expression){callback.call(this);}
30
+ else if(is_defined(fallback)){fallback.call(this);}};}
31
+ var userAgent=navigator.userAgent;var browser={agent:userAgent,mozilla:(/mozilla/.test(userAgent.toLowerCase()))&&(!/(compatible|webkit)/.test(userAgent.toLowerCase())),webkit:/webkit/.test(userAgent.toLowerCase()),firefox:/firefox/.test(userAgent.toLowerCase()),chrome:/webkit/.test(userAgent.toLowerCase()),safari:/safari/.test(userAgent.toLowerCase()),opera:/opera/.test(userAgent.toLowerCase()),msie:(/msie/.test(userAgent.toLowerCase()))&&(!/opera/.test(userAgent.toLowerCase()))};var readyBound=false;var isReady=false;var readyList=[];function domReady(){if(!isReady){isReady=true;if(readyList){for(var fn=0;fn<readyList.length;fn++){readyList[fn].call(window,[]);}
32
+ readyList=[];}}}
33
+ function addLoadEvent(func){var oldonload=window.onload;if(typeof window.onload!='function'){window.onload=func;}else{window.onload=function(){if(oldonload){oldonload();}
34
+ func();}}};function bindReady(){if(readyBound){return;}
35
+ readyBound=true;if(document.addEventListener&&!browser.opera){document.addEventListener("DOMContentLoaded",domReady,false);}
36
+ if(browser.msie&&window==top)(function(){if(isReady)return;try{document.documentElement.doScroll("left");}catch(error){setTimeout(arguments.callee,0);return;}
37
+ domReady();})();if(browser.opera){document.addEventListener("DOMContentLoaded",function(){if(isReady)return;for(var i=0;i<document.styleSheets.length;i++)
38
+ if(document.styleSheets[i].disabled){setTimeout(arguments.callee,0);return;}
39
+ domReady();},false);}
40
+ if(browser.safari){var numStyles;(function(){if(isReady)return;if(document.readyState!="loaded"&&document.readyState!="complete"){setTimeout(arguments.callee,0);return;}
41
+ if(numStyles===undefined){var links=document.getElementsByTagName("link");for(var i=0;i<links.length;i++){if(links[i].getAttribute('rel')=='stylesheet'){numStyles++;}}
42
+ var styles=document.getElementsByTagName("style");numStyles+=styles.length;}
43
+ if(document.styleSheets.length!=numStyles){setTimeout(arguments.callee,0);return;}
44
+ domReady();})();}
45
+ addLoadEvent(domReady);};window.NinjsDOM=function(){this.cached_selectors={};};NinjsDOM.method('ready',function(fn,args){bindReady();if(isReady){fn.call(window,[]);}
46
+ else{readyList.push(function(){return fn.call(window,[]);});}});bindReady();window.NinjsModule=function(name){this.dom=new NinjsDOM(this);this.browser=browser;this.data={};this.name=name;this.run_tests=false;this.tests=[];};NinjsModule.method('actions',function(){});NinjsModule.method('run',function(){var mod=this;this.dom.ready(function(){mod.execute();});});NinjsModule.method('execute',function(){if(this.run_tests){this._run_tests();}
27
47
  this.actions();});NinjsModule.method('elements',function(elements){if(is_undefined(elements)){if(is_typeof(Object,elements)){throw new SyntaxError("NinjsModule.elements(elements): elements is undefined");}
28
48
  else if(is_string(elements)){throw new SyntaxError("NinjsModule.elements(name): name is undefined");}}
29
- if(is_string(elements)){var name=elements;return is_defined(this.dom[name])?this.dom[name]:undefined;}
30
- else{this.call_on_ready(function(){for(var key in elements){if(elements.hasOwnProperty(key)){this.dom[key]=elements[key];}}});}});NinjsModule.method('set_data',function(key,value){if(is_undefined(key)){throw new SyntaxError('NinjsModule.set_data(key, value): key is undefined');}
49
+ if(is_string(elements)){var name=elements;return this.dom.cached_selectors[name];}
50
+ else{var dom=this.dom;dom.ready(function(){for(var key in elements){if(elements.hasOwnProperty(key)){dom.cached_selectors[key]=elements[key];}}});}});NinjsModule.method('set_data',function(key,value){if(is_undefined(key)){throw new SyntaxError('NinjsModule.set_data(key, value): key is undefined');}
31
51
  if(is_typeof(String,key)&&is_undefined(value)){throw new SyntaxError('NinjsModule.set_data(key, value): value is undefined');}
32
52
  if(is_typeof(String,key)){this.data[key]=value;}
33
53
  else if(is_typeof(Object,key)){var data=key;for(var property in data){this.data[property]=data[property];}}
34
54
  return this;});NinjsModule.method('add_test',function(test_file){this.tests.push(test_file);});NinjsModule.method('_run_tests',function(){var test_template=[];test_template.push('<div class="test-results" title="Test Results">');test_template.push('<h1 id="qunit-header">'+this.name+' module tests</h1>');test_template.push('<h2 id="qunit-banner"></h2>');test_template.push('<h2 id="qunit-userAgent"></h2>');test_template.push('<ol id="qunit-tests"></ol>');test_template.push('</div>');var qunit_dependencies='<script src="'+_.tests_path+'qunit/qunit.js"></script>';$.getScript(_.tests_path+'qunit/qunit.js');var qunit_styles='<link rel="stylesheet" href="'+_.tests_path+'qunit/qunit.css">';$('body').append(qunit_styles);$('body').append(test_template.join("\n"));this.tests.each(function(test){$.getScript(_.tests_path+test+'.test.js',function(){var test_results_dialog=$('.test-results');var height=$(window).height()-200;var width=$(window).width()-300;try{test_results_dialog.dialog({width:width,height:height,autoOpen:false,buttons:{"Thanks buddy":function(){test_results_dialog.dialog('close');}}});var failed=$('.failed');console.log(failed.html());test_results_dialog.dialog('open');}
35
- catch(error){alert("Test harness requires jQueryUI");}});});});var NinjsApplication=function(base_url,tests_path){if(is_defined(tests_path)){this.tests_path=tests_path;}
55
+ catch(error){alert("Test harness requires jQueryUI");}});});});window.NinjsApplication=function(base_url,tests_path){if(is_defined(tests_path)){this.tests_path=tests_path;}
36
56
  if(is_defined(base_url)){this.site_url=function(path){var path=path||'';return base_url+path;};}};NinjsApplication.method('add_module',function(name){if(is_undefined(name)){throw new SyntaxError("NinjsApplication.add_module(name): name is undefined");}
37
57
  if(is_defined(this[name])){throw new SyntaxError("NinjsApplication.add_module(name): '"+name+"' already declared");}
38
58
  if(this.name===name){throw new SyntaxError("NinjsApplication.add_module(name): a module cannot have the same name as the application");}
39
- return this[name]=new NinjsModule(name);});var myapp=new NinjsApplication();
59
+ return this[name]=new NinjsModule(name);});})();var myapp=new NinjsApplication();
@@ -1,535 +1,430 @@
1
- /* File: nin.js */
2
- /* File: extend.js */
3
- /* File: existence.js */
4
- if (is_defined === undefined) {
5
- /*
6
- Function: is_defined
7
- Checks if a variable is undefined. This is a convenience method to enhance clarity in your conditions.
8
-
9
- Parameters:
10
- suspect - suspect variable to test
11
-
12
- Returns:
13
- bool
14
-
15
- See Also:
16
-
17
- <is_undefined>
18
- */
19
- var is_defined = function(suspect) {
20
- return ((suspect === undefined) || (suspect === null)) ? false : true;
21
- };
22
- }
1
+ (function() {
2
+ if (window.is_defined === undefined) {
3
+ window.is_defined = function(suspect) {
4
+ return ((suspect === undefined) || (suspect === null)) ? false : true;
5
+ };
6
+ }
23
7
 
24
- if (!is_defined(is_undefined)) {
25
- /*
26
- Function: is_undefined
27
- Checks if a variable is defined. This is a convenience method to enhance clarity in your conditions.
8
+ if (!is_defined(window.is_undefined)) {
9
+ window.is_undefined = function(suspect) {
10
+ return (suspect === undefined) ? true : false;
11
+ };
12
+ }
28
13
 
29
- Parameters:
30
- suspect - suspect variable to test
14
+ if (is_undefined(window.is_typeof)) {
15
+ window.is_typeof = function(type, suspect) {
16
+ if (is_undefined(type)) {
17
+ throw new SyntaxError("is_typeof(Type, suspect): type is undefined");
18
+ }
19
+ if (is_undefined(suspect)) {
20
+ throw new SyntaxError("is_typeof(Type, suspect): suspect is undefined");
21
+ }
31
22
 
32
- Returns:
33
- bool
23
+ return (suspect.constructor == type) ? true : false;
24
+ };
25
+ }
34
26
 
35
- See Also:
27
+ if (is_undefined(window.is_numeric)) {
28
+ window.is_numeric = function(suspect) {
29
+ if(is_typeof(Number, suspect)) {
30
+ return true;
31
+ }
32
+ else {
33
+ var pattern = /^-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?$/i;
34
+ return pattern.test(suspect);
35
+ }
36
+ };
37
+ }
36
38
 
37
- <is_defined>
38
- */
39
- var is_undefined = function(suspect) {
40
- return (suspect === undefined) ? true : false;
41
- };
42
- }
43
-
44
- if (is_undefined(is_typeof)) {
45
- /*
46
- Function: is_typeof
47
- Strict type checking by comparing constructors.
48
- (Pro Javascript Techniques, John Resig, Apress p.24 Listing 2-8: Example of using the constructor property to determine the type of an object http://amzn.to/fTsDRg)
49
- Parameters:
50
- type - The type you expect (ie. String, Number, Array (note: without quotes): is_typeof(String, 'hello'): // true)
51
- suspect - The suspect variable to check against type
52
-
53
- Returns:
54
- bool
55
-
56
- See Also:
57
- <is_numeric>,
58
- <is_string>,
59
- <is_array>,
60
- <is_number>,
61
- <is_date>,
62
- <is_bool>,
63
- <is_regex>
64
- */
65
- var is_typeof = function(type, suspect) {
66
- if (is_undefined(type)) {
67
- throw new SyntaxError("is_typeof(Type, suspect): type is undefined");
68
- }
69
- if (is_undefined(suspect)) {
70
- throw new SyntaxError("is_typeof(Type, suspect): suspect is undefined");
71
- }
39
+ if (is_undefined(window.is_string)) {
40
+ window.is_string = function(suspect) {
41
+ return is_typeof(String, suspect);
42
+ };
43
+ }
72
44
 
73
- return (suspect.constructor == type) ? true : false;
74
- };
75
- }
76
-
77
- if (is_undefined(is_numeric)) {
78
- /*
79
- Function: is_numeric
80
- Determine if the suspect string represents a numeric value.
81
- (JavaScript: The Good Parts, Douglas Crockford, O'Reilly p.69 Chapter 7: Regular Expressions An Example)
82
- Parameters:
83
- suspect - variable to check for numeric value
84
-
85
- Returns:
86
- bool
87
-
88
- See Also:
89
- <is_number>
90
- */
91
- var is_numeric = function(suspect) {
92
- if(is_typeof(Number, suspect)) {
93
- return true;
94
- }
95
- else {
96
- var pattern = /^-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?$/i;
97
- return pattern.test(suspect);
98
- }
99
- };
100
- }
101
-
102
- if (is_undefined(is_string)) {
103
- /*
104
- Function: is_string
105
- Determine the suspect is a String. This is a proxy method for is_typeof(String, suspect).
106
-
107
- Parameters:
108
- suspect - supect variable to test
109
-
110
- Returns:
111
- bool
112
-
113
- See Also:
114
- <is_typeof>,
115
- <is_numeric>,
116
- <is_array>,
117
- <is_number>,
118
- <is_date>,
119
- <is_bool>,
120
- <is_regex>
121
- */
122
- var is_string = function(suspect) {
123
- return is_typeof(String, suspect);
124
- };
125
- }
126
-
127
- if (is_undefined(is_array)) {
128
- /*
129
- Function: is_array
130
- Determine if the suspect is an Array. This is a proxy method for is_typeof(Array, suspect).
131
-
132
- Parameters:
133
- suspect - suspect variable to test
134
-
135
- Returns:
136
- bool
137
-
138
- See Also:
139
- <is_typeof>,
140
- <is_numeric>,
141
- <is_string>,
142
- <is_number>,
143
- <is_date>,
144
- <is_bool>,
145
- <is_regex>
146
- */
147
- var is_array = function(suspect) {
148
- return is_typeof(Array, suspect);
149
- };
150
- }
151
-
152
- if (is_undefined(is_number)) {
153
- /*
154
- Function: is_number
155
- Determines if the suspect is a Number. This is a proxy method for is_typeof(Number, suspect).
156
-
157
- Parameters:
158
- suspect - suspect variable to test
159
-
160
- Returns:
161
- bool
162
-
163
- See Also:
164
- <is_typeof>,
165
- <is_numeric>,
166
- <is_string>,
167
- <is_array>,
168
- <is_date>,
169
- <is_bool>,
170
- <is_regex>
171
- */
172
- var is_number = function(suspect) {
173
- return is_typeof(Number, suspect);
174
- };
175
- }
176
-
177
- if (is_undefined(is_date)) {
178
- /*
179
- Function: is_date
180
- Determines if the suspect is a Date. This is a proxy method for is_typeof(Date, suspect).
181
-
182
- Parameters:
183
- suspect - suspect variable to test
184
-
185
- Returns:
186
- bool
187
-
188
- See Also:
189
- <is_typeof>,
190
- <is_numeric>,
191
- <is_string>,
192
- <is_array>,
193
- <is_number>,
194
- <is_bool>,
195
- <is_regex>
196
- */
197
- var is_date = function(suspect) {
198
- return is_typeof(Date, suspect);
199
- };
200
- }
201
-
202
- if (is_undefined(is_bool)) {
203
- /*
204
- Function: is_bool
205
- Determines if the suspect is a Boolean. This is a proxy method for is_typeof(Boolean, suspect).
206
-
207
- Parameters:
208
- suspect - suspect variable to test
209
-
210
- Returns:
211
- bool
212
-
213
- See Also:
214
- <is_typeof>,
215
- <is_numeric>,
216
- <is_string>,
217
- <is_array>,
218
- <is_number>,
219
- <is_regex>
220
- */
221
- var is_bool = function(suspect) {
222
- return is_typeof(Boolean, suspect);
223
- };
224
- }
225
-
226
- if (is_undefined(is_regex)) {
227
- /*
228
- Function: is_regex
229
- Determines if the suspect is a RegExp. This is a proxy method for is_typeof(RegExp, suspect).
230
-
231
- Parameters:
232
- suspect - suspect variable to test
233
-
234
- Returns:
235
- bool
236
-
237
- See Also:
238
- <is_typeof>,
239
- <is_numeric>,
240
- <is_string>,
241
- <is_array>,
242
- <is_number>,
243
- <is_bool>
244
- */
245
- var is_regex = function(suspect) {
246
- return is_typeof(RegExp, suspect);
247
- };
248
- }
249
-
250
-
251
- if (is_undefined(is_empty)) {
252
- /*
253
- Function: is_empty
254
- Determined if the suspect's length is less than one.
255
-
256
- Parameters:
257
- suspect - suspect variable to test
258
-
259
- Returns: bool
260
- */
261
- var is_empty = function(suspect) {
262
- return suspect.length === 0;
263
- };
264
- }
45
+ if (is_undefined(window.is_array)) {
46
+ window.is_array = function(suspect) {
47
+ return is_typeof(Array, suspect);
48
+ };
49
+ }
265
50
 
266
- if (is_undefined(is_not_empty)) {
267
- /*
268
- Function: is_not_empty
269
- Determined if the suspect's length is greater than one.
51
+ if (is_undefined(window.is_number)) {
52
+ window.is_number = function(suspect) {
53
+ return is_typeof(Number, suspect);
54
+ };
55
+ }
270
56
 
271
- Parameters:
272
- suspect - suspect variable to test
57
+ if (is_undefined(window.is_date)) {
58
+ window.is_date = function(suspect) {
59
+ return is_typeof(Date, suspect);
60
+ };
61
+ }
273
62
 
274
- Returns: bool
275
- */
276
- var is_not_empty = function(suspect) {
277
- return suspect.length >= 1;
278
- };
279
- }
280
-
281
- if (is_undefined(Function.prototype['method'])) {
282
- /*
283
- Function: method
284
- Method to add a method to an object (ie. String.method('my_method', my_func); // 'hello'.my_method())
285
-
286
- Parameters:
287
- name - name of the method
288
- func - function definition
289
-
290
- Returns:
291
- this (chainable)
292
-
293
- > String.method('custom_method', function() {
294
- > // define custom_method
295
- > });
296
- >
297
- > "hello".custom_method();
298
- */
299
- Function.prototype.method = function(name, func) {
300
- if (is_undefined(name)) {
301
- throw new SyntaxError("Object.method(name, func): name is undefined");
302
- }
63
+ if (is_undefined(window.is_bool)) {
64
+ window.is_bool = function(suspect) {
65
+ return is_typeof(Boolean, suspect);
66
+ };
67
+ }
303
68
 
304
- if (is_undefined(func)) {
305
- throw new SyntaxError("Object.method(name, func): func is undefined");
306
- }
69
+ if (is_undefined(window.is_regex)) {
70
+ window.is_regex = function(suspect) {
71
+ return is_typeof(RegExp, suspect);
72
+ };
73
+ }
307
74
 
308
- if (is_undefined(this.prototype[name])) {
309
- this.prototype[name] = func;
310
- return this;
311
- }
312
- };
313
- }
314
-
315
- if (is_undefined(unless)) {
316
- /*
317
- Function: unless
318
- Function to better express negative conditions (ie. if (!something))
319
-
320
- Parameters:
321
- expression - expression to be tested
322
- callback - function to be executed unless expression is true (see how that works)
323
- fallback - function to be executed if the expression is false (optional)
324
-
325
- Returns:
326
- undefined
327
-
328
- > unless(test_expression === 'some condition',
329
- > function() {
330
- > alert('we do something');
331
- > },
332
- > function() {
333
- > alert('we can do something if it meets the condition too');
334
- > }
335
- > );
336
- */
337
- var unless = function(expression, callback, fallback) {
338
- if (is_undefined(expression)) {
339
- throw new SyntaxError("unless(expression, callback[, fallback]): expression is undefined");
340
- }
341
75
 
342
- if (is_undefined(callback)) {
343
- throw new SyntaxError("unless(expression, callback[, fallback]): callback is undefined");
344
- }
76
+ if (is_undefined(window.is_empty)) {
77
+ window.is_empty = function(suspect) {
78
+ return suspect.length === 0;
79
+ };
80
+ }
345
81
 
346
- if (!expression) {
347
- callback.call(this);
348
- }
349
- else if (is_defined(fallback)) {
350
- fallback.call(this);
351
- }
352
- };
353
- }
354
- var NinjsModule = function(name) {
355
- this.dom = {};
356
- this.data = {};
357
- this.name = name;
358
- this.run_tests = false;
359
- this.tests = [];
360
- };
361
-
362
- NinjsModule.method('actions', function() {});
363
-
364
- NinjsModule.method('run', function() {
365
- this.call_on_ready(this.execute);
366
- });
367
-
368
- NinjsModule.method('call_on_ready', function(callback) {
369
- var timer;
370
- var module = this;
371
-
372
- function check_ready() {
373
- timer = setInterval(is_ready, 13);
82
+ if (is_undefined(window.is_not_empty)) {
83
+ window.is_not_empty = function(suspect) {
84
+ return suspect.length >= 1;
85
+ };
374
86
  }
375
87
 
376
- function is_ready() {
377
- if (document && document.getElementsByTagName && document.getElementById && document.body) {
378
- clearInterval(timer);
379
- timer = null;
380
- callback.call(module);
381
- }
88
+ if (is_undefined(Function.prototype['method'])) {
89
+ Function.prototype.method = function(name, func) {
90
+ if (is_undefined(name)) {
91
+ throw new SyntaxError("Object.method(name, func): name is undefined");
92
+ }
93
+
94
+ if (is_undefined(func)) {
95
+ throw new SyntaxError("Object.method(name, func): func is undefined");
96
+ }
97
+
98
+ if (is_undefined(this.prototype[name])) {
99
+ this.prototype[name] = func;
100
+ return this;
101
+ }
102
+ };
382
103
  }
383
104
 
384
- check_ready();
385
- });
105
+ if (is_undefined(window.unless)) {
106
+ window.unless = function(expression, callback, fallback) {
107
+ if (is_undefined(expression)) {
108
+ throw new SyntaxError("unless(expression, callback[, fallback]): expression is undefined");
109
+ }
386
110
 
387
- NinjsModule.method('execute', function() {
388
- if (this.run_tests) {
389
- this._run_tests();
111
+ if (is_undefined(callback)) {
112
+ throw new SyntaxError("unless(expression, callback[, fallback]): callback is undefined");
113
+ }
114
+
115
+ if (!expression) {
116
+ callback.call(this);
117
+ }
118
+ else if (is_defined(fallback)) {
119
+ fallback.call(this);
120
+ }
121
+ };
390
122
  }
123
+ if (is_undefined(Function.prototype['method'])) {
124
+ Function.prototype.method = function(name, func) {
125
+ if (is_undefined(name)) {
126
+ throw new SyntaxError("Object.method(name, func): name is undefined");
127
+ }
391
128
 
392
- this.actions();
393
- });
394
-
395
- NinjsModule.method('elements', function(elements) {
396
- if (is_undefined(elements)) {
397
- if (is_typeof(Object, elements)) {
398
- throw new SyntaxError("NinjsModule.elements(elements): elements is undefined");
399
- }
400
- else if (is_string(elements)) {
401
- throw new SyntaxError("NinjsModule.elements(name): name is undefined");
402
- }
129
+ if (is_undefined(func)) {
130
+ throw new SyntaxError("Object.method(name, func): func is undefined");
131
+ }
132
+
133
+ if (is_undefined(this.prototype[name])) {
134
+ this.prototype[name] = func;
135
+ return this;
136
+ }
137
+ };
403
138
  }
404
139
 
405
- if (is_string(elements)) {
406
- var name = elements;
407
- return is_defined(this.dom[name]) ? this.dom[name] : undefined;
140
+ if (is_undefined(window.unless)) {
141
+ window.unless = function(expression, callback, fallback) {
142
+ if (is_undefined(expression)) {
143
+ throw new SyntaxError("unless(expression, callback[, fallback]): expression is undefined");
144
+ }
145
+
146
+ if (is_undefined(callback)) {
147
+ throw new SyntaxError("unless(expression, callback[, fallback]): callback is undefined");
148
+ }
149
+
150
+ if (!expression) {
151
+ callback.call(this);
152
+ }
153
+ else if (is_defined(fallback)) {
154
+ fallback.call(this);
155
+ }
156
+ };
408
157
  }
409
- else {
410
- this.call_on_ready(function() {
411
- for(var key in elements) {
412
- if (elements.hasOwnProperty(key)) {
413
- this.dom[key] = elements[key];
158
+ var userAgent = navigator.userAgent;
159
+ var browser = {
160
+ agent: userAgent,
161
+ mozilla: (/mozilla/.test(userAgent.toLowerCase())) && (!/(compatible|webkit)/.test(userAgent.toLowerCase())),
162
+ webkit: /webkit/.test(userAgent.toLowerCase()),
163
+ firefox: /firefox/.test(userAgent.toLowerCase()),
164
+ chrome: /webkit/.test(userAgent.toLowerCase()),
165
+ safari: /safari/.test(userAgent.toLowerCase()),
166
+ opera: /opera/.test(userAgent.toLowerCase()),
167
+ msie: (/msie/.test(userAgent.toLowerCase())) && (!/opera/.test( userAgent.toLowerCase() ))
168
+ };
169
+
170
+ var readyBound = false;
171
+ var isReady = false;
172
+ var readyList = [];
173
+
174
+ function domReady() {
175
+ if (!isReady) {
176
+ isReady = true;
177
+ if (readyList) {
178
+ for(var fn = 0; fn < readyList.length; fn++) {
179
+ readyList[fn].call(window, []);
414
180
  }
181
+ readyList = [];
415
182
  }
416
- });
183
+ }
417
184
  }
418
- });
419
185
 
420
- NinjsModule.method('set_data', function(key, value) {
421
- if (is_undefined(key)) {
422
- throw new SyntaxError('NinjsModule.set_data(key, value): key is undefined');
423
- }
186
+ function addLoadEvent(func) {
187
+ var oldonload = window.onload;
188
+ if (typeof window.onload != 'function') {
189
+ window.onload = func;
190
+ } else {
191
+ window.onload = function() {
192
+ if (oldonload) {
193
+ oldonload();
194
+ }
195
+ func();
196
+ }
197
+ }
198
+ };
424
199
 
425
- if (is_typeof(String, key) && is_undefined(value)) {
426
- throw new SyntaxError('NinjsModule.set_data(key, value): value is undefined');
427
- }
200
+ function bindReady() {
201
+ if (readyBound) {
202
+ return;
203
+ }
428
204
 
429
- if (is_typeof(String, key)) {
430
- this.data[key] = value;
431
- }
432
- else if (is_typeof(Object, key)) {
433
- var data = key;
434
- for(var property in data) {
435
- this.data[property] = data[property];
205
+ readyBound = true;
206
+
207
+ if (document.addEventListener && !browser.opera) {
208
+ document.addEventListener("DOMContentLoaded", domReady, false);
436
209
  }
437
- }
438
210
 
439
- return this;
440
- });
441
-
442
- NinjsModule.method('add_test', function(test_file) {
443
- this.tests.push(test_file);
444
- });
445
-
446
- NinjsModule.method('_run_tests', function() {
447
- var test_template = [];
448
- test_template.push('<div class="test-results" title="Test Results">');
449
- test_template.push('<h1 id="qunit-header">' + this.name + ' module tests</h1>');
450
- test_template.push('<h2 id="qunit-banner"></h2>');
451
- test_template.push('<h2 id="qunit-userAgent"></h2>');
452
- test_template.push('<ol id="qunit-tests"></ol>');
453
- test_template.push('</div>');
454
-
455
- var qunit_dependencies = '<script src="' + _.tests_path +'qunit/qunit.js"></script>';
456
- $.getScript(_.tests_path + 'qunit/qunit.js');
457
- var qunit_styles = '<link rel="stylesheet" href="' + _.tests_path + 'qunit/qunit.css">';
458
- $('body').append(qunit_styles);
459
- $('body').append(test_template.join("\n"));
460
-
461
- this.tests.each(function(test) {
462
- $.getScript(_.tests_path + test + '.test.js', function() {
463
- var test_results_dialog = $('.test-results');
464
- var height = $(window).height() - 200;
465
- var width = $(window).width() - 300;
211
+ if (browser.msie && window == top) (function(){
212
+ if (isReady) return;
466
213
  try {
467
- test_results_dialog.dialog({
468
- width: width,
469
- height: height,
470
- autoOpen: false,
471
- buttons: {
472
- "Thanks buddy": function() {
473
- test_results_dialog.dialog('close');
474
- }
475
- }
476
- });
477
- var failed = $('.failed');
478
- console.log(failed.html());
479
- test_results_dialog.dialog('open');
480
- }
481
- catch(error) {
482
- alert("Test harness requires jQueryUI");
214
+ document.documentElement.doScroll("left");
215
+ } catch(error) {
216
+ setTimeout(arguments.callee, 0);
217
+ return;
483
218
  }
219
+ domReady();
220
+ })();
221
+
222
+ if (browser.opera) {
223
+ document.addEventListener( "DOMContentLoaded", function () {
224
+ if (isReady) return;
225
+ for (var i = 0; i < document.styleSheets.length; i++)
226
+ if (document.styleSheets[i].disabled) {
227
+ setTimeout( arguments.callee, 0 );
228
+ return;
229
+ }
230
+ domReady();
231
+ }, false);
232
+ }
233
+
234
+ if (browser.safari) {
235
+ var numStyles;
236
+ (function(){
237
+ if (isReady) return;
238
+ if (document.readyState != "loaded" && document.readyState != "complete") {
239
+ setTimeout( arguments.callee, 0 );
240
+ return;
241
+ }
242
+ if (numStyles === undefined) {
243
+ var links = document.getElementsByTagName("link");
244
+ for (var i=0; i < links.length; i++) {
245
+ if (links[i].getAttribute('rel') == 'stylesheet') {
246
+ numStyles++;
247
+ }
248
+ }
249
+ var styles = document.getElementsByTagName("style");
250
+ numStyles += styles.length;
251
+ }
252
+ if (document.styleSheets.length != numStyles) {
253
+ setTimeout( arguments.callee, 0 );
254
+ return;
255
+ }
256
+
257
+ domReady();
258
+ })();
259
+ }
260
+
261
+ addLoadEvent(domReady);
262
+ };
263
+
264
+ window.NinjsDOM = function() {
265
+ this.cached_selectors = {};
266
+ };
267
+
268
+ NinjsDOM.method('ready', function(fn, args) {
269
+ bindReady();
270
+
271
+ if (isReady) {
272
+ fn.call(window, []);
273
+ }
274
+ else {
275
+ readyList.push( function() { return fn.call(window, []); } );
276
+ }
277
+ });
278
+
279
+ bindReady();
280
+ window.NinjsModule = function(name) {
281
+ this.dom = new NinjsDOM(this);
282
+ this.browser = browser;
283
+ this.data = {};
284
+ this.name = name;
285
+ this.run_tests = false;
286
+ this.tests = [];
287
+ };
288
+
289
+ NinjsModule.method('actions', function() {});
290
+
291
+ NinjsModule.method('run', function() {
292
+ var mod = this;
293
+ this.dom.ready(function() {
294
+ mod.execute();
484
295
  });
485
296
  });
486
- });
487
- /*
488
- File: application.js
489
297
 
490
- Class: NinjsApplication
491
- An NinjsApplication object serves as your application's namespace and includes a utility to add modules to the application object.
298
+ NinjsModule.method('execute', function() {
299
+ if (this.run_tests) {
300
+ this._run_tests();
301
+ }
492
302
 
493
- See Also:
494
- <NinjsModule>
495
- */
303
+ this.actions();
304
+ });
496
305
 
497
- var NinjsApplication = function(base_url, tests_path) {
498
- if(is_defined(tests_path)) {
499
- this.tests_path = tests_path;
500
- }
306
+ NinjsModule.method('elements', function(elements) {
307
+ if (is_undefined(elements)) {
308
+ if (is_typeof(Object, elements)) {
309
+ throw new SyntaxError("NinjsModule.elements(elements): elements is undefined");
310
+ }
311
+ else if (is_string(elements)) {
312
+ throw new SyntaxError("NinjsModule.elements(name): name is undefined");
313
+ }
314
+ }
501
315
 
502
- if(is_defined(base_url)) {
503
- this.site_url = function(path) {
504
- var path = path || '';
505
- return base_url + path;
506
- };
507
- }
508
- };
316
+ if (is_string(elements)) {
317
+ var name = elements;
318
+ return this.dom.cached_selectors[name];
319
+ }
320
+ else {
321
+ var dom = this.dom;
322
+ dom.ready(function() {
323
+ for(var key in elements) {
324
+ if (elements.hasOwnProperty(key)) {
325
+ dom.cached_selectors[key] = elements[key];
326
+ }
327
+ }
328
+ });
329
+ }
330
+ });
509
331
 
510
- /*
511
- Method: add_module
512
- Adds a NinjsModule to the application.
332
+ NinjsModule.method('set_data', function(key, value) {
333
+ if (is_undefined(key)) {
334
+ throw new SyntaxError('NinjsModule.set_data(key, value): key is undefined');
335
+ }
513
336
 
514
- Parameters:
515
- name - the name of the module
337
+ if (is_typeof(String, key) && is_undefined(value)) {
338
+ throw new SyntaxError('NinjsModule.set_data(key, value): value is undefined');
339
+ }
516
340
 
517
- > myapp.add_module('my_module');
518
- */
519
- NinjsApplication.method('add_module', function(name) {
520
- if (is_undefined(name)) {
521
- throw new SyntaxError("NinjsApplication.add_module(name): name is undefined");
522
- }
341
+ if (is_typeof(String, key)) {
342
+ this.data[key] = value;
343
+ }
344
+ else if (is_typeof(Object, key)) {
345
+ var data = key;
346
+ for(var property in data) {
347
+ this.data[property] = data[property];
348
+ }
349
+ }
523
350
 
524
- if (is_defined(this[name])) {
525
- throw new SyntaxError("NinjsApplication.add_module(name): '" + name + "' already declared");
526
- }
351
+ return this;
352
+ });
527
353
 
528
- if (this.name === name) {
529
- throw new SyntaxError("NinjsApplication.add_module(name): a module cannot have the same name as the application");
530
- }
354
+ NinjsModule.method('add_test', function(test_file) {
355
+ this.tests.push(test_file);
356
+ });
531
357
 
532
- return this[name] = new NinjsModule(name);
533
- });
358
+ NinjsModule.method('_run_tests', function() {
359
+ var test_template = [];
360
+ test_template.push('<div class="test-results" title="Test Results">');
361
+ test_template.push('<h1 id="qunit-header">' + this.name + ' module tests</h1>');
362
+ test_template.push('<h2 id="qunit-banner"></h2>');
363
+ test_template.push('<h2 id="qunit-userAgent"></h2>');
364
+ test_template.push('<ol id="qunit-tests"></ol>');
365
+ test_template.push('</div>');
366
+
367
+ var qunit_dependencies = '<script src="' + _.tests_path +'qunit/qunit.js"></script>';
368
+ $.getScript(_.tests_path + 'qunit/qunit.js');
369
+ var qunit_styles = '<link rel="stylesheet" href="' + _.tests_path + 'qunit/qunit.css">';
370
+ $('body').append(qunit_styles);
371
+ $('body').append(test_template.join("\n"));
372
+
373
+ this.tests.each(function(test) {
374
+ $.getScript(_.tests_path + test + '.test.js', function() {
375
+ var test_results_dialog = $('.test-results');
376
+ var height = $(window).height() - 200;
377
+ var width = $(window).width() - 300;
378
+ try {
379
+ test_results_dialog.dialog({
380
+ width: width,
381
+ height: height,
382
+ autoOpen: false,
383
+ buttons: {
384
+ "Thanks buddy": function() {
385
+ test_results_dialog.dialog('close');
386
+ }
387
+ }
388
+ });
389
+ var failed = $('.failed');
390
+ console.log(failed.html());
391
+ test_results_dialog.dialog('open');
392
+ }
393
+ catch(error) {
394
+ alert("Test harness requires jQueryUI");
395
+ }
396
+ });
397
+ });
398
+ });
399
+
400
+ window.NinjsApplication = function(base_url, tests_path) {
401
+ if(is_defined(tests_path)) {
402
+ this.tests_path = tests_path;
403
+ }
404
+
405
+ if(is_defined(base_url)) {
406
+ this.site_url = function(path) {
407
+ var path = path || '';
408
+ return base_url + path;
409
+ };
410
+ }
411
+ };
412
+
413
+ NinjsApplication.method('add_module', function(name) {
414
+ if (is_undefined(name)) {
415
+ throw new SyntaxError("NinjsApplication.add_module(name): name is undefined");
416
+ }
417
+
418
+ if (is_defined(this[name])) {
419
+ throw new SyntaxError("NinjsApplication.add_module(name): '" + name + "' already declared");
420
+ }
421
+
422
+ if (this.name === name) {
423
+ throw new SyntaxError("NinjsApplication.add_module(name): a module cannot have the same name as the application");
424
+ }
425
+
426
+ return this[name] = new NinjsModule(name);
427
+ });
428
+ })();
534
429
 
535
430
  var myapp = new NinjsApplication();