batman-rails 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -2
- data/lib/batman/rails/version.rb +2 -2
- data/lib/generators/batman/install_generator.rb +46 -12
- data/lib/generators/batman/templates/batman_app.coffee +4 -5
- data/test/fixtures/application.js.coffee +9 -0
- data/test/install_generator_test.rb +51 -28
- data/vendor/assets/javascripts/batman/batman.js +778 -268
- metadata +24 -52
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Batman-Rails
|
2
2
|
|
3
|
-
Easily setup and use batman.js (0.
|
3
|
+
Easily setup and use batman.js (0.7.5) with rails 3.1
|
4
4
|
|
5
5
|
## Rails 3.1 setup
|
6
6
|
This gem requires the use of rails 3.1, coffeescript and the new rails asset pipeline provided by sprockets.
|
@@ -70,4 +70,3 @@ Install the gem and generate scaffolding.
|
|
70
70
|
|
71
71
|
You now have installed the batman-rails gem, setup a default directory structure for your frontend batman code.
|
72
72
|
Then you generated the usual rails server side crud scaffolding and finally generated batman.js code to provide a simple single page crud app.
|
73
|
-
You have one last step:
|
data/lib/batman/rails/version.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'generators/batman/common'
|
2
|
+
|
2
3
|
module Batman
|
3
4
|
module Generators
|
4
5
|
class InstallGenerator < ::Rails::Generators::Base
|
@@ -25,10 +26,49 @@ module Batman
|
|
25
26
|
|
26
27
|
def inject_batman
|
27
28
|
with_app_name do
|
28
|
-
|
29
|
+
application_file = File.join(js_path, "application.js")
|
30
|
+
file_type = :javascript
|
31
|
+
pattern = /\/\/=(?!.*\/\/=).*?$/m
|
32
|
+
|
33
|
+
unless exists?(application_file)
|
34
|
+
application_file = "#{application_file}.coffee"
|
35
|
+
file_type = :coffeescript
|
36
|
+
pattern = /#=(?!.*#=).*?$/m
|
37
|
+
end
|
38
|
+
|
39
|
+
raise Thor::Error, "Couldn't find either application.js or application.js.coffee files for use with batman!" unless exists?(application_file)
|
40
|
+
|
41
|
+
inject_into_file application_file, :before=>pattern do
|
42
|
+
batman_requires(file_type)
|
43
|
+
end
|
44
|
+
|
45
|
+
inject_into_file application_file, :after=>pattern do
|
46
|
+
ready_function(file_type)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
29
50
|
|
30
|
-
|
51
|
+
private
|
52
|
+
|
53
|
+
def ready_function(file_type=:javascript)
|
54
|
+
if file_type == :coffeescript
|
55
|
+
<<-CODE
|
56
|
+
\n# Run the Batman app
|
57
|
+
$(document).ready ->
|
58
|
+
#{js_app_name}.run()
|
59
|
+
CODE
|
60
|
+
else
|
31
61
|
<<-CODE
|
62
|
+
\n// Run the Batman app
|
63
|
+
$(document).ready(function(){
|
64
|
+
#{js_app_name}.run();
|
65
|
+
});
|
66
|
+
CODE
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def batman_requires(file_type=:javascript)
|
71
|
+
code = <<-CODE
|
32
72
|
\n// Batman.js and its adapters
|
33
73
|
//= require batman/batman
|
34
74
|
//= require batman/batman.jquery
|
@@ -41,17 +81,11 @@ module Batman
|
|
41
81
|
//= require_tree ./helpers
|
42
82
|
\n
|
43
83
|
CODE
|
44
|
-
|
84
|
+
file_type == :coffeescript ? code.gsub('//', '#') : code
|
85
|
+
end
|
45
86
|
|
46
|
-
|
47
|
-
|
48
|
-
\n// Run the Batman app
|
49
|
-
$(document).ready(function(){
|
50
|
-
#{js_app_name}.run();
|
51
|
-
});
|
52
|
-
CODE
|
53
|
-
end
|
54
|
-
end
|
87
|
+
def exists?(file)
|
88
|
+
File.exist?(File.join(destination_root, file))
|
55
89
|
end
|
56
90
|
end
|
57
91
|
end
|
@@ -3,12 +3,11 @@ window.<%= js_app_name %> = class <%= js_app_name %> extends Batman.App
|
|
3
3
|
# @root 'controller#all'
|
4
4
|
# @route '/controller/:id', 'controller#show', resource: 'model', action: 'show'
|
5
5
|
|
6
|
-
@run ->
|
7
|
-
console
|
8
|
-
true
|
6
|
+
@on 'run', ->
|
7
|
+
console?.log "Running ...."
|
9
8
|
|
10
|
-
@ready ->
|
11
|
-
console
|
9
|
+
@on 'ready', ->
|
10
|
+
console?.log "<%= js_app_name %> ready for use."
|
12
11
|
|
13
12
|
@flash: Batman()
|
14
13
|
@flash.accessor
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# This is a manifest file that'll be compiled into including all the files listed below.
|
2
|
+
# Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
|
3
|
+
# be included in the compiled file accessible from http://example.com/assets/application.js
|
4
|
+
# It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
5
|
+
# the compiled file.
|
6
|
+
#
|
7
|
+
#= require jquery
|
8
|
+
#= require jquery_ujs
|
9
|
+
#= require_tree .
|
@@ -2,75 +2,78 @@ require 'mocha'
|
|
2
2
|
require 'test_helper'
|
3
3
|
require 'generators/batman/install_generator'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
module InstallGeneratorTests
|
6
|
+
|
8
7
|
def setup
|
9
8
|
mkdir_p "#{destination_root}/app/assets/javascripts"
|
10
|
-
cp fixture(
|
9
|
+
cp fixture(application_javascript_path), "#{destination_root}/app/assets/javascripts"
|
11
10
|
Rails.application.class.stubs(:name).returns("Dummy::Application")
|
12
|
-
|
13
11
|
super
|
14
12
|
end
|
15
13
|
|
16
|
-
|
14
|
+
def teardown
|
15
|
+
Rails.application.class.unstub(:name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_batman_application_file_is_created
|
17
19
|
run_generator
|
18
|
-
|
20
|
+
|
19
21
|
assert_file "#{javascripts_path}/dummy.js.coffee" do |app|
|
20
22
|
assert_match /window\.Dummy = class Dummy extends Batman\.App/, app
|
21
|
-
assert_match /@
|
23
|
+
assert_match /@on 'ready', ->/, app
|
24
|
+
assert_match /@on 'run', ->/, app
|
22
25
|
end
|
23
26
|
end
|
24
|
-
|
25
|
-
|
27
|
+
|
28
|
+
def test_batman_application_file_is_created_for_two_word_application_name
|
26
29
|
Rails.application.class.stubs(:name).returns("FooBar::Application")
|
27
30
|
run_generator
|
28
|
-
|
31
|
+
|
29
32
|
assert_file "#{javascripts_path}/foo_bar.js.coffee" do |app|
|
30
33
|
assert_match /window\.FooBar = class FooBar extends Batman\.App/, app
|
31
34
|
end
|
32
35
|
end
|
33
|
-
|
34
|
-
|
36
|
+
|
37
|
+
def test_application_require_is_properly_setup_for_two_word_application_name
|
35
38
|
Rails.application.class.stubs(:name).returns("FooBar::Application")
|
36
39
|
run_generator
|
37
|
-
|
38
|
-
assert_file "#{javascripts_path}
|
40
|
+
|
41
|
+
assert_file "#{javascripts_path}/#{application_javascript_path}", /require foo_bar/
|
39
42
|
end
|
40
|
-
|
41
|
-
|
43
|
+
|
44
|
+
def test_batman_directory_structure_is_created
|
42
45
|
run_generator
|
43
|
-
|
46
|
+
|
44
47
|
%W{controllers models helpers}.each do |dir|
|
45
48
|
assert_directory "#{javascripts_path}/#{dir}"
|
46
49
|
assert_file "#{javascripts_path}/#{dir}/.gitkeep"
|
47
50
|
end
|
48
51
|
end
|
49
|
-
|
50
|
-
|
52
|
+
|
53
|
+
def test_no_gitkeep_files_are_created_when_skipping_git
|
51
54
|
run_generator [destination_root, "--skip-git"]
|
52
|
-
|
55
|
+
|
53
56
|
%W{controllers models helpers}.each do |dir|
|
54
57
|
assert_directory "#{javascripts_path}/#{dir}"
|
55
58
|
assert_no_file "#{javascripts_path}/#{dir}/.gitkeep"
|
56
59
|
end
|
57
60
|
end
|
58
|
-
|
59
|
-
|
61
|
+
|
62
|
+
def test_applicationjs_require_batman_jquery_rails_and_dummy
|
60
63
|
run_generator
|
61
|
-
|
62
|
-
assert_file "#{javascripts_path}
|
64
|
+
|
65
|
+
assert_file "#{javascripts_path}/#{application_javascript_path}" do |app|
|
63
66
|
%W{batman batman.jquery batman.rails}.each do |require|
|
64
|
-
|
67
|
+
assert_equal 1, app.scan(%r{require batman\/#{require}$}).length
|
65
68
|
end
|
66
69
|
|
67
70
|
assert_match /require dummy/, app
|
68
71
|
|
69
72
|
%W{models controllers helpers}.each do |require|
|
70
|
-
|
73
|
+
assert_equal 1, app.scan(/require_tree \.\/#{require}/).length
|
71
74
|
end
|
72
75
|
|
73
|
-
|
76
|
+
assert_equal 1, app.scan(/Dummy\.run\(\)/).length
|
74
77
|
end
|
75
78
|
end
|
76
79
|
|
@@ -80,3 +83,23 @@ class InstallGeneratorTest < Rails::Generators::TestCase
|
|
80
83
|
File.expand_path("fixtures/#{file}", File.dirname(__FILE__))
|
81
84
|
end
|
82
85
|
end
|
86
|
+
|
87
|
+
class InstallGeneratorWithApplicationJavascriptTest < Rails::Generators::TestCase
|
88
|
+
tests Batman::Generators::InstallGenerator
|
89
|
+
|
90
|
+
def application_javascript_path
|
91
|
+
"application.js"
|
92
|
+
end
|
93
|
+
|
94
|
+
include InstallGeneratorTests
|
95
|
+
end
|
96
|
+
|
97
|
+
class InstallGeneratorWithApplicationCoffeescriptTest < Rails::Generators::TestCase
|
98
|
+
tests Batman::Generators::InstallGenerator
|
99
|
+
|
100
|
+
def application_javascript_path
|
101
|
+
"application.js.coffee"
|
102
|
+
end
|
103
|
+
|
104
|
+
include InstallGeneratorTests
|
105
|
+
end
|
@@ -1,6 +1,11 @@
|
|
1
1
|
(function() {
|
2
|
-
var $addEventListener, $block, $extendsEnumerable, $findName, $functionName, $get, $hasAddEventListener, $isChildOf, $mixin, $passError, $preventDefault, $redirect, $removeEventListener, $removeNode, $setInnerHTML, $typeOf, $unbindNode, $unbindTree, $unmixin, Batman, BatmanObject, Binding, Validators, buntUndefined, camelize_rx, capitalize_rx, container, developer, div, filters, helpers, isEmptyDataObject, k, mixins, t, underscore_rx1, underscore_rx2, _Batman, _i, _len, _objectToString, _ref, _stateMachine_setState;
|
3
|
-
var __slice = Array.prototype.slice, __hasProp = Object.prototype.hasOwnProperty,
|
2
|
+
var $addEventListener, $appendChild, $block, $clearImmediate, $extendsEnumerable, $findName, $functionName, $get, $hasAddEventListener, $isChildOf, $mixin, $passError, $preventDefault, $redirect, $removeEventListener, $removeNode, $setImmediate, $setInnerHTML, $trackBinding, $typeOf, $unbindNode, $unbindTree, $unmixin, Batman, BatmanObject, Binding, Validators, buntUndefined, camelize_rx, capitalize_rx, container, developer, div, filters, helpers, isEmptyDataObject, k, mixins, t, underscore_rx1, underscore_rx2, _Batman, _i, _implementImmediates, _len, _objectToString, _ref, _stateMachine_setState;
|
3
|
+
var __slice = Array.prototype.slice, __hasProp = Object.prototype.hasOwnProperty, __indexOf = Array.prototype.indexOf || function(item) {
|
4
|
+
for (var i = 0, l = this.length; i < l; i++) {
|
5
|
+
if (this[i] === item) return i;
|
6
|
+
}
|
7
|
+
return -1;
|
8
|
+
}, __extends = function(child, parent) {
|
4
9
|
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
|
5
10
|
function ctor() { this.constructor = child; }
|
6
11
|
ctor.prototype = parent.prototype;
|
@@ -133,6 +138,97 @@
|
|
133
138
|
}
|
134
139
|
return false;
|
135
140
|
};
|
141
|
+
_implementImmediates = function() {
|
142
|
+
var $clearImmediate, $setImmediate, canUsePostMessage, count, functions, getHandle, handler, prefix, tasks;
|
143
|
+
canUsePostMessage = function() {
|
144
|
+
var async, oldMessage;
|
145
|
+
if (!container.postMessage) {
|
146
|
+
return false;
|
147
|
+
}
|
148
|
+
async = true;
|
149
|
+
oldMessage = container.onmessage;
|
150
|
+
container.onmessage = function() {
|
151
|
+
return async = false;
|
152
|
+
};
|
153
|
+
container.postMessage("", "*");
|
154
|
+
container.onmessage = oldMessage;
|
155
|
+
return async;
|
156
|
+
};
|
157
|
+
tasks = new Batman.SimpleHash;
|
158
|
+
count = 0;
|
159
|
+
getHandle = function() {
|
160
|
+
return "go" + (++count);
|
161
|
+
};
|
162
|
+
if (container.setImmediate) {
|
163
|
+
$setImmediate = container.setImmediate;
|
164
|
+
$clearImmediate = container.clearImmediate;
|
165
|
+
} else if (container.msSetImmediate) {
|
166
|
+
$setImmediate = msSetImmediate;
|
167
|
+
$clearImmediate = msClearImmediate;
|
168
|
+
} else if (canUsePostMessage()) {
|
169
|
+
prefix = 'com.batman.';
|
170
|
+
functions = new Batman.SimpleHash;
|
171
|
+
handler = function(e) {
|
172
|
+
var handle, _base;
|
173
|
+
if (!~e.data.search(prefix)) {
|
174
|
+
return;
|
175
|
+
}
|
176
|
+
handle = e.data.substring(prefix.length);
|
177
|
+
return typeof (_base = tasks.unset(handle)) === "function" ? _base() : void 0;
|
178
|
+
};
|
179
|
+
if (container.addEventListener) {
|
180
|
+
container.addEventListener('message', handler, false);
|
181
|
+
} else {
|
182
|
+
container.attachEvent('onmessage', handler);
|
183
|
+
}
|
184
|
+
$setImmediate = function(f) {
|
185
|
+
var handle;
|
186
|
+
tasks.set(handle = getHandle(), f);
|
187
|
+
container.postMessage(prefix + handle, "*");
|
188
|
+
return handle;
|
189
|
+
};
|
190
|
+
$clearImmediate = function(handle) {
|
191
|
+
return tasks.unset(handle);
|
192
|
+
};
|
193
|
+
} else if (typeof document !== 'undefined' && __indexOf.call(document.createElement("script"), "onreadystatechange") >= 0) {
|
194
|
+
$setImmediate = function(f) {
|
195
|
+
var handle, script;
|
196
|
+
handle = getHandle();
|
197
|
+
script = document.createElement("script");
|
198
|
+
script.onreadystatechange = function() {
|
199
|
+
var _base;
|
200
|
+
if (typeof (_base = tasks.get(handle)) === "function") {
|
201
|
+
_base();
|
202
|
+
}
|
203
|
+
script.onreadystatechange = null;
|
204
|
+
script.parentNode.removeChild(script);
|
205
|
+
return script = null;
|
206
|
+
};
|
207
|
+
document.documentElement.appendChild(script);
|
208
|
+
return handle;
|
209
|
+
};
|
210
|
+
$clearImmediate = function(handle) {
|
211
|
+
return tasks.unset(handle);
|
212
|
+
};
|
213
|
+
} else {
|
214
|
+
$setImmediate = function(f) {
|
215
|
+
return setTimeout(f, 0);
|
216
|
+
};
|
217
|
+
$clearImmediate = function(handle) {
|
218
|
+
return clearTimeout(handle);
|
219
|
+
};
|
220
|
+
}
|
221
|
+
Batman.setImmediate = $setImmediate;
|
222
|
+
return Batman.clearImmediate = $clearImmediate;
|
223
|
+
};
|
224
|
+
Batman.setImmediate = $setImmediate = function() {
|
225
|
+
_implementImmediates();
|
226
|
+
return Batman.setImmediate.apply(this, arguments);
|
227
|
+
};
|
228
|
+
Batman.clearImmediate = $clearImmediate = function() {
|
229
|
+
_implementImmediates();
|
230
|
+
return Batman.clearImmediate.apply(this, arguments);
|
231
|
+
};
|
136
232
|
Batman.translate = function(x, values) {
|
137
233
|
if (values == null) {
|
138
234
|
values = {};
|
@@ -231,6 +327,7 @@
|
|
231
327
|
}
|
232
328
|
};
|
233
329
|
Batman.developer = developer;
|
330
|
+
developer.assert((function() {}).bind, "Error! Batman needs Function.bind to work! Please shim it using something like es5-shim or augmentjs!");
|
234
331
|
camelize_rx = /(?:^|_|\-)(.)/g;
|
235
332
|
capitalize_rx = /(^|\s)([a-z])/g;
|
236
333
|
underscore_rx1 = /([A-Z]+)([A-Z][a-z])/g;
|
@@ -351,7 +448,7 @@
|
|
351
448
|
key = this.key;
|
352
449
|
return this.base._batman.ancestors(function(ancestor) {
|
353
450
|
var handlers;
|
354
|
-
if (ancestor.isEventEmitter) {
|
451
|
+
if (ancestor.isEventEmitter && ancestor.hasEvent(key)) {
|
355
452
|
handlers = ancestor.event(key).handlers;
|
356
453
|
return handlers.forEach(iterator);
|
357
454
|
}
|
@@ -401,13 +498,17 @@
|
|
401
498
|
})();
|
402
499
|
Batman.EventEmitter = {
|
403
500
|
isEventEmitter: true,
|
501
|
+
hasEvent: function(key) {
|
502
|
+
var _ref, _ref2;
|
503
|
+
return (_ref = this._batman) != null ? typeof _ref.get === "function" ? (_ref2 = _ref.get('events')) != null ? _ref2.hasKey(key) : void 0 : void 0 : void 0;
|
504
|
+
},
|
404
505
|
event: function(key) {
|
405
506
|
var eventClass, events, existingEvent, existingEvents, newEvent, _base, _ref;
|
406
507
|
Batman.initializeObject(this);
|
407
508
|
eventClass = this.eventClass || Batman.Event;
|
408
509
|
events = (_base = this._batman).events || (_base.events = new Batman.SimpleHash);
|
409
|
-
if (
|
410
|
-
return existingEvent;
|
510
|
+
if (events.hasKey(key)) {
|
511
|
+
return existingEvent = events.get(key);
|
411
512
|
} else {
|
412
513
|
existingEvents = this._batman.get('events');
|
413
514
|
newEvent = events.set(key, new eventClass(this, key));
|
@@ -538,7 +639,7 @@
|
|
538
639
|
if (this.base.isObservable) {
|
539
640
|
return this.base._batman.ancestors(function(ancestor) {
|
540
641
|
var handlers, property;
|
541
|
-
if (ancestor.isObservable) {
|
642
|
+
if (ancestor.isObservable && ancestor.hasProperty(key)) {
|
542
643
|
property = ancestor.property(key);
|
543
644
|
handlers = property.event('change').handlers;
|
544
645
|
return handlers.forEach(iterator);
|
@@ -549,9 +650,15 @@
|
|
549
650
|
Property.prototype.pushSourceTracker = function() {
|
550
651
|
return Batman.Property._sourceTrackerStack.push(new Batman.SimpleSet);
|
551
652
|
};
|
653
|
+
Property.prototype.pushDummySourceTracker = function() {
|
654
|
+
return Batman.Property._sourceTrackerStack.push(null);
|
655
|
+
};
|
656
|
+
Property.prototype.popSourceTracker = function() {
|
657
|
+
return Batman.Property._sourceTrackerStack.pop();
|
658
|
+
};
|
552
659
|
Property.prototype.updateSourcesFromTracker = function() {
|
553
660
|
var handler, newSources;
|
554
|
-
newSources =
|
661
|
+
newSources = this.popSourceTracker();
|
555
662
|
handler = this.sourceChangeHandler();
|
556
663
|
this._eachSourceChangeEvent(function(e) {
|
557
664
|
return e.removeHandler(handler);
|
@@ -613,15 +720,19 @@
|
|
613
720
|
};
|
614
721
|
Property.prototype.setValue = function(val) {
|
615
722
|
var result, _ref;
|
723
|
+
this.pushDummySourceTracker();
|
616
724
|
this.cached = false;
|
617
725
|
result = (_ref = this.accessor().set) != null ? _ref.call(this.base, this.key, val) : void 0;
|
618
726
|
this.refresh();
|
727
|
+
this.popSourceTracker();
|
619
728
|
return result;
|
620
729
|
};
|
621
730
|
Property.prototype.unsetValue = function() {
|
622
731
|
var result, _ref;
|
732
|
+
this.pushDummySourceTracker();
|
623
733
|
result = (_ref = this.accessor().unset) != null ? _ref.call(this.base, this.key) : void 0;
|
624
734
|
this.refresh();
|
735
|
+
this.popSourceTracker();
|
625
736
|
return result;
|
626
737
|
};
|
627
738
|
Property.prototype.forget = function(handler) {
|
@@ -640,6 +751,14 @@
|
|
640
751
|
this.getValue();
|
641
752
|
return this;
|
642
753
|
};
|
754
|
+
Property.prototype.removeSourceHandlers = function() {
|
755
|
+
var handler;
|
756
|
+
handler = this.sourceChangeHandler();
|
757
|
+
this._eachSourceChangeEvent(function(e) {
|
758
|
+
return e.removeHandler(handler);
|
759
|
+
});
|
760
|
+
return this.forget();
|
761
|
+
};
|
643
762
|
Property.prototype.fire = function() {
|
644
763
|
var _ref;
|
645
764
|
return (_ref = this.changeEvent()).fire.apply(_ref, arguments);
|
@@ -727,6 +846,10 @@
|
|
727
846
|
})();
|
728
847
|
Batman.Observable = {
|
729
848
|
isObservable: true,
|
849
|
+
hasProperty: function(key) {
|
850
|
+
var _ref, _ref2;
|
851
|
+
return (_ref = this._batman) != null ? (_ref2 = _ref.properties) != null ? typeof _ref2.hasKey === "function" ? _ref2.hasKey(key) : void 0 : void 0 : void 0;
|
852
|
+
},
|
730
853
|
property: function(key) {
|
731
854
|
var properties, propertyClass, _base;
|
732
855
|
Batman.initializeObject(this);
|
@@ -914,7 +1037,7 @@
|
|
914
1037
|
for (key in this) {
|
915
1038
|
if (!__hasProp.call(this, key)) continue;
|
916
1039
|
value = this[key];
|
917
|
-
if (key !== "_batman") {
|
1040
|
+
if (key !== "_batman" && key !== "hashKey" && key !== "_objectID") {
|
918
1041
|
obj[key] = value.toJSON ? value.toJSON() : value;
|
919
1042
|
}
|
920
1043
|
}
|
@@ -1121,12 +1244,16 @@
|
|
1121
1244
|
return val;
|
1122
1245
|
};
|
1123
1246
|
SimpleHash.prototype.unset = function(key) {
|
1124
|
-
var index, obj, pair, pairs, value, _len, _ref;
|
1125
|
-
|
1247
|
+
var hashKey, index, obj, pair, pairs, value, _len, _ref;
|
1248
|
+
hashKey = this.hashKeyFor(key);
|
1249
|
+
if (pairs = this._storage[hashKey]) {
|
1126
1250
|
for (index = 0, _len = pairs.length; index < _len; index++) {
|
1127
1251
|
_ref = pairs[index], obj = _ref[0], value = _ref[1];
|
1128
1252
|
if (this.equality(obj, key)) {
|
1129
1253
|
pair = pairs.splice(index, 1);
|
1254
|
+
if (!pairs.length) {
|
1255
|
+
delete this._storage[hashKey];
|
1256
|
+
}
|
1130
1257
|
this.length--;
|
1131
1258
|
return pair[0][1];
|
1132
1259
|
}
|
@@ -1425,8 +1552,8 @@
|
|
1425
1552
|
__extends(SetObserver, Batman.Object);
|
1426
1553
|
function SetObserver(base) {
|
1427
1554
|
this.base = base;
|
1428
|
-
this._itemObservers = new Batman.
|
1429
|
-
this._setObservers = new Batman.
|
1555
|
+
this._itemObservers = new Batman.SimpleHash;
|
1556
|
+
this._setObservers = new Batman.SimpleHash;
|
1430
1557
|
this._setObservers.set("itemsWereAdded", __bind(function() {
|
1431
1558
|
return this.fire.apply(this, ['itemsWereAdded'].concat(__slice.call(arguments)));
|
1432
1559
|
}, this));
|
@@ -1441,7 +1568,7 @@
|
|
1441
1568
|
SetObserver.prototype._getOrSetObserverForItemAndKey = function(item, key) {
|
1442
1569
|
return this._itemObservers.getOrSet(item, __bind(function() {
|
1443
1570
|
var observersByKey;
|
1444
|
-
observersByKey = new Batman.
|
1571
|
+
observersByKey = new Batman.SimpleHash;
|
1445
1572
|
return observersByKey.getOrSet(key, __bind(function() {
|
1446
1573
|
return this.observerForItemAndKey(item, key);
|
1447
1574
|
}, this));
|
@@ -1679,7 +1806,7 @@
|
|
1679
1806
|
this.base = base;
|
1680
1807
|
this.key = key;
|
1681
1808
|
SetIndex.__super__.constructor.call(this);
|
1682
|
-
this._storage = new Batman.
|
1809
|
+
this._storage = new Batman.SimpleHash;
|
1683
1810
|
if (this.base.isEventEmitter) {
|
1684
1811
|
this._setObserver = new Batman.SetObserver(this.base);
|
1685
1812
|
this._setObserver.observedItemKeys = [this.key];
|
@@ -1735,7 +1862,12 @@
|
|
1735
1862
|
return this._removeItemFromKey(item, this._keyForItem(item));
|
1736
1863
|
};
|
1737
1864
|
SetIndex.prototype._removeItemFromKey = function(item, key) {
|
1738
|
-
|
1865
|
+
var results;
|
1866
|
+
results = this._resultSetForKey(key);
|
1867
|
+
results.remove(item);
|
1868
|
+
if (results.isEmpty()) {
|
1869
|
+
return this._storage.unset(key);
|
1870
|
+
}
|
1739
1871
|
};
|
1740
1872
|
SetIndex.prototype._resultSetForKey = function(key) {
|
1741
1873
|
return this._storage.getOrSet(key, function() {
|
@@ -1765,8 +1897,8 @@
|
|
1765
1897
|
UniqueSetIndex.prototype._removeItemFromKey = function(item, key) {
|
1766
1898
|
var resultSet;
|
1767
1899
|
resultSet = this._resultSetForKey(key);
|
1768
|
-
|
1769
|
-
if (resultSet.
|
1900
|
+
UniqueSetIndex.__super__._removeItemFromKey.apply(this, arguments);
|
1901
|
+
if (resultSet.isEmpty()) {
|
1770
1902
|
return this._uniqueIndex.unset(key);
|
1771
1903
|
} else {
|
1772
1904
|
return this._uniqueIndex.set(key, resultSet.toArray()[0]);
|
@@ -1915,9 +2047,9 @@
|
|
1915
2047
|
}
|
1916
2048
|
}
|
1917
2049
|
Request.observeAll('url', function() {
|
1918
|
-
return this._autosendTimeout =
|
2050
|
+
return this._autosendTimeout = $setImmediate(__bind(function() {
|
1919
2051
|
return this.send();
|
1920
|
-
}, this))
|
2052
|
+
}, this));
|
1921
2053
|
});
|
1922
2054
|
Request.prototype.send = function() {
|
1923
2055
|
return developer.error("Please source a dependency file for a request implementation");
|
@@ -1935,8 +2067,8 @@
|
|
1935
2067
|
App.__super__.constructor.apply(this, arguments);
|
1936
2068
|
}
|
1937
2069
|
App.requirePath = '';
|
1938
|
-
developer["do"](function() {
|
1939
|
-
|
2070
|
+
developer["do"](__bind(function() {
|
2071
|
+
App.require = function() {
|
1940
2072
|
var base, name, names, path, _i, _len;
|
1941
2073
|
path = arguments[0], names = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
1942
2074
|
base = this.requirePath + path;
|
@@ -1961,22 +2093,23 @@
|
|
1961
2093
|
}
|
1962
2094
|
return this;
|
1963
2095
|
};
|
1964
|
-
|
1965
|
-
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
1978
|
-
};
|
2096
|
+
this.controller = function() {
|
2097
|
+
var names;
|
2098
|
+
names = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
2099
|
+
names = names.map(function(n) {
|
2100
|
+
return n + '_controller';
|
2101
|
+
});
|
2102
|
+
return this.require.apply(this, ['controllers'].concat(__slice.call(names)));
|
2103
|
+
};
|
2104
|
+
this.model = function() {
|
2105
|
+
return this.require.apply(this, ['models'].concat(__slice.call(arguments)));
|
2106
|
+
};
|
2107
|
+
return this.view = function() {
|
2108
|
+
return this.require.apply(this, ['views'].concat(__slice.call(arguments)));
|
2109
|
+
};
|
2110
|
+
}, App));
|
1979
2111
|
App.layout = void 0;
|
2112
|
+
App.event('ready').oneShot = true;
|
1980
2113
|
App.event('run').oneShot = true;
|
1981
2114
|
App.run = function() {
|
1982
2115
|
if (Batman.currentApp) {
|
@@ -1998,14 +2131,18 @@
|
|
1998
2131
|
if (typeof this.dispatcher === 'undefined') {
|
1999
2132
|
this.dispatcher || (this.dispatcher = new Batman.Dispatcher(this));
|
2000
2133
|
}
|
2134
|
+
this.observe('layout', __bind(function(layout) {
|
2135
|
+
return layout != null ? layout.on('ready', __bind(function() {
|
2136
|
+
return this.fire('ready');
|
2137
|
+
}, this)) : void 0;
|
2138
|
+
}, this));
|
2001
2139
|
if (typeof this.layout === 'undefined') {
|
2002
2140
|
this.set('layout', new Batman.View({
|
2003
2141
|
contexts: [this],
|
2004
2142
|
node: document
|
2005
2143
|
}));
|
2006
|
-
|
2007
|
-
|
2008
|
-
}, this));
|
2144
|
+
} else if (typeof this.layout === 'string') {
|
2145
|
+
this.set('layout', new this[helpers.camelize(this.layout) + 'View']);
|
2009
2146
|
}
|
2010
2147
|
if (typeof this.historyManager === 'undefined' && this.dispatcher.routeMap) {
|
2011
2148
|
this.on('run', __bind(function() {
|
@@ -2030,7 +2167,7 @@
|
|
2030
2167
|
return this;
|
2031
2168
|
};
|
2032
2169
|
return App;
|
2033
|
-
})();
|
2170
|
+
}).call(this);
|
2034
2171
|
Batman.Route = (function() {
|
2035
2172
|
var escapeRegExp, namedOrSplat, namedParam, queryParam, splatParam;
|
2036
2173
|
__extends(Route, Batman.Object);
|
@@ -2181,7 +2318,7 @@
|
|
2181
2318
|
}
|
2182
2319
|
};
|
2183
2320
|
Dispatcher.prototype.findUrl = function(params) {
|
2184
|
-
var action, controller, key, matches, options, route, url, value, _ref, _ref2;
|
2321
|
+
var action, controller, key, matches, options, paramsCopy, queryString, regex, route, url, value, _ref, _ref2;
|
2185
2322
|
_ref = this.routeMap;
|
2186
2323
|
for (url in _ref) {
|
2187
2324
|
route = _ref[url];
|
@@ -2192,21 +2329,43 @@
|
|
2192
2329
|
} else {
|
2193
2330
|
action = route.get('action');
|
2194
2331
|
if (typeof action === 'function') {
|
2195
|
-
continue;
|
2196
|
-
}
|
2197
|
-
_ref2 = action, controller = _ref2.controller, action = _ref2.action;
|
2198
|
-
if (controller === params.controller && action === (params.action || 'index')) {
|
2199
2332
|
matches = true;
|
2333
|
+
} else {
|
2334
|
+
_ref2 = action, controller = _ref2.controller, action = _ref2.action;
|
2335
|
+
if (controller === params.controller && action === (params.action || 'index')) {
|
2336
|
+
matches = true;
|
2337
|
+
}
|
2200
2338
|
}
|
2201
2339
|
}
|
2202
2340
|
if (!matches) {
|
2203
2341
|
continue;
|
2204
2342
|
}
|
2343
|
+
$mixin(paramsCopy = {}, params);
|
2344
|
+
$unmixin(paramsCopy, {
|
2345
|
+
controller: null,
|
2346
|
+
action: null,
|
2347
|
+
resource: null,
|
2348
|
+
url: null,
|
2349
|
+
signature: null,
|
2350
|
+
target: null
|
2351
|
+
});
|
2205
2352
|
for (key in params) {
|
2206
2353
|
value = params[key];
|
2207
|
-
|
2354
|
+
regex = new RegExp('[:|\*]' + key);
|
2355
|
+
if (!regex.test(url)) {
|
2356
|
+
continue;
|
2357
|
+
}
|
2358
|
+
url = url.replace(regex, value);
|
2359
|
+
paramsCopy[key] = null;
|
2360
|
+
delete paramsCopy[key];
|
2361
|
+
}
|
2362
|
+
queryString = '';
|
2363
|
+
for (key in paramsCopy) {
|
2364
|
+
value = paramsCopy[key];
|
2365
|
+
queryString += !queryString ? '?' : '&';
|
2366
|
+
queryString += key + '=' + value;
|
2208
2367
|
}
|
2209
|
-
return url;
|
2368
|
+
return url + queryString;
|
2210
2369
|
}
|
2211
2370
|
};
|
2212
2371
|
Dispatcher.prototype.dispatch = function(url) {
|
@@ -2265,7 +2424,7 @@
|
|
2265
2424
|
}
|
2266
2425
|
this.first = true;
|
2267
2426
|
Batman.currentApp.prevent('ready');
|
2268
|
-
return
|
2427
|
+
return $setImmediate(this.parseHash);
|
2269
2428
|
};
|
2270
2429
|
HashHistory.prototype.stop = function() {
|
2271
2430
|
if (this.interval) {
|
@@ -2347,6 +2506,9 @@
|
|
2347
2506
|
}
|
2348
2507
|
resource = helpers.pluralize(resource);
|
2349
2508
|
controller = options.controller || resource;
|
2509
|
+
if (options.parentResource) {
|
2510
|
+
resource = "" + options.parentResource + "/:" + (helpers.singularize(options.parentResource)) + "Id/" + resource;
|
2511
|
+
}
|
2350
2512
|
if (options.index !== false) {
|
2351
2513
|
this.route(resource, "" + controller + "#index", {
|
2352
2514
|
resource: controller,
|
@@ -2387,7 +2549,18 @@
|
|
2387
2549
|
return app.route("" + resource + "/:id/" + url, "" + controller + "#" + (methodName || url));
|
2388
2550
|
}
|
2389
2551
|
}) : void 0;
|
2390
|
-
}
|
2552
|
+
},
|
2553
|
+
resources: __bind(function(childResource, options, callback) {
|
2554
|
+
if (options == null) {
|
2555
|
+
options = {};
|
2556
|
+
}
|
2557
|
+
if (typeof options === 'function') {
|
2558
|
+
callback = options;
|
2559
|
+
options = {};
|
2560
|
+
}
|
2561
|
+
options.parentResource = resource;
|
2562
|
+
return this.resources(childResource, options, callback);
|
2563
|
+
}, this)
|
2391
2564
|
};
|
2392
2565
|
return callback.call(ops);
|
2393
2566
|
}
|
@@ -2509,6 +2682,8 @@
|
|
2509
2682
|
return;
|
2510
2683
|
}
|
2511
2684
|
if (!options.view) {
|
2685
|
+
options.contexts || (options.contexts = []);
|
2686
|
+
options.contexts.push(this);
|
2512
2687
|
options.source || (options.source = helpers.underscore($functionName(this.constructor).replace('Controller', '')) + '/' + this._currentAction + '.html');
|
2513
2688
|
options.view = new Batman.View(options);
|
2514
2689
|
}
|
@@ -2516,10 +2691,9 @@
|
|
2516
2691
|
if ((_ref = Batman.currentApp) != null) {
|
2517
2692
|
_ref.prevent('ready');
|
2518
2693
|
}
|
2519
|
-
view.contexts.push(this);
|
2520
2694
|
view.on('ready', function() {
|
2521
2695
|
var _ref2, _ref3;
|
2522
|
-
Batman.DOM.replace('main', view.get('node'));
|
2696
|
+
Batman.DOM.replace(options.into || 'main', view.get('node'));
|
2523
2697
|
if ((_ref2 = Batman.currentApp) != null) {
|
2524
2698
|
_ref2.allow('ready');
|
2525
2699
|
}
|
@@ -2737,7 +2911,7 @@
|
|
2737
2911
|
Model.accessor('id', {
|
2738
2912
|
get: function() {
|
2739
2913
|
var pk;
|
2740
|
-
pk = this.constructor.
|
2914
|
+
pk = this.constructor.primaryKey;
|
2741
2915
|
if (pk === 'id') {
|
2742
2916
|
return this.id;
|
2743
2917
|
} else {
|
@@ -2749,7 +2923,7 @@
|
|
2749
2923
|
if (typeof v === "string" && !isNaN(intId = parseInt(v, 10))) {
|
2750
2924
|
v = intId;
|
2751
2925
|
}
|
2752
|
-
pk = this.constructor.
|
2926
|
+
pk = this.constructor.primaryKey;
|
2753
2927
|
if (pk === 'id') {
|
2754
2928
|
return this.id = v;
|
2755
2929
|
} else {
|
@@ -2856,6 +3030,13 @@
|
|
2856
3030
|
}
|
2857
3031
|
});
|
2858
3032
|
}
|
3033
|
+
developer["do"](function() {
|
3034
|
+
if ((!decoders) || decoders.reduce((function(sum, x) {
|
3035
|
+
return sum + x;
|
3036
|
+
}), 0) <= 1) {
|
3037
|
+
return developer.warn("Warning: Model " + (this.get('storageKey')) + " has suspiciously few decoders!");
|
3038
|
+
}
|
3039
|
+
});
|
2859
3040
|
return this.mixin(obj);
|
2860
3041
|
};
|
2861
3042
|
Model.actsAsStateMachine(true);
|
@@ -3379,6 +3560,7 @@
|
|
3379
3560
|
RestStorage.prototype.serializeAsForm = true;
|
3380
3561
|
function RestStorage() {
|
3381
3562
|
RestStorage.__super__.constructor.apply(this, arguments);
|
3563
|
+
this.defaultOptions = $mixin({}, this.defaultOptions);
|
3382
3564
|
this.recordJsonNamespace = helpers.singularize(this.modelKey);
|
3383
3565
|
this.collectionJsonNamespace = helpers.pluralize(this.modelKey);
|
3384
3566
|
}
|
@@ -3567,63 +3749,93 @@
|
|
3567
3749
|
};
|
3568
3750
|
return RestStorage;
|
3569
3751
|
})();
|
3752
|
+
Batman.ViewSourceCache = (function() {
|
3753
|
+
__extends(ViewSourceCache, Batman.Object);
|
3754
|
+
function ViewSourceCache() {
|
3755
|
+
ViewSourceCache.__super__.constructor.apply(this, arguments);
|
3756
|
+
this.sources = {};
|
3757
|
+
this.requests = {};
|
3758
|
+
}
|
3759
|
+
ViewSourceCache.prototype.propertyClass = Batman.Property;
|
3760
|
+
ViewSourceCache.accessor({
|
3761
|
+
get: function(k) {
|
3762
|
+
var url;
|
3763
|
+
if (this.sources[k] != null) {
|
3764
|
+
return this.sources[k];
|
3765
|
+
}
|
3766
|
+
if (this.requests[k] == null) {
|
3767
|
+
this.requests = new Batman.Request({
|
3768
|
+
url: url = "" + Batman.View.prototype.prefix + "/" + k,
|
3769
|
+
type: 'html',
|
3770
|
+
success: __bind(function(response) {
|
3771
|
+
return this.set(k, response);
|
3772
|
+
}, this),
|
3773
|
+
error: function(response) {
|
3774
|
+
throw new Error("Could not load view from " + url);
|
3775
|
+
}
|
3776
|
+
});
|
3777
|
+
}
|
3778
|
+
},
|
3779
|
+
set: function(k, v) {
|
3780
|
+
return this.sources[k] = v;
|
3781
|
+
}
|
3782
|
+
});
|
3783
|
+
return ViewSourceCache;
|
3784
|
+
})();
|
3570
3785
|
Batman.View = (function() {
|
3571
3786
|
__extends(View, Batman.Object);
|
3572
3787
|
function View(options) {
|
3573
|
-
var context;
|
3788
|
+
var context, node;
|
3574
3789
|
this.contexts = [];
|
3575
3790
|
View.__super__.constructor.call(this, options);
|
3576
3791
|
if (context = this.get('context')) {
|
3577
3792
|
this.contexts.push(context);
|
3578
3793
|
this.unset('context');
|
3579
3794
|
}
|
3795
|
+
if (node = this.get('node')) {
|
3796
|
+
this.render(node);
|
3797
|
+
} else {
|
3798
|
+
this.observe('node', __bind(function(node) {
|
3799
|
+
return this.render(node);
|
3800
|
+
}, this));
|
3801
|
+
}
|
3580
3802
|
}
|
3581
|
-
View.
|
3803
|
+
View.sourceCache = new Batman.ViewSourceCache();
|
3582
3804
|
View.prototype.source = '';
|
3583
3805
|
View.prototype.html = '';
|
3584
3806
|
View.prototype.node = null;
|
3585
3807
|
View.prototype.contentFor = null;
|
3586
3808
|
View.prototype.event('ready').oneShot = true;
|
3587
3809
|
View.prototype.prefix = 'views';
|
3588
|
-
View.
|
3589
|
-
|
3590
|
-
|
3591
|
-
|
3592
|
-
|
3593
|
-
View.prototype.reloadSource = function() {
|
3594
|
-
var source, url;
|
3810
|
+
View.accessor('html', function() {
|
3811
|
+
var source;
|
3812
|
+
if (this.html && this.html.length > 0) {
|
3813
|
+
return this.html;
|
3814
|
+
}
|
3595
3815
|
source = this.get('source');
|
3596
3816
|
if (!source) {
|
3597
3817
|
return;
|
3598
3818
|
}
|
3599
|
-
|
3600
|
-
|
3601
|
-
|
3602
|
-
|
3603
|
-
|
3604
|
-
|
3605
|
-
|
3606
|
-
|
3607
|
-
return
|
3608
|
-
}, this),
|
3609
|
-
error: function(response) {
|
3610
|
-
throw new Error("Could not load view from " + url);
|
3819
|
+
return this.html = this.constructor.sourceCache.get(source);
|
3820
|
+
});
|
3821
|
+
View.accessor('node', {
|
3822
|
+
get: function() {
|
3823
|
+
var html;
|
3824
|
+
if (!this.node) {
|
3825
|
+
html = this.get('html');
|
3826
|
+
if (!(html && html.length > 0)) {
|
3827
|
+
return;
|
3611
3828
|
}
|
3612
|
-
|
3613
|
-
|
3614
|
-
|
3615
|
-
|
3616
|
-
|
3617
|
-
|
3618
|
-
|
3619
|
-
if (this.node !== node) {
|
3620
|
-
return this.set('node', node);
|
3829
|
+
this.node = document.createElement('div');
|
3830
|
+
$setInnerHTML(this.node, html);
|
3831
|
+
}
|
3832
|
+
return this.node;
|
3833
|
+
},
|
3834
|
+
set: function(_, node) {
|
3835
|
+
return this.node = node;
|
3621
3836
|
}
|
3622
3837
|
});
|
3623
|
-
View.
|
3624
|
-
if (!node) {
|
3625
|
-
return;
|
3626
|
-
}
|
3838
|
+
View.prototype.render = function(node) {
|
3627
3839
|
this.event('ready').resetOneShot();
|
3628
3840
|
if (this._renderer) {
|
3629
3841
|
this._renderer.forgetAll();
|
@@ -3637,7 +3849,7 @@
|
|
3637
3849
|
}
|
3638
3850
|
if (this.contentFor && node) {
|
3639
3851
|
$setInnerHTML(this.contentFor, '');
|
3640
|
-
return this.contentFor
|
3852
|
+
return $appendChild(this.contentFor, node);
|
3641
3853
|
} else if (yieldTo) {
|
3642
3854
|
if (contents = Batman.DOM._yieldContents[yieldTo]) {
|
3643
3855
|
return contents.push(node);
|
@@ -3650,12 +3862,13 @@
|
|
3650
3862
|
return this.fire('ready', node);
|
3651
3863
|
}, this));
|
3652
3864
|
}
|
3653
|
-
}
|
3865
|
+
};
|
3654
3866
|
return View;
|
3655
3867
|
})();
|
3656
3868
|
Batman.Renderer = (function() {
|
3657
3869
|
var bindingRegexp, k, sortBindings, _i, _len, _ref;
|
3658
3870
|
__extends(Renderer, Batman.Object);
|
3871
|
+
Renderer.prototype.deferEvery = 50;
|
3659
3872
|
function Renderer(node, callback, contexts) {
|
3660
3873
|
var _ref;
|
3661
3874
|
this.node = node;
|
@@ -3669,7 +3882,7 @@
|
|
3669
3882
|
this.on('parsed', callback);
|
3670
3883
|
}
|
3671
3884
|
this.context = contexts instanceof Batman.RenderContext ? contexts : (_ref = Batman.RenderContext).start.apply(_ref, contexts);
|
3672
|
-
this.timeout =
|
3885
|
+
this.timeout = $setImmediate(this.start);
|
3673
3886
|
}
|
3674
3887
|
Renderer.prototype.start = function() {
|
3675
3888
|
this.startTime = new Date;
|
@@ -3714,9 +3927,9 @@
|
|
3714
3927
|
};
|
3715
3928
|
Renderer.prototype.parseNode = function(node) {
|
3716
3929
|
var attr, bindings, key, name, nextNode, readerArgs, result, skipChildren, varIndex, _base, _base2, _j, _len2, _name, _name2, _ref2;
|
3717
|
-
if (new Date - this.startTime >
|
3930
|
+
if (this.deferEvery && (new Date - this.startTime) > this.deferEvery) {
|
3718
3931
|
this.resumeNode = node;
|
3719
|
-
this.timeout =
|
3932
|
+
this.timeout = $setImmediate(this.resume);
|
3720
3933
|
return;
|
3721
3934
|
}
|
3722
3935
|
if (node.getAttribute && node.attributes) {
|
@@ -3871,6 +4084,19 @@
|
|
3871
4084
|
}
|
3872
4085
|
this;
|
3873
4086
|
}
|
4087
|
+
Binding.prototype.destroy = function() {
|
4088
|
+
var k, _results;
|
4089
|
+
this.forget();
|
4090
|
+
this._batman.properties.forEach(function(key, property) {
|
4091
|
+
return property.removeSourceHandlers();
|
4092
|
+
});
|
4093
|
+
_results = [];
|
4094
|
+
for (k in this) {
|
4095
|
+
if (!__hasProp.call(this, k)) continue;
|
4096
|
+
_results.push(delete this[k]);
|
4097
|
+
}
|
4098
|
+
return _results;
|
4099
|
+
};
|
3874
4100
|
Binding.prototype.parseFilter = function() {
|
3875
4101
|
var args, filter, filterName, filterString, filters, key, keyPath, orig, split;
|
3876
4102
|
this.filterFunctions = [];
|
@@ -4159,21 +4385,21 @@
|
|
4159
4385
|
return true;
|
4160
4386
|
},
|
4161
4387
|
yield: function(node, key) {
|
4162
|
-
|
4388
|
+
$setImmediate(function() {
|
4163
4389
|
return Batman.DOM.yield(key, node);
|
4164
|
-
})
|
4390
|
+
});
|
4165
4391
|
return true;
|
4166
4392
|
},
|
4167
4393
|
contentfor: function(node, key) {
|
4168
|
-
|
4394
|
+
$setImmediate(function() {
|
4169
4395
|
return Batman.DOM.contentFor(key, node);
|
4170
|
-
})
|
4396
|
+
});
|
4171
4397
|
return true;
|
4172
4398
|
},
|
4173
4399
|
replace: function(node, key) {
|
4174
|
-
|
4400
|
+
$setImmediate(function() {
|
4175
4401
|
return Batman.DOM.replace(key, node);
|
4176
|
-
})
|
4402
|
+
});
|
4177
4403
|
return true;
|
4178
4404
|
}
|
4179
4405
|
},
|
@@ -4315,75 +4541,7 @@
|
|
4315
4541
|
},
|
4316
4542
|
binders: {
|
4317
4543
|
select: function(node, key, context, renderer, only) {
|
4318
|
-
|
4319
|
-
_ref = context.findKey(key), boundValue = _ref[0], container = _ref[1];
|
4320
|
-
updateSelectBinding = __bind(function() {
|
4321
|
-
var c, selections;
|
4322
|
-
selections = node.multiple ? (function() {
|
4323
|
-
var _i, _len, _ref2, _results;
|
4324
|
-
_ref2 = node.children;
|
4325
|
-
_results = [];
|
4326
|
-
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
4327
|
-
c = _ref2[_i];
|
4328
|
-
if (c.selected) {
|
4329
|
-
_results.push(c.value);
|
4330
|
-
}
|
4331
|
-
}
|
4332
|
-
return _results;
|
4333
|
-
})() : node.value;
|
4334
|
-
if (selections.length === 1) {
|
4335
|
-
selections = selections[0];
|
4336
|
-
}
|
4337
|
-
return container.set(key, selections);
|
4338
|
-
}, this);
|
4339
|
-
updateOptionBindings = __bind(function() {
|
4340
|
-
var child, data, subBoundValue, subContainer, subContext, subKey, _i, _len, _ref2, _ref3, _results;
|
4341
|
-
_ref2 = node.children;
|
4342
|
-
_results = [];
|
4343
|
-
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
4344
|
-
child = _ref2[_i];
|
4345
|
-
_results.push((data = Batman.data(child, 'selected')) ? (subContext = data.context) && (subKey = data.key) ? ((_ref3 = subContext.findKey(subKey), subBoundValue = _ref3[0], subContainer = _ref3[1], _ref3), child.selected !== subBoundValue ? subContainer.set(subKey, child.selected) : void 0) : void 0 : void 0);
|
4346
|
-
}
|
4347
|
-
return _results;
|
4348
|
-
}, this);
|
4349
|
-
renderer.on('rendered', function() {
|
4350
|
-
var dataChange, nodeChange;
|
4351
|
-
dataChange = function(newValue) {
|
4352
|
-
var child, match, matches, value, valueToChild, _i, _j, _k, _len, _len2, _len3, _ref2, _ref3;
|
4353
|
-
if (newValue instanceof Array) {
|
4354
|
-
valueToChild = {};
|
4355
|
-
_ref2 = node.children;
|
4356
|
-
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
4357
|
-
child = _ref2[_i];
|
4358
|
-
child.selected = false;
|
4359
|
-
matches = valueToChild[child.value];
|
4360
|
-
if (matches) {
|
4361
|
-
matches.push(child);
|
4362
|
-
} else {
|
4363
|
-
matches = [child];
|
4364
|
-
}
|
4365
|
-
valueToChild[child.value] = matches;
|
4366
|
-
}
|
4367
|
-
for (_j = 0, _len2 = newValue.length; _j < _len2; _j++) {
|
4368
|
-
value = newValue[_j];
|
4369
|
-
_ref3 = valueToChild[value];
|
4370
|
-
for (_k = 0, _len3 = _ref3.length; _k < _len3; _k++) {
|
4371
|
-
match = _ref3[_k];
|
4372
|
-
match.selected = true;
|
4373
|
-
}
|
4374
|
-
}
|
4375
|
-
} else {
|
4376
|
-
node.value = newValue;
|
4377
|
-
}
|
4378
|
-
return updateOptionBindings();
|
4379
|
-
};
|
4380
|
-
nodeChange = function() {
|
4381
|
-
updateSelectBinding();
|
4382
|
-
return updateOptionBindings();
|
4383
|
-
};
|
4384
|
-
Batman.data(node, 'updateBinding', updateSelectBinding);
|
4385
|
-
return context.bind(node, key, dataChange, nodeChange, only);
|
4386
|
-
});
|
4544
|
+
new Batman.DOM.Select(node, key, context, renderer, only);
|
4387
4545
|
return true;
|
4388
4546
|
},
|
4389
4547
|
style: function(node, attr, key, context, renderer, only) {
|
@@ -4408,14 +4566,18 @@
|
|
4408
4566
|
return true;
|
4409
4567
|
},
|
4410
4568
|
file: function(node, key, context, renderer, only) {
|
4411
|
-
context.bind(node, key, function() {
|
4412
|
-
|
4413
|
-
|
4414
|
-
|
4415
|
-
|
4416
|
-
actualObject = subContext.get('proxiedObject');
|
4569
|
+
context.bind(node, key, (function() {}), function(node, subContext) {
|
4570
|
+
var actualObject, adapter, keyContext, segments, _i, _len, _ref;
|
4571
|
+
segments = key.split('.');
|
4572
|
+
if (segments.length > 1) {
|
4573
|
+
keyContext = subContext.get(segments.slice(0, -1).join('.'));
|
4417
4574
|
} else {
|
4418
|
-
|
4575
|
+
keyContext = subContext;
|
4576
|
+
}
|
4577
|
+
if (keyContext instanceof Batman.RenderContext.ContextProxy) {
|
4578
|
+
actualObject = keyContext.get('proxiedObject');
|
4579
|
+
} else {
|
4580
|
+
actualObject = keyContext;
|
4419
4581
|
}
|
4420
4582
|
if (actualObject.hasStorage && actualObject.hasStorage()) {
|
4421
4583
|
_ref = actualObject._batman.get('storage');
|
@@ -4519,13 +4681,15 @@
|
|
4519
4681
|
Batman.DOM._yields[name] = node;
|
4520
4682
|
if (contents = Batman.DOM._yieldContents[name]) {
|
4521
4683
|
if (_replaceContent) {
|
4522
|
-
$setInnerHTML(node, '');
|
4684
|
+
$setInnerHTML(node, '', true);
|
4523
4685
|
}
|
4524
4686
|
for (_i = 0, _len = contents.length; _i < _len; _i++) {
|
4525
4687
|
content = contents[_i];
|
4526
4688
|
if (!Batman.data(content, 'yielded')) {
|
4527
|
-
|
4528
|
-
|
4689
|
+
if ($isChildOf(node, content)) {
|
4690
|
+
content = content.cloneNode(true);
|
4691
|
+
}
|
4692
|
+
$appendChild(node, content, true);
|
4529
4693
|
Batman.data(content, 'yielded', true);
|
4530
4694
|
}
|
4531
4695
|
}
|
@@ -4548,8 +4712,21 @@
|
|
4548
4712
|
replace: function(name, node) {
|
4549
4713
|
return Batman.DOM.contentFor(name, node, true);
|
4550
4714
|
},
|
4715
|
+
trackBinding: $trackBinding = function(binding, node) {
|
4716
|
+
var bindings;
|
4717
|
+
if (bindings = Batman.data(node, 'bindings')) {
|
4718
|
+
return bindings.add(binding);
|
4719
|
+
} else {
|
4720
|
+
return Batman.data(node, 'bindings', new Batman.SimpleSet(binding));
|
4721
|
+
}
|
4722
|
+
},
|
4551
4723
|
unbindNode: $unbindNode = function(node) {
|
4552
|
-
var eventListeners, eventName, listeners;
|
4724
|
+
var bindings, eventListeners, eventName, listeners;
|
4725
|
+
if (bindings = Batman.data(node, 'bindings')) {
|
4726
|
+
bindings.forEach(function(binding) {
|
4727
|
+
return binding.destroy();
|
4728
|
+
});
|
4729
|
+
}
|
4553
4730
|
if (listeners = Batman.data(node, 'listeners')) {
|
4554
4731
|
for (eventName in listeners) {
|
4555
4732
|
eventListeners = listeners[eventName];
|
@@ -4579,7 +4756,16 @@
|
|
4579
4756
|
}
|
4580
4757
|
return _results;
|
4581
4758
|
},
|
4582
|
-
setInnerHTML: $setInnerHTML = function(
|
4759
|
+
setInnerHTML: $setInnerHTML = function() {
|
4760
|
+
var args, child, hide, html, node, _i, _len, _ref;
|
4761
|
+
node = arguments[0], html = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
|
4762
|
+
_ref = node.childNodes;
|
4763
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
4764
|
+
child = _ref[_i];
|
4765
|
+
if (hide = Batman.data(child, 'hide')) {
|
4766
|
+
hide.apply(child, args);
|
4767
|
+
}
|
4768
|
+
}
|
4583
4769
|
$unbindTree(node, false);
|
4584
4770
|
return node != null ? node.innerHTML = html : void 0;
|
4585
4771
|
},
|
@@ -4588,6 +4774,14 @@
|
|
4588
4774
|
$unbindTree(node);
|
4589
4775
|
return node != null ? (_ref = node.parentNode) != null ? _ref.removeChild(node) : void 0 : void 0;
|
4590
4776
|
},
|
4777
|
+
appendChild: $appendChild = function() {
|
4778
|
+
var args, child, parent, _ref;
|
4779
|
+
parent = arguments[0], child = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
|
4780
|
+
if ((_ref = Batman.data(child, 'show')) != null) {
|
4781
|
+
_ref.apply(child, args);
|
4782
|
+
}
|
4783
|
+
return parent.appendChild(child);
|
4784
|
+
},
|
4591
4785
|
valueForNode: function(node, value) {
|
4592
4786
|
var isSetting;
|
4593
4787
|
if (value == null) {
|
@@ -4653,26 +4847,131 @@
|
|
4653
4847
|
},
|
4654
4848
|
hasAddEventListener: $hasAddEventListener = !!(typeof window !== "undefined" && window !== null ? window.addEventListener : void 0)
|
4655
4849
|
};
|
4850
|
+
Batman.DOM.AbstractBinding = (function() {
|
4851
|
+
function AbstractBinding(node) {
|
4852
|
+
Batman.DOM.trackBinding(this, node);
|
4853
|
+
}
|
4854
|
+
AbstractBinding.prototype.destroy = function() {};
|
4855
|
+
return AbstractBinding;
|
4856
|
+
})();
|
4857
|
+
Batman.DOM.Select = (function() {
|
4858
|
+
__extends(Select, Batman.DOM.AbstractBinding);
|
4859
|
+
function Select(node, key, context, renderer, only) {
|
4860
|
+
this.node = node;
|
4861
|
+
this.key = key;
|
4862
|
+
this.context = context;
|
4863
|
+
this.renderer = renderer;
|
4864
|
+
this.only = only;
|
4865
|
+
this.updateOptionBindings = __bind(this.updateOptionBindings, this);
|
4866
|
+
this.updateSelectBinding = __bind(this.updateSelectBinding, this);
|
4867
|
+
this.nodeChange = __bind(this.nodeChange, this);
|
4868
|
+
this.dataChange = __bind(this.dataChange, this);
|
4869
|
+
Select.__super__.constructor.apply(this, arguments);
|
4870
|
+
this.container = context.findKey(key)[1];
|
4871
|
+
renderer.on('rendered', __bind(function() {
|
4872
|
+
Batman.data(node, 'updateBinding', this.updateSelectBinding);
|
4873
|
+
return context.bind(node, key, this.dataChange, this.nodeChange, only);
|
4874
|
+
}, this));
|
4875
|
+
}
|
4876
|
+
Select.prototype.dataChange = function(newValue) {
|
4877
|
+
var child, match, matches, value, valueToChild, _i, _j, _k, _len, _len2, _len3, _ref, _ref2;
|
4878
|
+
if (newValue instanceof Array) {
|
4879
|
+
valueToChild = {};
|
4880
|
+
_ref = this.node.children;
|
4881
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
4882
|
+
child = _ref[_i];
|
4883
|
+
child.selected = false;
|
4884
|
+
matches = valueToChild[child.value];
|
4885
|
+
if (matches) {
|
4886
|
+
matches.push(child);
|
4887
|
+
} else {
|
4888
|
+
matches = [child];
|
4889
|
+
}
|
4890
|
+
valueToChild[child.value] = matches;
|
4891
|
+
}
|
4892
|
+
for (_j = 0, _len2 = newValue.length; _j < _len2; _j++) {
|
4893
|
+
value = newValue[_j];
|
4894
|
+
_ref2 = valueToChild[value];
|
4895
|
+
for (_k = 0, _len3 = _ref2.length; _k < _len3; _k++) {
|
4896
|
+
match = _ref2[_k];
|
4897
|
+
match.selected = true;
|
4898
|
+
}
|
4899
|
+
}
|
4900
|
+
} else {
|
4901
|
+
this.node.value = newValue;
|
4902
|
+
}
|
4903
|
+
return this.updateOptionBindings();
|
4904
|
+
};
|
4905
|
+
Select.prototype.nodeChange = function() {
|
4906
|
+
this.updateSelectBinding();
|
4907
|
+
return this.updateOptionBindings();
|
4908
|
+
};
|
4909
|
+
Select.prototype.updateSelectBinding = function() {
|
4910
|
+
var c, selections;
|
4911
|
+
selections = this.node.multiple ? (function() {
|
4912
|
+
var _i, _len, _ref, _results;
|
4913
|
+
_ref = this.node.children;
|
4914
|
+
_results = [];
|
4915
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
4916
|
+
c = _ref[_i];
|
4917
|
+
if (c.selected) {
|
4918
|
+
_results.push(c.value);
|
4919
|
+
}
|
4920
|
+
}
|
4921
|
+
return _results;
|
4922
|
+
}).call(this) : this.node.value;
|
4923
|
+
if (selections.length === 1) {
|
4924
|
+
selections = selections[0];
|
4925
|
+
}
|
4926
|
+
return this.container.set(this.key, selections);
|
4927
|
+
};
|
4928
|
+
Select.prototype.updateOptionBindings = function() {
|
4929
|
+
var child, data, subBoundValue, subContainer, subContext, subKey, _i, _len, _ref, _ref2, _results;
|
4930
|
+
_ref = this.node.children;
|
4931
|
+
_results = [];
|
4932
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
4933
|
+
child = _ref[_i];
|
4934
|
+
_results.push((data = Batman.data(child, 'selected')) ? (subContext = data.context) && (subKey = data.key) ? ((_ref2 = subContext.findKey(subKey), subBoundValue = _ref2[0], subContainer = _ref2[1], _ref2), child.selected !== subBoundValue ? subContainer.set(subKey, child.selected) : void 0) : void 0 : void 0);
|
4935
|
+
}
|
4936
|
+
return _results;
|
4937
|
+
};
|
4938
|
+
return Select;
|
4939
|
+
})();
|
4656
4940
|
Batman.DOM.Style = (function() {
|
4941
|
+
__extends(Style, Batman.DOM.AbstractBinding);
|
4657
4942
|
function Style(node, key, context) {
|
4658
4943
|
this.node = node;
|
4659
4944
|
this.key = key;
|
4660
4945
|
this.context = context;
|
4946
|
+
this.unbindCurrentHash = __bind(this.unbindCurrentHash, this);
|
4661
4947
|
this.reapplyOldStyles = __bind(this.reapplyOldStyles, this);
|
4662
4948
|
this.setStyle = __bind(this.setStyle, this);
|
4663
4949
|
this.bindSingleAttribute = __bind(this.bindSingleAttribute, this);
|
4664
4950
|
this.onItemsRemoved = __bind(this.onItemsRemoved, this);
|
4665
4951
|
this.onItemsAdded = __bind(this.onItemsAdded, this);
|
4666
4952
|
this.dataChange = __bind(this.dataChange, this);
|
4953
|
+
this.destroy = __bind(this.destroy, this);
|
4954
|
+
Style.__super__.constructor.apply(this, arguments);
|
4667
4955
|
this.oldStyles = {};
|
4668
4956
|
context.bind(node, key, this.dataChange, function() {});
|
4669
4957
|
}
|
4958
|
+
Style.prototype.destroy = function() {
|
4959
|
+
var k, _results;
|
4960
|
+
this.unbindCurrentHash();
|
4961
|
+
_results = [];
|
4962
|
+
for (k in this) {
|
4963
|
+
if (!__hasProp.call(this, k)) continue;
|
4964
|
+
_results.push(delete this[k]);
|
4965
|
+
}
|
4966
|
+
return _results;
|
4967
|
+
};
|
4670
4968
|
Style.prototype.dataChange = function(value) {
|
4671
4969
|
var cssName, cssValue, key, keyValue, keypathContext, keypathValue, style, _i, _len, _ref, _ref2, _ref3, _results;
|
4672
4970
|
if (!value) {
|
4673
4971
|
this.reapplyOldStyles();
|
4674
4972
|
return;
|
4675
4973
|
}
|
4974
|
+
this.unbindCurrentHash();
|
4676
4975
|
if (typeof value === 'string' && (this.boundValueType = 'string')) {
|
4677
4976
|
this.reapplyOldStyles();
|
4678
4977
|
_ref = value.split(';');
|
@@ -4684,10 +4983,6 @@
|
|
4684
4983
|
return;
|
4685
4984
|
}
|
4686
4985
|
if (value instanceof Batman.Hash && (this.boundValueType = 'batman.hash')) {
|
4687
|
-
if (this.styleHash) {
|
4688
|
-
this.styleHash.event('itemsWereRemoved').removeHandler(this.onItemsRemoved);
|
4689
|
-
this.styleHash.event('itemsWereAdded').removeHandler(this.onItemsAdded);
|
4690
|
-
}
|
4691
4986
|
this.styleHash = value;
|
4692
4987
|
value.on('itemsWereAdded', this.onItemsAdded);
|
4693
4988
|
value.on('itemsWereRemoved', this.onItemsRemoved);
|
@@ -4738,11 +5033,19 @@
|
|
4738
5033
|
}
|
4739
5034
|
return _results;
|
4740
5035
|
};
|
5036
|
+
Style.prototype.unbindCurrentHash = function() {
|
5037
|
+
if (this.styleHash) {
|
5038
|
+
this.styleHash.event('itemsWereRemoved').removeHandler(this.onItemsRemoved);
|
5039
|
+
return this.styleHash.event('itemsWereAdded').removeHandler(this.onItemsAdded);
|
5040
|
+
}
|
5041
|
+
};
|
4741
5042
|
return Style;
|
4742
5043
|
})();
|
4743
5044
|
Batman.DOM.Iterator = (function() {
|
4744
|
-
Iterator.
|
4745
|
-
Iterator.prototype.
|
5045
|
+
__extends(Iterator, Batman.DOM.AbstractBinding);
|
5046
|
+
Iterator.prototype.deferEvery = 50;
|
5047
|
+
Iterator.prototype.currentActionNumber = 0;
|
5048
|
+
Iterator.prototype.queuedActionNumber = 0;
|
4746
5049
|
function Iterator(sourceNode, iteratorName, key, context, parentRenderer) {
|
4747
5050
|
this.iteratorName = iteratorName;
|
4748
5051
|
this.key = key;
|
@@ -4751,24 +5054,35 @@
|
|
4751
5054
|
this.arrayChanged = __bind(this.arrayChanged, this);
|
4752
5055
|
this.collectionChange = __bind(this.collectionChange, this);
|
4753
5056
|
this.nodeMap = new Batman.SimpleHash;
|
5057
|
+
this.actionMap = new Batman.SimpleHash;
|
4754
5058
|
this.rendererMap = new Batman.SimpleHash;
|
5059
|
+
this.actions = [];
|
4755
5060
|
this.prototypeNode = sourceNode.cloneNode(true);
|
4756
5061
|
this.prototypeNode.removeAttribute("data-foreach-" + iteratorName);
|
4757
5062
|
this.parentNode = sourceNode.parentNode;
|
4758
5063
|
this.siblingNode = sourceNode.nextSibling;
|
4759
|
-
this.parentRenderer.on('parsed', function() {
|
5064
|
+
this.parentRenderer.on('parsed', __bind(function() {
|
5065
|
+
this.prototypeNode[Batman.expando] = sourceNode[Batman.expando];
|
5066
|
+
delete sourceNode[Batman.expando];
|
4760
5067
|
return $removeNode(sourceNode);
|
4761
|
-
});
|
4762
|
-
this.
|
5068
|
+
}, this));
|
5069
|
+
this.parentRenderer.prevent('rendered');
|
5070
|
+
Iterator.__super__.constructor.call(this, this.parentNode);
|
4763
5071
|
this.fragment = document.createDocumentFragment();
|
4764
5072
|
context.bind(sourceNode, key, this.collectionChange, function() {});
|
4765
5073
|
}
|
4766
|
-
Iterator.prototype.
|
4767
|
-
var
|
5074
|
+
Iterator.prototype.destroy = function() {
|
5075
|
+
var k;
|
5076
|
+
$unbindNode(this.prototypeNode);
|
5077
|
+
this.unbindCollection();
|
5078
|
+
for (k in this) {
|
5079
|
+
if (!__hasProp.call(this, k)) continue;
|
5080
|
+
delete this[k];
|
5081
|
+
}
|
5082
|
+
return this.destroyed = true;
|
5083
|
+
};
|
5084
|
+
Iterator.prototype.unbindCollection = function() {
|
4768
5085
|
if (this.collection) {
|
4769
|
-
if (newCollection === this.collection) {
|
4770
|
-
return;
|
4771
|
-
}
|
4772
5086
|
this.nodeMap.forEach(function(item, node) {
|
4773
5087
|
return $removeNode(node);
|
4774
5088
|
});
|
@@ -4777,13 +5091,19 @@
|
|
4777
5091
|
return renderer.stop();
|
4778
5092
|
});
|
4779
5093
|
this.rendererMap.clear();
|
4780
|
-
if (this.collection.
|
4781
|
-
this.collection.forget(this.arrayChanged);
|
5094
|
+
if (this.collection.isObservable && this.collection.toArray) {
|
5095
|
+
return this.collection.forget('toArray', this.arrayChanged);
|
4782
5096
|
} else if (this.collection.isEventEmitter) {
|
4783
|
-
this.collection.event('itemsWereAdded').removeHandler(this.
|
4784
|
-
this.collection.event('itemsWereRemoved').removeHandler(this.currentRemovedHandler);
|
5097
|
+
this.collection.event('itemsWereAdded').removeHandler(this.currentAddedHandler);
|
5098
|
+
return this.collection.event('itemsWereRemoved').removeHandler(this.currentRemovedHandler);
|
4785
5099
|
}
|
4786
5100
|
}
|
5101
|
+
};
|
5102
|
+
Iterator.prototype.collectionChange = function(newCollection) {
|
5103
|
+
var key, value, _ref;
|
5104
|
+
if (newCollection !== this.collection) {
|
5105
|
+
this.unbindCollection();
|
5106
|
+
}
|
4787
5107
|
this.collection = newCollection;
|
4788
5108
|
if (this.collection) {
|
4789
5109
|
if (this.collection.isObservable && this.collection.toArray) {
|
@@ -4796,8 +5116,7 @@
|
|
4796
5116
|
for (i = 0, _len = items.length; i < _len; i++) {
|
4797
5117
|
item = items[i];
|
4798
5118
|
_results.push(this.addItem(item, {
|
4799
|
-
fragment: true
|
4800
|
-
addNumber: this.currentAddFunction + i
|
5119
|
+
fragment: true
|
4801
5120
|
}));
|
4802
5121
|
}
|
4803
5122
|
return _results;
|
@@ -4814,24 +5133,49 @@
|
|
4814
5133
|
}, this));
|
4815
5134
|
}
|
4816
5135
|
if (this.collection.toArray) {
|
4817
|
-
|
5136
|
+
this.arrayChanged();
|
4818
5137
|
} else if (this.collection.forEach) {
|
4819
|
-
|
5138
|
+
this.collection.forEach(__bind(function(item) {
|
4820
5139
|
return this.addItem(item);
|
4821
5140
|
}, this));
|
4822
5141
|
} else {
|
4823
5142
|
_ref = this.collection;
|
4824
|
-
_results = [];
|
4825
5143
|
for (key in _ref) {
|
4826
5144
|
if (!__hasProp.call(_ref, key)) continue;
|
4827
5145
|
value = _ref[key];
|
4828
|
-
|
5146
|
+
this.addItem(key);
|
4829
5147
|
}
|
4830
|
-
return _results;
|
4831
5148
|
}
|
4832
5149
|
} else {
|
4833
|
-
|
5150
|
+
developer.warn("Warning! data-foreach-" + this.iteratorName + " called with an undefined binding. Key was: " + this.key + ".");
|
5151
|
+
}
|
5152
|
+
return this.processActionQueue();
|
5153
|
+
};
|
5154
|
+
Iterator.prototype.arrayChanged = function() {
|
5155
|
+
var existingNode, item, newItemsInOrder, trackingNodeMap, _i, _len;
|
5156
|
+
newItemsInOrder = this.collection.toArray();
|
5157
|
+
trackingNodeMap = new Batman.SimpleHash;
|
5158
|
+
for (_i = 0, _len = newItemsInOrder.length; _i < _len; _i++) {
|
5159
|
+
item = newItemsInOrder[_i];
|
5160
|
+
existingNode = this.nodeMap.get(item);
|
5161
|
+
trackingNodeMap.set(item, true);
|
5162
|
+
if (existingNode) {
|
5163
|
+
this.insertItem(item, existingNode, {
|
5164
|
+
fragment: false,
|
5165
|
+
actionNumber: this.queuedActionNumber++,
|
5166
|
+
sync: true
|
5167
|
+
});
|
5168
|
+
} else {
|
5169
|
+
this.addItem(item, {
|
5170
|
+
fragment: false
|
5171
|
+
});
|
5172
|
+
}
|
4834
5173
|
}
|
5174
|
+
return this.nodeMap.forEach(__bind(function(item, node) {
|
5175
|
+
if (!trackingNodeMap.hasKey(item)) {
|
5176
|
+
return this.removeItem(item);
|
5177
|
+
}
|
5178
|
+
}, this));
|
4835
5179
|
};
|
4836
5180
|
Iterator.prototype.addItem = function(item, options) {
|
4837
5181
|
var childRenderer, finish, self;
|
@@ -4840,26 +5184,37 @@
|
|
4840
5184
|
fragment: true
|
4841
5185
|
};
|
4842
5186
|
}
|
4843
|
-
options.addNumber = this.queuedAddNumber++;
|
4844
5187
|
this.parentRenderer.prevent('rendered');
|
4845
|
-
finish = __bind(function() {
|
4846
|
-
this.parentRenderer.allow('rendered');
|
4847
|
-
return this.parentRenderer.fire('rendered');
|
4848
|
-
}, this);
|
4849
5188
|
self = this;
|
5189
|
+
options.actionNumber = this.queuedActionNumber++;
|
4850
5190
|
childRenderer = new Batman.Renderer(this._nodeForItem(item), (function() {
|
4851
5191
|
return self.insertItem(item, this.node, options);
|
4852
5192
|
}), this.context.descend(item, this.iteratorName));
|
4853
5193
|
this.rendererMap.set(item, childRenderer);
|
5194
|
+
finish = __bind(function() {
|
5195
|
+
if (this.destroyed) {
|
5196
|
+
return;
|
5197
|
+
}
|
5198
|
+
this.parentRenderer.allow('rendered');
|
5199
|
+
return this.parentRenderer.fire('rendered');
|
5200
|
+
}, this);
|
4854
5201
|
childRenderer.on('rendered', finish);
|
4855
|
-
|
4856
|
-
this.
|
4857
|
-
|
4858
|
-
|
5202
|
+
childRenderer.on('stopped', __bind(function() {
|
5203
|
+
if (this.destroyed) {
|
5204
|
+
return;
|
5205
|
+
}
|
5206
|
+
this.actions[options.actionNumber] = function() {};
|
5207
|
+
finish();
|
5208
|
+
return this.processActionQueue();
|
4859
5209
|
}, this));
|
5210
|
+
return item;
|
4860
5211
|
};
|
4861
5212
|
Iterator.prototype.removeItem = function(item) {
|
4862
5213
|
var hideFunction, oldNode;
|
5214
|
+
if (this.destroyed) {
|
5215
|
+
return;
|
5216
|
+
}
|
5217
|
+
this._removeOldAction(item);
|
4863
5218
|
oldNode = this.nodeMap.unset(item);
|
4864
5219
|
if (oldNode) {
|
4865
5220
|
if (hideFunction = Batman.data(oldNode, 'hide')) {
|
@@ -4869,57 +5224,43 @@
|
|
4869
5224
|
}
|
4870
5225
|
}
|
4871
5226
|
};
|
4872
|
-
Iterator.prototype.arrayChanged = function() {
|
4873
|
-
var existingNode, item, newItemsInOrder, trackingNodeMap, _i, _len;
|
4874
|
-
newItemsInOrder = this.collection.toArray();
|
4875
|
-
trackingNodeMap = new Batman.SimpleHash;
|
4876
|
-
for (_i = 0, _len = newItemsInOrder.length; _i < _len; _i++) {
|
4877
|
-
item = newItemsInOrder[_i];
|
4878
|
-
existingNode = this.nodeMap.get(item);
|
4879
|
-
trackingNodeMap.set(item, true);
|
4880
|
-
if (existingNode) {
|
4881
|
-
this.insertItem(item, existingNode, {
|
4882
|
-
fragment: false,
|
4883
|
-
addNumber: this.queuedAddNumber++,
|
4884
|
-
sync: true
|
4885
|
-
});
|
4886
|
-
} else {
|
4887
|
-
this.addItem(item, {
|
4888
|
-
fragment: false
|
4889
|
-
});
|
4890
|
-
}
|
4891
|
-
}
|
4892
|
-
return this.nodeMap.forEach(__bind(function(item, node) {
|
4893
|
-
if (!trackingNodeMap.hasKey(item)) {
|
4894
|
-
return this.removeItem(item);
|
4895
|
-
}
|
4896
|
-
}, this));
|
4897
|
-
};
|
4898
5227
|
Iterator.prototype.insertItem = function(item, node, options) {
|
5228
|
+
var futureActionNumber, _base, _base2, _name, _name2;
|
4899
5229
|
if (options == null) {
|
4900
5230
|
options = {};
|
4901
5231
|
}
|
4902
|
-
if (this.
|
4903
|
-
|
5232
|
+
if (this.destroyed) {
|
5233
|
+
return;
|
5234
|
+
}
|
5235
|
+
futureActionNumber = this.actionMap.get(item);
|
5236
|
+
if ((futureActionNumber != null) && futureActionNumber > options.actionNumber) {
|
5237
|
+
this.actions[options.actionNumber] = function() {};
|
4904
5238
|
} else {
|
4905
|
-
this.
|
4906
|
-
this.
|
4907
|
-
|
4908
|
-
|
4909
|
-
|
4910
|
-
|
4911
|
-
|
4912
|
-
|
4913
|
-
|
4914
|
-
if (
|
4915
|
-
return
|
5239
|
+
this._removeOldAction(item);
|
5240
|
+
this.actionMap.set(item, options.actionNumber);
|
5241
|
+
if (this.nodeMap.get(item) !== node) {
|
5242
|
+
(_base = this.actions)[_name = options.actionNumber] || (_base[_name] = function() {});
|
5243
|
+
} else {
|
5244
|
+
this.rendererMap.unset(item);
|
5245
|
+
(_base2 = this.actions)[_name2 = options.actionNumber] || (_base2[_name2] = function() {
|
5246
|
+
var show;
|
5247
|
+
show = Batman.data(node, 'show');
|
5248
|
+
if (typeof show === 'function') {
|
5249
|
+
return show.call(node, {
|
5250
|
+
before: this.siblingNode
|
5251
|
+
});
|
4916
5252
|
} else {
|
4917
|
-
|
5253
|
+
if (options.fragment) {
|
5254
|
+
return this.fragment.appendChild(node);
|
5255
|
+
} else {
|
5256
|
+
return this.parentNode.insertBefore(node, this.siblingNode);
|
5257
|
+
}
|
4918
5258
|
}
|
4919
|
-
}
|
4920
|
-
}
|
5259
|
+
});
|
5260
|
+
}
|
4921
5261
|
}
|
4922
|
-
|
5262
|
+
this.actions[options.actionNumber].item = item;
|
5263
|
+
return this.processActionQueue();
|
4923
5264
|
};
|
4924
5265
|
Iterator.prototype._nodeForItem = function(item) {
|
4925
5266
|
var newNode;
|
@@ -4927,16 +5268,43 @@
|
|
4927
5268
|
this.nodeMap.set(item, newNode);
|
4928
5269
|
return newNode;
|
4929
5270
|
};
|
4930
|
-
Iterator.prototype.
|
4931
|
-
var
|
4932
|
-
|
4933
|
-
|
4934
|
-
|
4935
|
-
this.
|
5271
|
+
Iterator.prototype._removeOldAction = function(item) {
|
5272
|
+
var oldActionNumber;
|
5273
|
+
oldActionNumber = this.actionMap.get(item);
|
5274
|
+
if ((oldActionNumber != null) && oldActionNumber > this.currentActionNumber) {
|
5275
|
+
this.actionMap.unset(item);
|
5276
|
+
return this.actions[oldActionNumber] = function() {};
|
5277
|
+
}
|
5278
|
+
};
|
5279
|
+
Iterator.prototype.processActionQueue = function() {
|
5280
|
+
if (this.destroyed) {
|
5281
|
+
return;
|
4936
5282
|
}
|
4937
|
-
if (this.
|
4938
|
-
this.
|
4939
|
-
|
5283
|
+
if (!this.actionQueueTimeout) {
|
5284
|
+
return this.actionQueueTimeout = $setImmediate(__bind(function() {
|
5285
|
+
var f, startTime;
|
5286
|
+
if (this.destroyed) {
|
5287
|
+
return;
|
5288
|
+
}
|
5289
|
+
delete this.actionQueueTimeout;
|
5290
|
+
startTime = new Date;
|
5291
|
+
while (!!(f = this.actions[this.currentActionNumber])) {
|
5292
|
+
this.actions[this.currentActionNumber] = true;
|
5293
|
+
f.call(this);
|
5294
|
+
this.currentActionNumber++;
|
5295
|
+
if (this.deferEvery && (new Date - startTime) > this.deferEvery) {
|
5296
|
+
return this.processActionQueue();
|
5297
|
+
}
|
5298
|
+
}
|
5299
|
+
if (this.fragment && this.rendererMap.length === 0 && this.fragment.hasChildNodes()) {
|
5300
|
+
this.parentNode.insertBefore(this.fragment, this.siblingNode);
|
5301
|
+
this.fragment = document.createDocumentFragment();
|
5302
|
+
}
|
5303
|
+
if (this.currentActionNumber === this.queuedActionNumber) {
|
5304
|
+
this.parentRenderer.allow('rendered');
|
5305
|
+
return this.parentRenderer.fire('rendered');
|
5306
|
+
}
|
5307
|
+
}, this));
|
4940
5308
|
}
|
4941
5309
|
};
|
4942
5310
|
return Iterator;
|
@@ -5011,7 +5379,23 @@
|
|
5011
5379
|
meta: buntUndefined(function(value, keypath) {
|
5012
5380
|
developer.assert(value.meta, "Error, value doesn't have a meta to filter on!");
|
5013
5381
|
return value.meta.get(keypath);
|
5014
|
-
})
|
5382
|
+
}),
|
5383
|
+
interpolate: function(string, interpolationKeypaths) {
|
5384
|
+
var k, v, values;
|
5385
|
+
if (string == null) {
|
5386
|
+
return;
|
5387
|
+
}
|
5388
|
+
values = {};
|
5389
|
+
for (k in interpolationKeypaths) {
|
5390
|
+
v = interpolationKeypaths[k];
|
5391
|
+
values[k] = this.findKey(v)[0];
|
5392
|
+
if (!(values[k] != null)) {
|
5393
|
+
Batman.developer.warn("Warning! Undefined interpolation key " + k + " for interpolation", string);
|
5394
|
+
values[k] = '';
|
5395
|
+
}
|
5396
|
+
}
|
5397
|
+
return Batman.helpers.interpolate(string, values);
|
5398
|
+
}
|
5015
5399
|
};
|
5016
5400
|
_ref = ['capitalize', 'singularize', 'underscore', 'camelize'];
|
5017
5401
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
@@ -5176,11 +5560,137 @@
|
|
5176
5560
|
}
|
5177
5561
|
}
|
5178
5562
|
};
|
5563
|
+
Batman.Paginator = (function() {
|
5564
|
+
__extends(Paginator, Batman.Object);
|
5565
|
+
function Paginator() {
|
5566
|
+
Paginator.__super__.constructor.apply(this, arguments);
|
5567
|
+
}
|
5568
|
+
Paginator.Cache = (function() {
|
5569
|
+
function Cache(offset, limit, items) {
|
5570
|
+
this.offset = offset;
|
5571
|
+
this.limit = limit;
|
5572
|
+
this.items = items;
|
5573
|
+
this.length = items.length;
|
5574
|
+
this.reach = offset + limit;
|
5575
|
+
}
|
5576
|
+
Cache.prototype.containsItemsForOffsetAndLimit = function(offset, limit) {
|
5577
|
+
return offset >= this.offset && (offset + limit) <= this.reach;
|
5578
|
+
};
|
5579
|
+
Cache.prototype.itemsForOffsetAndLimit = function(offset, limit) {
|
5580
|
+
var begin, end;
|
5581
|
+
if (!this.containsItemsForOffsetAndLimit(offset, limit)) {
|
5582
|
+
return;
|
5583
|
+
}
|
5584
|
+
begin = offset - this.offset;
|
5585
|
+
end = begin + limit;
|
5586
|
+
return this.items.slice(begin, end);
|
5587
|
+
};
|
5588
|
+
return Cache;
|
5589
|
+
})();
|
5590
|
+
Paginator.prototype.offset = 0;
|
5591
|
+
Paginator.prototype.limit = 10;
|
5592
|
+
Paginator.prototype.totalCount = 0;
|
5593
|
+
Paginator.prototype.offsetFromPageAndLimit = function(page, limit) {
|
5594
|
+
return Math.round((+page - 1) * limit);
|
5595
|
+
};
|
5596
|
+
Paginator.prototype.pageFromOffsetAndLimit = function(offset, limit) {
|
5597
|
+
return offset / limit + 1;
|
5598
|
+
};
|
5599
|
+
Paginator.prototype.toArray = function() {
|
5600
|
+
var cache, items, limit, offset;
|
5601
|
+
cache = this.get('cache');
|
5602
|
+
offset = this.get('offset');
|
5603
|
+
limit = this.get('limit');
|
5604
|
+
items = cache != null ? cache.itemsForOffsetAndLimit(offset, limit) : void 0;
|
5605
|
+
if (!items) {
|
5606
|
+
this.loadItemsForOffsetAndLimit(offset, limit);
|
5607
|
+
}
|
5608
|
+
return items || [];
|
5609
|
+
};
|
5610
|
+
Paginator.prototype.page = function() {
|
5611
|
+
return this.pageFromOffsetAndLimit(this.get('offset'), this.get('limit'));
|
5612
|
+
};
|
5613
|
+
Paginator.prototype.pageCount = function() {
|
5614
|
+
return Math.ceil(this.get('totalCount') / this.get('limit'));
|
5615
|
+
};
|
5616
|
+
Paginator.prototype.previousPage = function() {
|
5617
|
+
return this.set('page', this.get('page') - 1);
|
5618
|
+
};
|
5619
|
+
Paginator.prototype.nextPage = function() {
|
5620
|
+
return this.set('page', this.get('page') + 1);
|
5621
|
+
};
|
5622
|
+
Paginator.prototype.loadItemsForOffsetAndLimit = function(offset, limit) {};
|
5623
|
+
Paginator.prototype.updateCache = function(offset, limit, items) {
|
5624
|
+
return this.set('cache', new Batman.Paginator.Cache(offset, limit, items));
|
5625
|
+
};
|
5626
|
+
Paginator.accessor('toArray', Paginator.prototype.toArray);
|
5627
|
+
Paginator.accessor('offset', 'limit', 'totalCount', {
|
5628
|
+
get: Batman.Property.defaultAccessor.get,
|
5629
|
+
set: function(key, value) {
|
5630
|
+
return Batman.Property.defaultAccessor.set.call(this, key, +value);
|
5631
|
+
}
|
5632
|
+
});
|
5633
|
+
Paginator.accessor('page', {
|
5634
|
+
get: Paginator.prototype.page,
|
5635
|
+
set: function(_, value) {
|
5636
|
+
value = +value;
|
5637
|
+
this.set('offset', this.offsetFromPageAndLimit(value, this.get('limit')));
|
5638
|
+
return value;
|
5639
|
+
}
|
5640
|
+
});
|
5641
|
+
Paginator.accessor('pageCount', Paginator.prototype.pageCount);
|
5642
|
+
return Paginator;
|
5643
|
+
})();
|
5644
|
+
Batman.ModelPaginator = (function() {
|
5645
|
+
__extends(ModelPaginator, Batman.Paginator);
|
5646
|
+
function ModelPaginator() {
|
5647
|
+
ModelPaginator.__super__.constructor.apply(this, arguments);
|
5648
|
+
}
|
5649
|
+
ModelPaginator.prototype.cachePadding = 0;
|
5650
|
+
ModelPaginator.prototype.paddedOffset = function(offset) {
|
5651
|
+
offset -= this.cachePadding;
|
5652
|
+
if (offset < 0) {
|
5653
|
+
return 0;
|
5654
|
+
} else {
|
5655
|
+
return offset;
|
5656
|
+
}
|
5657
|
+
};
|
5658
|
+
ModelPaginator.prototype.paddedLimit = function(limit) {
|
5659
|
+
return limit + this.cachePadding * 2;
|
5660
|
+
};
|
5661
|
+
ModelPaginator.prototype.loadItemsForOffsetAndLimit = function(offset, limit) {
|
5662
|
+
var k, params, v, _ref2;
|
5663
|
+
params = this.paramsForOffsetAndLimit(offset, limit);
|
5664
|
+
_ref2 = this.params;
|
5665
|
+
for (k in _ref2) {
|
5666
|
+
v = _ref2[k];
|
5667
|
+
params[k] = v;
|
5668
|
+
}
|
5669
|
+
return this.model.load(params, __bind(function(err, records) {
|
5670
|
+
if (err == null) {
|
5671
|
+
return this.updateCache(this.offsetFromParams(params), this.limitFromParams(params), records);
|
5672
|
+
}
|
5673
|
+
}, this));
|
5674
|
+
};
|
5675
|
+
ModelPaginator.prototype.paramsForOffsetAndLimit = function(offset, limit) {
|
5676
|
+
return {
|
5677
|
+
offset: this.paddedOffset(offset),
|
5678
|
+
limit: this.paddedLimit(limit)
|
5679
|
+
};
|
5680
|
+
};
|
5681
|
+
ModelPaginator.prototype.offsetFromParams = function(params) {
|
5682
|
+
return params.offset;
|
5683
|
+
};
|
5684
|
+
ModelPaginator.prototype.limitFromParams = function(params) {
|
5685
|
+
return params.limit;
|
5686
|
+
};
|
5687
|
+
return ModelPaginator;
|
5688
|
+
})();
|
5179
5689
|
container = typeof exports !== "undefined" && exports !== null ? (module.exports = Batman, global) : (window.Batman = Batman, window);
|
5180
5690
|
$mixin(container, Batman.Observable);
|
5181
5691
|
Batman.exportHelpers = function(onto) {
|
5182
5692
|
var k, _j, _len2, _ref2;
|
5183
|
-
_ref2 = ['mixin', 'unmixin', 'route', 'redirect', 'typeOf', 'redirect'];
|
5693
|
+
_ref2 = ['mixin', 'unmixin', 'route', 'redirect', 'typeOf', 'redirect', 'setImmediate'];
|
5184
5694
|
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
|
5185
5695
|
k = _ref2[_j];
|
5186
5696
|
onto["$" + k] = Batman[k];
|