batman-rails 0.0.9 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/Gemfile +1 -1
- data/LICENSE.txt +22 -0
- data/README.md +43 -39
- data/Rakefile +2 -9
- data/batman-rails.gemspec +20 -21
- data/lib/batman-rails.rb +8 -1
- data/lib/batman-rails/version.rb +6 -0
- data/lib/generators/batman/app_generator.rb +117 -0
- data/lib/generators/batman/controller_generator.rb +8 -17
- data/lib/generators/batman/html_generator.rb +42 -0
- data/lib/generators/batman/model_generator.rb +2 -2
- data/lib/generators/batman/scaffold_generator.rb +14 -4
- data/lib/generators/batman/view_generator.rb +18 -0
- data/lib/generators/{batman/common.rb → common.rb} +19 -5
- data/lib/templates/batman/application_controller.coffee +1 -0
- data/lib/templates/batman/batman_app.coffee +20 -0
- data/lib/templates/batman/controller.coffee +7 -0
- data/lib/templates/batman/html/edit.html +2 -0
- data/lib/templates/batman/html/index.html +2 -0
- data/lib/templates/batman/html/main_index.html +259 -0
- data/lib/templates/batman/html/show.html +2 -0
- data/lib/templates/batman/main_controller.coffee +8 -0
- data/lib/templates/batman/model.coffee +13 -0
- data/lib/templates/batman/view.coffee +7 -0
- data/lib/templates/rails/controller.rb +7 -0
- data/lib/templates/rails/index.html +0 -0
- data/lib/templates/rails/layout.html +15 -0
- data/test/app_generator_test.rb +111 -0
- data/test/controller_generator_test.rb +41 -15
- data/test/model_generator_test.rb +47 -16
- data/test/test_helper.rb +3 -3
- data/test/view_generator_test.rb +36 -0
- data/vendor/assets/images/batman/bullet.png +0 -0
- data/vendor/assets/images/batman/content-bg-fade.png +0 -0
- data/vendor/assets/images/batman/content-bg.png +0 -0
- data/vendor/assets/images/batman/header-wrapper-bg.jpg +0 -0
- data/vendor/assets/images/batman/logo.png +0 -0
- data/vendor/assets/javascripts/batman/batman.jquery.js +16 -74
- data/vendor/assets/javascripts/batman/batman.js +8951 -8551
- data/vendor/assets/javascripts/batman/batman.paginator.js +216 -0
- data/vendor/assets/javascripts/batman/batman.rails.js +78 -33
- data/vendor/assets/javascripts/batman/es5-shim.js +0 -0
- metadata +76 -57
- data/lib/batman/rails.rb +0 -6
- data/lib/batman/rails/engine.rb +0 -6
- data/lib/batman/rails/version.rb +0 -6
- data/lib/generators/batman/helper_generator.rb +0 -14
- data/lib/generators/batman/install_generator.rb +0 -93
- data/lib/generators/batman/templates/batman_app.coffee +0 -24
- data/lib/generators/batman/templates/controller.coffee +0 -5
- data/lib/generators/batman/templates/helper.coffee +0 -5
- data/lib/generators/batman/templates/model.coffee +0 -7
- data/test/install_generator_test.rb +0 -105
- data/vendor/assets/javascripts/batman/batman.i18n.js +0 -116
- data/vendor/assets/javascripts/batman/batman.solo.js +0 -558
data/lib/batman/rails.rb
DELETED
data/lib/batman/rails/engine.rb
DELETED
data/lib/batman/rails/version.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'generators/batman/common'
|
2
|
-
module Batman
|
3
|
-
module Generators
|
4
|
-
class HelperGenerator < ::Rails::Generators::NamedBase
|
5
|
-
include Common
|
6
|
-
|
7
|
-
desc "This generator creates a Batman helper"
|
8
|
-
|
9
|
-
def create_batman_helper
|
10
|
-
template "helper.coffee", "#{js_path}/helpers/#{plural_name.downcase}_helper.js.coffee"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
@@ -1,93 +0,0 @@
|
|
1
|
-
require 'generators/batman/common'
|
2
|
-
|
3
|
-
module Batman
|
4
|
-
module Generators
|
5
|
-
class InstallGenerator < ::Rails::Generators::Base
|
6
|
-
include Common
|
7
|
-
requires_app_name
|
8
|
-
|
9
|
-
desc "This generator installs Batman.js with a default folder layout"
|
10
|
-
|
11
|
-
class_option :skip_git, :type => :boolean, :aliases => "-G", :default => false,
|
12
|
-
:desc => "Skip Git ignores and keeps"
|
13
|
-
|
14
|
-
def create_batman_app
|
15
|
-
with_app_name do
|
16
|
-
template "batman_app.coffee", "#{js_path}/#{app_name}.js.coffee"
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def create_directories
|
21
|
-
%w(models controllers helpers).each do |dir|
|
22
|
-
empty_directory "#{js_path}/#{dir}"
|
23
|
-
create_file "#{js_path}/#{dir}/.gitkeep" unless options[:skip_git]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def inject_batman
|
28
|
-
with_app_name do
|
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
|
50
|
-
|
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
|
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
|
72
|
-
\n// Batman.js and its adapters
|
73
|
-
//= require batman/es5-shim
|
74
|
-
//= require batman/batman
|
75
|
-
//= require batman/batman.jquery
|
76
|
-
//= require batman/batman.rails
|
77
|
-
|
78
|
-
//= require #{app_name}
|
79
|
-
|
80
|
-
//= require_tree ./models
|
81
|
-
//= require_tree ./controllers
|
82
|
-
//= require_tree ./helpers
|
83
|
-
\n
|
84
|
-
CODE
|
85
|
-
file_type == :coffeescript ? code.gsub('//', '#') : code
|
86
|
-
end
|
87
|
-
|
88
|
-
def exists?(file)
|
89
|
-
File.exist?(File.join(destination_root, file))
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
window.<%= js_app_name %> = class <%= js_app_name %> extends Batman.App
|
2
|
-
|
3
|
-
# @root 'controller#all'
|
4
|
-
# @route '/controller/:id', 'controller#show', resource: 'model', action: 'show'
|
5
|
-
|
6
|
-
@on 'run', ->
|
7
|
-
console?.log "Running ...."
|
8
|
-
|
9
|
-
@on 'ready', ->
|
10
|
-
console?.log "<%= js_app_name %> ready for use."
|
11
|
-
|
12
|
-
@flash: Batman()
|
13
|
-
@flash.accessor
|
14
|
-
get: (key) -> @[key]
|
15
|
-
set: (key, value) ->
|
16
|
-
@[key] = value
|
17
|
-
if value isnt ''
|
18
|
-
setTimeout =>
|
19
|
-
@set(key, '')
|
20
|
-
, 2000
|
21
|
-
value
|
22
|
-
|
23
|
-
@flashSuccess: (message) -> @set 'flash.success', message
|
24
|
-
@flashError: (message) -> @set 'flash.error', message
|
@@ -1,105 +0,0 @@
|
|
1
|
-
require 'mocha'
|
2
|
-
require 'test_helper'
|
3
|
-
require 'generators/batman/install_generator'
|
4
|
-
|
5
|
-
module InstallGeneratorTests
|
6
|
-
|
7
|
-
def setup
|
8
|
-
mkdir_p "#{destination_root}/app/assets/javascripts"
|
9
|
-
cp fixture(application_javascript_path), "#{destination_root}/app/assets/javascripts"
|
10
|
-
Rails.application.class.stubs(:name).returns("Dummy::Application")
|
11
|
-
super
|
12
|
-
end
|
13
|
-
|
14
|
-
def teardown
|
15
|
-
Rails.application.class.unstub(:name)
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_batman_application_file_is_created
|
19
|
-
run_generator
|
20
|
-
|
21
|
-
assert_file "#{javascripts_path}/dummy.js.coffee" do |app|
|
22
|
-
assert_match /window\.Dummy = class Dummy extends Batman\.App/, app
|
23
|
-
assert_match /@on 'ready', ->/, app
|
24
|
-
assert_match /@on 'run', ->/, app
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_batman_application_file_is_created_for_two_word_application_name
|
29
|
-
Rails.application.class.stubs(:name).returns("FooBar::Application")
|
30
|
-
run_generator
|
31
|
-
|
32
|
-
assert_file "#{javascripts_path}/foo_bar.js.coffee" do |app|
|
33
|
-
assert_match /window\.FooBar = class FooBar extends Batman\.App/, app
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def test_application_require_is_properly_setup_for_two_word_application_name
|
38
|
-
Rails.application.class.stubs(:name).returns("FooBar::Application")
|
39
|
-
run_generator
|
40
|
-
|
41
|
-
assert_file "#{javascripts_path}/#{application_javascript_path}", /require foo_bar/
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_batman_directory_structure_is_created
|
45
|
-
run_generator
|
46
|
-
|
47
|
-
%W{controllers models helpers}.each do |dir|
|
48
|
-
assert_directory "#{javascripts_path}/#{dir}"
|
49
|
-
assert_file "#{javascripts_path}/#{dir}/.gitkeep"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_no_gitkeep_files_are_created_when_skipping_git
|
54
|
-
run_generator [destination_root, "--skip-git"]
|
55
|
-
|
56
|
-
%W{controllers models helpers}.each do |dir|
|
57
|
-
assert_directory "#{javascripts_path}/#{dir}"
|
58
|
-
assert_no_file "#{javascripts_path}/#{dir}/.gitkeep"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def test_applicationjs_require_batman_jquery_rails_and_dummy
|
63
|
-
run_generator
|
64
|
-
|
65
|
-
assert_file "#{javascripts_path}/#{application_javascript_path}" do |app|
|
66
|
-
%W{batman batman.jquery batman.rails}.each do |require|
|
67
|
-
assert_equal 1, app.scan(%r{require batman\/#{require}$}).length
|
68
|
-
end
|
69
|
-
|
70
|
-
assert_match /require dummy/, app
|
71
|
-
|
72
|
-
%W{models controllers helpers}.each do |require|
|
73
|
-
assert_equal 1, app.scan(/require_tree \.\/#{require}/).length
|
74
|
-
end
|
75
|
-
|
76
|
-
assert_equal 1, app.scan(/Dummy\.run\(\)/).length
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
private
|
81
|
-
|
82
|
-
def fixture(file)
|
83
|
-
File.expand_path("fixtures/#{file}", File.dirname(__FILE__))
|
84
|
-
end
|
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,116 +0,0 @@
|
|
1
|
-
(function() {
|
2
|
-
var translationsAlias,
|
3
|
-
__hasProp = {}.hasOwnProperty,
|
4
|
-
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
5
|
-
|
6
|
-
Batman.I18N = (function(_super) {
|
7
|
-
|
8
|
-
__extends(I18N, _super);
|
9
|
-
|
10
|
-
I18N.defaultLocale = "en";
|
11
|
-
|
12
|
-
I18N.classAccessor('locale', {
|
13
|
-
get: function() {
|
14
|
-
return this.locale || this.get('defaultLocale');
|
15
|
-
},
|
16
|
-
set: function(k, v) {
|
17
|
-
return this.locale = v;
|
18
|
-
},
|
19
|
-
unset: function() {
|
20
|
-
var x;
|
21
|
-
x = this.locale;
|
22
|
-
delete this.locale;
|
23
|
-
return x;
|
24
|
-
}
|
25
|
-
});
|
26
|
-
|
27
|
-
I18N.classAccessor('translations', function() {
|
28
|
-
return this.get("locales." + (this.get('locale')));
|
29
|
-
});
|
30
|
-
|
31
|
-
I18N.translate = function(key, values) {
|
32
|
-
var translation;
|
33
|
-
translation = this.get("translations." + key);
|
34
|
-
if (!(translation != null)) {
|
35
|
-
Batman.developer.warn("Warning, undefined translation " + key + " when in local " + (this.get('locale')));
|
36
|
-
return "";
|
37
|
-
}
|
38
|
-
return Batman.helpers.interpolate(translation, values);
|
39
|
-
};
|
40
|
-
|
41
|
-
I18N.enable = function() {
|
42
|
-
var _this = this;
|
43
|
-
this._oldTranslation = Batman.translate;
|
44
|
-
this.locales.set('en', Batman.translate.messages);
|
45
|
-
return Batman.translate = function() {
|
46
|
-
return _this.translate.apply(_this, arguments);
|
47
|
-
};
|
48
|
-
};
|
49
|
-
|
50
|
-
I18N.disable = function() {
|
51
|
-
return Batman.translate = this._oldTranslation;
|
52
|
-
};
|
53
|
-
|
54
|
-
function I18N() {
|
55
|
-
Batman.developer.error("Can't instantiate i18n!");
|
56
|
-
}
|
57
|
-
|
58
|
-
return I18N;
|
59
|
-
|
60
|
-
})(Batman.Object);
|
61
|
-
|
62
|
-
Batman.I18N.LocalesStorage = (function(_super) {
|
63
|
-
|
64
|
-
__extends(LocalesStorage, _super);
|
65
|
-
|
66
|
-
function LocalesStorage() {
|
67
|
-
this.isStorage = true;
|
68
|
-
this._storage = {};
|
69
|
-
LocalesStorage.__super__.constructor.apply(this, arguments);
|
70
|
-
}
|
71
|
-
|
72
|
-
LocalesStorage.accessor({
|
73
|
-
get: function(k) {
|
74
|
-
var _this = this;
|
75
|
-
if (!this._storage[k]) {
|
76
|
-
this._storage[k] = {};
|
77
|
-
new Batman.Request({
|
78
|
-
url: "/locales/" + k + ".json",
|
79
|
-
success: function(data) {
|
80
|
-
return _this.set(k, data[k]);
|
81
|
-
},
|
82
|
-
error: function(xhr) {
|
83
|
-
throw new Error("Couldn't load locale file " + k + "!");
|
84
|
-
}
|
85
|
-
});
|
86
|
-
}
|
87
|
-
return this._storage[k];
|
88
|
-
},
|
89
|
-
set: function(k, v) {
|
90
|
-
return this._storage[k] = v;
|
91
|
-
},
|
92
|
-
unset: function(k) {
|
93
|
-
var x;
|
94
|
-
x = this._storage[k];
|
95
|
-
delete this._storage[k];
|
96
|
-
return x;
|
97
|
-
}
|
98
|
-
});
|
99
|
-
|
100
|
-
return LocalesStorage;
|
101
|
-
|
102
|
-
})(Batman.Object);
|
103
|
-
|
104
|
-
Batman.I18N.set('locales', new Batman.I18N.LocalesStorage);
|
105
|
-
|
106
|
-
Batman.Filters.t = Batman.Filters.translate = Batman.Filters.interpolate;
|
107
|
-
|
108
|
-
translationsAlias = Batman();
|
109
|
-
|
110
|
-
translationsAlias.accessor('t', function() {
|
111
|
-
return Batman.I18N.get('translations');
|
112
|
-
});
|
113
|
-
|
114
|
-
Batman.RenderContext.base = Batman.RenderContext.base.descend(translationsAlias);
|
115
|
-
|
116
|
-
}).call(this);
|
@@ -1,558 +0,0 @@
|
|
1
|
-
/*!
|
2
|
-
* Reqwest! A general purpose XHR connection manager
|
3
|
-
* (c) Dustin Diaz 2011
|
4
|
-
* https://github.com/ded/reqwest
|
5
|
-
* license MIT
|
6
|
-
*/
|
7
|
-
!function (name, definition) {
|
8
|
-
if (typeof module != 'undefined') module.exports = definition()
|
9
|
-
else if (typeof define == 'function' && define.amd) define(name, definition)
|
10
|
-
else this[name] = definition()
|
11
|
-
}('reqwest', function () {
|
12
|
-
|
13
|
-
var context = this
|
14
|
-
, win = window
|
15
|
-
, doc = document
|
16
|
-
, old = context.reqwest
|
17
|
-
, twoHundo = /^20\d$/
|
18
|
-
, byTag = 'getElementsByTagName'
|
19
|
-
, readyState = 'readyState'
|
20
|
-
, contentType = 'Content-Type'
|
21
|
-
, requestedWith = 'X-Requested-With'
|
22
|
-
, head = doc[byTag]('head')[0]
|
23
|
-
, uniqid = 0
|
24
|
-
, lastValue // data stored by the most recent JSONP callback
|
25
|
-
, xmlHttpRequest = 'XMLHttpRequest'
|
26
|
-
, isArray = typeof Array.isArray == 'function' ? Array.isArray : function (a) {
|
27
|
-
return a instanceof Array
|
28
|
-
}
|
29
|
-
, defaultHeaders = {
|
30
|
-
contentType: 'application/x-www-form-urlencoded'
|
31
|
-
, accept: {
|
32
|
-
'*': 'text/javascript, text/html, application/xml, text/xml, */*'
|
33
|
-
, xml: 'application/xml, text/xml'
|
34
|
-
, html: 'text/html'
|
35
|
-
, text: 'text/plain'
|
36
|
-
, json: 'application/json, text/javascript'
|
37
|
-
, js: 'application/javascript, text/javascript'
|
38
|
-
}
|
39
|
-
, requestedWith: xmlHttpRequest
|
40
|
-
}
|
41
|
-
, xhr = win[xmlHttpRequest] ?
|
42
|
-
function () {
|
43
|
-
return new XMLHttpRequest()
|
44
|
-
} :
|
45
|
-
function () {
|
46
|
-
return new ActiveXObject('Microsoft.XMLHTTP')
|
47
|
-
}
|
48
|
-
|
49
|
-
function handleReadyState(o, success, error) {
|
50
|
-
return function () {
|
51
|
-
if (o && o[readyState] == 4) {
|
52
|
-
if (twoHundo.test(o.status)) {
|
53
|
-
success(o)
|
54
|
-
} else {
|
55
|
-
error(o)
|
56
|
-
}
|
57
|
-
}
|
58
|
-
}
|
59
|
-
}
|
60
|
-
|
61
|
-
function setHeaders(http, o) {
|
62
|
-
var headers = o.headers || {}, h
|
63
|
-
headers.Accept = headers.Accept || defaultHeaders.accept[o.type] || defaultHeaders.accept['*']
|
64
|
-
// breaks cross-origin requests with legacy browsers
|
65
|
-
if (!o.crossOrigin && !headers[requestedWith]) headers[requestedWith] = defaultHeaders.requestedWith
|
66
|
-
if (!headers[contentType]) headers[contentType] = o.contentType || defaultHeaders.contentType
|
67
|
-
for (h in headers) {
|
68
|
-
headers.hasOwnProperty(h) && http.setRequestHeader(h, headers[h])
|
69
|
-
}
|
70
|
-
}
|
71
|
-
|
72
|
-
function generalCallback(data) {
|
73
|
-
lastValue = data
|
74
|
-
}
|
75
|
-
|
76
|
-
function urlappend(url, s) {
|
77
|
-
return url + (/\?/.test(url) ? '&' : '?') + s
|
78
|
-
}
|
79
|
-
|
80
|
-
function handleJsonp(o, fn, err, url) {
|
81
|
-
var reqId = uniqid++
|
82
|
-
, cbkey = o.jsonpCallback || 'callback' // the 'callback' key
|
83
|
-
, cbval = o.jsonpCallbackName || ('reqwest_' + reqId) // the 'callback' value
|
84
|
-
, cbreg = new RegExp('((^|\\?|&)' + cbkey + ')=([^&]+)')
|
85
|
-
, match = url.match(cbreg)
|
86
|
-
, script = doc.createElement('script')
|
87
|
-
, loaded = 0
|
88
|
-
|
89
|
-
if (match) {
|
90
|
-
if (match[3] === '?') {
|
91
|
-
url = url.replace(cbreg, '$1=' + cbval) // wildcard callback func name
|
92
|
-
} else {
|
93
|
-
cbval = match[3] // provided callback func name
|
94
|
-
}
|
95
|
-
} else {
|
96
|
-
url = urlappend(url, cbkey + '=' + cbval) // no callback details, add 'em
|
97
|
-
}
|
98
|
-
|
99
|
-
win[cbval] = generalCallback
|
100
|
-
|
101
|
-
script.type = 'text/javascript'
|
102
|
-
script.src = url
|
103
|
-
script.async = true
|
104
|
-
if (typeof script.onreadystatechange !== 'undefined') {
|
105
|
-
// need this for IE due to out-of-order onreadystatechange(), binding script
|
106
|
-
// execution to an event listener gives us control over when the script
|
107
|
-
// is executed. See http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html
|
108
|
-
script.event = 'onclick'
|
109
|
-
script.htmlFor = script.id = '_reqwest_' + reqId
|
110
|
-
}
|
111
|
-
|
112
|
-
script.onload = script.onreadystatechange = function () {
|
113
|
-
if ((script[readyState] && script[readyState] !== 'complete' && script[readyState] !== 'loaded') || loaded) {
|
114
|
-
return false
|
115
|
-
}
|
116
|
-
script.onload = script.onreadystatechange = null
|
117
|
-
script.onclick && script.onclick()
|
118
|
-
// Call the user callback with the last value stored and clean up values and scripts.
|
119
|
-
o.success && o.success(lastValue)
|
120
|
-
lastValue = undefined
|
121
|
-
head.removeChild(script)
|
122
|
-
loaded = 1
|
123
|
-
}
|
124
|
-
|
125
|
-
// Add the script to the DOM head
|
126
|
-
head.appendChild(script)
|
127
|
-
}
|
128
|
-
|
129
|
-
function getRequest(o, fn, err) {
|
130
|
-
var method = (o.method || 'GET').toUpperCase()
|
131
|
-
, url = typeof o === 'string' ? o : o.url
|
132
|
-
// convert non-string objects to query-string form unless o.processData is false
|
133
|
-
, data = (o.processData !== false && o.data && typeof o.data !== 'string')
|
134
|
-
? reqwest.toQueryString(o.data)
|
135
|
-
: (o.data || null)
|
136
|
-
, http
|
137
|
-
|
138
|
-
// if we're working on a GET request and we have data then we should append
|
139
|
-
// query string to end of URL and not post data
|
140
|
-
if ((o.type == 'jsonp' || method == 'GET') && data) {
|
141
|
-
url = urlappend(url, data)
|
142
|
-
data = null
|
143
|
-
}
|
144
|
-
|
145
|
-
if (o.type == 'jsonp') return handleJsonp(o, fn, err, url)
|
146
|
-
|
147
|
-
http = xhr()
|
148
|
-
http.open(method, url, true)
|
149
|
-
setHeaders(http, o)
|
150
|
-
http.onreadystatechange = handleReadyState(http, fn, err)
|
151
|
-
o.before && o.before(http)
|
152
|
-
http.send(data)
|
153
|
-
return http
|
154
|
-
}
|
155
|
-
|
156
|
-
function Reqwest(o, fn) {
|
157
|
-
this.o = o
|
158
|
-
this.fn = fn
|
159
|
-
init.apply(this, arguments)
|
160
|
-
}
|
161
|
-
|
162
|
-
function setType(url) {
|
163
|
-
var m = url.match(/\.(json|jsonp|html|xml)(\?|$)/)
|
164
|
-
return m ? m[1] : 'js'
|
165
|
-
}
|
166
|
-
|
167
|
-
function init(o, fn) {
|
168
|
-
this.url = typeof o == 'string' ? o : o.url
|
169
|
-
this.timeout = null
|
170
|
-
var type = o.type || setType(this.url)
|
171
|
-
, self = this
|
172
|
-
fn = fn || function () {}
|
173
|
-
|
174
|
-
if (o.timeout) {
|
175
|
-
this.timeout = setTimeout(function () {
|
176
|
-
self.abort()
|
177
|
-
}, o.timeout)
|
178
|
-
}
|
179
|
-
|
180
|
-
function complete(resp) {
|
181
|
-
o.timeout && clearTimeout(self.timeout)
|
182
|
-
self.timeout = null
|
183
|
-
o.complete && o.complete(resp)
|
184
|
-
}
|
185
|
-
|
186
|
-
function success(resp) {
|
187
|
-
var r = resp.responseText
|
188
|
-
if (r) {
|
189
|
-
switch (type) {
|
190
|
-
case 'json':
|
191
|
-
try {
|
192
|
-
resp = win.JSON ? win.JSON.parse(r) : eval('(' + r + ')')
|
193
|
-
} catch (err) {
|
194
|
-
return error(resp, 'Could not parse JSON in response', err)
|
195
|
-
}
|
196
|
-
break;
|
197
|
-
case 'js':
|
198
|
-
resp = eval(r)
|
199
|
-
break;
|
200
|
-
case 'html':
|
201
|
-
resp = r
|
202
|
-
break;
|
203
|
-
}
|
204
|
-
}
|
205
|
-
|
206
|
-
fn(resp)
|
207
|
-
o.success && o.success(resp)
|
208
|
-
|
209
|
-
complete(resp)
|
210
|
-
}
|
211
|
-
|
212
|
-
function error(resp, msg, t) {
|
213
|
-
o.error && o.error(resp, msg, t)
|
214
|
-
complete(resp)
|
215
|
-
}
|
216
|
-
|
217
|
-
this.request = getRequest(o, success, error)
|
218
|
-
}
|
219
|
-
|
220
|
-
Reqwest.prototype = {
|
221
|
-
abort: function () {
|
222
|
-
this.request.abort()
|
223
|
-
}
|
224
|
-
|
225
|
-
, retry: function () {
|
226
|
-
init.call(this, this.o, this.fn)
|
227
|
-
}
|
228
|
-
}
|
229
|
-
|
230
|
-
function reqwest(o, fn) {
|
231
|
-
return new Reqwest(o, fn)
|
232
|
-
}
|
233
|
-
|
234
|
-
// normalize newline variants according to spec -> CRLF
|
235
|
-
function normalize(s) {
|
236
|
-
return s ? s.replace(/\r?\n/g, '\r\n') : ''
|
237
|
-
}
|
238
|
-
|
239
|
-
function serial(el, cb) {
|
240
|
-
var n = el.name
|
241
|
-
, t = el.tagName.toLowerCase()
|
242
|
-
, optCb = function(o) {
|
243
|
-
// IE gives value="" even where there is no value attribute
|
244
|
-
// 'specified' ref: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-862529273
|
245
|
-
if (o && !o.disabled)
|
246
|
-
cb(n, normalize(o.attributes.value && o.attributes.value.specified ? o.value : o.text))
|
247
|
-
}
|
248
|
-
|
249
|
-
// don't serialize elements that are disabled or without a name
|
250
|
-
if (el.disabled || !n) return;
|
251
|
-
|
252
|
-
switch (t) {
|
253
|
-
case 'input':
|
254
|
-
if (!/reset|button|image|file/i.test(el.type)) {
|
255
|
-
var ch = /checkbox/i.test(el.type)
|
256
|
-
, ra = /radio/i.test(el.type)
|
257
|
-
, val = el.value;
|
258
|
-
// WebKit gives us "" instead of "on" if a checkbox has no value, so correct it here
|
259
|
-
(!(ch || ra) || el.checked) && cb(n, normalize(ch && val === '' ? 'on' : val))
|
260
|
-
}
|
261
|
-
break;
|
262
|
-
case 'textarea':
|
263
|
-
cb(n, normalize(el.value))
|
264
|
-
break;
|
265
|
-
case 'select':
|
266
|
-
if (el.type.toLowerCase() === 'select-one') {
|
267
|
-
optCb(el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null)
|
268
|
-
} else {
|
269
|
-
for (var i = 0; el.length && i < el.length; i++) {
|
270
|
-
el.options[i].selected && optCb(el.options[i])
|
271
|
-
}
|
272
|
-
}
|
273
|
-
break;
|
274
|
-
}
|
275
|
-
}
|
276
|
-
|
277
|
-
// collect up all form elements found from the passed argument elements all
|
278
|
-
// the way down to child elements; pass a '<form>' or form fields.
|
279
|
-
// called with 'this'=callback to use for serial() on each element
|
280
|
-
function eachFormElement() {
|
281
|
-
var cb = this
|
282
|
-
, e, i, j
|
283
|
-
, serializeSubtags = function(e, tags) {
|
284
|
-
for (var i = 0; i < tags.length; i++) {
|
285
|
-
var fa = e[byTag](tags[i])
|
286
|
-
for (j = 0; j < fa.length; j++) serial(fa[j], cb)
|
287
|
-
}
|
288
|
-
}
|
289
|
-
|
290
|
-
for (i = 0; i < arguments.length; i++) {
|
291
|
-
e = arguments[i]
|
292
|
-
if (/input|select|textarea/i.test(e.tagName)) serial(e, cb)
|
293
|
-
serializeSubtags(e, [ 'input', 'select', 'textarea' ])
|
294
|
-
}
|
295
|
-
}
|
296
|
-
|
297
|
-
// standard query string style serialization
|
298
|
-
function serializeQueryString() {
|
299
|
-
return reqwest.toQueryString(reqwest.serializeArray.apply(null, arguments))
|
300
|
-
}
|
301
|
-
|
302
|
-
// { 'name': 'value', ... } style serialization
|
303
|
-
function serializeHash() {
|
304
|
-
var hash = {}
|
305
|
-
eachFormElement.apply(function (name, value) {
|
306
|
-
if (name in hash) {
|
307
|
-
hash[name] && !isArray(hash[name]) && (hash[name] = [hash[name]])
|
308
|
-
hash[name].push(value)
|
309
|
-
} else hash[name] = value
|
310
|
-
}, arguments)
|
311
|
-
return hash
|
312
|
-
}
|
313
|
-
|
314
|
-
// [ { name: 'name', value: 'value' }, ... ] style serialization
|
315
|
-
reqwest.serializeArray = function () {
|
316
|
-
var arr = []
|
317
|
-
eachFormElement.apply(function(name, value) {
|
318
|
-
arr.push({name: name, value: value})
|
319
|
-
}, arguments)
|
320
|
-
return arr
|
321
|
-
}
|
322
|
-
|
323
|
-
reqwest.serialize = function () {
|
324
|
-
if (arguments.length === 0) return ''
|
325
|
-
var opt, fn
|
326
|
-
, args = Array.prototype.slice.call(arguments, 0)
|
327
|
-
|
328
|
-
opt = args.pop()
|
329
|
-
opt && opt.nodeType && args.push(opt) && (opt = null)
|
330
|
-
opt && (opt = opt.type)
|
331
|
-
|
332
|
-
if (opt == 'map') fn = serializeHash
|
333
|
-
else if (opt == 'array') fn = reqwest.serializeArray
|
334
|
-
else fn = serializeQueryString
|
335
|
-
|
336
|
-
return fn.apply(null, args)
|
337
|
-
}
|
338
|
-
|
339
|
-
reqwest.toQueryString = function (o) {
|
340
|
-
var qs = '', i
|
341
|
-
, enc = encodeURIComponent
|
342
|
-
, push = function (k, v) {
|
343
|
-
qs += enc(k) + '=' + enc(v) + '&'
|
344
|
-
}
|
345
|
-
|
346
|
-
if (isArray(o)) {
|
347
|
-
for (i = 0; o && i < o.length; i++) push(o[i].name, o[i].value)
|
348
|
-
} else {
|
349
|
-
for (var k in o) {
|
350
|
-
if (!Object.hasOwnProperty.call(o, k)) continue;
|
351
|
-
var v = o[k]
|
352
|
-
if (isArray(v)) {
|
353
|
-
for (i = 0; i < v.length; i++) push(k, v[i])
|
354
|
-
} else push(k, o[k])
|
355
|
-
}
|
356
|
-
}
|
357
|
-
|
358
|
-
// spaces should be + according to spec
|
359
|
-
return qs.replace(/&$/, '').replace(/%20/g,'+')
|
360
|
-
}
|
361
|
-
|
362
|
-
// jQuery and Zepto compatibility, differences can be remapped here so you can call
|
363
|
-
// .ajax.compat(options, callback)
|
364
|
-
reqwest.compat = function (o, fn) {
|
365
|
-
if (o) {
|
366
|
-
o.type && (o.method = o.type) && delete o.type
|
367
|
-
o.dataType && (o.type = o.dataType)
|
368
|
-
o.jsonpCallback && (o.jsonpCallbackName = o.jsonpCallback) && delete o.jsonpCallback
|
369
|
-
o.jsonp && (o.jsonpCallback = o.jsonp)
|
370
|
-
}
|
371
|
-
return new Reqwest(o, fn)
|
372
|
-
}
|
373
|
-
|
374
|
-
return reqwest
|
375
|
-
});
|
376
|
-
|
377
|
-
(function() {
|
378
|
-
var _ref, _ref1;
|
379
|
-
|
380
|
-
Batman.extend(Batman.DOM, {
|
381
|
-
querySelectorAll: (typeof window !== "undefined" && window !== null ? (_ref = window.document) != null ? _ref.querySelectorAll : void 0 : void 0) != null ? function(node, selector) {
|
382
|
-
return node.querySelectorAll(selector);
|
383
|
-
} : function() {
|
384
|
-
return Batman.developer.error("Please include either jQuery or a querySelectorAll polyfill, or set Batman.DOM.querySelectorAll to return an empty array.");
|
385
|
-
},
|
386
|
-
querySelector: (typeof window !== "undefined" && window !== null ? (_ref1 = window.document) != null ? _ref1.querySelector : void 0 : void 0) != null ? function(node, selector) {
|
387
|
-
return node.querySelector(selector);
|
388
|
-
} : function() {
|
389
|
-
return Batman.developer.error("Please include either jQuery or a querySelector polyfill, or set Batman.DOM.querySelector to an empty function.");
|
390
|
-
},
|
391
|
-
setInnerHTML: function(node, html) {
|
392
|
-
var child, childNodes, result, _i, _j, _len, _len1;
|
393
|
-
childNodes = (function() {
|
394
|
-
var _i, _len, _ref2, _results;
|
395
|
-
_ref2 = node.childNodes;
|
396
|
-
_results = [];
|
397
|
-
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
|
398
|
-
child = _ref2[_i];
|
399
|
-
_results.push(child);
|
400
|
-
}
|
401
|
-
return _results;
|
402
|
-
})();
|
403
|
-
for (_i = 0, _len = childNodes.length; _i < _len; _i++) {
|
404
|
-
child = childNodes[_i];
|
405
|
-
Batman.DOM.willRemoveNode(child);
|
406
|
-
}
|
407
|
-
result = node.innerHTML = html;
|
408
|
-
for (_j = 0, _len1 = childNodes.length; _j < _len1; _j++) {
|
409
|
-
child = childNodes[_j];
|
410
|
-
Batman.DOM.didRemoveNode(child);
|
411
|
-
}
|
412
|
-
return result;
|
413
|
-
},
|
414
|
-
removeNode: function(node) {
|
415
|
-
var _ref2;
|
416
|
-
Batman.DOM.willRemoveNode(node);
|
417
|
-
if ((_ref2 = node.parentNode) != null) {
|
418
|
-
_ref2.removeChild(node);
|
419
|
-
}
|
420
|
-
return Batman.DOM.didRemoveNode(node);
|
421
|
-
},
|
422
|
-
destroyNode: function(node) {
|
423
|
-
Batman.DOM.willDestroyNode(node);
|
424
|
-
Batman.DOM.removeNode(node);
|
425
|
-
return Batman.DOM.didDestroyNode(node);
|
426
|
-
},
|
427
|
-
appendChild: function(parent, child) {
|
428
|
-
Batman.DOM.willInsertNode(child);
|
429
|
-
parent.appendChild(child);
|
430
|
-
return Batman.DOM.didInsertNode(child);
|
431
|
-
}
|
432
|
-
});
|
433
|
-
|
434
|
-
}).call(this);
|
435
|
-
|
436
|
-
(function() {
|
437
|
-
var prefixes;
|
438
|
-
|
439
|
-
Batman.Request.prototype._parseResponseHeaders = function(xhr) {
|
440
|
-
var headers;
|
441
|
-
return headers = xhr.getAllResponseHeaders().split('\n').reduce(function(acc, header) {
|
442
|
-
var key, matches, value;
|
443
|
-
if (matches = header.match(/([^:]*):\s*(.*)/)) {
|
444
|
-
key = matches[1];
|
445
|
-
value = matches[2];
|
446
|
-
acc[key] = value;
|
447
|
-
}
|
448
|
-
return acc;
|
449
|
-
}, {});
|
450
|
-
};
|
451
|
-
|
452
|
-
Batman.Request.prototype.send = function(data) {
|
453
|
-
var options, xhr, _ref,
|
454
|
-
_this = this;
|
455
|
-
if (data == null) {
|
456
|
-
data = this.get('data');
|
457
|
-
}
|
458
|
-
this.fire('loading');
|
459
|
-
options = {
|
460
|
-
url: this.get('url'),
|
461
|
-
method: this.get('method'),
|
462
|
-
type: this.get('type'),
|
463
|
-
headers: this.get('headers'),
|
464
|
-
success: function(response) {
|
465
|
-
_this.mixin({
|
466
|
-
xhr: xhr,
|
467
|
-
response: response,
|
468
|
-
status: typeof xhr !== "undefined" && xhr !== null ? xhr.status : void 0,
|
469
|
-
responseHeaders: _this._parseResponseHeaders(xhr)
|
470
|
-
});
|
471
|
-
return _this.fire('success', response);
|
472
|
-
},
|
473
|
-
error: function(xhr) {
|
474
|
-
_this.mixin({
|
475
|
-
xhr: xhr,
|
476
|
-
response: xhr.responseText || xhr.content,
|
477
|
-
status: xhr.status,
|
478
|
-
responseHeaders: _this._parseResponseHeaders(xhr)
|
479
|
-
});
|
480
|
-
xhr.request = _this;
|
481
|
-
return _this.fire('error', xhr);
|
482
|
-
},
|
483
|
-
complete: function() {
|
484
|
-
return _this.fire('loaded');
|
485
|
-
}
|
486
|
-
};
|
487
|
-
if ((_ref = options.method) === 'PUT' || _ref === 'POST') {
|
488
|
-
if (this.hasFileUploads()) {
|
489
|
-
options.data = this.constructor.objectToFormData(data);
|
490
|
-
} else {
|
491
|
-
options.contentType = this.get('contentType');
|
492
|
-
options.data = Batman.URI.queryFromParams(data);
|
493
|
-
}
|
494
|
-
} else {
|
495
|
-
options.data = data;
|
496
|
-
}
|
497
|
-
return xhr = (reqwest(options)).request;
|
498
|
-
};
|
499
|
-
|
500
|
-
prefixes = ['Webkit', 'Moz', 'O', 'ms', ''];
|
501
|
-
|
502
|
-
Batman.mixins.animation = {
|
503
|
-
initialize: function() {
|
504
|
-
var prefix, _i, _len;
|
505
|
-
for (_i = 0, _len = prefixes.length; _i < _len; _i++) {
|
506
|
-
prefix = prefixes[_i];
|
507
|
-
this.style["" + prefix + "Transform"] = 'scale(1, 1)';
|
508
|
-
this.style.opacity = 1;
|
509
|
-
this.style["" + prefix + "TransitionProperty"] = "" + (prefix ? '-' + prefix.toLowerCase() + '-' : '') + "transform, opacity";
|
510
|
-
this.style["" + prefix + "TransitionDuration"] = "0.8s, 0.55s";
|
511
|
-
this.style["" + prefix + "TransformOrigin"] = "left top";
|
512
|
-
}
|
513
|
-
return this;
|
514
|
-
},
|
515
|
-
show: function(addToParent) {
|
516
|
-
var show, _ref, _ref1,
|
517
|
-
_this = this;
|
518
|
-
show = function() {
|
519
|
-
var prefix, _i, _len;
|
520
|
-
_this.style.opacity = 1;
|
521
|
-
for (_i = 0, _len = prefixes.length; _i < _len; _i++) {
|
522
|
-
prefix = prefixes[_i];
|
523
|
-
_this.style["" + prefix + "Transform"] = 'scale(1, 1)';
|
524
|
-
}
|
525
|
-
return _this;
|
526
|
-
};
|
527
|
-
if (addToParent) {
|
528
|
-
if ((_ref = addToParent.append) != null) {
|
529
|
-
_ref.appendChild(this);
|
530
|
-
}
|
531
|
-
if ((_ref1 = addToParent.before) != null) {
|
532
|
-
_ref1.parentNode.insertBefore(this, addToParent.before);
|
533
|
-
}
|
534
|
-
setTimeout(show, 0);
|
535
|
-
} else {
|
536
|
-
show();
|
537
|
-
}
|
538
|
-
return this;
|
539
|
-
},
|
540
|
-
hide: function(shouldRemove) {
|
541
|
-
var prefix, _i, _len,
|
542
|
-
_this = this;
|
543
|
-
this.style.opacity = 0;
|
544
|
-
for (_i = 0, _len = prefixes.length; _i < _len; _i++) {
|
545
|
-
prefix = prefixes[_i];
|
546
|
-
this.style["" + prefix + "Transform"] = 'scale(0, 0)';
|
547
|
-
}
|
548
|
-
if (shouldRemove) {
|
549
|
-
setTimeout((function() {
|
550
|
-
var _ref;
|
551
|
-
return (_ref = _this.parentNode) != null ? _ref.removeChild(_this) : void 0;
|
552
|
-
}), 600);
|
553
|
-
}
|
554
|
-
return this;
|
555
|
-
}
|
556
|
-
};
|
557
|
-
|
558
|
-
}).call(this);
|