batman-rails 0.0.1 → 0.0.2
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.
- 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];
|