rails-i18nterface 0.1.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 +7 -0
- data/MIT-LICENSE +22 -0
- data/README.md +109 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/rails_i18nterface/application.js +8 -0
- data/app/assets/javascripts/rails_i18nterface/base.js +62 -0
- data/app/assets/javascripts/rails_i18nterface/ender.js +3260 -0
- data/app/assets/javascripts/rails_i18nterface/ender.min.js +45 -0
- data/app/assets/stylesheets/rails_i18nterface/application.css +450 -0
- data/app/controllers/rails_i18nterface/application_controller.rb +4 -0
- data/app/controllers/rails_i18nterface/translate_controller.rb +255 -0
- data/app/helpers/rails_i18nterface/application_helper.rb +4 -0
- data/app/helpers/rails_i18nterface/translate_helper.rb +74 -0
- data/app/models/translation.rb +4 -0
- data/app/views/layouts/rails_i18nterface/translate.html.erb +13 -0
- data/app/views/rails_i18nterface/translate/_namespaces.html.erb +1 -0
- data/app/views/rails_i18nterface/translate/_pagination.html.erb +18 -0
- data/app/views/rails_i18nterface/translate/index.html.erb +132 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20110921112044_create_translations.rb +18 -0
- data/lib/rails-i18nterface.rb +8 -0
- data/lib/rails-i18nterface/engine.rb +7 -0
- data/lib/rails-i18nterface/file.rb +35 -0
- data/lib/rails-i18nterface/keys.rb +192 -0
- data/lib/rails-i18nterface/log.rb +35 -0
- data/lib/rails-i18nterface/storage.rb +29 -0
- data/lib/rails-i18nterface/version.rb +3 -0
- data/lib/tasks/rails-i18nterface.rake +4 -0
- data/spec/controllers/translate_controller_spec.rb +135 -0
- data/spec/internal/app/assets/javascripts/application.js +2 -0
- data/spec/internal/app/assets/stylesheets/application.css +3 -0
- data/spec/internal/app/controllers/application_controller.rb +4 -0
- data/spec/internal/app/models/article.rb +11 -0
- data/spec/internal/app/views/application/index.html.erb +5 -0
- data/spec/internal/app/views/categories/category.erb +1 -0
- data/spec/internal/app/views/categories/category.html +1 -0
- data/spec/internal/app/views/categories/category.html.erb +1 -0
- data/spec/internal/app/views/categories/category.rhtml +5 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/routes.rb +4 -0
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +3 -0
- data/spec/internal/log/test.log +521 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/lib/file_spec.rb +53 -0
- data/spec/lib/keys_spec.rb +179 -0
- data/spec/lib/log_spec.rb +46 -0
- data/spec/lib/storage_spec.rb +33 -0
- data/spec/requests/search_spec.rb +62 -0
- data/spec/spec_helper.rb +37 -0
- metadata +200 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9f7afb70be8d0c0bf696b8b490be4b1314119b2c
|
4
|
+
data.tar.gz: 78d9b7b1cb33eb49c9f67d133181b9282b3802a4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 65280e7d68f0b1b2d5e28804ba53ff669d50b57bb6b398e78fbd68cb6fd214ad9519015ed710358a249ba7b01529fecdfea97873d5879b6a309da6f48043b160
|
7
|
+
data.tar.gz: ab47fa811503def3de2abd0dce9099bab87389ac1ea77440d1fa8d2392ba65a2caba0e16bf0969d10517cd22ff1ae41bc084dbd437c269f593b406b393489e46
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright 2009 Peter Marklund, Joakim Westerlund, Claudius Coenen
|
2
|
+
Copyright 2011 Larry Sprock, Artin Boghosain, Michal Hantl
|
3
|
+
Copyright 2013 Mose
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
# Rails I18nterface
|
2
|
+
|
3
|
+
[](http://travis-ci.org/mose/rails-i18nterface)
|
4
|
+
[](https://codeclimate.com/github/mose/rails-i18nterface)
|
5
|
+
|
6
|
+
This is a fork of an overhaul of a fork of a fork if rails-translate.
|
7
|
+
|
8
|
+
It was originally created by [Peter Marklund and Joakim Westerlund @ mynewsdesk](https://github.com/mynewsdesk/translate)
|
9
|
+
and later adapted to rails 3.0 by [Claudius Coenen](https://github.com/ccoenen/rails-translate).
|
10
|
+
This version is a spinoff of Claudius Coenen's version by [Larry Sprock](https://github.com/lardawge/rails-i18nterface).
|
11
|
+
It was renamed, refactored and prepared for rails 3.1 as an Engine. Over this work
|
12
|
+
[Michal Hantl](https://github.com/hakunin/rails-i18nterface) made a bunch of nice UI modifications
|
13
|
+
on his fork. Since then it was mroe or less abandonned.
|
14
|
+
|
15
|
+
I took over the evolution with some new features:
|
16
|
+
|
17
|
+
* testing using combustion and rspec
|
18
|
+
* redesign of the layout
|
19
|
+
* navigation overhaul, spliting of the namespaces in a foldable menu
|
20
|
+
* gathering of first-level translations under a ROOT container
|
21
|
+
* gemification and release of a version 0.0.2
|
22
|
+
* (the 0.0.1 was the original work from Larry Sprock but was not published as a gem)
|
23
|
+
* compatibility with rails 4 and ruby 2
|
24
|
+
|
25
|
+

|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
In Gemfile
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
gem 'rails-i18nterface'
|
33
|
+
```
|
34
|
+
In routes.rb
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
mount RailsI18nterface::Engine => "/translate", :as => "translate_engine"
|
38
|
+
```
|
39
|
+
Copy migration to store translated values and migrate
|
40
|
+
```
|
41
|
+
rake railties:install:migrations
|
42
|
+
rake db:migrate
|
43
|
+
```
|
44
|
+
### Protect access
|
45
|
+
|
46
|
+
You may want to protect the translation engine to admin and create a constraint
|
47
|
+
in your route:
|
48
|
+
```ruby
|
49
|
+
constraints AdminConstraint.new do
|
50
|
+
mount RailsI18nterface::Engine => "/translate", :as => "translate_engine"
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
Then create a `config/initializers/admin_constraint.rb` containing:
|
55
|
+
```ruby
|
56
|
+
class AdminConstraint
|
57
|
+
def matches?(request)
|
58
|
+
current_user && current_user.is_admin?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
(this example is for devise users, but you can adjust it to return true or false
|
63
|
+
according to your own context).
|
64
|
+
|
65
|
+
### Confifuration
|
66
|
+
|
67
|
+
You can configure `from_locales` and `to_locales` explicitly in your
|
68
|
+
`environments/development.rb` by adding
|
69
|
+
```ruby
|
70
|
+
config.from_locales = [:en]
|
71
|
+
config.to_locales = [:ja, :es, :fr]
|
72
|
+
```
|
73
|
+
Where `[:en]` and `[:ja, :es, :fr]` could be replaced by locale list of your choice.
|
74
|
+
|
75
|
+
## Todo
|
76
|
+
|
77
|
+
* fix the code smell reported by code climate
|
78
|
+
** extract code from the controller to a lib
|
79
|
+
** refactor the libs in a cleaner way
|
80
|
+
** apply rubocop and follow his law
|
81
|
+
* extend testing to refactored libs
|
82
|
+
* change navigation to an ajax-driven reload
|
83
|
+
|
84
|
+
## License
|
85
|
+
|
86
|
+
```
|
87
|
+
Copyright 2009 Peter Marklund, Joakim Westerlund, Claudius Coenen
|
88
|
+
Copyright 2011 Larry Sprock, Artin Boghosain, Michal Hantl
|
89
|
+
Copyright 2013 Mose
|
90
|
+
|
91
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
92
|
+
a copy of this software and associated documentation files (the
|
93
|
+
"Software"), to deal in the Software without restriction, including
|
94
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
95
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
96
|
+
permit persons to whom the Software is furnished to do so, subject to
|
97
|
+
the following conditions:
|
98
|
+
|
99
|
+
The above copyright notice and this permission notice shall be
|
100
|
+
included in all copies or substantial portions of the Software.
|
101
|
+
|
102
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
103
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
104
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
105
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
106
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
107
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
108
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
109
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
require 'bundler/setup'
|
8
|
+
|
9
|
+
require "bundler/gem_tasks"
|
10
|
+
Bundler::GemHelper.install_tasks
|
11
|
+
|
12
|
+
require "rake/testtask"
|
13
|
+
|
14
|
+
|
15
|
+
require "rspec/core/rake_task" # RSpec 2.0
|
16
|
+
task :spec do
|
17
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
18
|
+
t.rspec_opts = ["-c", "-f progress", "-r ./spec/spec_helper.rb"]
|
19
|
+
t.pattern = 'spec/**/*_spec.rb'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
task :default => :spec
|
@@ -0,0 +1,8 @@
|
|
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 rails_i18nterface/ender
|
8
|
+
//= require rails_i18nterface/base
|
@@ -0,0 +1,62 @@
|
|
1
|
+
$.domReady(function() {
|
2
|
+
function getFocus() {
|
3
|
+
url = window.location.href;
|
4
|
+
m = url.indexOf("key_pattern");
|
5
|
+
if (m !== -1) {
|
6
|
+
focus = url.slice(url.indexOf("=", m)+1, url.indexOf("&", m));
|
7
|
+
} else {
|
8
|
+
focus = false;
|
9
|
+
}
|
10
|
+
return focus;
|
11
|
+
}
|
12
|
+
function openNav(focus) {
|
13
|
+
if (focus) {
|
14
|
+
if (focus === '.') {
|
15
|
+
items = ['.'];
|
16
|
+
} else if (!focus.indexOf('.')) {
|
17
|
+
items = ['ROOT',focus];
|
18
|
+
} else {
|
19
|
+
items = focus.split(/\./);
|
20
|
+
}
|
21
|
+
namespace = [];
|
22
|
+
while (it = items.shift()) {
|
23
|
+
namespace.push(it);
|
24
|
+
join = namespace.join('.');
|
25
|
+
it = $("#namespaces span[data-id='"+join+"']");
|
26
|
+
if (it.length > 0) {
|
27
|
+
$(it.selector).siblings("ul").toggleClass("view");
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
return;
|
32
|
+
}
|
33
|
+
var focus = getFocus();
|
34
|
+
openNav(focus);
|
35
|
+
function filterThat(s,start) {
|
36
|
+
if (start) {
|
37
|
+
$("#key_type").val("starts_with");
|
38
|
+
} else {
|
39
|
+
$("#key_type").val("contains");
|
40
|
+
}
|
41
|
+
$("#key_pattern_value").val(s);
|
42
|
+
document.forms['filter_form'].submit();
|
43
|
+
}
|
44
|
+
$("#namespaces ul li").on("click", function(e) {
|
45
|
+
e.preventDefault();
|
46
|
+
e.stopPropagation();
|
47
|
+
$(this).children("ul").toggleClass("view");
|
48
|
+
});
|
49
|
+
$("#namespaces ul li .display").on("click", function(e) {
|
50
|
+
e.preventDefault();
|
51
|
+
e.stopPropagation();
|
52
|
+
filter = $(this).data("id");
|
53
|
+
filterThat(filter,true);
|
54
|
+
});
|
55
|
+
$("#namespaces ul li.item").on("click", function(e) {
|
56
|
+
e.preventDefault();
|
57
|
+
e.stopPropagation();
|
58
|
+
filter = $(this).data("id");
|
59
|
+
filterThat(filter,false);
|
60
|
+
});
|
61
|
+
|
62
|
+
});
|
@@ -0,0 +1,3260 @@
|
|
1
|
+
/*!
|
2
|
+
* =============================================================
|
3
|
+
* Ender: open module JavaScript framework (https://ender.no.de)
|
4
|
+
* Build: ender build jeesh reqwest --output app/assets/javascripts/rails_i18nterface/ender
|
5
|
+
* =============================================================
|
6
|
+
*/
|
7
|
+
|
8
|
+
/*!
|
9
|
+
* Ender: open module JavaScript framework (client-lib)
|
10
|
+
* copyright Dustin Diaz & Jacob Thornton 2011-2012 (@ded @fat)
|
11
|
+
* http://ender.jit.su
|
12
|
+
* License MIT
|
13
|
+
*/
|
14
|
+
(function (context) {
|
15
|
+
|
16
|
+
// a global object for node.js module compatiblity
|
17
|
+
// ============================================
|
18
|
+
|
19
|
+
context['global'] = context
|
20
|
+
|
21
|
+
// Implements simple module system
|
22
|
+
// losely based on CommonJS Modules spec v1.1.1
|
23
|
+
// ============================================
|
24
|
+
|
25
|
+
var modules = {}
|
26
|
+
, old = context['$']
|
27
|
+
, oldEnder = context['ender']
|
28
|
+
, oldRequire = context['require']
|
29
|
+
, oldProvide = context['provide']
|
30
|
+
|
31
|
+
function require (identifier) {
|
32
|
+
// modules can be required from ender's build system, or found on the window
|
33
|
+
var module = modules['$' + identifier] || window[identifier]
|
34
|
+
if (!module) throw new Error("Ender Error: Requested module '" + identifier + "' has not been defined.")
|
35
|
+
return module
|
36
|
+
}
|
37
|
+
|
38
|
+
function provide (name, what) {
|
39
|
+
return (modules['$' + name] = what)
|
40
|
+
}
|
41
|
+
|
42
|
+
context['provide'] = provide
|
43
|
+
context['require'] = require
|
44
|
+
|
45
|
+
function aug(o, o2) {
|
46
|
+
for (var k in o2) k != 'noConflict' && k != '_VERSION' && (o[k] = o2[k])
|
47
|
+
return o
|
48
|
+
}
|
49
|
+
|
50
|
+
/**
|
51
|
+
* main Ender return object
|
52
|
+
* @constructor
|
53
|
+
* @param {Array|Node|string} s a CSS selector or DOM node(s)
|
54
|
+
* @param {Array.|Node} r a root node(s)
|
55
|
+
*/
|
56
|
+
function Ender(s, r) {
|
57
|
+
var elements
|
58
|
+
, i
|
59
|
+
|
60
|
+
this.selector = s
|
61
|
+
// string || node || nodelist || window
|
62
|
+
if (typeof s == 'undefined') {
|
63
|
+
elements = []
|
64
|
+
this.selector = ''
|
65
|
+
} else if (typeof s == 'string' || s.nodeName || (s.length && 'item' in s) || s == window) {
|
66
|
+
elements = ender._select(s, r)
|
67
|
+
} else {
|
68
|
+
elements = isFinite(s.length) ? s : [s]
|
69
|
+
}
|
70
|
+
this.length = elements.length
|
71
|
+
for (i = this.length; i--;) this[i] = elements[i]
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
* @param {function(el, i, inst)} fn
|
76
|
+
* @param {Object} opt_scope
|
77
|
+
* @returns {Ender}
|
78
|
+
*/
|
79
|
+
Ender.prototype['forEach'] = function (fn, opt_scope) {
|
80
|
+
var i, l
|
81
|
+
// opt out of native forEach so we can intentionally call our own scope
|
82
|
+
// defaulting to the current item and be able to return self
|
83
|
+
for (i = 0, l = this.length; i < l; ++i) i in this && fn.call(opt_scope || this[i], this[i], i, this)
|
84
|
+
// return self for chaining
|
85
|
+
return this
|
86
|
+
}
|
87
|
+
|
88
|
+
Ender.prototype.$ = ender // handy reference to self
|
89
|
+
|
90
|
+
|
91
|
+
function ender(s, r) {
|
92
|
+
return new Ender(s, r)
|
93
|
+
}
|
94
|
+
|
95
|
+
ender['_VERSION'] = '0.4.3-dev'
|
96
|
+
|
97
|
+
ender.fn = Ender.prototype // for easy compat to jQuery plugins
|
98
|
+
|
99
|
+
ender.ender = function (o, chain) {
|
100
|
+
aug(chain ? Ender.prototype : ender, o)
|
101
|
+
}
|
102
|
+
|
103
|
+
ender._select = function (s, r) {
|
104
|
+
if (typeof s == 'string') return (r || document).querySelectorAll(s)
|
105
|
+
if (s.nodeName) return [s]
|
106
|
+
return s
|
107
|
+
}
|
108
|
+
|
109
|
+
|
110
|
+
// use callback to receive Ender's require & provide and remove them from global
|
111
|
+
ender.noConflict = function (callback) {
|
112
|
+
context['$'] = old
|
113
|
+
if (callback) {
|
114
|
+
context['provide'] = oldProvide
|
115
|
+
context['require'] = oldRequire
|
116
|
+
context['ender'] = oldEnder
|
117
|
+
if (typeof callback == 'function') callback(require, provide, this)
|
118
|
+
}
|
119
|
+
return this
|
120
|
+
}
|
121
|
+
|
122
|
+
if (typeof module !== 'undefined' && module.exports) module.exports = ender
|
123
|
+
// use subscript notation as extern for Closure compilation
|
124
|
+
context['ender'] = context['$'] = ender
|
125
|
+
|
126
|
+
}(this));
|
127
|
+
|
128
|
+
(function () {
|
129
|
+
|
130
|
+
var module = { exports: {} }, exports = module.exports;
|
131
|
+
|
132
|
+
/*!
|
133
|
+
* Reqwest! A general purpose XHR connection manager
|
134
|
+
* (c) Dustin Diaz 2012
|
135
|
+
* https://github.com/ded/reqwest
|
136
|
+
* license MIT
|
137
|
+
*/
|
138
|
+
!function (name, definition) {
|
139
|
+
if (typeof module != 'undefined' && module.exports) module.exports = definition()
|
140
|
+
else if (typeof define == 'function' && define.amd) define(definition)
|
141
|
+
else this[name] = definition()
|
142
|
+
}('reqwest', function () {
|
143
|
+
|
144
|
+
var win = window
|
145
|
+
, doc = document
|
146
|
+
, twoHundo = /^20\d$/
|
147
|
+
, byTag = 'getElementsByTagName'
|
148
|
+
, readyState = 'readyState'
|
149
|
+
, contentType = 'Content-Type'
|
150
|
+
, requestedWith = 'X-Requested-With'
|
151
|
+
, head = doc[byTag]('head')[0]
|
152
|
+
, uniqid = 0
|
153
|
+
, callbackPrefix = 'reqwest_' + (+new Date())
|
154
|
+
, lastValue // data stored by the most recent JSONP callback
|
155
|
+
, xmlHttpRequest = 'XMLHttpRequest'
|
156
|
+
|
157
|
+
var isArray = typeof Array.isArray == 'function' ? Array.isArray : function (a) {
|
158
|
+
return a instanceof Array
|
159
|
+
}
|
160
|
+
var defaultHeaders = {
|
161
|
+
contentType: 'application/x-www-form-urlencoded'
|
162
|
+
, requestedWith: xmlHttpRequest
|
163
|
+
, accept: {
|
164
|
+
'*': 'text/javascript, text/html, application/xml, text/xml, */*'
|
165
|
+
, xml: 'application/xml, text/xml'
|
166
|
+
, html: 'text/html'
|
167
|
+
, text: 'text/plain'
|
168
|
+
, json: 'application/json, text/javascript'
|
169
|
+
, js: 'application/javascript, text/javascript'
|
170
|
+
}
|
171
|
+
}
|
172
|
+
var xhr = win[xmlHttpRequest] ?
|
173
|
+
function () {
|
174
|
+
return new XMLHttpRequest()
|
175
|
+
} :
|
176
|
+
function () {
|
177
|
+
return new ActiveXObject('Microsoft.XMLHTTP')
|
178
|
+
}
|
179
|
+
|
180
|
+
function handleReadyState(o, success, error) {
|
181
|
+
return function () {
|
182
|
+
if (o && o[readyState] == 4) {
|
183
|
+
o.onreadystatechange = undefined;
|
184
|
+
if (twoHundo.test(o.status)) {
|
185
|
+
success(o)
|
186
|
+
} else {
|
187
|
+
error(o)
|
188
|
+
}
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
192
|
+
|
193
|
+
function setHeaders(http, o) {
|
194
|
+
var headers = o.headers || {}, h
|
195
|
+
headers.Accept = headers.Accept || defaultHeaders.accept[o.type] || defaultHeaders.accept['*']
|
196
|
+
// breaks cross-origin requests with legacy browsers
|
197
|
+
if (!o.crossOrigin && !headers[requestedWith]) headers[requestedWith] = defaultHeaders.requestedWith
|
198
|
+
if (!headers[contentType]) headers[contentType] = o.contentType || defaultHeaders.contentType
|
199
|
+
for (h in headers) {
|
200
|
+
headers.hasOwnProperty(h) && http.setRequestHeader(h, headers[h])
|
201
|
+
}
|
202
|
+
}
|
203
|
+
|
204
|
+
function setCredentials(http, o) {
|
205
|
+
if (typeof o.withCredentials !== "undefined" && typeof http.withCredentials !== "undefined") {
|
206
|
+
http.withCredentials = !!o.withCredentials
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
function generalCallback(data) {
|
211
|
+
lastValue = data
|
212
|
+
}
|
213
|
+
|
214
|
+
function urlappend(url, s) {
|
215
|
+
return url + (/\?/.test(url) ? '&' : '?') + s
|
216
|
+
}
|
217
|
+
|
218
|
+
function handleJsonp(o, fn, err, url) {
|
219
|
+
var reqId = uniqid++
|
220
|
+
, cbkey = o.jsonpCallback || 'callback' // the 'callback' key
|
221
|
+
, cbval = o.jsonpCallbackName || reqwest.getcallbackPrefix(reqId)
|
222
|
+
// , cbval = o.jsonpCallbackName || ('reqwest_' + reqId) // the 'callback' value
|
223
|
+
, cbreg = new RegExp('((^|\\?|&)' + cbkey + ')=([^&]+)')
|
224
|
+
, match = url.match(cbreg)
|
225
|
+
, script = doc.createElement('script')
|
226
|
+
, loaded = 0
|
227
|
+
, isIE10 = navigator.userAgent.indexOf('MSIE 10.0') !== -1
|
228
|
+
|
229
|
+
if (match) {
|
230
|
+
if (match[3] === '?') {
|
231
|
+
url = url.replace(cbreg, '$1=' + cbval) // wildcard callback func name
|
232
|
+
} else {
|
233
|
+
cbval = match[3] // provided callback func name
|
234
|
+
}
|
235
|
+
} else {
|
236
|
+
url = urlappend(url, cbkey + '=' + cbval) // no callback details, add 'em
|
237
|
+
}
|
238
|
+
|
239
|
+
win[cbval] = generalCallback
|
240
|
+
|
241
|
+
script.type = 'text/javascript'
|
242
|
+
script.src = url
|
243
|
+
script.async = true
|
244
|
+
if (typeof script.onreadystatechange !== 'undefined' && !isIE10) {
|
245
|
+
// need this for IE due to out-of-order onreadystatechange(), binding script
|
246
|
+
// execution to an event listener gives us control over when the script
|
247
|
+
// is executed. See http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html
|
248
|
+
//
|
249
|
+
// if this hack is used in IE10 jsonp callback are never called
|
250
|
+
script.event = 'onclick'
|
251
|
+
script.htmlFor = script.id = '_reqwest_' + reqId
|
252
|
+
}
|
253
|
+
|
254
|
+
script.onload = script.onreadystatechange = function () {
|
255
|
+
if ((script[readyState] && script[readyState] !== 'complete' && script[readyState] !== 'loaded') || loaded) {
|
256
|
+
return false
|
257
|
+
}
|
258
|
+
script.onload = script.onreadystatechange = null
|
259
|
+
script.onclick && script.onclick()
|
260
|
+
// Call the user callback with the last value stored and clean up values and scripts.
|
261
|
+
o.success && o.success(lastValue)
|
262
|
+
lastValue = undefined
|
263
|
+
head.removeChild(script)
|
264
|
+
loaded = 1
|
265
|
+
}
|
266
|
+
|
267
|
+
// Add the script to the DOM head
|
268
|
+
head.appendChild(script)
|
269
|
+
}
|
270
|
+
|
271
|
+
function getRequest(o, fn, err) {
|
272
|
+
var method = (o.method || 'GET').toUpperCase()
|
273
|
+
, url = typeof o === 'string' ? o : o.url
|
274
|
+
// convert non-string objects to query-string form unless o.processData is false
|
275
|
+
, data = (o.processData !== false && o.data && typeof o.data !== 'string')
|
276
|
+
? reqwest.toQueryString(o.data)
|
277
|
+
: (o.data || null)
|
278
|
+
, http
|
279
|
+
|
280
|
+
// if we're working on a GET request and we have data then we should append
|
281
|
+
// query string to end of URL and not post data
|
282
|
+
if ((o.type == 'jsonp' || method == 'GET') && data) {
|
283
|
+
url = urlappend(url, data)
|
284
|
+
data = null
|
285
|
+
}
|
286
|
+
|
287
|
+
if (o.type == 'jsonp') return handleJsonp(o, fn, err, url)
|
288
|
+
|
289
|
+
http = xhr()
|
290
|
+
http.open(method, url, true)
|
291
|
+
setHeaders(http, o)
|
292
|
+
setCredentials(http, o)
|
293
|
+
http.onreadystatechange = handleReadyState(http, fn, err)
|
294
|
+
o.before && o.before(http)
|
295
|
+
http.send(data)
|
296
|
+
return http
|
297
|
+
}
|
298
|
+
|
299
|
+
function Reqwest(o, fn) {
|
300
|
+
this.o = o
|
301
|
+
this.fn = fn
|
302
|
+
|
303
|
+
init.apply(this, arguments)
|
304
|
+
}
|
305
|
+
|
306
|
+
function setType(url) {
|
307
|
+
var m = url.match(/\.(json|jsonp|html|xml)(\?|$)/)
|
308
|
+
return m ? m[1] : 'js'
|
309
|
+
}
|
310
|
+
|
311
|
+
function init(o, fn) {
|
312
|
+
|
313
|
+
this.url = typeof o == 'string' ? o : o.url
|
314
|
+
this.timeout = null
|
315
|
+
|
316
|
+
// whether request has been fulfilled for purpose
|
317
|
+
// of tracking the Promises
|
318
|
+
this._fulfilled = false
|
319
|
+
// success handlers
|
320
|
+
this._fulfillmentHandlers = []
|
321
|
+
// error handlers
|
322
|
+
this._errorHandlers = []
|
323
|
+
// complete (both success and fail) handlers
|
324
|
+
this._completeHandlers = []
|
325
|
+
this._erred = false
|
326
|
+
this._responseArgs = {}
|
327
|
+
|
328
|
+
var self = this
|
329
|
+
, type = o.type || setType(this.url)
|
330
|
+
|
331
|
+
fn = fn || function () {}
|
332
|
+
|
333
|
+
if (o.timeout) {
|
334
|
+
this.timeout = setTimeout(function () {
|
335
|
+
self.abort()
|
336
|
+
}, o.timeout)
|
337
|
+
}
|
338
|
+
|
339
|
+
if (o.success) {
|
340
|
+
this._fulfillmentHandlers.push(function () {
|
341
|
+
o.success.apply(o, arguments)
|
342
|
+
})
|
343
|
+
}
|
344
|
+
|
345
|
+
if (o.error) {
|
346
|
+
this._errorHandlers.push(function () {
|
347
|
+
o.error.apply(o, arguments)
|
348
|
+
})
|
349
|
+
}
|
350
|
+
|
351
|
+
if (o.complete) {
|
352
|
+
this._completeHandlers.push(function () {
|
353
|
+
o.complete.apply(o, arguments)
|
354
|
+
})
|
355
|
+
}
|
356
|
+
|
357
|
+
function complete(resp) {
|
358
|
+
o.timeout && clearTimeout(self.timeout)
|
359
|
+
self.timeout = null
|
360
|
+
while (self._completeHandlers.length > 0) {
|
361
|
+
self._completeHandlers.shift()(resp)
|
362
|
+
}
|
363
|
+
}
|
364
|
+
|
365
|
+
function success(resp) {
|
366
|
+
var r = resp.responseText
|
367
|
+
if (r) {
|
368
|
+
switch (type) {
|
369
|
+
case 'json':
|
370
|
+
try {
|
371
|
+
resp = win.JSON ? win.JSON.parse(r) : eval('(' + r + ')')
|
372
|
+
} catch (err) {
|
373
|
+
return error(resp, 'Could not parse JSON in response', err)
|
374
|
+
}
|
375
|
+
break;
|
376
|
+
case 'js':
|
377
|
+
resp = eval(r)
|
378
|
+
break;
|
379
|
+
case 'html':
|
380
|
+
resp = r
|
381
|
+
break;
|
382
|
+
case 'xml':
|
383
|
+
resp = resp.responseXML;
|
384
|
+
break;
|
385
|
+
}
|
386
|
+
}
|
387
|
+
|
388
|
+
self._responseArgs.resp = resp
|
389
|
+
self._fulfilled = true
|
390
|
+
fn(resp)
|
391
|
+
while (self._fulfillmentHandlers.length > 0) {
|
392
|
+
self._fulfillmentHandlers.shift()(resp)
|
393
|
+
}
|
394
|
+
|
395
|
+
complete(resp)
|
396
|
+
}
|
397
|
+
|
398
|
+
function error(resp, msg, t) {
|
399
|
+
self._responseArgs.resp = resp
|
400
|
+
self._responseArgs.msg = msg
|
401
|
+
self._responseArgs.t = t
|
402
|
+
self._erred = true
|
403
|
+
while (self._errorHandlers.length > 0) {
|
404
|
+
self._errorHandlers.shift()(resp, msg, t)
|
405
|
+
}
|
406
|
+
complete(resp)
|
407
|
+
}
|
408
|
+
|
409
|
+
this.request = getRequest(o, success, error)
|
410
|
+
}
|
411
|
+
|
412
|
+
Reqwest.prototype = {
|
413
|
+
abort: function () {
|
414
|
+
this.request.abort()
|
415
|
+
}
|
416
|
+
|
417
|
+
, retry: function () {
|
418
|
+
init.call(this, this.o, this.fn)
|
419
|
+
}
|
420
|
+
|
421
|
+
/**
|
422
|
+
* Small deviation from the Promises A CommonJs specification
|
423
|
+
* http://wiki.commonjs.org/wiki/Promises/A
|
424
|
+
*/
|
425
|
+
|
426
|
+
/**
|
427
|
+
* `then` will execute upon successful requests
|
428
|
+
*/
|
429
|
+
, then: function (success, fail) {
|
430
|
+
if (this._fulfilled) {
|
431
|
+
success(this._responseArgs.resp)
|
432
|
+
} else if (this._erred) {
|
433
|
+
fail(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)
|
434
|
+
} else {
|
435
|
+
this._fulfillmentHandlers.push(success)
|
436
|
+
this._errorHandlers.push(fail)
|
437
|
+
}
|
438
|
+
return this
|
439
|
+
}
|
440
|
+
|
441
|
+
/**
|
442
|
+
* `always` will execute whether the request succeeds or fails
|
443
|
+
*/
|
444
|
+
, always: function (fn) {
|
445
|
+
if (this._fulfilled || this._erred) {
|
446
|
+
fn(this._responseArgs.resp)
|
447
|
+
} else {
|
448
|
+
this._completeHandlers.push(fn)
|
449
|
+
}
|
450
|
+
return this
|
451
|
+
}
|
452
|
+
|
453
|
+
/**
|
454
|
+
* `fail` will execute when the request fails
|
455
|
+
*/
|
456
|
+
, fail: function (fn) {
|
457
|
+
if (this._erred) {
|
458
|
+
fn(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)
|
459
|
+
} else {
|
460
|
+
this._errorHandlers.push(fn)
|
461
|
+
}
|
462
|
+
return this
|
463
|
+
}
|
464
|
+
}
|
465
|
+
|
466
|
+
function reqwest(o, fn) {
|
467
|
+
return new Reqwest(o, fn)
|
468
|
+
}
|
469
|
+
|
470
|
+
// normalize newline variants according to spec -> CRLF
|
471
|
+
function normalize(s) {
|
472
|
+
return s ? s.replace(/\r?\n/g, '\r\n') : ''
|
473
|
+
}
|
474
|
+
|
475
|
+
function serial(el, cb) {
|
476
|
+
var n = el.name
|
477
|
+
, t = el.tagName.toLowerCase()
|
478
|
+
, optCb = function (o) {
|
479
|
+
// IE gives value="" even where there is no value attribute
|
480
|
+
// 'specified' ref: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-862529273
|
481
|
+
if (o && !o.disabled)
|
482
|
+
cb(n, normalize(o.attributes.value && o.attributes.value.specified ? o.value : o.text))
|
483
|
+
}
|
484
|
+
|
485
|
+
// don't serialize elements that are disabled or without a name
|
486
|
+
if (el.disabled || !n) return;
|
487
|
+
|
488
|
+
switch (t) {
|
489
|
+
case 'input':
|
490
|
+
if (!/reset|button|image|file/i.test(el.type)) {
|
491
|
+
var ch = /checkbox/i.test(el.type)
|
492
|
+
, ra = /radio/i.test(el.type)
|
493
|
+
, val = el.value;
|
494
|
+
// WebKit gives us "" instead of "on" if a checkbox has no value, so correct it here
|
495
|
+
(!(ch || ra) || el.checked) && cb(n, normalize(ch && val === '' ? 'on' : val))
|
496
|
+
}
|
497
|
+
break;
|
498
|
+
case 'textarea':
|
499
|
+
cb(n, normalize(el.value))
|
500
|
+
break;
|
501
|
+
case 'select':
|
502
|
+
if (el.type.toLowerCase() === 'select-one') {
|
503
|
+
optCb(el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null)
|
504
|
+
} else {
|
505
|
+
for (var i = 0; el.length && i < el.length; i++) {
|
506
|
+
el.options[i].selected && optCb(el.options[i])
|
507
|
+
}
|
508
|
+
}
|
509
|
+
break;
|
510
|
+
}
|
511
|
+
}
|
512
|
+
|
513
|
+
// collect up all form elements found from the passed argument elements all
|
514
|
+
// the way down to child elements; pass a '<form>' or form fields.
|
515
|
+
// called with 'this'=callback to use for serial() on each element
|
516
|
+
function eachFormElement() {
|
517
|
+
var cb = this
|
518
|
+
, e, i, j
|
519
|
+
, serializeSubtags = function (e, tags) {
|
520
|
+
for (var i = 0; i < tags.length; i++) {
|
521
|
+
var fa = e[byTag](tags[i])
|
522
|
+
for (j = 0; j < fa.length; j++) serial(fa[j], cb)
|
523
|
+
}
|
524
|
+
}
|
525
|
+
|
526
|
+
for (i = 0; i < arguments.length; i++) {
|
527
|
+
e = arguments[i]
|
528
|
+
if (/input|select|textarea/i.test(e.tagName)) serial(e, cb)
|
529
|
+
serializeSubtags(e, [ 'input', 'select', 'textarea' ])
|
530
|
+
}
|
531
|
+
}
|
532
|
+
|
533
|
+
// standard query string style serialization
|
534
|
+
function serializeQueryString() {
|
535
|
+
return reqwest.toQueryString(reqwest.serializeArray.apply(null, arguments))
|
536
|
+
}
|
537
|
+
|
538
|
+
// { 'name': 'value', ... } style serialization
|
539
|
+
function serializeHash() {
|
540
|
+
var hash = {}
|
541
|
+
eachFormElement.apply(function (name, value) {
|
542
|
+
if (name in hash) {
|
543
|
+
hash[name] && !isArray(hash[name]) && (hash[name] = [hash[name]])
|
544
|
+
hash[name].push(value)
|
545
|
+
} else hash[name] = value
|
546
|
+
}, arguments)
|
547
|
+
return hash
|
548
|
+
}
|
549
|
+
|
550
|
+
// [ { name: 'name', value: 'value' }, ... ] style serialization
|
551
|
+
reqwest.serializeArray = function () {
|
552
|
+
var arr = []
|
553
|
+
eachFormElement.apply(function (name, value) {
|
554
|
+
arr.push({name: name, value: value})
|
555
|
+
}, arguments)
|
556
|
+
return arr
|
557
|
+
}
|
558
|
+
|
559
|
+
reqwest.serialize = function () {
|
560
|
+
if (arguments.length === 0) return ''
|
561
|
+
var opt, fn
|
562
|
+
, args = Array.prototype.slice.call(arguments, 0)
|
563
|
+
|
564
|
+
opt = args.pop()
|
565
|
+
opt && opt.nodeType && args.push(opt) && (opt = null)
|
566
|
+
opt && (opt = opt.type)
|
567
|
+
|
568
|
+
if (opt == 'map') fn = serializeHash
|
569
|
+
else if (opt == 'array') fn = reqwest.serializeArray
|
570
|
+
else fn = serializeQueryString
|
571
|
+
|
572
|
+
return fn.apply(null, args)
|
573
|
+
}
|
574
|
+
|
575
|
+
reqwest.toQueryString = function (o) {
|
576
|
+
var qs = '', i
|
577
|
+
, enc = encodeURIComponent
|
578
|
+
, push = function (k, v) {
|
579
|
+
qs += enc(k) + '=' + enc(v) + '&'
|
580
|
+
}
|
581
|
+
|
582
|
+
if (isArray(o)) {
|
583
|
+
for (i = 0; o && i < o.length; i++) push(o[i].name, o[i].value)
|
584
|
+
} else {
|
585
|
+
for (var k in o) {
|
586
|
+
if (!Object.hasOwnProperty.call(o, k)) continue;
|
587
|
+
var v = o[k]
|
588
|
+
if (isArray(v)) {
|
589
|
+
for (i = 0; i < v.length; i++) push(k, v[i])
|
590
|
+
} else push(k, o[k])
|
591
|
+
}
|
592
|
+
}
|
593
|
+
|
594
|
+
// spaces should be + according to spec
|
595
|
+
return qs.replace(/&$/, '').replace(/%20/g, '+')
|
596
|
+
}
|
597
|
+
|
598
|
+
reqwest.getcallbackPrefix = function (reqId) {
|
599
|
+
return callbackPrefix
|
600
|
+
}
|
601
|
+
|
602
|
+
// jQuery and Zepto compatibility, differences can be remapped here so you can call
|
603
|
+
// .ajax.compat(options, callback)
|
604
|
+
reqwest.compat = function (o, fn) {
|
605
|
+
if (o) {
|
606
|
+
o.type && (o.method = o.type) && delete o.type
|
607
|
+
o.dataType && (o.type = o.dataType)
|
608
|
+
o.jsonpCallback && (o.jsonpCallbackName = o.jsonpCallback) && delete o.jsonpCallback
|
609
|
+
o.jsonp && (o.jsonpCallback = o.jsonp)
|
610
|
+
}
|
611
|
+
return new Reqwest(o, fn)
|
612
|
+
}
|
613
|
+
|
614
|
+
return reqwest
|
615
|
+
});
|
616
|
+
|
617
|
+
|
618
|
+
provide("reqwest", module.exports);
|
619
|
+
|
620
|
+
!function ($) {
|
621
|
+
var r = require('reqwest')
|
622
|
+
, integrate = function(method) {
|
623
|
+
return function() {
|
624
|
+
var args = Array.prototype.slice.call(arguments, 0)
|
625
|
+
, i = (this && this.length) || 0
|
626
|
+
while (i--) args.unshift(this[i])
|
627
|
+
return r[method].apply(null, args)
|
628
|
+
}
|
629
|
+
}
|
630
|
+
, s = integrate('serialize')
|
631
|
+
, sa = integrate('serializeArray')
|
632
|
+
|
633
|
+
$.ender({
|
634
|
+
ajax: r
|
635
|
+
, serialize: r.serialize
|
636
|
+
, serializeArray: r.serializeArray
|
637
|
+
, toQueryString: r.toQueryString
|
638
|
+
})
|
639
|
+
|
640
|
+
$.ender({
|
641
|
+
serialize: s
|
642
|
+
, serializeArray: sa
|
643
|
+
}, true)
|
644
|
+
}(ender);
|
645
|
+
|
646
|
+
|
647
|
+
}());
|
648
|
+
|
649
|
+
(function () {
|
650
|
+
|
651
|
+
var module = { exports: {} }, exports = module.exports;
|
652
|
+
|
653
|
+
/*!
|
654
|
+
* Bean - copyright (c) Jacob Thornton 2011-2012
|
655
|
+
* https://github.com/fat/bean
|
656
|
+
* MIT license
|
657
|
+
*/
|
658
|
+
!(function (name, context, definition) {
|
659
|
+
if (typeof module != 'undefined' && module.exports) module.exports = definition(name, context);
|
660
|
+
else if (typeof define == 'function' && typeof define.amd == 'object') define(definition);
|
661
|
+
else context[name] = definition(name, context);
|
662
|
+
}('bean', this, function (name, context) {
|
663
|
+
var win = window
|
664
|
+
, old = context[name]
|
665
|
+
, namespaceRegex = /[^\.]*(?=\..*)\.|.*/
|
666
|
+
, nameRegex = /\..*/
|
667
|
+
, addEvent = 'addEventListener'
|
668
|
+
, removeEvent = 'removeEventListener'
|
669
|
+
, doc = document || {}
|
670
|
+
, root = doc.documentElement || {}
|
671
|
+
, W3C_MODEL = root[addEvent]
|
672
|
+
, eventSupport = W3C_MODEL ? addEvent : 'attachEvent'
|
673
|
+
, ONE = {} // singleton for quick matching making add() do one()
|
674
|
+
|
675
|
+
, slice = Array.prototype.slice
|
676
|
+
, str2arr = function (s, d) { return s.split(d || ' ') }
|
677
|
+
, isString = function (o) { return typeof o == 'string' }
|
678
|
+
, isFunction = function (o) { return typeof o == 'function' }
|
679
|
+
|
680
|
+
// events that we consider to be 'native', anything not in this list will
|
681
|
+
// be treated as a custom event
|
682
|
+
, standardNativeEvents =
|
683
|
+
'click dblclick mouseup mousedown contextmenu ' + // mouse buttons
|
684
|
+
'mousewheel mousemultiwheel DOMMouseScroll ' + // mouse wheel
|
685
|
+
'mouseover mouseout mousemove selectstart selectend ' + // mouse movement
|
686
|
+
'keydown keypress keyup ' + // keyboard
|
687
|
+
'orientationchange ' + // mobile
|
688
|
+
'focus blur change reset select submit ' + // form elements
|
689
|
+
'load unload beforeunload resize move DOMContentLoaded ' + // window
|
690
|
+
'readystatechange message ' + // window
|
691
|
+
'error abort scroll ' // misc
|
692
|
+
// element.fireEvent('onXYZ'... is not forgiving if we try to fire an event
|
693
|
+
// that doesn't actually exist, so make sure we only do these on newer browsers
|
694
|
+
, w3cNativeEvents =
|
695
|
+
'show ' + // mouse buttons
|
696
|
+
'input invalid ' + // form elements
|
697
|
+
'touchstart touchmove touchend touchcancel ' + // touch
|
698
|
+
'gesturestart gesturechange gestureend ' + // gesture
|
699
|
+
'textinput' + // TextEvent
|
700
|
+
'readystatechange pageshow pagehide popstate ' + // window
|
701
|
+
'hashchange offline online ' + // window
|
702
|
+
'afterprint beforeprint ' + // printing
|
703
|
+
'dragstart dragenter dragover dragleave drag drop dragend ' + // dnd
|
704
|
+
'loadstart progress suspend emptied stalled loadmetadata ' + // media
|
705
|
+
'loadeddata canplay canplaythrough playing waiting seeking ' + // media
|
706
|
+
'seeked ended durationchange timeupdate play pause ratechange ' + // media
|
707
|
+
'volumechange cuechange ' + // media
|
708
|
+
'checking noupdate downloading cached updateready obsolete ' // appcache
|
709
|
+
|
710
|
+
// convert to a hash for quick lookups
|
711
|
+
, nativeEvents = (function (hash, events, i) {
|
712
|
+
for (i = 0; i < events.length; i++) events[i] && (hash[events[i]] = 1)
|
713
|
+
return hash
|
714
|
+
}({}, str2arr(standardNativeEvents + (W3C_MODEL ? w3cNativeEvents : ''))))
|
715
|
+
|
716
|
+
// custom events are events that we *fake*, they are not provided natively but
|
717
|
+
// we can use native events to generate them
|
718
|
+
, customEvents = (function () {
|
719
|
+
var isAncestor = 'compareDocumentPosition' in root
|
720
|
+
? function (element, container) {
|
721
|
+
return container.compareDocumentPosition && (container.compareDocumentPosition(element) & 16) === 16
|
722
|
+
}
|
723
|
+
: 'contains' in root
|
724
|
+
? function (element, container) {
|
725
|
+
container = container.nodeType === 9 || container === window ? root : container
|
726
|
+
return container !== element && container.contains(element)
|
727
|
+
}
|
728
|
+
: function (element, container) {
|
729
|
+
while (element = element.parentNode) if (element === container) return 1
|
730
|
+
return 0
|
731
|
+
}
|
732
|
+
, check = function (event) {
|
733
|
+
var related = event.relatedTarget
|
734
|
+
return !related
|
735
|
+
? related == null
|
736
|
+
: (related !== this && related.prefix !== 'xul' && !/document/.test(this.toString())
|
737
|
+
&& !isAncestor(related, this))
|
738
|
+
}
|
739
|
+
|
740
|
+
return {
|
741
|
+
mouseenter: { base: 'mouseover', condition: check }
|
742
|
+
, mouseleave: { base: 'mouseout', condition: check }
|
743
|
+
, mousewheel: { base: /Firefox/.test(navigator.userAgent) ? 'DOMMouseScroll' : 'mousewheel' }
|
744
|
+
}
|
745
|
+
}())
|
746
|
+
|
747
|
+
// we provide a consistent Event object across browsers by taking the actual DOM
|
748
|
+
// event object and generating a new one from its properties.
|
749
|
+
, Event = (function () {
|
750
|
+
// a whitelist of properties (for different event types) tells us what to check for and copy
|
751
|
+
var commonProps = str2arr('altKey attrChange attrName bubbles cancelable ctrlKey currentTarget ' +
|
752
|
+
'detail eventPhase getModifierState isTrusted metaKey relatedNode relatedTarget shiftKey ' +
|
753
|
+
'srcElement target timeStamp type view which propertyName')
|
754
|
+
, mouseProps = commonProps.concat(str2arr('button buttons clientX clientY dataTransfer ' +
|
755
|
+
'fromElement offsetX offsetY pageX pageY screenX screenY toElement'))
|
756
|
+
, mouseWheelProps = mouseProps.concat(str2arr('wheelDelta wheelDeltaX wheelDeltaY wheelDeltaZ ' +
|
757
|
+
'axis')) // 'axis' is FF specific
|
758
|
+
, keyProps = commonProps.concat(str2arr('char charCode key keyCode keyIdentifier ' +
|
759
|
+
'keyLocation location'))
|
760
|
+
, textProps = commonProps.concat(str2arr('data'))
|
761
|
+
, touchProps = commonProps.concat(str2arr('touches targetTouches changedTouches scale rotation'))
|
762
|
+
, messageProps = commonProps.concat(str2arr('data origin source'))
|
763
|
+
, stateProps = commonProps.concat(str2arr('state'))
|
764
|
+
, overOutRegex = /over|out/
|
765
|
+
// some event types need special handling and some need special properties, do that all here
|
766
|
+
, typeFixers = [
|
767
|
+
{ // key events
|
768
|
+
reg: /key/i
|
769
|
+
, fix: function (event, newEvent) {
|
770
|
+
newEvent.keyCode = event.keyCode || event.which
|
771
|
+
return keyProps
|
772
|
+
}
|
773
|
+
}
|
774
|
+
, { // mouse events
|
775
|
+
reg: /click|mouse(?!(.*wheel|scroll))|menu|drag|drop/i
|
776
|
+
, fix: function (event, newEvent, type) {
|
777
|
+
newEvent.rightClick = event.which === 3 || event.button === 2
|
778
|
+
newEvent.pos = { x: 0, y: 0 }
|
779
|
+
if (event.pageX || event.pageY) {
|
780
|
+
newEvent.clientX = event.pageX
|
781
|
+
newEvent.clientY = event.pageY
|
782
|
+
} else if (event.clientX || event.clientY) {
|
783
|
+
newEvent.clientX = event.clientX + doc.body.scrollLeft + root.scrollLeft
|
784
|
+
newEvent.clientY = event.clientY + doc.body.scrollTop + root.scrollTop
|
785
|
+
}
|
786
|
+
if (overOutRegex.test(type)) {
|
787
|
+
newEvent.relatedTarget = event.relatedTarget
|
788
|
+
|| event[(type == 'mouseover' ? 'from' : 'to') + 'Element']
|
789
|
+
}
|
790
|
+
return mouseProps
|
791
|
+
}
|
792
|
+
}
|
793
|
+
, { // mouse wheel events
|
794
|
+
reg: /mouse.*(wheel|scroll)/i
|
795
|
+
, fix: function () { return mouseWheelProps }
|
796
|
+
}
|
797
|
+
, { // TextEvent
|
798
|
+
reg: /^text/i
|
799
|
+
, fix: function () { return textProps }
|
800
|
+
}
|
801
|
+
, { // touch and gesture events
|
802
|
+
reg: /^touch|^gesture/i
|
803
|
+
, fix: function () { return touchProps }
|
804
|
+
}
|
805
|
+
, { // message events
|
806
|
+
reg: /^message$/i
|
807
|
+
, fix: function () { return messageProps }
|
808
|
+
}
|
809
|
+
, { // popstate events
|
810
|
+
reg: /^popstate$/i
|
811
|
+
, fix: function () { return stateProps }
|
812
|
+
}
|
813
|
+
, { // everything else
|
814
|
+
reg: /.*/
|
815
|
+
, fix: function () { return commonProps }
|
816
|
+
}
|
817
|
+
]
|
818
|
+
, typeFixerMap = {} // used to map event types to fixer functions (above), a basic cache mechanism
|
819
|
+
|
820
|
+
, Event = function (event, element, isNative) {
|
821
|
+
if (!arguments.length) return
|
822
|
+
event = event || ((element.ownerDocument || element.document || element).parentWindow || win).event
|
823
|
+
this.originalEvent = event
|
824
|
+
this.isNative = isNative
|
825
|
+
this.isBean = true
|
826
|
+
|
827
|
+
if (!event) return
|
828
|
+
|
829
|
+
var type = event.type
|
830
|
+
, target = event.target || event.srcElement
|
831
|
+
, i, l, p, props, fixer
|
832
|
+
|
833
|
+
this.target = target && target.nodeType === 3 ? target.parentNode : target
|
834
|
+
|
835
|
+
if (isNative) { // we only need basic augmentation on custom events, the rest expensive & pointless
|
836
|
+
fixer = typeFixerMap[type]
|
837
|
+
if (!fixer) { // haven't encountered this event type before, map a fixer function for it
|
838
|
+
for (i = 0, l = typeFixers.length; i < l; i++) {
|
839
|
+
if (typeFixers[i].reg.test(type)) { // guaranteed to match at least one, last is .*
|
840
|
+
typeFixerMap[type] = fixer = typeFixers[i].fix
|
841
|
+
break
|
842
|
+
}
|
843
|
+
}
|
844
|
+
}
|
845
|
+
|
846
|
+
props = fixer(event, this, type)
|
847
|
+
for (i = props.length; i--;) {
|
848
|
+
if (!((p = props[i]) in this) && p in event) this[p] = event[p]
|
849
|
+
}
|
850
|
+
}
|
851
|
+
}
|
852
|
+
|
853
|
+
// preventDefault() and stopPropagation() are a consistent interface to those functions
|
854
|
+
// on the DOM, stop() is an alias for both of them together
|
855
|
+
Event.prototype.preventDefault = function () {
|
856
|
+
if (this.originalEvent.preventDefault) this.originalEvent.preventDefault()
|
857
|
+
else this.originalEvent.returnValue = false
|
858
|
+
}
|
859
|
+
Event.prototype.stopPropagation = function () {
|
860
|
+
if (this.originalEvent.stopPropagation) this.originalEvent.stopPropagation()
|
861
|
+
else this.originalEvent.cancelBubble = true
|
862
|
+
}
|
863
|
+
Event.prototype.stop = function () {
|
864
|
+
this.preventDefault()
|
865
|
+
this.stopPropagation()
|
866
|
+
this.stopped = true
|
867
|
+
}
|
868
|
+
// stopImmediatePropagation() has to be handled internally because we manage the event list for
|
869
|
+
// each element
|
870
|
+
// note that originalElement may be a Bean#Event object in some situations
|
871
|
+
Event.prototype.stopImmediatePropagation = function () {
|
872
|
+
if (this.originalEvent.stopImmediatePropagation) this.originalEvent.stopImmediatePropagation()
|
873
|
+
this.isImmediatePropagationStopped = function () { return true }
|
874
|
+
}
|
875
|
+
Event.prototype.isImmediatePropagationStopped = function () {
|
876
|
+
return this.originalEvent.isImmediatePropagationStopped && this.originalEvent.isImmediatePropagationStopped()
|
877
|
+
}
|
878
|
+
Event.prototype.clone = function (currentTarget) {
|
879
|
+
//TODO: this is ripe for optimisation, new events are *expensive*
|
880
|
+
// improving this will speed up delegated events
|
881
|
+
var ne = new Event(this, this.element, this.isNative)
|
882
|
+
ne.currentTarget = currentTarget
|
883
|
+
return ne
|
884
|
+
}
|
885
|
+
|
886
|
+
return Event
|
887
|
+
}())
|
888
|
+
|
889
|
+
// if we're in old IE we can't do onpropertychange on doc or win so we use doc.documentElement for both
|
890
|
+
, targetElement = function (element, isNative) {
|
891
|
+
return !W3C_MODEL && !isNative && (element === doc || element === win) ? root : element
|
892
|
+
}
|
893
|
+
|
894
|
+
/**
|
895
|
+
* Bean maintains an internal registry for event listeners. We don't touch elements, objects
|
896
|
+
* or functions to identify them, instead we store everything in the registry.
|
897
|
+
* Each event listener has a RegEntry object, we have one 'registry' for the whole instance.
|
898
|
+
*/
|
899
|
+
, RegEntry = (function () {
|
900
|
+
// each handler is wrapped so we can handle delegation and custom events
|
901
|
+
var wrappedHandler = function (element, fn, condition, args) {
|
902
|
+
var call = function (event, eargs) {
|
903
|
+
return fn.apply(element, args ? slice.call(eargs, event ? 0 : 1).concat(args) : eargs)
|
904
|
+
}
|
905
|
+
, findTarget = function (event, eventElement) {
|
906
|
+
return fn.__beanDel ? fn.__beanDel.ft(event.target, element) : eventElement
|
907
|
+
}
|
908
|
+
, handler = condition
|
909
|
+
? function (event) {
|
910
|
+
var target = findTarget(event, this) // deleated event
|
911
|
+
if (condition.apply(target, arguments)) {
|
912
|
+
if (event) event.currentTarget = target
|
913
|
+
return call(event, arguments)
|
914
|
+
}
|
915
|
+
}
|
916
|
+
: function (event) {
|
917
|
+
if (fn.__beanDel) event = event.clone(findTarget(event)) // delegated event, fix the fix
|
918
|
+
return call(event, arguments)
|
919
|
+
}
|
920
|
+
handler.__beanDel = fn.__beanDel
|
921
|
+
return handler
|
922
|
+
}
|
923
|
+
|
924
|
+
, RegEntry = function (element, type, handler, original, namespaces, args, root) {
|
925
|
+
var customType = customEvents[type]
|
926
|
+
, isNative
|
927
|
+
|
928
|
+
if (type == 'unload') {
|
929
|
+
// self clean-up
|
930
|
+
handler = once(removeListener, element, type, handler, original)
|
931
|
+
}
|
932
|
+
|
933
|
+
if (customType) {
|
934
|
+
if (customType.condition) {
|
935
|
+
handler = wrappedHandler(element, handler, customType.condition, args)
|
936
|
+
}
|
937
|
+
type = customType.base || type
|
938
|
+
}
|
939
|
+
|
940
|
+
this.isNative = isNative = nativeEvents[type] && !!element[eventSupport]
|
941
|
+
this.customType = !W3C_MODEL && !isNative && type
|
942
|
+
this.element = element
|
943
|
+
this.type = type
|
944
|
+
this.original = original
|
945
|
+
this.namespaces = namespaces
|
946
|
+
this.eventType = W3C_MODEL || isNative ? type : 'propertychange'
|
947
|
+
this.target = targetElement(element, isNative)
|
948
|
+
this[eventSupport] = !!this.target[eventSupport]
|
949
|
+
this.root = root
|
950
|
+
this.handler = wrappedHandler(element, handler, null, args)
|
951
|
+
}
|
952
|
+
|
953
|
+
// given a list of namespaces, is our entry in any of them?
|
954
|
+
RegEntry.prototype.inNamespaces = function (checkNamespaces) {
|
955
|
+
var i, j, c = 0
|
956
|
+
if (!checkNamespaces) return true
|
957
|
+
if (!this.namespaces) return false
|
958
|
+
for (i = checkNamespaces.length; i--;) {
|
959
|
+
for (j = this.namespaces.length; j--;) {
|
960
|
+
if (checkNamespaces[i] == this.namespaces[j]) c++
|
961
|
+
}
|
962
|
+
}
|
963
|
+
return checkNamespaces.length === c
|
964
|
+
}
|
965
|
+
|
966
|
+
// match by element, original fn (opt), handler fn (opt)
|
967
|
+
RegEntry.prototype.matches = function (checkElement, checkOriginal, checkHandler) {
|
968
|
+
return this.element === checkElement &&
|
969
|
+
(!checkOriginal || this.original === checkOriginal) &&
|
970
|
+
(!checkHandler || this.handler === checkHandler)
|
971
|
+
}
|
972
|
+
|
973
|
+
return RegEntry
|
974
|
+
}())
|
975
|
+
|
976
|
+
, registry = (function () {
|
977
|
+
// our map stores arrays by event type, just because it's better than storing
|
978
|
+
// everything in a single array.
|
979
|
+
// uses '$' as a prefix for the keys for safety and 'r' as a special prefix for
|
980
|
+
// rootListeners so we can look them up fast
|
981
|
+
var map = {}
|
982
|
+
|
983
|
+
// generic functional search of our registry for matching listeners,
|
984
|
+
// `fn` returns false to break out of the loop
|
985
|
+
, forAll = function (element, type, original, handler, root, fn) {
|
986
|
+
var pfx = root ? 'r' : '$'
|
987
|
+
if (!type || type == '*') {
|
988
|
+
// search the whole registry
|
989
|
+
for (var t in map) {
|
990
|
+
if (t.charAt(0) == pfx) {
|
991
|
+
forAll(element, t.substr(1), original, handler, root, fn)
|
992
|
+
}
|
993
|
+
}
|
994
|
+
} else {
|
995
|
+
var i = 0, l, list = map[pfx + type], all = element == '*'
|
996
|
+
if (!list) return
|
997
|
+
for (l = list.length; i < l; i++) {
|
998
|
+
if ((all || list[i].matches(element, original, handler)) && !fn(list[i], list, i, type)) return
|
999
|
+
}
|
1000
|
+
}
|
1001
|
+
}
|
1002
|
+
|
1003
|
+
, has = function (element, type, original, root) {
|
1004
|
+
// we're not using forAll here simply because it's a bit slower and this
|
1005
|
+
// needs to be fast
|
1006
|
+
var i, list = map[(root ? 'r' : '$') + type]
|
1007
|
+
if (list) {
|
1008
|
+
for (i = list.length; i--;) {
|
1009
|
+
if (!list[i].root && list[i].matches(element, original, null)) return true
|
1010
|
+
}
|
1011
|
+
}
|
1012
|
+
return false
|
1013
|
+
}
|
1014
|
+
|
1015
|
+
, get = function (element, type, original, root) {
|
1016
|
+
var entries = []
|
1017
|
+
forAll(element, type, original, null, root, function (entry) {
|
1018
|
+
return entries.push(entry)
|
1019
|
+
})
|
1020
|
+
return entries
|
1021
|
+
}
|
1022
|
+
|
1023
|
+
, put = function (entry) {
|
1024
|
+
var has = !entry.root && !this.has(entry.element, entry.type, null, false)
|
1025
|
+
, key = (entry.root ? 'r' : '$') + entry.type
|
1026
|
+
;(map[key] || (map[key] = [])).push(entry)
|
1027
|
+
return has
|
1028
|
+
}
|
1029
|
+
|
1030
|
+
, del = function (entry) {
|
1031
|
+
forAll(entry.element, entry.type, null, entry.handler, entry.root, function (entry, list, i) {
|
1032
|
+
list.splice(i, 1)
|
1033
|
+
entry.removed = true
|
1034
|
+
if (list.length === 0) delete map[(entry.root ? 'r' : '$') + entry.type]
|
1035
|
+
return false
|
1036
|
+
})
|
1037
|
+
}
|
1038
|
+
|
1039
|
+
// dump all entries, used for onunload
|
1040
|
+
, entries = function () {
|
1041
|
+
var t, entries = []
|
1042
|
+
for (t in map) {
|
1043
|
+
if (t.charAt(0) == '$') entries = entries.concat(map[t])
|
1044
|
+
}
|
1045
|
+
return entries
|
1046
|
+
}
|
1047
|
+
|
1048
|
+
return { has: has, get: get, put: put, del: del, entries: entries }
|
1049
|
+
}())
|
1050
|
+
|
1051
|
+
// we need a selector engine for delegated events, use querySelectorAll if it exists
|
1052
|
+
// but for older browsers we need Qwery, Sizzle or similar
|
1053
|
+
, selectorEngine
|
1054
|
+
, setSelectorEngine = function (e) {
|
1055
|
+
if (!arguments.length) {
|
1056
|
+
selectorEngine = doc.querySelectorAll
|
1057
|
+
? function (s, r) {
|
1058
|
+
return r.querySelectorAll(s)
|
1059
|
+
}
|
1060
|
+
: function () {
|
1061
|
+
throw new Error('Bean: No selector engine installed') // eeek
|
1062
|
+
}
|
1063
|
+
} else {
|
1064
|
+
selectorEngine = e
|
1065
|
+
}
|
1066
|
+
}
|
1067
|
+
|
1068
|
+
// we attach this listener to each DOM event that we need to listen to, only once
|
1069
|
+
// per event type per DOM element
|
1070
|
+
, rootListener = function (event, type) {
|
1071
|
+
if (!W3C_MODEL && type && event && event.propertyName != '_on' + type) return
|
1072
|
+
|
1073
|
+
var listeners = registry.get(this, type || event.type, null, false)
|
1074
|
+
, l = listeners.length
|
1075
|
+
, i = 0
|
1076
|
+
|
1077
|
+
event = new Event(event, this, true)
|
1078
|
+
if (type) event.type = type
|
1079
|
+
|
1080
|
+
// iterate through all handlers registered for this type, calling them unless they have
|
1081
|
+
// been removed by a previous handler or stopImmediatePropagation() has been called
|
1082
|
+
for (; i < l && !event.isImmediatePropagationStopped(); i++) {
|
1083
|
+
if (!listeners[i].removed) listeners[i].handler.call(this, event)
|
1084
|
+
}
|
1085
|
+
}
|
1086
|
+
|
1087
|
+
// add and remove listeners to DOM elements
|
1088
|
+
, listener = W3C_MODEL
|
1089
|
+
? function (element, type, add) {
|
1090
|
+
// new browsers
|
1091
|
+
element[add ? addEvent : removeEvent](type, rootListener, false)
|
1092
|
+
}
|
1093
|
+
: function (element, type, add, custom) {
|
1094
|
+
// IE8 and below, use attachEvent/detachEvent and we have to piggy-back propertychange events
|
1095
|
+
// to simulate event bubbling etc.
|
1096
|
+
var entry
|
1097
|
+
if (add) {
|
1098
|
+
registry.put(entry = new RegEntry(
|
1099
|
+
element
|
1100
|
+
, custom || type
|
1101
|
+
, function (event) { // handler
|
1102
|
+
rootListener.call(element, event, custom)
|
1103
|
+
}
|
1104
|
+
, rootListener
|
1105
|
+
, null
|
1106
|
+
, null
|
1107
|
+
, true // is root
|
1108
|
+
))
|
1109
|
+
if (custom && element['_on' + custom] == null) element['_on' + custom] = 0
|
1110
|
+
entry.target.attachEvent('on' + entry.eventType, entry.handler)
|
1111
|
+
} else {
|
1112
|
+
entry = registry.get(element, custom || type, rootListener, true)[0]
|
1113
|
+
if (entry) {
|
1114
|
+
entry.target.detachEvent('on' + entry.eventType, entry.handler)
|
1115
|
+
registry.del(entry)
|
1116
|
+
}
|
1117
|
+
}
|
1118
|
+
}
|
1119
|
+
|
1120
|
+
, once = function (rm, element, type, fn, originalFn) {
|
1121
|
+
// wrap the handler in a handler that does a remove as well
|
1122
|
+
return function () {
|
1123
|
+
fn.apply(this, arguments)
|
1124
|
+
rm(element, type, originalFn)
|
1125
|
+
}
|
1126
|
+
}
|
1127
|
+
|
1128
|
+
, removeListener = function (element, orgType, handler, namespaces) {
|
1129
|
+
var type = orgType && orgType.replace(nameRegex, '')
|
1130
|
+
, handlers = registry.get(element, type, null, false)
|
1131
|
+
, removed = {}
|
1132
|
+
, i, l
|
1133
|
+
|
1134
|
+
for (i = 0, l = handlers.length; i < l; i++) {
|
1135
|
+
if ((!handler || handlers[i].original === handler) && handlers[i].inNamespaces(namespaces)) {
|
1136
|
+
// TODO: this is problematic, we have a registry.get() and registry.del() that
|
1137
|
+
// both do registry searches so we waste cycles doing this. Needs to be rolled into
|
1138
|
+
// a single registry.forAll(fn) that removes while finding, but the catch is that
|
1139
|
+
// we'll be splicing the arrays that we're iterating over. Needs extra tests to
|
1140
|
+
// make sure we don't screw it up. @rvagg
|
1141
|
+
registry.del(handlers[i])
|
1142
|
+
if (!removed[handlers[i].eventType] && handlers[i][eventSupport])
|
1143
|
+
removed[handlers[i].eventType] = { t: handlers[i].eventType, c: handlers[i].type }
|
1144
|
+
}
|
1145
|
+
}
|
1146
|
+
// check each type/element for removed listeners and remove the rootListener where it's no longer needed
|
1147
|
+
for (i in removed) {
|
1148
|
+
if (!registry.has(element, removed[i].t, null, false)) {
|
1149
|
+
// last listener of this type, remove the rootListener
|
1150
|
+
listener(element, removed[i].t, false, removed[i].c)
|
1151
|
+
}
|
1152
|
+
}
|
1153
|
+
}
|
1154
|
+
|
1155
|
+
// set up a delegate helper using the given selector, wrap the handler function
|
1156
|
+
, delegate = function (selector, fn) {
|
1157
|
+
//TODO: findTarget (therefore $) is called twice, once for match and once for
|
1158
|
+
// setting e.currentTarget, fix this so it's only needed once
|
1159
|
+
var findTarget = function (target, root) {
|
1160
|
+
var i, array = isString(selector) ? selectorEngine(selector, root) : selector
|
1161
|
+
for (; target && target !== root; target = target.parentNode) {
|
1162
|
+
for (i = array.length; i--;) {
|
1163
|
+
if (array[i] === target) return target
|
1164
|
+
}
|
1165
|
+
}
|
1166
|
+
}
|
1167
|
+
, handler = function (e) {
|
1168
|
+
var match = findTarget(e.target, this)
|
1169
|
+
if (match) fn.apply(match, arguments)
|
1170
|
+
}
|
1171
|
+
|
1172
|
+
// __beanDel isn't pleasant but it's a private function, not exposed outside of Bean
|
1173
|
+
handler.__beanDel = {
|
1174
|
+
ft : findTarget // attach it here for customEvents to use too
|
1175
|
+
, selector : selector
|
1176
|
+
}
|
1177
|
+
return handler
|
1178
|
+
}
|
1179
|
+
|
1180
|
+
, fireListener = W3C_MODEL ? function (isNative, type, element) {
|
1181
|
+
// modern browsers, do a proper dispatchEvent()
|
1182
|
+
var evt = doc.createEvent(isNative ? 'HTMLEvents' : 'UIEvents')
|
1183
|
+
evt[isNative ? 'initEvent' : 'initUIEvent'](type, true, true, win, 1)
|
1184
|
+
element.dispatchEvent(evt)
|
1185
|
+
} : function (isNative, type, element) {
|
1186
|
+
// old browser use onpropertychange, just increment a custom property to trigger the event
|
1187
|
+
element = targetElement(element, isNative)
|
1188
|
+
isNative ? element.fireEvent('on' + type, doc.createEventObject()) : element['_on' + type]++
|
1189
|
+
}
|
1190
|
+
|
1191
|
+
/**
|
1192
|
+
* Public API: off(), on(), add(), (remove()), one(), fire(), clone()
|
1193
|
+
*/
|
1194
|
+
|
1195
|
+
/**
|
1196
|
+
* off(element[, eventType(s)[, handler ]])
|
1197
|
+
*/
|
1198
|
+
, off = function (element, typeSpec, fn) {
|
1199
|
+
var isTypeStr = isString(typeSpec)
|
1200
|
+
, k, type, namespaces, i
|
1201
|
+
|
1202
|
+
if (isTypeStr && typeSpec.indexOf(' ') > 0) {
|
1203
|
+
// off(el, 't1 t2 t3', fn) or off(el, 't1 t2 t3')
|
1204
|
+
typeSpec = str2arr(typeSpec)
|
1205
|
+
for (i = typeSpec.length; i--;)
|
1206
|
+
off(element, typeSpec[i], fn)
|
1207
|
+
return element
|
1208
|
+
}
|
1209
|
+
|
1210
|
+
type = isTypeStr && typeSpec.replace(nameRegex, '')
|
1211
|
+
if (type && customEvents[type]) type = customEvents[type].base
|
1212
|
+
|
1213
|
+
if (!typeSpec || isTypeStr) {
|
1214
|
+
// off(el) or off(el, t1.ns) or off(el, .ns) or off(el, .ns1.ns2.ns3)
|
1215
|
+
if (namespaces = isTypeStr && typeSpec.replace(namespaceRegex, '')) namespaces = str2arr(namespaces, '.')
|
1216
|
+
removeListener(element, type, fn, namespaces)
|
1217
|
+
} else if (isFunction(typeSpec)) {
|
1218
|
+
// off(el, fn)
|
1219
|
+
removeListener(element, null, typeSpec)
|
1220
|
+
} else {
|
1221
|
+
// off(el, { t1: fn1, t2, fn2 })
|
1222
|
+
for (k in typeSpec) {
|
1223
|
+
if (typeSpec.hasOwnProperty(k)) off(element, k, typeSpec[k])
|
1224
|
+
}
|
1225
|
+
}
|
1226
|
+
|
1227
|
+
return element
|
1228
|
+
}
|
1229
|
+
|
1230
|
+
/**
|
1231
|
+
* on(element, eventType(s)[, selector], handler[, args ])
|
1232
|
+
*/
|
1233
|
+
, on = function(element, events, selector, fn) {
|
1234
|
+
var originalFn, type, types, i, args, entry, first
|
1235
|
+
|
1236
|
+
//TODO: the undefined check means you can't pass an 'args' argument, fix this perhaps?
|
1237
|
+
if (selector === undefined && typeof events == 'object') {
|
1238
|
+
//TODO: this can't handle delegated events
|
1239
|
+
for (type in events) {
|
1240
|
+
if (events.hasOwnProperty(type)) {
|
1241
|
+
on.call(this, element, type, events[type])
|
1242
|
+
}
|
1243
|
+
}
|
1244
|
+
return
|
1245
|
+
}
|
1246
|
+
|
1247
|
+
if (!isFunction(selector)) {
|
1248
|
+
// delegated event
|
1249
|
+
originalFn = fn
|
1250
|
+
args = slice.call(arguments, 4)
|
1251
|
+
fn = delegate(selector, originalFn, selectorEngine)
|
1252
|
+
} else {
|
1253
|
+
args = slice.call(arguments, 3)
|
1254
|
+
fn = originalFn = selector
|
1255
|
+
}
|
1256
|
+
|
1257
|
+
types = str2arr(events)
|
1258
|
+
|
1259
|
+
// special case for one(), wrap in a self-removing handler
|
1260
|
+
if (this === ONE) {
|
1261
|
+
fn = once(off, element, events, fn, originalFn)
|
1262
|
+
}
|
1263
|
+
|
1264
|
+
for (i = types.length; i--;) {
|
1265
|
+
// add new handler to the registry and check if it's the first for this element/type
|
1266
|
+
first = registry.put(entry = new RegEntry(
|
1267
|
+
element
|
1268
|
+
, types[i].replace(nameRegex, '') // event type
|
1269
|
+
, fn
|
1270
|
+
, originalFn
|
1271
|
+
, str2arr(types[i].replace(namespaceRegex, ''), '.') // namespaces
|
1272
|
+
, args
|
1273
|
+
, false // not root
|
1274
|
+
))
|
1275
|
+
if (entry[eventSupport] && first) {
|
1276
|
+
// first event of this type on this element, add root listener
|
1277
|
+
listener(element, entry.eventType, true, entry.customType)
|
1278
|
+
}
|
1279
|
+
}
|
1280
|
+
|
1281
|
+
return element
|
1282
|
+
}
|
1283
|
+
|
1284
|
+
/**
|
1285
|
+
* add(element[, selector], eventType(s), handler[, args ])
|
1286
|
+
*
|
1287
|
+
* Deprecated: kept (for now) for backward-compatibility
|
1288
|
+
*/
|
1289
|
+
, add = function (element, events, fn, delfn) {
|
1290
|
+
return on.apply(
|
1291
|
+
null
|
1292
|
+
, !isString(fn)
|
1293
|
+
? slice.call(arguments)
|
1294
|
+
: [ element, fn, events, delfn ].concat(arguments.length > 3 ? slice.call(arguments, 5) : [])
|
1295
|
+
)
|
1296
|
+
}
|
1297
|
+
|
1298
|
+
/**
|
1299
|
+
* one(element, eventType(s)[, selector], handler[, args ])
|
1300
|
+
*/
|
1301
|
+
, one = function () {
|
1302
|
+
return on.apply(ONE, arguments)
|
1303
|
+
}
|
1304
|
+
|
1305
|
+
/**
|
1306
|
+
* fire(element, eventType(s)[, args ])
|
1307
|
+
*
|
1308
|
+
* The optional 'args' argument must be an array, if no 'args' argument is provided
|
1309
|
+
* then we can use the browser's DOM event system, otherwise we trigger handlers manually
|
1310
|
+
*/
|
1311
|
+
, fire = function (element, type, args) {
|
1312
|
+
var types = str2arr(type)
|
1313
|
+
, i, j, l, names, handlers
|
1314
|
+
|
1315
|
+
for (i = types.length; i--;) {
|
1316
|
+
type = types[i].replace(nameRegex, '')
|
1317
|
+
if (names = types[i].replace(namespaceRegex, '')) names = str2arr(names, '.')
|
1318
|
+
if (!names && !args && element[eventSupport]) {
|
1319
|
+
fireListener(nativeEvents[type], type, element)
|
1320
|
+
} else {
|
1321
|
+
// non-native event, either because of a namespace, arguments or a non DOM element
|
1322
|
+
// iterate over all listeners and manually 'fire'
|
1323
|
+
handlers = registry.get(element, type, null, false)
|
1324
|
+
args = [false].concat(args)
|
1325
|
+
for (j = 0, l = handlers.length; j < l; j++) {
|
1326
|
+
if (handlers[j].inNamespaces(names)) {
|
1327
|
+
handlers[j].handler.apply(element, args)
|
1328
|
+
}
|
1329
|
+
}
|
1330
|
+
}
|
1331
|
+
}
|
1332
|
+
return element
|
1333
|
+
}
|
1334
|
+
|
1335
|
+
/**
|
1336
|
+
* clone(dstElement, srcElement[, eventType ])
|
1337
|
+
*
|
1338
|
+
* TODO: perhaps for consistency we should allow the same flexibility in type specifiers?
|
1339
|
+
*/
|
1340
|
+
, clone = function (element, from, type) {
|
1341
|
+
var handlers = registry.get(from, type, null, false)
|
1342
|
+
, l = handlers.length
|
1343
|
+
, i = 0
|
1344
|
+
, args, beanDel
|
1345
|
+
|
1346
|
+
for (; i < l; i++) {
|
1347
|
+
if (handlers[i].original) {
|
1348
|
+
args = [ element, handlers[i].type ]
|
1349
|
+
if (beanDel = handlers[i].handler.__beanDel) args.push(beanDel.selector)
|
1350
|
+
args.push(handlers[i].original)
|
1351
|
+
on.apply(null, args)
|
1352
|
+
}
|
1353
|
+
}
|
1354
|
+
return element
|
1355
|
+
}
|
1356
|
+
|
1357
|
+
, bean = {
|
1358
|
+
on : on
|
1359
|
+
, add : add
|
1360
|
+
, one : one
|
1361
|
+
, off : off
|
1362
|
+
, remove : off
|
1363
|
+
, clone : clone
|
1364
|
+
, fire : fire
|
1365
|
+
, setSelectorEngine : setSelectorEngine
|
1366
|
+
, noConflict : function () {
|
1367
|
+
context[name] = old
|
1368
|
+
return this
|
1369
|
+
}
|
1370
|
+
}
|
1371
|
+
|
1372
|
+
// for IE, clean up on unload to avoid leaks
|
1373
|
+
if (win.attachEvent) {
|
1374
|
+
var cleanup = function () {
|
1375
|
+
var i, entries = registry.entries()
|
1376
|
+
for (i in entries) {
|
1377
|
+
if (entries[i].type && entries[i].type !== 'unload') off(entries[i].element, entries[i].type)
|
1378
|
+
}
|
1379
|
+
win.detachEvent('onunload', cleanup)
|
1380
|
+
win.CollectGarbage && win.CollectGarbage()
|
1381
|
+
}
|
1382
|
+
win.attachEvent('onunload', cleanup)
|
1383
|
+
}
|
1384
|
+
|
1385
|
+
// initialize selector engine to internal default (qSA or throw Error)
|
1386
|
+
setSelectorEngine()
|
1387
|
+
|
1388
|
+
return bean
|
1389
|
+
}));
|
1390
|
+
|
1391
|
+
|
1392
|
+
provide("bean", module.exports);
|
1393
|
+
|
1394
|
+
!function ($) {
|
1395
|
+
var b = require('bean')
|
1396
|
+
|
1397
|
+
, integrate = function (method, type, method2) {
|
1398
|
+
var _args = type ? [type] : []
|
1399
|
+
return function () {
|
1400
|
+
for (var i = 0, l = this.length; i < l; i++) {
|
1401
|
+
if (!arguments.length && method == 'on' && type) method = 'fire'
|
1402
|
+
b[method].apply(this, [this[i]].concat(_args, Array.prototype.slice.call(arguments, 0)))
|
1403
|
+
}
|
1404
|
+
return this
|
1405
|
+
}
|
1406
|
+
}
|
1407
|
+
|
1408
|
+
, add = integrate('add')
|
1409
|
+
, on = integrate('on')
|
1410
|
+
, one = integrate('one')
|
1411
|
+
, off = integrate('off')
|
1412
|
+
, fire = integrate('fire')
|
1413
|
+
, clone = integrate('clone')
|
1414
|
+
|
1415
|
+
, hover = function (enter, leave, i) { // i for internal
|
1416
|
+
for (i = this.length; i--;) {
|
1417
|
+
b.on.call(this, this[i], 'mouseenter', enter)
|
1418
|
+
b.on.call(this, this[i], 'mouseleave', leave)
|
1419
|
+
}
|
1420
|
+
return this
|
1421
|
+
}
|
1422
|
+
|
1423
|
+
, methods = {
|
1424
|
+
on : on
|
1425
|
+
, addListener : on
|
1426
|
+
, bind : on
|
1427
|
+
, listen : on
|
1428
|
+
, delegate : add // jQuery compat, same arg order as add()
|
1429
|
+
|
1430
|
+
, one : one
|
1431
|
+
|
1432
|
+
, off : off
|
1433
|
+
, unbind : off
|
1434
|
+
, unlisten : off
|
1435
|
+
, removeListener : off
|
1436
|
+
, undelegate : off
|
1437
|
+
|
1438
|
+
, emit : fire
|
1439
|
+
, trigger : fire
|
1440
|
+
|
1441
|
+
, cloneEvents : clone
|
1442
|
+
|
1443
|
+
, hover : hover
|
1444
|
+
}
|
1445
|
+
|
1446
|
+
, shortcuts =
|
1447
|
+
('blur change click dblclick error focus focusin focusout keydown keypress '
|
1448
|
+
+ 'keyup load mousedown mouseenter mouseleave mouseout mouseover mouseup '
|
1449
|
+
+ 'mousemove resize scroll select submit unload').split(' ')
|
1450
|
+
|
1451
|
+
for (var i = shortcuts.length; i--;) {
|
1452
|
+
methods[shortcuts[i]] = integrate('on', shortcuts[i])
|
1453
|
+
}
|
1454
|
+
|
1455
|
+
b.setSelectorEngine($)
|
1456
|
+
|
1457
|
+
$.ender(methods, true)
|
1458
|
+
}(ender);
|
1459
|
+
|
1460
|
+
}());
|
1461
|
+
|
1462
|
+
(function () {
|
1463
|
+
|
1464
|
+
var module = { exports: {} }, exports = module.exports;
|
1465
|
+
|
1466
|
+
/*!
|
1467
|
+
* domready (c) Dustin Diaz 2012 - License MIT
|
1468
|
+
*/
|
1469
|
+
!function (name, definition) {
|
1470
|
+
if (typeof module != 'undefined') module.exports = definition()
|
1471
|
+
else if (typeof define == 'function' && typeof define.amd == 'object') define(definition)
|
1472
|
+
else this[name] = definition()
|
1473
|
+
}('domready', function (ready) {
|
1474
|
+
|
1475
|
+
var fns = [], fn, f = false
|
1476
|
+
, doc = document
|
1477
|
+
, testEl = doc.documentElement
|
1478
|
+
, hack = testEl.doScroll
|
1479
|
+
, domContentLoaded = 'DOMContentLoaded'
|
1480
|
+
, addEventListener = 'addEventListener'
|
1481
|
+
, onreadystatechange = 'onreadystatechange'
|
1482
|
+
, readyState = 'readyState'
|
1483
|
+
, loaded = /^loade|c/.test(doc[readyState])
|
1484
|
+
|
1485
|
+
function flush(f) {
|
1486
|
+
loaded = 1
|
1487
|
+
while (f = fns.shift()) f()
|
1488
|
+
}
|
1489
|
+
|
1490
|
+
doc[addEventListener] && doc[addEventListener](domContentLoaded, fn = function () {
|
1491
|
+
doc.removeEventListener(domContentLoaded, fn, f)
|
1492
|
+
flush()
|
1493
|
+
}, f)
|
1494
|
+
|
1495
|
+
|
1496
|
+
hack && doc.attachEvent(onreadystatechange, fn = function () {
|
1497
|
+
if (/^c/.test(doc[readyState])) {
|
1498
|
+
doc.detachEvent(onreadystatechange, fn)
|
1499
|
+
flush()
|
1500
|
+
}
|
1501
|
+
})
|
1502
|
+
|
1503
|
+
return (ready = hack ?
|
1504
|
+
function (fn) {
|
1505
|
+
self != top ?
|
1506
|
+
loaded ? fn() : fns.push(fn) :
|
1507
|
+
function () {
|
1508
|
+
try {
|
1509
|
+
testEl.doScroll('left')
|
1510
|
+
} catch (e) {
|
1511
|
+
return setTimeout(function() { ready(fn) }, 50)
|
1512
|
+
}
|
1513
|
+
fn()
|
1514
|
+
}()
|
1515
|
+
} :
|
1516
|
+
function (fn) {
|
1517
|
+
loaded ? fn() : fns.push(fn)
|
1518
|
+
})
|
1519
|
+
})
|
1520
|
+
|
1521
|
+
provide("domready", module.exports);
|
1522
|
+
|
1523
|
+
!function ($) {
|
1524
|
+
var ready = require('domready')
|
1525
|
+
$.ender({domReady: ready})
|
1526
|
+
$.ender({
|
1527
|
+
ready: function (f) {
|
1528
|
+
ready(f)
|
1529
|
+
return this
|
1530
|
+
}
|
1531
|
+
}, true)
|
1532
|
+
}(ender);
|
1533
|
+
|
1534
|
+
}());
|
1535
|
+
|
1536
|
+
(function () {
|
1537
|
+
|
1538
|
+
var module = { exports: {} }, exports = module.exports;
|
1539
|
+
|
1540
|
+
/*!
|
1541
|
+
* @preserve Qwery - A Blazing Fast query selector engine
|
1542
|
+
* https://github.com/ded/qwery
|
1543
|
+
* copyright Dustin Diaz 2012
|
1544
|
+
* MIT License
|
1545
|
+
*/
|
1546
|
+
|
1547
|
+
(function (name, context, definition) {
|
1548
|
+
if (typeof module != 'undefined' && module.exports) module.exports = definition()
|
1549
|
+
else if (typeof context['define'] == 'function' && context['define']['amd']) define(definition)
|
1550
|
+
else context[name] = definition()
|
1551
|
+
})('qwery', this, function () {
|
1552
|
+
var doc = document
|
1553
|
+
, html = doc.documentElement
|
1554
|
+
, byClass = 'getElementsByClassName'
|
1555
|
+
, byTag = 'getElementsByTagName'
|
1556
|
+
, qSA = 'querySelectorAll'
|
1557
|
+
, useNativeQSA = 'useNativeQSA'
|
1558
|
+
, tagName = 'tagName'
|
1559
|
+
, nodeType = 'nodeType'
|
1560
|
+
, select // main select() method, assign later
|
1561
|
+
|
1562
|
+
, id = /#([\w\-]+)/
|
1563
|
+
, clas = /\.[\w\-]+/g
|
1564
|
+
, idOnly = /^#([\w\-]+)$/
|
1565
|
+
, classOnly = /^\.([\w\-]+)$/
|
1566
|
+
, tagOnly = /^([\w\-]+)$/
|
1567
|
+
, tagAndOrClass = /^([\w]+)?\.([\w\-]+)$/
|
1568
|
+
, splittable = /(^|,)\s*[>~+]/
|
1569
|
+
, normalizr = /^\s+|\s*([,\s\+\~>]|$)\s*/g
|
1570
|
+
, splitters = /[\s\>\+\~]/
|
1571
|
+
, splittersMore = /(?![\s\w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^'"]*\]|[\s\w\+\-]*\))/
|
1572
|
+
, specialChars = /([.*+?\^=!:${}()|\[\]\/\\])/g
|
1573
|
+
, simple = /^(\*|[a-z0-9]+)?(?:([\.\#]+[\w\-\.#]+)?)/
|
1574
|
+
, attr = /\[([\w\-]+)(?:([\|\^\$\*\~]?\=)['"]?([ \w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^]+)["']?)?\]/
|
1575
|
+
, pseudo = /:([\w\-]+)(\(['"]?([^()]+)['"]?\))?/
|
1576
|
+
, easy = new RegExp(idOnly.source + '|' + tagOnly.source + '|' + classOnly.source)
|
1577
|
+
, dividers = new RegExp('(' + splitters.source + ')' + splittersMore.source, 'g')
|
1578
|
+
, tokenizr = new RegExp(splitters.source + splittersMore.source)
|
1579
|
+
, chunker = new RegExp(simple.source + '(' + attr.source + ')?' + '(' + pseudo.source + ')?')
|
1580
|
+
|
1581
|
+
var walker = {
|
1582
|
+
' ': function (node) {
|
1583
|
+
return node && node !== html && node.parentNode
|
1584
|
+
}
|
1585
|
+
, '>': function (node, contestant) {
|
1586
|
+
return node && node.parentNode == contestant.parentNode && node.parentNode
|
1587
|
+
}
|
1588
|
+
, '~': function (node) {
|
1589
|
+
return node && node.previousSibling
|
1590
|
+
}
|
1591
|
+
, '+': function (node, contestant, p1, p2) {
|
1592
|
+
if (!node) return false
|
1593
|
+
return (p1 = previous(node)) && (p2 = previous(contestant)) && p1 == p2 && p1
|
1594
|
+
}
|
1595
|
+
}
|
1596
|
+
|
1597
|
+
function cache() {
|
1598
|
+
this.c = {}
|
1599
|
+
}
|
1600
|
+
cache.prototype = {
|
1601
|
+
g: function (k) {
|
1602
|
+
return this.c[k] || undefined
|
1603
|
+
}
|
1604
|
+
, s: function (k, v, r) {
|
1605
|
+
v = r ? new RegExp(v) : v
|
1606
|
+
return (this.c[k] = v)
|
1607
|
+
}
|
1608
|
+
}
|
1609
|
+
|
1610
|
+
var classCache = new cache()
|
1611
|
+
, cleanCache = new cache()
|
1612
|
+
, attrCache = new cache()
|
1613
|
+
, tokenCache = new cache()
|
1614
|
+
|
1615
|
+
function classRegex(c) {
|
1616
|
+
return classCache.g(c) || classCache.s(c, '(^|\\s+)' + c + '(\\s+|$)', 1)
|
1617
|
+
}
|
1618
|
+
|
1619
|
+
// not quite as fast as inline loops in older browsers so don't use liberally
|
1620
|
+
function each(a, fn) {
|
1621
|
+
var i = 0, l = a.length
|
1622
|
+
for (; i < l; i++) fn(a[i])
|
1623
|
+
}
|
1624
|
+
|
1625
|
+
function flatten(ar) {
|
1626
|
+
for (var r = [], i = 0, l = ar.length; i < l; ++i) arrayLike(ar[i]) ? (r = r.concat(ar[i])) : (r[r.length] = ar[i])
|
1627
|
+
return r
|
1628
|
+
}
|
1629
|
+
|
1630
|
+
function arrayify(ar) {
|
1631
|
+
var i = 0, l = ar.length, r = []
|
1632
|
+
for (; i < l; i++) r[i] = ar[i]
|
1633
|
+
return r
|
1634
|
+
}
|
1635
|
+
|
1636
|
+
function previous(n) {
|
1637
|
+
while (n = n.previousSibling) if (n[nodeType] == 1) break;
|
1638
|
+
return n
|
1639
|
+
}
|
1640
|
+
|
1641
|
+
function q(query) {
|
1642
|
+
return query.match(chunker)
|
1643
|
+
}
|
1644
|
+
|
1645
|
+
// called using `this` as element and arguments from regex group results.
|
1646
|
+
// given => div.hello[title="world"]:foo('bar')
|
1647
|
+
// div.hello[title="world"]:foo('bar'), div, .hello, [title="world"], title, =, world, :foo('bar'), foo, ('bar'), bar]
|
1648
|
+
function interpret(whole, tag, idsAndClasses, wholeAttribute, attribute, qualifier, value, wholePseudo, pseudo, wholePseudoVal, pseudoVal) {
|
1649
|
+
var i, m, k, o, classes
|
1650
|
+
if (this[nodeType] !== 1) return false
|
1651
|
+
if (tag && tag !== '*' && this[tagName] && this[tagName].toLowerCase() !== tag) return false
|
1652
|
+
if (idsAndClasses && (m = idsAndClasses.match(id)) && m[1] !== this.id) return false
|
1653
|
+
if (idsAndClasses && (classes = idsAndClasses.match(clas))) {
|
1654
|
+
for (i = classes.length; i--;) if (!classRegex(classes[i].slice(1)).test(this.className)) return false
|
1655
|
+
}
|
1656
|
+
if (pseudo && qwery.pseudos[pseudo] && !qwery.pseudos[pseudo](this, pseudoVal)) return false
|
1657
|
+
if (wholeAttribute && !value) { // select is just for existance of attrib
|
1658
|
+
o = this.attributes
|
1659
|
+
for (k in o) {
|
1660
|
+
if (Object.prototype.hasOwnProperty.call(o, k) && (o[k].name || k) == attribute) {
|
1661
|
+
return this
|
1662
|
+
}
|
1663
|
+
}
|
1664
|
+
}
|
1665
|
+
if (wholeAttribute && !checkAttr(qualifier, getAttr(this, attribute) || '', value)) {
|
1666
|
+
// select is for attrib equality
|
1667
|
+
return false
|
1668
|
+
}
|
1669
|
+
return this
|
1670
|
+
}
|
1671
|
+
|
1672
|
+
function clean(s) {
|
1673
|
+
return cleanCache.g(s) || cleanCache.s(s, s.replace(specialChars, '\\$1'))
|
1674
|
+
}
|
1675
|
+
|
1676
|
+
function checkAttr(qualify, actual, val) {
|
1677
|
+
switch (qualify) {
|
1678
|
+
case '=':
|
1679
|
+
return actual == val
|
1680
|
+
case '^=':
|
1681
|
+
return actual.match(attrCache.g('^=' + val) || attrCache.s('^=' + val, '^' + clean(val), 1))
|
1682
|
+
case '$=':
|
1683
|
+
return actual.match(attrCache.g('$=' + val) || attrCache.s('$=' + val, clean(val) + '$', 1))
|
1684
|
+
case '*=':
|
1685
|
+
return actual.match(attrCache.g(val) || attrCache.s(val, clean(val), 1))
|
1686
|
+
case '~=':
|
1687
|
+
return actual.match(attrCache.g('~=' + val) || attrCache.s('~=' + val, '(?:^|\\s+)' + clean(val) + '(?:\\s+|$)', 1))
|
1688
|
+
case '|=':
|
1689
|
+
return actual.match(attrCache.g('|=' + val) || attrCache.s('|=' + val, '^' + clean(val) + '(-|$)', 1))
|
1690
|
+
}
|
1691
|
+
return 0
|
1692
|
+
}
|
1693
|
+
|
1694
|
+
// given a selector, first check for simple cases then collect all base candidate matches and filter
|
1695
|
+
function _qwery(selector, _root) {
|
1696
|
+
var r = [], ret = [], i, l, m, token, tag, els, intr, item, root = _root
|
1697
|
+
, tokens = tokenCache.g(selector) || tokenCache.s(selector, selector.split(tokenizr))
|
1698
|
+
, dividedTokens = selector.match(dividers)
|
1699
|
+
|
1700
|
+
if (!tokens.length) return r
|
1701
|
+
|
1702
|
+
token = (tokens = tokens.slice(0)).pop() // copy cached tokens, take the last one
|
1703
|
+
if (tokens.length && (m = tokens[tokens.length - 1].match(idOnly))) root = byId(_root, m[1])
|
1704
|
+
if (!root) return r
|
1705
|
+
|
1706
|
+
intr = q(token)
|
1707
|
+
// collect base candidates to filter
|
1708
|
+
els = root !== _root && root[nodeType] !== 9 && dividedTokens && /^[+~]$/.test(dividedTokens[dividedTokens.length - 1]) ?
|
1709
|
+
function (r) {
|
1710
|
+
while (root = root.nextSibling) {
|
1711
|
+
root[nodeType] == 1 && (intr[1] ? intr[1] == root[tagName].toLowerCase() : 1) && (r[r.length] = root)
|
1712
|
+
}
|
1713
|
+
return r
|
1714
|
+
}([]) :
|
1715
|
+
root[byTag](intr[1] || '*')
|
1716
|
+
// filter elements according to the right-most part of the selector
|
1717
|
+
for (i = 0, l = els.length; i < l; i++) {
|
1718
|
+
if (item = interpret.apply(els[i], intr)) r[r.length] = item
|
1719
|
+
}
|
1720
|
+
if (!tokens.length) return r
|
1721
|
+
|
1722
|
+
// filter further according to the rest of the selector (the left side)
|
1723
|
+
each(r, function (e) { if (ancestorMatch(e, tokens, dividedTokens)) ret[ret.length] = e })
|
1724
|
+
return ret
|
1725
|
+
}
|
1726
|
+
|
1727
|
+
// compare element to a selector
|
1728
|
+
function is(el, selector, root) {
|
1729
|
+
if (isNode(selector)) return el == selector
|
1730
|
+
if (arrayLike(selector)) return !!~flatten(selector).indexOf(el) // if selector is an array, is el a member?
|
1731
|
+
|
1732
|
+
var selectors = selector.split(','), tokens, dividedTokens
|
1733
|
+
while (selector = selectors.pop()) {
|
1734
|
+
tokens = tokenCache.g(selector) || tokenCache.s(selector, selector.split(tokenizr))
|
1735
|
+
dividedTokens = selector.match(dividers)
|
1736
|
+
tokens = tokens.slice(0) // copy array
|
1737
|
+
if (interpret.apply(el, q(tokens.pop())) && (!tokens.length || ancestorMatch(el, tokens, dividedTokens, root))) {
|
1738
|
+
return true
|
1739
|
+
}
|
1740
|
+
}
|
1741
|
+
return false
|
1742
|
+
}
|
1743
|
+
|
1744
|
+
// given elements matching the right-most part of a selector, filter out any that don't match the rest
|
1745
|
+
function ancestorMatch(el, tokens, dividedTokens, root) {
|
1746
|
+
var cand
|
1747
|
+
// recursively work backwards through the tokens and up the dom, covering all options
|
1748
|
+
function crawl(e, i, p) {
|
1749
|
+
while (p = walker[dividedTokens[i]](p, e)) {
|
1750
|
+
if (isNode(p) && (interpret.apply(p, q(tokens[i])))) {
|
1751
|
+
if (i) {
|
1752
|
+
if (cand = crawl(p, i - 1, p)) return cand
|
1753
|
+
} else return p
|
1754
|
+
}
|
1755
|
+
}
|
1756
|
+
}
|
1757
|
+
return (cand = crawl(el, tokens.length - 1, el)) && (!root || isAncestor(cand, root))
|
1758
|
+
}
|
1759
|
+
|
1760
|
+
function isNode(el, t) {
|
1761
|
+
return el && typeof el === 'object' && (t = el[nodeType]) && (t == 1 || t == 9)
|
1762
|
+
}
|
1763
|
+
|
1764
|
+
function uniq(ar) {
|
1765
|
+
var a = [], i, j;
|
1766
|
+
o:
|
1767
|
+
for (i = 0; i < ar.length; ++i) {
|
1768
|
+
for (j = 0; j < a.length; ++j) if (a[j] == ar[i]) continue o
|
1769
|
+
a[a.length] = ar[i]
|
1770
|
+
}
|
1771
|
+
return a
|
1772
|
+
}
|
1773
|
+
|
1774
|
+
function arrayLike(o) {
|
1775
|
+
return (typeof o === 'object' && isFinite(o.length))
|
1776
|
+
}
|
1777
|
+
|
1778
|
+
function normalizeRoot(root) {
|
1779
|
+
if (!root) return doc
|
1780
|
+
if (typeof root == 'string') return qwery(root)[0]
|
1781
|
+
if (!root[nodeType] && arrayLike(root)) return root[0]
|
1782
|
+
return root
|
1783
|
+
}
|
1784
|
+
|
1785
|
+
function byId(root, id, el) {
|
1786
|
+
// if doc, query on it, else query the parent doc or if a detached fragment rewrite the query and run on the fragment
|
1787
|
+
return root[nodeType] === 9 ? root.getElementById(id) :
|
1788
|
+
root.ownerDocument &&
|
1789
|
+
(((el = root.ownerDocument.getElementById(id)) && isAncestor(el, root) && el) ||
|
1790
|
+
(!isAncestor(root, root.ownerDocument) && select('[id="' + id + '"]', root)[0]))
|
1791
|
+
}
|
1792
|
+
|
1793
|
+
function qwery(selector, _root) {
|
1794
|
+
var m, el, root = normalizeRoot(_root)
|
1795
|
+
|
1796
|
+
// easy, fast cases that we can dispatch with simple DOM calls
|
1797
|
+
if (!root || !selector) return []
|
1798
|
+
if (selector === window || isNode(selector)) {
|
1799
|
+
return !_root || (selector !== window && isNode(root) && isAncestor(selector, root)) ? [selector] : []
|
1800
|
+
}
|
1801
|
+
if (selector && arrayLike(selector)) return flatten(selector)
|
1802
|
+
if (m = selector.match(easy)) {
|
1803
|
+
if (m[1]) return (el = byId(root, m[1])) ? [el] : []
|
1804
|
+
if (m[2]) return arrayify(root[byTag](m[2]))
|
1805
|
+
if (hasByClass && m[3]) return arrayify(root[byClass](m[3]))
|
1806
|
+
}
|
1807
|
+
|
1808
|
+
return select(selector, root)
|
1809
|
+
}
|
1810
|
+
|
1811
|
+
// where the root is not document and a relationship selector is first we have to
|
1812
|
+
// do some awkward adjustments to get it to work, even with qSA
|
1813
|
+
function collectSelector(root, collector) {
|
1814
|
+
return function (s) {
|
1815
|
+
var oid, nid
|
1816
|
+
if (splittable.test(s)) {
|
1817
|
+
if (root[nodeType] !== 9) {
|
1818
|
+
// make sure the el has an id, rewrite the query, set root to doc and run it
|
1819
|
+
if (!(nid = oid = root.getAttribute('id'))) root.setAttribute('id', nid = '__qwerymeupscotty')
|
1820
|
+
s = '[id="' + nid + '"]' + s // avoid byId and allow us to match context element
|
1821
|
+
collector(root.parentNode || root, s, true)
|
1822
|
+
oid || root.removeAttribute('id')
|
1823
|
+
}
|
1824
|
+
return;
|
1825
|
+
}
|
1826
|
+
s.length && collector(root, s, false)
|
1827
|
+
}
|
1828
|
+
}
|
1829
|
+
|
1830
|
+
var isAncestor = 'compareDocumentPosition' in html ?
|
1831
|
+
function (element, container) {
|
1832
|
+
return (container.compareDocumentPosition(element) & 16) == 16
|
1833
|
+
} : 'contains' in html ?
|
1834
|
+
function (element, container) {
|
1835
|
+
container = container[nodeType] === 9 || container == window ? html : container
|
1836
|
+
return container !== element && container.contains(element)
|
1837
|
+
} :
|
1838
|
+
function (element, container) {
|
1839
|
+
while (element = element.parentNode) if (element === container) return 1
|
1840
|
+
return 0
|
1841
|
+
}
|
1842
|
+
, getAttr = function () {
|
1843
|
+
// detect buggy IE src/href getAttribute() call
|
1844
|
+
var e = doc.createElement('p')
|
1845
|
+
return ((e.innerHTML = '<a href="#x">x</a>') && e.firstChild.getAttribute('href') != '#x') ?
|
1846
|
+
function (e, a) {
|
1847
|
+
return a === 'class' ? e.className : (a === 'href' || a === 'src') ?
|
1848
|
+
e.getAttribute(a, 2) : e.getAttribute(a)
|
1849
|
+
} :
|
1850
|
+
function (e, a) { return e.getAttribute(a) }
|
1851
|
+
}()
|
1852
|
+
, hasByClass = !!doc[byClass]
|
1853
|
+
// has native qSA support
|
1854
|
+
, hasQSA = doc.querySelector && doc[qSA]
|
1855
|
+
// use native qSA
|
1856
|
+
, selectQSA = function (selector, root) {
|
1857
|
+
var result = [], ss, e
|
1858
|
+
try {
|
1859
|
+
if (root[nodeType] === 9 || !splittable.test(selector)) {
|
1860
|
+
// most work is done right here, defer to qSA
|
1861
|
+
return arrayify(root[qSA](selector))
|
1862
|
+
}
|
1863
|
+
// special case where we need the services of `collectSelector()`
|
1864
|
+
each(ss = selector.split(','), collectSelector(root, function (ctx, s) {
|
1865
|
+
e = ctx[qSA](s)
|
1866
|
+
if (e.length == 1) result[result.length] = e.item(0)
|
1867
|
+
else if (e.length) result = result.concat(arrayify(e))
|
1868
|
+
}))
|
1869
|
+
return ss.length > 1 && result.length > 1 ? uniq(result) : result
|
1870
|
+
} catch (ex) { }
|
1871
|
+
return selectNonNative(selector, root)
|
1872
|
+
}
|
1873
|
+
// no native selector support
|
1874
|
+
, selectNonNative = function (selector, root) {
|
1875
|
+
var result = [], items, m, i, l, r, ss
|
1876
|
+
selector = selector.replace(normalizr, '$1')
|
1877
|
+
if (m = selector.match(tagAndOrClass)) {
|
1878
|
+
r = classRegex(m[2])
|
1879
|
+
items = root[byTag](m[1] || '*')
|
1880
|
+
for (i = 0, l = items.length; i < l; i++) {
|
1881
|
+
if (r.test(items[i].className)) result[result.length] = items[i]
|
1882
|
+
}
|
1883
|
+
return result
|
1884
|
+
}
|
1885
|
+
// more complex selector, get `_qwery()` to do the work for us
|
1886
|
+
each(ss = selector.split(','), collectSelector(root, function (ctx, s, rewrite) {
|
1887
|
+
r = _qwery(s, ctx)
|
1888
|
+
for (i = 0, l = r.length; i < l; i++) {
|
1889
|
+
if (ctx[nodeType] === 9 || rewrite || isAncestor(r[i], root)) result[result.length] = r[i]
|
1890
|
+
}
|
1891
|
+
}))
|
1892
|
+
return ss.length > 1 && result.length > 1 ? uniq(result) : result
|
1893
|
+
}
|
1894
|
+
, configure = function (options) {
|
1895
|
+
// configNativeQSA: use fully-internal selector or native qSA where present
|
1896
|
+
if (typeof options[useNativeQSA] !== 'undefined')
|
1897
|
+
select = !options[useNativeQSA] ? selectNonNative : hasQSA ? selectQSA : selectNonNative
|
1898
|
+
}
|
1899
|
+
|
1900
|
+
configure({ useNativeQSA: true })
|
1901
|
+
|
1902
|
+
qwery.configure = configure
|
1903
|
+
qwery.uniq = uniq
|
1904
|
+
qwery.is = is
|
1905
|
+
qwery.pseudos = {}
|
1906
|
+
|
1907
|
+
return qwery
|
1908
|
+
});
|
1909
|
+
|
1910
|
+
|
1911
|
+
provide("qwery", module.exports);
|
1912
|
+
|
1913
|
+
(function ($) {
|
1914
|
+
var q = function () {
|
1915
|
+
var r
|
1916
|
+
try {
|
1917
|
+
r = require('qwery')
|
1918
|
+
} catch (ex) {
|
1919
|
+
r = require('qwery-mobile')
|
1920
|
+
} finally {
|
1921
|
+
return r
|
1922
|
+
}
|
1923
|
+
}()
|
1924
|
+
|
1925
|
+
$.pseudos = q.pseudos
|
1926
|
+
|
1927
|
+
$._select = function (s, r) {
|
1928
|
+
// detect if sibling module 'bonzo' is available at run-time
|
1929
|
+
// rather than load-time since technically it's not a dependency and
|
1930
|
+
// can be loaded in any order
|
1931
|
+
// hence the lazy function re-definition
|
1932
|
+
return ($._select = (function () {
|
1933
|
+
var b
|
1934
|
+
if (typeof $.create == 'function') return function (s, r) {
|
1935
|
+
return /^\s*</.test(s) ? $.create(s, r) : q(s, r)
|
1936
|
+
}
|
1937
|
+
try {
|
1938
|
+
b = require('bonzo')
|
1939
|
+
return function (s, r) {
|
1940
|
+
return /^\s*</.test(s) ? b.create(s, r) : q(s, r)
|
1941
|
+
}
|
1942
|
+
} catch (e) { }
|
1943
|
+
return q
|
1944
|
+
})())(s, r)
|
1945
|
+
}
|
1946
|
+
|
1947
|
+
$.ender({
|
1948
|
+
find: function (s) {
|
1949
|
+
var r = [], i, l, j, k, els
|
1950
|
+
for (i = 0, l = this.length; i < l; i++) {
|
1951
|
+
els = q(s, this[i])
|
1952
|
+
for (j = 0, k = els.length; j < k; j++) r.push(els[j])
|
1953
|
+
}
|
1954
|
+
return $(q.uniq(r))
|
1955
|
+
}
|
1956
|
+
, and: function (s) {
|
1957
|
+
var plus = $(s)
|
1958
|
+
for (var i = this.length, j = 0, l = this.length + plus.length; i < l; i++, j++) {
|
1959
|
+
this[i] = plus[j]
|
1960
|
+
}
|
1961
|
+
this.length += plus.length
|
1962
|
+
return this
|
1963
|
+
}
|
1964
|
+
, is: function(s, r) {
|
1965
|
+
var i, l
|
1966
|
+
for (i = 0, l = this.length; i < l; i++) {
|
1967
|
+
if (q.is(this[i], s, r)) {
|
1968
|
+
return true
|
1969
|
+
}
|
1970
|
+
}
|
1971
|
+
return false
|
1972
|
+
}
|
1973
|
+
}, true)
|
1974
|
+
}(ender));
|
1975
|
+
|
1976
|
+
|
1977
|
+
}());
|
1978
|
+
|
1979
|
+
(function () {
|
1980
|
+
|
1981
|
+
var module = { exports: {} }, exports = module.exports;
|
1982
|
+
|
1983
|
+
/*!
|
1984
|
+
* Bonzo: DOM Utility (c) Dustin Diaz 2012
|
1985
|
+
* https://github.com/ded/bonzo
|
1986
|
+
* License MIT
|
1987
|
+
*/
|
1988
|
+
(function (name, context, definition) {
|
1989
|
+
if (typeof module != 'undefined' && module.exports) module.exports = definition()
|
1990
|
+
else if (typeof context['define'] == 'function' && context['define']['amd']) define(definition)
|
1991
|
+
else context[name] = definition()
|
1992
|
+
})('bonzo', this, function() {
|
1993
|
+
var win = window
|
1994
|
+
, doc = win.document
|
1995
|
+
, html = doc.documentElement
|
1996
|
+
, parentNode = 'parentNode'
|
1997
|
+
, specialAttributes = /^(checked|value|selected|disabled)$/i
|
1998
|
+
, specialTags = /^(select|fieldset|table|tbody|tfoot|td|tr|colgroup)$/i // tags that we have trouble inserting *into*
|
1999
|
+
, simpleScriptTagRe = /\s*<script +src=['"]([^'"]+)['"]>/
|
2000
|
+
, table = ['<table>', '</table>', 1]
|
2001
|
+
, td = ['<table><tbody><tr>', '</tr></tbody></table>', 3]
|
2002
|
+
, option = ['<select>', '</select>', 1]
|
2003
|
+
, noscope = ['_', '', 0, 1]
|
2004
|
+
, tagMap = { // tags that we have trouble *inserting*
|
2005
|
+
thead: table, tbody: table, tfoot: table, colgroup: table, caption: table
|
2006
|
+
, tr: ['<table><tbody>', '</tbody></table>', 2]
|
2007
|
+
, th: td , td: td
|
2008
|
+
, col: ['<table><colgroup>', '</colgroup></table>', 2]
|
2009
|
+
, fieldset: ['<form>', '</form>', 1]
|
2010
|
+
, legend: ['<form><fieldset>', '</fieldset></form>', 2]
|
2011
|
+
, option: option, optgroup: option
|
2012
|
+
, script: noscope, style: noscope, link: noscope, param: noscope, base: noscope
|
2013
|
+
}
|
2014
|
+
, stateAttributes = /^(checked|selected|disabled)$/
|
2015
|
+
, ie = /msie/i.test(navigator.userAgent)
|
2016
|
+
, hasClass, addClass, removeClass
|
2017
|
+
, uidMap = {}
|
2018
|
+
, uuids = 0
|
2019
|
+
, digit = /^-?[\d\.]+$/
|
2020
|
+
, dattr = /^data-(.+)$/
|
2021
|
+
, px = 'px'
|
2022
|
+
, setAttribute = 'setAttribute'
|
2023
|
+
, getAttribute = 'getAttribute'
|
2024
|
+
, byTag = 'getElementsByTagName'
|
2025
|
+
, features = function() {
|
2026
|
+
var e = doc.createElement('p')
|
2027
|
+
e.innerHTML = '<a href="#x">x</a><table style="float:left;"></table>'
|
2028
|
+
return {
|
2029
|
+
hrefExtended: e[byTag]('a')[0][getAttribute]('href') != '#x' // IE < 8
|
2030
|
+
, autoTbody: e[byTag]('tbody').length !== 0 // IE < 8
|
2031
|
+
, computedStyle: doc.defaultView && doc.defaultView.getComputedStyle
|
2032
|
+
, cssFloat: e[byTag]('table')[0].style.styleFloat ? 'styleFloat' : 'cssFloat'
|
2033
|
+
, transform: function () {
|
2034
|
+
var props = ['transform', 'webkitTransform', 'MozTransform', 'OTransform', 'msTransform'], i
|
2035
|
+
for (i = 0; i < props.length; i++) {
|
2036
|
+
if (props[i] in e.style) return props[i]
|
2037
|
+
}
|
2038
|
+
}()
|
2039
|
+
, classList: 'classList' in e
|
2040
|
+
, opasity: function () {
|
2041
|
+
return typeof doc.createElement('a').style.opacity !== 'undefined'
|
2042
|
+
}()
|
2043
|
+
}
|
2044
|
+
}()
|
2045
|
+
, trimReplace = /(^\s*|\s*$)/g
|
2046
|
+
, whitespaceRegex = /\s+/
|
2047
|
+
, toString = String.prototype.toString
|
2048
|
+
, unitless = { lineHeight: 1, zoom: 1, zIndex: 1, opacity: 1, boxFlex: 1, WebkitBoxFlex: 1, MozBoxFlex: 1 }
|
2049
|
+
, query = doc.querySelectorAll && function (selector) { return doc.querySelectorAll(selector) }
|
2050
|
+
, trim = String.prototype.trim ?
|
2051
|
+
function (s) {
|
2052
|
+
return s.trim()
|
2053
|
+
} :
|
2054
|
+
function (s) {
|
2055
|
+
return s.replace(trimReplace, '')
|
2056
|
+
}
|
2057
|
+
|
2058
|
+
|
2059
|
+
function isNode(node) {
|
2060
|
+
return node && node.nodeName && (node.nodeType == 1 || node.nodeType == 11)
|
2061
|
+
}
|
2062
|
+
|
2063
|
+
|
2064
|
+
function normalize(node, host, clone) {
|
2065
|
+
var i, l, ret
|
2066
|
+
if (typeof node == 'string') return bonzo.create(node)
|
2067
|
+
if (isNode(node)) node = [ node ]
|
2068
|
+
if (clone) {
|
2069
|
+
ret = [] // don't change original array
|
2070
|
+
for (i = 0, l = node.length; i < l; i++) ret[i] = cloneNode(host, node[i])
|
2071
|
+
return ret
|
2072
|
+
}
|
2073
|
+
return node
|
2074
|
+
}
|
2075
|
+
|
2076
|
+
|
2077
|
+
/**
|
2078
|
+
* @param {string} c a class name to test
|
2079
|
+
* @return {boolean}
|
2080
|
+
*/
|
2081
|
+
function classReg(c) {
|
2082
|
+
return new RegExp("(^|\\s+)" + c + "(\\s+|$)")
|
2083
|
+
}
|
2084
|
+
|
2085
|
+
|
2086
|
+
/**
|
2087
|
+
* @param {Bonzo|Array} ar
|
2088
|
+
* @param {function(Object, number, (Bonzo|Array))} fn
|
2089
|
+
* @param {Object=} opt_scope
|
2090
|
+
* @param {boolean=} opt_rev
|
2091
|
+
* @return {Bonzo|Array}
|
2092
|
+
*/
|
2093
|
+
function each(ar, fn, opt_scope, opt_rev) {
|
2094
|
+
var ind, i = 0, l = ar.length
|
2095
|
+
for (; i < l; i++) {
|
2096
|
+
ind = opt_rev ? ar.length - i - 1 : i
|
2097
|
+
fn.call(opt_scope || ar[ind], ar[ind], ind, ar)
|
2098
|
+
}
|
2099
|
+
return ar
|
2100
|
+
}
|
2101
|
+
|
2102
|
+
|
2103
|
+
/**
|
2104
|
+
* @param {Bonzo|Array} ar
|
2105
|
+
* @param {function(Object, number, (Bonzo|Array))} fn
|
2106
|
+
* @param {Object=} opt_scope
|
2107
|
+
* @return {Bonzo|Array}
|
2108
|
+
*/
|
2109
|
+
function deepEach(ar, fn, opt_scope) {
|
2110
|
+
for (var i = 0, l = ar.length; i < l; i++) {
|
2111
|
+
if (isNode(ar[i])) {
|
2112
|
+
deepEach(ar[i].childNodes, fn, opt_scope)
|
2113
|
+
fn.call(opt_scope || ar[i], ar[i], i, ar)
|
2114
|
+
}
|
2115
|
+
}
|
2116
|
+
return ar
|
2117
|
+
}
|
2118
|
+
|
2119
|
+
|
2120
|
+
/**
|
2121
|
+
* @param {string} s
|
2122
|
+
* @return {string}
|
2123
|
+
*/
|
2124
|
+
function camelize(s) {
|
2125
|
+
return s.replace(/-(.)/g, function (m, m1) {
|
2126
|
+
return m1.toUpperCase()
|
2127
|
+
})
|
2128
|
+
}
|
2129
|
+
|
2130
|
+
|
2131
|
+
/**
|
2132
|
+
* @param {string} s
|
2133
|
+
* @return {string}
|
2134
|
+
*/
|
2135
|
+
function decamelize(s) {
|
2136
|
+
return s ? s.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase() : s
|
2137
|
+
}
|
2138
|
+
|
2139
|
+
|
2140
|
+
/**
|
2141
|
+
* @param {Element} el
|
2142
|
+
* @return {*}
|
2143
|
+
*/
|
2144
|
+
function data(el) {
|
2145
|
+
el[getAttribute]('data-node-uid') || el[setAttribute]('data-node-uid', ++uuids)
|
2146
|
+
var uid = el[getAttribute]('data-node-uid')
|
2147
|
+
return uidMap[uid] || (uidMap[uid] = {})
|
2148
|
+
}
|
2149
|
+
|
2150
|
+
|
2151
|
+
/**
|
2152
|
+
* removes the data associated with an element
|
2153
|
+
* @param {Element} el
|
2154
|
+
*/
|
2155
|
+
function clearData(el) {
|
2156
|
+
var uid = el[getAttribute]('data-node-uid')
|
2157
|
+
if (uid) delete uidMap[uid]
|
2158
|
+
}
|
2159
|
+
|
2160
|
+
|
2161
|
+
function dataValue(d) {
|
2162
|
+
var f
|
2163
|
+
try {
|
2164
|
+
return (d === null || d === undefined) ? undefined :
|
2165
|
+
d === 'true' ? true :
|
2166
|
+
d === 'false' ? false :
|
2167
|
+
d === 'null' ? null :
|
2168
|
+
(f = parseFloat(d)) == d ? f : d;
|
2169
|
+
} catch(e) {}
|
2170
|
+
return undefined
|
2171
|
+
}
|
2172
|
+
|
2173
|
+
|
2174
|
+
/**
|
2175
|
+
* @param {Bonzo|Array} ar
|
2176
|
+
* @param {function(Object, number, (Bonzo|Array))} fn
|
2177
|
+
* @param {Object=} opt_scope
|
2178
|
+
* @return {boolean} whether `some`thing was found
|
2179
|
+
*/
|
2180
|
+
function some(ar, fn, opt_scope) {
|
2181
|
+
for (var i = 0, j = ar.length; i < j; ++i) if (fn.call(opt_scope || null, ar[i], i, ar)) return true
|
2182
|
+
return false
|
2183
|
+
}
|
2184
|
+
|
2185
|
+
|
2186
|
+
/**
|
2187
|
+
* this could be a giant enum of CSS properties
|
2188
|
+
* but in favor of file size sans-closure deadcode optimizations
|
2189
|
+
* we're just asking for any ol string
|
2190
|
+
* then it gets transformed into the appropriate style property for JS access
|
2191
|
+
* @param {string} p
|
2192
|
+
* @return {string}
|
2193
|
+
*/
|
2194
|
+
function styleProperty(p) {
|
2195
|
+
(p == 'transform' && (p = features.transform)) ||
|
2196
|
+
(/^transform-?[Oo]rigin$/.test(p) && (p = features.transform + 'Origin')) ||
|
2197
|
+
(p == 'float' && (p = features.cssFloat))
|
2198
|
+
return p ? camelize(p) : null
|
2199
|
+
}
|
2200
|
+
|
2201
|
+
var getStyle = features.computedStyle ?
|
2202
|
+
function (el, property) {
|
2203
|
+
var value = null
|
2204
|
+
, computed = doc.defaultView.getComputedStyle(el, '')
|
2205
|
+
computed && (value = computed[property])
|
2206
|
+
return el.style[property] || value
|
2207
|
+
} :
|
2208
|
+
|
2209
|
+
(ie && html.currentStyle) ?
|
2210
|
+
|
2211
|
+
/**
|
2212
|
+
* @param {Element} el
|
2213
|
+
* @param {string} property
|
2214
|
+
* @return {string|number}
|
2215
|
+
*/
|
2216
|
+
function (el, property) {
|
2217
|
+
if (property == 'opacity' && !features.opasity) {
|
2218
|
+
var val = 100
|
2219
|
+
try {
|
2220
|
+
val = el['filters']['DXImageTransform.Microsoft.Alpha'].opacity
|
2221
|
+
} catch (e1) {
|
2222
|
+
try {
|
2223
|
+
val = el['filters']('alpha').opacity
|
2224
|
+
} catch (e2) {}
|
2225
|
+
}
|
2226
|
+
return val / 100
|
2227
|
+
}
|
2228
|
+
var value = el.currentStyle ? el.currentStyle[property] : null
|
2229
|
+
return el.style[property] || value
|
2230
|
+
} :
|
2231
|
+
|
2232
|
+
function (el, property) {
|
2233
|
+
return el.style[property]
|
2234
|
+
}
|
2235
|
+
|
2236
|
+
// this insert method is intense
|
2237
|
+
function insert(target, host, fn, rev) {
|
2238
|
+
var i = 0, self = host || this, r = []
|
2239
|
+
// target nodes could be a css selector if it's a string and a selector engine is present
|
2240
|
+
// otherwise, just use target
|
2241
|
+
, nodes = query && typeof target == 'string' && target.charAt(0) != '<' ? query(target) : target
|
2242
|
+
// normalize each node in case it's still a string and we need to create nodes on the fly
|
2243
|
+
each(normalize(nodes), function (t, j) {
|
2244
|
+
each(self, function (el) {
|
2245
|
+
fn(t, r[i++] = j > 0 ? cloneNode(self, el) : el)
|
2246
|
+
}, null, rev)
|
2247
|
+
}, this, rev)
|
2248
|
+
self.length = i
|
2249
|
+
each(r, function (e) {
|
2250
|
+
self[--i] = e
|
2251
|
+
}, null, !rev)
|
2252
|
+
return self
|
2253
|
+
}
|
2254
|
+
|
2255
|
+
|
2256
|
+
/**
|
2257
|
+
* sets an element to an explicit x/y position on the page
|
2258
|
+
* @param {Element} el
|
2259
|
+
* @param {?number} x
|
2260
|
+
* @param {?number} y
|
2261
|
+
*/
|
2262
|
+
function xy(el, x, y) {
|
2263
|
+
var $el = bonzo(el)
|
2264
|
+
, style = $el.css('position')
|
2265
|
+
, offset = $el.offset()
|
2266
|
+
, rel = 'relative'
|
2267
|
+
, isRel = style == rel
|
2268
|
+
, delta = [parseInt($el.css('left'), 10), parseInt($el.css('top'), 10)]
|
2269
|
+
|
2270
|
+
if (style == 'static') {
|
2271
|
+
$el.css('position', rel)
|
2272
|
+
style = rel
|
2273
|
+
}
|
2274
|
+
|
2275
|
+
isNaN(delta[0]) && (delta[0] = isRel ? 0 : el.offsetLeft)
|
2276
|
+
isNaN(delta[1]) && (delta[1] = isRel ? 0 : el.offsetTop)
|
2277
|
+
|
2278
|
+
x != null && (el.style.left = x - offset.left + delta[0] + px)
|
2279
|
+
y != null && (el.style.top = y - offset.top + delta[1] + px)
|
2280
|
+
|
2281
|
+
}
|
2282
|
+
|
2283
|
+
// classList support for class management
|
2284
|
+
// altho to be fair, the api sucks because it won't accept multiple classes at once
|
2285
|
+
if (features.classList) {
|
2286
|
+
hasClass = function (el, c) {
|
2287
|
+
return el.classList.contains(c)
|
2288
|
+
}
|
2289
|
+
addClass = function (el, c) {
|
2290
|
+
el.classList.add(c)
|
2291
|
+
}
|
2292
|
+
removeClass = function (el, c) {
|
2293
|
+
el.classList.remove(c)
|
2294
|
+
}
|
2295
|
+
}
|
2296
|
+
else {
|
2297
|
+
hasClass = function (el, c) {
|
2298
|
+
return classReg(c).test(el.className)
|
2299
|
+
}
|
2300
|
+
addClass = function (el, c) {
|
2301
|
+
el.className = trim(el.className + ' ' + c)
|
2302
|
+
}
|
2303
|
+
removeClass = function (el, c) {
|
2304
|
+
el.className = trim(el.className.replace(classReg(c), ' '))
|
2305
|
+
}
|
2306
|
+
}
|
2307
|
+
|
2308
|
+
|
2309
|
+
/**
|
2310
|
+
* this allows method calling for setting values
|
2311
|
+
*
|
2312
|
+
* @example
|
2313
|
+
* bonzo(elements).css('color', function (el) {
|
2314
|
+
* return el.getAttribute('data-original-color')
|
2315
|
+
* })
|
2316
|
+
*
|
2317
|
+
* @param {Element} el
|
2318
|
+
* @param {function (Element)|string}
|
2319
|
+
* @return {string}
|
2320
|
+
*/
|
2321
|
+
function setter(el, v) {
|
2322
|
+
return typeof v == 'function' ? v(el) : v
|
2323
|
+
}
|
2324
|
+
|
2325
|
+
/**
|
2326
|
+
* @constructor
|
2327
|
+
* @param {Array.<Element>|Element|Node|string} elements
|
2328
|
+
*/
|
2329
|
+
function Bonzo(elements) {
|
2330
|
+
this.length = 0
|
2331
|
+
if (elements) {
|
2332
|
+
elements = typeof elements !== 'string' &&
|
2333
|
+
!elements.nodeType &&
|
2334
|
+
typeof elements.length !== 'undefined' ?
|
2335
|
+
elements :
|
2336
|
+
[elements]
|
2337
|
+
this.length = elements.length
|
2338
|
+
for (var i = 0; i < elements.length; i++) this[i] = elements[i]
|
2339
|
+
}
|
2340
|
+
}
|
2341
|
+
|
2342
|
+
Bonzo.prototype = {
|
2343
|
+
|
2344
|
+
/**
|
2345
|
+
* @param {number} index
|
2346
|
+
* @return {Element|Node}
|
2347
|
+
*/
|
2348
|
+
get: function (index) {
|
2349
|
+
return this[index] || null
|
2350
|
+
}
|
2351
|
+
|
2352
|
+
// itetators
|
2353
|
+
/**
|
2354
|
+
* @param {function(Element|Node)} fn
|
2355
|
+
* @param {Object=} opt_scope
|
2356
|
+
* @return {Bonzo}
|
2357
|
+
*/
|
2358
|
+
, each: function (fn, opt_scope) {
|
2359
|
+
return each(this, fn, opt_scope)
|
2360
|
+
}
|
2361
|
+
|
2362
|
+
/**
|
2363
|
+
* @param {Function} fn
|
2364
|
+
* @param {Object=} opt_scope
|
2365
|
+
* @return {Bonzo}
|
2366
|
+
*/
|
2367
|
+
, deepEach: function (fn, opt_scope) {
|
2368
|
+
return deepEach(this, fn, opt_scope)
|
2369
|
+
}
|
2370
|
+
|
2371
|
+
|
2372
|
+
/**
|
2373
|
+
* @param {Function} fn
|
2374
|
+
* @param {Function=} opt_reject
|
2375
|
+
* @return {Array}
|
2376
|
+
*/
|
2377
|
+
, map: function (fn, opt_reject) {
|
2378
|
+
var m = [], n, i
|
2379
|
+
for (i = 0; i < this.length; i++) {
|
2380
|
+
n = fn.call(this, this[i], i)
|
2381
|
+
opt_reject ? (opt_reject(n) && m.push(n)) : m.push(n)
|
2382
|
+
}
|
2383
|
+
return m
|
2384
|
+
}
|
2385
|
+
|
2386
|
+
// text and html inserters!
|
2387
|
+
|
2388
|
+
/**
|
2389
|
+
* @param {string} h the HTML to insert
|
2390
|
+
* @param {boolean=} opt_text whether to set or get text content
|
2391
|
+
* @return {Bonzo|string}
|
2392
|
+
*/
|
2393
|
+
, html: function (h, opt_text) {
|
2394
|
+
var method = opt_text
|
2395
|
+
? html.textContent === undefined ? 'innerText' : 'textContent'
|
2396
|
+
: 'innerHTML'
|
2397
|
+
, that = this
|
2398
|
+
, append = function (el, i) {
|
2399
|
+
each(normalize(h, that, i), function (node) {
|
2400
|
+
el.appendChild(node)
|
2401
|
+
})
|
2402
|
+
}
|
2403
|
+
, updateElement = function (el, i) {
|
2404
|
+
try {
|
2405
|
+
if (opt_text || (typeof h == 'string' && !specialTags.test(el.tagName))) {
|
2406
|
+
return el[method] = h
|
2407
|
+
}
|
2408
|
+
} catch (e) {}
|
2409
|
+
append(el, i)
|
2410
|
+
}
|
2411
|
+
return typeof h != 'undefined'
|
2412
|
+
? this.empty().each(updateElement)
|
2413
|
+
: this[0] ? this[0][method] : ''
|
2414
|
+
}
|
2415
|
+
|
2416
|
+
/**
|
2417
|
+
* @param {string=} opt_text the text to set, otherwise this is a getter
|
2418
|
+
* @return {Bonzo|string}
|
2419
|
+
*/
|
2420
|
+
, text: function (opt_text) {
|
2421
|
+
return this.html(opt_text, true)
|
2422
|
+
}
|
2423
|
+
|
2424
|
+
// more related insertion methods
|
2425
|
+
|
2426
|
+
/**
|
2427
|
+
* @param {Bonzo|string|Element|Array} node
|
2428
|
+
* @return {Bonzo}
|
2429
|
+
*/
|
2430
|
+
, append: function (node) {
|
2431
|
+
var that = this
|
2432
|
+
return this.each(function (el, i) {
|
2433
|
+
each(normalize(node, that, i), function (i) {
|
2434
|
+
el.appendChild(i)
|
2435
|
+
})
|
2436
|
+
})
|
2437
|
+
}
|
2438
|
+
|
2439
|
+
|
2440
|
+
/**
|
2441
|
+
* @param {Bonzo|string|Element|Array} node
|
2442
|
+
* @return {Bonzo}
|
2443
|
+
*/
|
2444
|
+
, prepend: function (node) {
|
2445
|
+
var that = this
|
2446
|
+
return this.each(function (el, i) {
|
2447
|
+
var first = el.firstChild
|
2448
|
+
each(normalize(node, that, i), function (i) {
|
2449
|
+
el.insertBefore(i, first)
|
2450
|
+
})
|
2451
|
+
})
|
2452
|
+
}
|
2453
|
+
|
2454
|
+
|
2455
|
+
/**
|
2456
|
+
* @param {Bonzo|string|Element|Array} target the location for which you'll insert your new content
|
2457
|
+
* @param {Object=} opt_host an optional host scope (primarily used when integrated with Ender)
|
2458
|
+
* @return {Bonzo}
|
2459
|
+
*/
|
2460
|
+
, appendTo: function (target, opt_host) {
|
2461
|
+
return insert.call(this, target, opt_host, function (t, el) {
|
2462
|
+
t.appendChild(el)
|
2463
|
+
})
|
2464
|
+
}
|
2465
|
+
|
2466
|
+
|
2467
|
+
/**
|
2468
|
+
* @param {Bonzo|string|Element|Array} target the location for which you'll insert your new content
|
2469
|
+
* @param {Object=} opt_host an optional host scope (primarily used when integrated with Ender)
|
2470
|
+
* @return {Bonzo}
|
2471
|
+
*/
|
2472
|
+
, prependTo: function (target, opt_host) {
|
2473
|
+
return insert.call(this, target, opt_host, function (t, el) {
|
2474
|
+
t.insertBefore(el, t.firstChild)
|
2475
|
+
}, 1)
|
2476
|
+
}
|
2477
|
+
|
2478
|
+
|
2479
|
+
/**
|
2480
|
+
* @param {Bonzo|string|Element|Array} node
|
2481
|
+
* @return {Bonzo}
|
2482
|
+
*/
|
2483
|
+
, before: function (node) {
|
2484
|
+
var that = this
|
2485
|
+
return this.each(function (el, i) {
|
2486
|
+
each(normalize(node, that, i), function (i) {
|
2487
|
+
el[parentNode].insertBefore(i, el)
|
2488
|
+
})
|
2489
|
+
})
|
2490
|
+
}
|
2491
|
+
|
2492
|
+
|
2493
|
+
/**
|
2494
|
+
* @param {Bonzo|string|Element|Array} node
|
2495
|
+
* @return {Bonzo}
|
2496
|
+
*/
|
2497
|
+
, after: function (node) {
|
2498
|
+
var that = this
|
2499
|
+
return this.each(function (el, i) {
|
2500
|
+
each(normalize(node, that, i), function (i) {
|
2501
|
+
el[parentNode].insertBefore(i, el.nextSibling)
|
2502
|
+
}, null, 1)
|
2503
|
+
})
|
2504
|
+
}
|
2505
|
+
|
2506
|
+
|
2507
|
+
/**
|
2508
|
+
* @param {Bonzo|string|Element|Array} target the location for which you'll insert your new content
|
2509
|
+
* @param {Object=} opt_host an optional host scope (primarily used when integrated with Ender)
|
2510
|
+
* @return {Bonzo}
|
2511
|
+
*/
|
2512
|
+
, insertBefore: function (target, opt_host) {
|
2513
|
+
return insert.call(this, target, opt_host, function (t, el) {
|
2514
|
+
t[parentNode].insertBefore(el, t)
|
2515
|
+
})
|
2516
|
+
}
|
2517
|
+
|
2518
|
+
|
2519
|
+
/**
|
2520
|
+
* @param {Bonzo|string|Element|Array} target the location for which you'll insert your new content
|
2521
|
+
* @param {Object=} opt_host an optional host scope (primarily used when integrated with Ender)
|
2522
|
+
* @return {Bonzo}
|
2523
|
+
*/
|
2524
|
+
, insertAfter: function (target, opt_host) {
|
2525
|
+
return insert.call(this, target, opt_host, function (t, el) {
|
2526
|
+
var sibling = t.nextSibling
|
2527
|
+
sibling ?
|
2528
|
+
t[parentNode].insertBefore(el, sibling) :
|
2529
|
+
t[parentNode].appendChild(el)
|
2530
|
+
}, 1)
|
2531
|
+
}
|
2532
|
+
|
2533
|
+
|
2534
|
+
/**
|
2535
|
+
* @param {Bonzo|string|Element|Array} node
|
2536
|
+
* @return {Bonzo}
|
2537
|
+
*/
|
2538
|
+
, replaceWith: function (node) {
|
2539
|
+
bonzo(normalize(node)).insertAfter(this)
|
2540
|
+
return this.remove()
|
2541
|
+
}
|
2542
|
+
|
2543
|
+
// class management
|
2544
|
+
|
2545
|
+
/**
|
2546
|
+
* @param {string} c
|
2547
|
+
* @return {Bonzo}
|
2548
|
+
*/
|
2549
|
+
, addClass: function (c) {
|
2550
|
+
c = toString.call(c).split(whitespaceRegex)
|
2551
|
+
return this.each(function (el) {
|
2552
|
+
// we `each` here so you can do $el.addClass('foo bar')
|
2553
|
+
each(c, function (c) {
|
2554
|
+
if (c && !hasClass(el, setter(el, c)))
|
2555
|
+
addClass(el, setter(el, c))
|
2556
|
+
})
|
2557
|
+
})
|
2558
|
+
}
|
2559
|
+
|
2560
|
+
|
2561
|
+
/**
|
2562
|
+
* @param {string} c
|
2563
|
+
* @return {Bonzo}
|
2564
|
+
*/
|
2565
|
+
, removeClass: function (c) {
|
2566
|
+
c = toString.call(c).split(whitespaceRegex)
|
2567
|
+
return this.each(function (el) {
|
2568
|
+
each(c, function (c) {
|
2569
|
+
if (c && hasClass(el, setter(el, c)))
|
2570
|
+
removeClass(el, setter(el, c))
|
2571
|
+
})
|
2572
|
+
})
|
2573
|
+
}
|
2574
|
+
|
2575
|
+
|
2576
|
+
/**
|
2577
|
+
* @param {string} c
|
2578
|
+
* @return {boolean}
|
2579
|
+
*/
|
2580
|
+
, hasClass: function (c) {
|
2581
|
+
c = toString.call(c).split(whitespaceRegex)
|
2582
|
+
return some(this, function (el) {
|
2583
|
+
return some(c, function (c) {
|
2584
|
+
return c && hasClass(el, c)
|
2585
|
+
})
|
2586
|
+
})
|
2587
|
+
}
|
2588
|
+
|
2589
|
+
|
2590
|
+
/**
|
2591
|
+
* @param {string} c classname to toggle
|
2592
|
+
* @param {boolean=} opt_condition whether to add or remove the class straight away
|
2593
|
+
* @return {Bonzo}
|
2594
|
+
*/
|
2595
|
+
, toggleClass: function (c, opt_condition) {
|
2596
|
+
c = toString.call(c).split(whitespaceRegex)
|
2597
|
+
return this.each(function (el) {
|
2598
|
+
each(c, function (c) {
|
2599
|
+
if (c) {
|
2600
|
+
typeof opt_condition !== 'undefined' ?
|
2601
|
+
opt_condition ? !hasClass(el, c) && addClass(el, c) : removeClass(el, c) :
|
2602
|
+
hasClass(el, c) ? removeClass(el, c) : addClass(el, c)
|
2603
|
+
}
|
2604
|
+
})
|
2605
|
+
})
|
2606
|
+
}
|
2607
|
+
|
2608
|
+
// display togglers
|
2609
|
+
|
2610
|
+
/**
|
2611
|
+
* @param {string=} opt_type useful to set back to anything other than an empty string
|
2612
|
+
* @return {Bonzo}
|
2613
|
+
*/
|
2614
|
+
, show: function (opt_type) {
|
2615
|
+
opt_type = typeof opt_type == 'string' ? opt_type : ''
|
2616
|
+
return this.each(function (el) {
|
2617
|
+
el.style.display = opt_type
|
2618
|
+
})
|
2619
|
+
}
|
2620
|
+
|
2621
|
+
|
2622
|
+
/**
|
2623
|
+
* @return {Bonzo}
|
2624
|
+
*/
|
2625
|
+
, hide: function () {
|
2626
|
+
return this.each(function (el) {
|
2627
|
+
el.style.display = 'none'
|
2628
|
+
})
|
2629
|
+
}
|
2630
|
+
|
2631
|
+
|
2632
|
+
/**
|
2633
|
+
* @param {Function=} opt_callback
|
2634
|
+
* @param {string=} opt_type
|
2635
|
+
* @return {Bonzo}
|
2636
|
+
*/
|
2637
|
+
, toggle: function (opt_callback, opt_type) {
|
2638
|
+
opt_type = typeof opt_type == 'string' ? opt_type : '';
|
2639
|
+
typeof opt_callback != 'function' && (opt_callback = null)
|
2640
|
+
return this.each(function (el) {
|
2641
|
+
el.style.display = (el.offsetWidth || el.offsetHeight) ? 'none' : opt_type;
|
2642
|
+
opt_callback && opt_callback.call(el)
|
2643
|
+
})
|
2644
|
+
}
|
2645
|
+
|
2646
|
+
|
2647
|
+
// DOM Walkers & getters
|
2648
|
+
|
2649
|
+
/**
|
2650
|
+
* @return {Element|Node}
|
2651
|
+
*/
|
2652
|
+
, first: function () {
|
2653
|
+
return bonzo(this.length ? this[0] : [])
|
2654
|
+
}
|
2655
|
+
|
2656
|
+
|
2657
|
+
/**
|
2658
|
+
* @return {Element|Node}
|
2659
|
+
*/
|
2660
|
+
, last: function () {
|
2661
|
+
return bonzo(this.length ? this[this.length - 1] : [])
|
2662
|
+
}
|
2663
|
+
|
2664
|
+
|
2665
|
+
/**
|
2666
|
+
* @return {Element|Node}
|
2667
|
+
*/
|
2668
|
+
, next: function () {
|
2669
|
+
return this.related('nextSibling')
|
2670
|
+
}
|
2671
|
+
|
2672
|
+
|
2673
|
+
/**
|
2674
|
+
* @return {Element|Node}
|
2675
|
+
*/
|
2676
|
+
, previous: function () {
|
2677
|
+
return this.related('previousSibling')
|
2678
|
+
}
|
2679
|
+
|
2680
|
+
|
2681
|
+
/**
|
2682
|
+
* @return {Element|Node}
|
2683
|
+
*/
|
2684
|
+
, parent: function() {
|
2685
|
+
return this.related(parentNode)
|
2686
|
+
}
|
2687
|
+
|
2688
|
+
|
2689
|
+
/**
|
2690
|
+
* @private
|
2691
|
+
* @param {string} method the directional DOM method
|
2692
|
+
* @return {Element|Node}
|
2693
|
+
*/
|
2694
|
+
, related: function (method) {
|
2695
|
+
return this.map(
|
2696
|
+
function (el) {
|
2697
|
+
el = el[method]
|
2698
|
+
while (el && el.nodeType !== 1) {
|
2699
|
+
el = el[method]
|
2700
|
+
}
|
2701
|
+
return el || 0
|
2702
|
+
},
|
2703
|
+
function (el) {
|
2704
|
+
return el
|
2705
|
+
}
|
2706
|
+
)
|
2707
|
+
}
|
2708
|
+
|
2709
|
+
|
2710
|
+
/**
|
2711
|
+
* @return {Bonzo}
|
2712
|
+
*/
|
2713
|
+
, focus: function () {
|
2714
|
+
this.length && this[0].focus()
|
2715
|
+
return this
|
2716
|
+
}
|
2717
|
+
|
2718
|
+
|
2719
|
+
/**
|
2720
|
+
* @return {Bonzo}
|
2721
|
+
*/
|
2722
|
+
, blur: function () {
|
2723
|
+
this.length && this[0].blur()
|
2724
|
+
return this
|
2725
|
+
}
|
2726
|
+
|
2727
|
+
// style getter setter & related methods
|
2728
|
+
|
2729
|
+
/**
|
2730
|
+
* @param {Object|string} o
|
2731
|
+
* @param {string=} opt_v
|
2732
|
+
* @return {Bonzo|string}
|
2733
|
+
*/
|
2734
|
+
, css: function (o, opt_v) {
|
2735
|
+
var p, iter = o
|
2736
|
+
// is this a request for just getting a style?
|
2737
|
+
if (opt_v === undefined && typeof o == 'string') {
|
2738
|
+
// repurpose 'v'
|
2739
|
+
opt_v = this[0]
|
2740
|
+
if (!opt_v) return null
|
2741
|
+
if (opt_v === doc || opt_v === win) {
|
2742
|
+
p = (opt_v === doc) ? bonzo.doc() : bonzo.viewport()
|
2743
|
+
return o == 'width' ? p.width : o == 'height' ? p.height : ''
|
2744
|
+
}
|
2745
|
+
return (o = styleProperty(o)) ? getStyle(opt_v, o) : null
|
2746
|
+
}
|
2747
|
+
|
2748
|
+
if (typeof o == 'string') {
|
2749
|
+
iter = {}
|
2750
|
+
iter[o] = opt_v
|
2751
|
+
}
|
2752
|
+
|
2753
|
+
if (ie && iter.opacity) {
|
2754
|
+
// oh this 'ol gamut
|
2755
|
+
iter.filter = 'alpha(opacity=' + (iter.opacity * 100) + ')'
|
2756
|
+
// give it layout
|
2757
|
+
iter.zoom = o.zoom || 1;
|
2758
|
+
delete iter.opacity;
|
2759
|
+
}
|
2760
|
+
|
2761
|
+
function fn(el, p, v) {
|
2762
|
+
for (var k in iter) {
|
2763
|
+
if (iter.hasOwnProperty(k)) {
|
2764
|
+
v = iter[k];
|
2765
|
+
// change "5" to "5px" - unless you're line-height, which is allowed
|
2766
|
+
(p = styleProperty(k)) && digit.test(v) && !(p in unitless) && (v += px)
|
2767
|
+
try { el.style[p] = setter(el, v) } catch(e) {}
|
2768
|
+
}
|
2769
|
+
}
|
2770
|
+
}
|
2771
|
+
return this.each(fn)
|
2772
|
+
}
|
2773
|
+
|
2774
|
+
|
2775
|
+
/**
|
2776
|
+
* @param {number=} opt_x
|
2777
|
+
* @param {number=} opt_y
|
2778
|
+
* @return {Bonzo|number}
|
2779
|
+
*/
|
2780
|
+
, offset: function (opt_x, opt_y) {
|
2781
|
+
if (opt_x && typeof opt_x == 'object' && (typeof opt_x.top == 'number' || typeof opt_x.left == 'number')) {
|
2782
|
+
return this.each(function (el) {
|
2783
|
+
xy(el, opt_x.left, opt_x.top)
|
2784
|
+
})
|
2785
|
+
} else if (typeof opt_x == 'number' || typeof opt_y == 'number') {
|
2786
|
+
return this.each(function (el) {
|
2787
|
+
xy(el, opt_x, opt_y)
|
2788
|
+
})
|
2789
|
+
}
|
2790
|
+
if (!this[0]) return {
|
2791
|
+
top: 0
|
2792
|
+
, left: 0
|
2793
|
+
, height: 0
|
2794
|
+
, width: 0
|
2795
|
+
}
|
2796
|
+
var el = this[0]
|
2797
|
+
, de = el.ownerDocument.documentElement
|
2798
|
+
, bcr = el.getBoundingClientRect()
|
2799
|
+
, scroll = getWindowScroll()
|
2800
|
+
, width = el.offsetWidth
|
2801
|
+
, height = el.offsetHeight
|
2802
|
+
, top = bcr.top + scroll.y - Math.max(0, de && de.clientTop, doc.body.clientTop)
|
2803
|
+
, left = bcr.left + scroll.x - Math.max(0, de && de.clientLeft, doc.body.clientLeft)
|
2804
|
+
|
2805
|
+
return {
|
2806
|
+
top: top
|
2807
|
+
, left: left
|
2808
|
+
, height: height
|
2809
|
+
, width: width
|
2810
|
+
}
|
2811
|
+
}
|
2812
|
+
|
2813
|
+
|
2814
|
+
/**
|
2815
|
+
* @return {number}
|
2816
|
+
*/
|
2817
|
+
, dim: function () {
|
2818
|
+
if (!this.length) return { height: 0, width: 0 }
|
2819
|
+
var el = this[0]
|
2820
|
+
, de = el.nodeType == 9 && el.documentElement // document
|
2821
|
+
, orig = !de && !!el.style && !el.offsetWidth && !el.offsetHeight ?
|
2822
|
+
// el isn't visible, can't be measured properly, so fix that
|
2823
|
+
function (t) {
|
2824
|
+
var s = {
|
2825
|
+
position: el.style.position || ''
|
2826
|
+
, visibility: el.style.visibility || ''
|
2827
|
+
, display: el.style.display || ''
|
2828
|
+
}
|
2829
|
+
t.first().css({
|
2830
|
+
position: 'absolute'
|
2831
|
+
, visibility: 'hidden'
|
2832
|
+
, display: 'block'
|
2833
|
+
})
|
2834
|
+
return s
|
2835
|
+
}(this) : null
|
2836
|
+
, width = de
|
2837
|
+
? Math.max(el.body.scrollWidth, el.body.offsetWidth, de.scrollWidth, de.offsetWidth, de.clientWidth)
|
2838
|
+
: el.offsetWidth
|
2839
|
+
, height = de
|
2840
|
+
? Math.max(el.body.scrollHeight, el.body.offsetHeight, de.scrollWidth, de.offsetWidth, de.clientHeight)
|
2841
|
+
: el.offsetHeight
|
2842
|
+
|
2843
|
+
orig && this.first().css(orig)
|
2844
|
+
return {
|
2845
|
+
height: height
|
2846
|
+
, width: width
|
2847
|
+
}
|
2848
|
+
}
|
2849
|
+
|
2850
|
+
// attributes are hard. go shopping
|
2851
|
+
|
2852
|
+
/**
|
2853
|
+
* @param {string} k an attribute to get or set
|
2854
|
+
* @param {string=} opt_v the value to set
|
2855
|
+
* @return {Bonzo|string}
|
2856
|
+
*/
|
2857
|
+
, attr: function (k, opt_v) {
|
2858
|
+
var el = this[0]
|
2859
|
+
if (typeof k != 'string' && !(k instanceof String)) {
|
2860
|
+
for (var n in k) {
|
2861
|
+
k.hasOwnProperty(n) && this.attr(n, k[n])
|
2862
|
+
}
|
2863
|
+
return this
|
2864
|
+
}
|
2865
|
+
return typeof opt_v == 'undefined' ?
|
2866
|
+
!el ? null : specialAttributes.test(k) ?
|
2867
|
+
stateAttributes.test(k) && typeof el[k] == 'string' ?
|
2868
|
+
true : el[k] : (k == 'href' || k =='src') && features.hrefExtended ?
|
2869
|
+
el[getAttribute](k, 2) : el[getAttribute](k) :
|
2870
|
+
this.each(function (el) {
|
2871
|
+
specialAttributes.test(k) ? (el[k] = setter(el, opt_v)) : el[setAttribute](k, setter(el, opt_v))
|
2872
|
+
})
|
2873
|
+
}
|
2874
|
+
|
2875
|
+
|
2876
|
+
/**
|
2877
|
+
* @param {string} k
|
2878
|
+
* @return {Bonzo}
|
2879
|
+
*/
|
2880
|
+
, removeAttr: function (k) {
|
2881
|
+
return this.each(function (el) {
|
2882
|
+
stateAttributes.test(k) ? (el[k] = false) : el.removeAttribute(k)
|
2883
|
+
})
|
2884
|
+
}
|
2885
|
+
|
2886
|
+
|
2887
|
+
/**
|
2888
|
+
* @param {string=} opt_s
|
2889
|
+
* @return {Bonzo|string}
|
2890
|
+
*/
|
2891
|
+
, val: function (s) {
|
2892
|
+
return (typeof s == 'string') ?
|
2893
|
+
this.attr('value', s) :
|
2894
|
+
this.length ? this[0].value : null
|
2895
|
+
}
|
2896
|
+
|
2897
|
+
// use with care and knowledge. this data() method uses data attributes on the DOM nodes
|
2898
|
+
// to do this differently costs a lot more code. c'est la vie
|
2899
|
+
/**
|
2900
|
+
* @param {string|Object=} opt_k the key for which to get or set data
|
2901
|
+
* @param {Object=} opt_v
|
2902
|
+
* @return {Bonzo|Object}
|
2903
|
+
*/
|
2904
|
+
, data: function (opt_k, opt_v) {
|
2905
|
+
var el = this[0], o, m
|
2906
|
+
if (typeof opt_v === 'undefined') {
|
2907
|
+
if (!el) return null
|
2908
|
+
o = data(el)
|
2909
|
+
if (typeof opt_k === 'undefined') {
|
2910
|
+
each(el.attributes, function (a) {
|
2911
|
+
(m = ('' + a.name).match(dattr)) && (o[camelize(m[1])] = dataValue(a.value))
|
2912
|
+
})
|
2913
|
+
return o
|
2914
|
+
} else {
|
2915
|
+
if (typeof o[opt_k] === 'undefined')
|
2916
|
+
o[opt_k] = dataValue(this.attr('data-' + decamelize(opt_k)))
|
2917
|
+
return o[opt_k]
|
2918
|
+
}
|
2919
|
+
} else {
|
2920
|
+
return this.each(function (el) { data(el)[opt_k] = opt_v })
|
2921
|
+
}
|
2922
|
+
}
|
2923
|
+
|
2924
|
+
// DOM detachment & related
|
2925
|
+
|
2926
|
+
/**
|
2927
|
+
* @return {Bonzo}
|
2928
|
+
*/
|
2929
|
+
, remove: function () {
|
2930
|
+
this.deepEach(clearData)
|
2931
|
+
return this.detach()
|
2932
|
+
}
|
2933
|
+
|
2934
|
+
|
2935
|
+
/**
|
2936
|
+
* @return {Bonzo}
|
2937
|
+
*/
|
2938
|
+
, empty: function () {
|
2939
|
+
return this.each(function (el) {
|
2940
|
+
deepEach(el.childNodes, clearData)
|
2941
|
+
|
2942
|
+
while (el.firstChild) {
|
2943
|
+
el.removeChild(el.firstChild)
|
2944
|
+
}
|
2945
|
+
})
|
2946
|
+
}
|
2947
|
+
|
2948
|
+
|
2949
|
+
/**
|
2950
|
+
* @return {Bonzo}
|
2951
|
+
*/
|
2952
|
+
, detach: function () {
|
2953
|
+
return this.each(function (el) {
|
2954
|
+
el[parentNode] && el[parentNode].removeChild(el)
|
2955
|
+
})
|
2956
|
+
}
|
2957
|
+
|
2958
|
+
// who uses a mouse anyway? oh right.
|
2959
|
+
|
2960
|
+
/**
|
2961
|
+
* @param {number} y
|
2962
|
+
*/
|
2963
|
+
, scrollTop: function (y) {
|
2964
|
+
return scroll.call(this, null, y, 'y')
|
2965
|
+
}
|
2966
|
+
|
2967
|
+
|
2968
|
+
/**
|
2969
|
+
* @param {number} x
|
2970
|
+
*/
|
2971
|
+
, scrollLeft: function (x) {
|
2972
|
+
return scroll.call(this, x, null, 'x')
|
2973
|
+
}
|
2974
|
+
|
2975
|
+
}
|
2976
|
+
|
2977
|
+
|
2978
|
+
function cloneNode(host, el) {
|
2979
|
+
var c = el.cloneNode(true)
|
2980
|
+
, cloneElems
|
2981
|
+
, elElems
|
2982
|
+
|
2983
|
+
// check for existence of an event cloner
|
2984
|
+
// preferably https://github.com/fat/bean
|
2985
|
+
// otherwise Bonzo won't do this for you
|
2986
|
+
if (host.$ && typeof host.cloneEvents == 'function') {
|
2987
|
+
host.$(c).cloneEvents(el)
|
2988
|
+
|
2989
|
+
// clone events from every child node
|
2990
|
+
cloneElems = host.$(c).find('*')
|
2991
|
+
elElems = host.$(el).find('*')
|
2992
|
+
|
2993
|
+
for (var i = 0; i < elElems.length; i++)
|
2994
|
+
host.$(cloneElems[i]).cloneEvents(elElems[i])
|
2995
|
+
}
|
2996
|
+
return c
|
2997
|
+
}
|
2998
|
+
|
2999
|
+
function scroll(x, y, type) {
|
3000
|
+
var el = this[0]
|
3001
|
+
if (!el) return this
|
3002
|
+
if (x == null && y == null) {
|
3003
|
+
return (isBody(el) ? getWindowScroll() : { x: el.scrollLeft, y: el.scrollTop })[type]
|
3004
|
+
}
|
3005
|
+
if (isBody(el)) {
|
3006
|
+
win.scrollTo(x, y)
|
3007
|
+
} else {
|
3008
|
+
x != null && (el.scrollLeft = x)
|
3009
|
+
y != null && (el.scrollTop = y)
|
3010
|
+
}
|
3011
|
+
return this
|
3012
|
+
}
|
3013
|
+
|
3014
|
+
function isBody(element) {
|
3015
|
+
return element === win || (/^(?:body|html)$/i).test(element.tagName)
|
3016
|
+
}
|
3017
|
+
|
3018
|
+
function getWindowScroll() {
|
3019
|
+
return { x: win.pageXOffset || html.scrollLeft, y: win.pageYOffset || html.scrollTop }
|
3020
|
+
}
|
3021
|
+
|
3022
|
+
function createScriptFromHtml(html) {
|
3023
|
+
var scriptEl = document.createElement('script')
|
3024
|
+
, matches = html.match(simpleScriptTagRe)
|
3025
|
+
scriptEl.src = matches[1]
|
3026
|
+
return scriptEl
|
3027
|
+
}
|
3028
|
+
|
3029
|
+
/**
|
3030
|
+
* @param {Array.<Element>|Element|Node|string} els
|
3031
|
+
* @return {Bonzo}
|
3032
|
+
*/
|
3033
|
+
function bonzo(els) {
|
3034
|
+
return new Bonzo(els)
|
3035
|
+
}
|
3036
|
+
|
3037
|
+
bonzo.setQueryEngine = function (q) {
|
3038
|
+
query = q;
|
3039
|
+
delete bonzo.setQueryEngine
|
3040
|
+
}
|
3041
|
+
|
3042
|
+
bonzo.aug = function (o, target) {
|
3043
|
+
// for those standalone bonzo users. this love is for you.
|
3044
|
+
for (var k in o) {
|
3045
|
+
o.hasOwnProperty(k) && ((target || Bonzo.prototype)[k] = o[k])
|
3046
|
+
}
|
3047
|
+
}
|
3048
|
+
|
3049
|
+
bonzo.create = function (node) {
|
3050
|
+
// hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
|
3051
|
+
return typeof node == 'string' && node !== '' ?
|
3052
|
+
function () {
|
3053
|
+
if (simpleScriptTagRe.test(node)) return [createScriptFromHtml(node)]
|
3054
|
+
var tag = node.match(/^\s*<([^\s>]+)/)
|
3055
|
+
, el = doc.createElement('div')
|
3056
|
+
, els = []
|
3057
|
+
, p = tag ? tagMap[tag[1].toLowerCase()] : null
|
3058
|
+
, dep = p ? p[2] + 1 : 1
|
3059
|
+
, ns = p && p[3]
|
3060
|
+
, pn = parentNode
|
3061
|
+
, tb = features.autoTbody && p && p[0] == '<table>' && !(/<tbody/i).test(node)
|
3062
|
+
|
3063
|
+
el.innerHTML = p ? (p[0] + node + p[1]) : node
|
3064
|
+
while (dep--) el = el.firstChild
|
3065
|
+
// for IE NoScope, we may insert cruft at the begining just to get it to work
|
3066
|
+
if (ns && el && el.nodeType !== 1) el = el.nextSibling
|
3067
|
+
do {
|
3068
|
+
// tbody special case for IE<8, creates tbody on any empty table
|
3069
|
+
// we don't want it if we're just after a <thead>, <caption>, etc.
|
3070
|
+
if ((!tag || el.nodeType == 1) && (!tb || (el.tagName && el.tagName != 'TBODY'))) {
|
3071
|
+
els.push(el)
|
3072
|
+
}
|
3073
|
+
} while (el = el.nextSibling)
|
3074
|
+
// IE < 9 gives us a parentNode which messes up insert() check for cloning
|
3075
|
+
// `dep` > 1 can also cause problems with the insert() check (must do this last)
|
3076
|
+
each(els, function(el) { el[pn] && el[pn].removeChild(el) })
|
3077
|
+
return els
|
3078
|
+
}() : isNode(node) ? [node.cloneNode(true)] : []
|
3079
|
+
}
|
3080
|
+
|
3081
|
+
bonzo.doc = function () {
|
3082
|
+
var vp = bonzo.viewport()
|
3083
|
+
return {
|
3084
|
+
width: Math.max(doc.body.scrollWidth, html.scrollWidth, vp.width)
|
3085
|
+
, height: Math.max(doc.body.scrollHeight, html.scrollHeight, vp.height)
|
3086
|
+
}
|
3087
|
+
}
|
3088
|
+
|
3089
|
+
bonzo.firstChild = function (el) {
|
3090
|
+
for (var c = el.childNodes, i = 0, j = (c && c.length) || 0, e; i < j; i++) {
|
3091
|
+
if (c[i].nodeType === 1) e = c[j = i]
|
3092
|
+
}
|
3093
|
+
return e
|
3094
|
+
}
|
3095
|
+
|
3096
|
+
bonzo.viewport = function () {
|
3097
|
+
return {
|
3098
|
+
width: ie ? html.clientWidth : self.innerWidth
|
3099
|
+
, height: ie ? html.clientHeight : self.innerHeight
|
3100
|
+
}
|
3101
|
+
}
|
3102
|
+
|
3103
|
+
bonzo.isAncestor = 'compareDocumentPosition' in html ?
|
3104
|
+
function (container, element) {
|
3105
|
+
return (container.compareDocumentPosition(element) & 16) == 16
|
3106
|
+
} : 'contains' in html ?
|
3107
|
+
function (container, element) {
|
3108
|
+
return container !== element && container.contains(element);
|
3109
|
+
} :
|
3110
|
+
function (container, element) {
|
3111
|
+
while (element = element[parentNode]) {
|
3112
|
+
if (element === container) {
|
3113
|
+
return true
|
3114
|
+
}
|
3115
|
+
}
|
3116
|
+
return false
|
3117
|
+
}
|
3118
|
+
|
3119
|
+
return bonzo
|
3120
|
+
}); // the only line we care about using a semi-colon. placed here for concatenation tools
|
3121
|
+
|
3122
|
+
|
3123
|
+
provide("bonzo", module.exports);
|
3124
|
+
|
3125
|
+
(function ($) {
|
3126
|
+
|
3127
|
+
var b = require('bonzo')
|
3128
|
+
b.setQueryEngine($)
|
3129
|
+
$.ender(b)
|
3130
|
+
$.ender(b(), true)
|
3131
|
+
$.ender({
|
3132
|
+
create: function (node) {
|
3133
|
+
return $(b.create(node))
|
3134
|
+
}
|
3135
|
+
})
|
3136
|
+
|
3137
|
+
$.id = function (id) {
|
3138
|
+
return $([document.getElementById(id)])
|
3139
|
+
}
|
3140
|
+
|
3141
|
+
function indexOf(ar, val) {
|
3142
|
+
for (var i = 0; i < ar.length; i++) if (ar[i] === val) return i
|
3143
|
+
return -1
|
3144
|
+
}
|
3145
|
+
|
3146
|
+
function uniq(ar) {
|
3147
|
+
var r = [], i = 0, j = 0, k, item, inIt
|
3148
|
+
for (; item = ar[i]; ++i) {
|
3149
|
+
inIt = false
|
3150
|
+
for (k = 0; k < r.length; ++k) {
|
3151
|
+
if (r[k] === item) {
|
3152
|
+
inIt = true; break
|
3153
|
+
}
|
3154
|
+
}
|
3155
|
+
if (!inIt) r[j++] = item
|
3156
|
+
}
|
3157
|
+
return r
|
3158
|
+
}
|
3159
|
+
|
3160
|
+
$.ender({
|
3161
|
+
parents: function (selector, closest) {
|
3162
|
+
if (!this.length) return this
|
3163
|
+
if (!selector) selector = '*'
|
3164
|
+
var collection = $(selector), j, k, p, r = []
|
3165
|
+
for (j = 0, k = this.length; j < k; j++) {
|
3166
|
+
p = this[j]
|
3167
|
+
while (p = p.parentNode) {
|
3168
|
+
if (~indexOf(collection, p)) {
|
3169
|
+
r.push(p)
|
3170
|
+
if (closest) break;
|
3171
|
+
}
|
3172
|
+
}
|
3173
|
+
}
|
3174
|
+
return $(uniq(r))
|
3175
|
+
}
|
3176
|
+
|
3177
|
+
, parent: function() {
|
3178
|
+
return $(uniq(b(this).parent()))
|
3179
|
+
}
|
3180
|
+
|
3181
|
+
, closest: function (selector) {
|
3182
|
+
return this.parents(selector, true)
|
3183
|
+
}
|
3184
|
+
|
3185
|
+
, first: function () {
|
3186
|
+
return $(this.length ? this[0] : this)
|
3187
|
+
}
|
3188
|
+
|
3189
|
+
, last: function () {
|
3190
|
+
return $(this.length ? this[this.length - 1] : [])
|
3191
|
+
}
|
3192
|
+
|
3193
|
+
, next: function () {
|
3194
|
+
return $(b(this).next())
|
3195
|
+
}
|
3196
|
+
|
3197
|
+
, previous: function () {
|
3198
|
+
return $(b(this).previous())
|
3199
|
+
}
|
3200
|
+
|
3201
|
+
, appendTo: function (t) {
|
3202
|
+
return b(this.selector).appendTo(t, this)
|
3203
|
+
}
|
3204
|
+
|
3205
|
+
, prependTo: function (t) {
|
3206
|
+
return b(this.selector).prependTo(t, this)
|
3207
|
+
}
|
3208
|
+
|
3209
|
+
, insertAfter: function (t) {
|
3210
|
+
return b(this.selector).insertAfter(t, this)
|
3211
|
+
}
|
3212
|
+
|
3213
|
+
, insertBefore: function (t) {
|
3214
|
+
return b(this.selector).insertBefore(t, this)
|
3215
|
+
}
|
3216
|
+
|
3217
|
+
, siblings: function () {
|
3218
|
+
var i, l, p, r = []
|
3219
|
+
for (i = 0, l = this.length; i < l; i++) {
|
3220
|
+
p = this[i]
|
3221
|
+
while (p = p.previousSibling) p.nodeType == 1 && r.push(p)
|
3222
|
+
p = this[i]
|
3223
|
+
while (p = p.nextSibling) p.nodeType == 1 && r.push(p)
|
3224
|
+
}
|
3225
|
+
return $(r)
|
3226
|
+
}
|
3227
|
+
|
3228
|
+
, children: function () {
|
3229
|
+
var i, l, el, r = []
|
3230
|
+
for (i = 0, l = this.length; i < l; i++) {
|
3231
|
+
if (!(el = b.firstChild(this[i]))) continue;
|
3232
|
+
r.push(el)
|
3233
|
+
while (el = el.nextSibling) el.nodeType == 1 && r.push(el)
|
3234
|
+
}
|
3235
|
+
return $(uniq(r))
|
3236
|
+
}
|
3237
|
+
|
3238
|
+
, height: function (v) {
|
3239
|
+
return dimension.call(this, 'height', v)
|
3240
|
+
}
|
3241
|
+
|
3242
|
+
, width: function (v) {
|
3243
|
+
return dimension.call(this, 'width', v)
|
3244
|
+
}
|
3245
|
+
}, true)
|
3246
|
+
|
3247
|
+
/**
|
3248
|
+
* @param {string} type either width or height
|
3249
|
+
* @param {number=} opt_v becomes a setter instead of a getter
|
3250
|
+
* @return {number}
|
3251
|
+
*/
|
3252
|
+
function dimension(type, opt_v) {
|
3253
|
+
return typeof opt_v == 'undefined'
|
3254
|
+
? b(this).dim()[type]
|
3255
|
+
: this.css(type, opt_v)
|
3256
|
+
}
|
3257
|
+
}(ender));
|
3258
|
+
|
3259
|
+
}());
|
3260
|
+
|