bootstrap_pager 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +18 -0
- data/.idea/encodings.xml +5 -0
- data/.idea/misc.xml +5 -0
- data/.idea/modules.xml +9 -0
- data/.idea/pager.iml +50 -0
- data/.idea/scopes/scope_settings.xml +5 -0
- data/.idea/vcs.xml +7 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +307 -0
- data/Rakefile +42 -0
- data/app/assets/javascripts/infinitescroll.js +8 -0
- data/app/helpers/pager_helper.rb +5 -0
- data/app/views/pager/_first_page.html.erb +11 -0
- data/app/views/pager/_first_page.html.haml +9 -0
- data/app/views/pager/_first_page.html.slim +10 -0
- data/app/views/pager/_gap.html.erb +8 -0
- data/app/views/pager/_gap.html.haml +8 -0
- data/app/views/pager/_gap.html.slim +10 -0
- data/app/views/pager/_last_page.html.erb +11 -0
- data/app/views/pager/_last_page.html.haml +9 -0
- data/app/views/pager/_last_page.html.slim +10 -0
- data/app/views/pager/_next_page.html.erb +11 -0
- data/app/views/pager/_next_page.html.haml +9 -0
- data/app/views/pager/_next_page.html.slim +10 -0
- data/app/views/pager/_page.html.erb +14 -0
- data/app/views/pager/_page.html.haml +11 -0
- data/app/views/pager/_page.html.slim +13 -0
- data/app/views/pager/_paginator.html.erb +25 -0
- data/app/views/pager/_paginator.html.haml +19 -0
- data/app/views/pager/_paginator.html.slim +20 -0
- data/app/views/pager/_prev_page.html.erb +11 -0
- data/app/views/pager/_prev_page.html.haml +9 -0
- data/app/views/pager/_prev_page.html.slim +10 -0
- data/bootstrap_pager.gemspec +36 -0
- data/config/locales/pager.yml +19 -0
- data/gemfiles/active_record_30.gemfile +9 -0
- data/gemfiles/active_record_31.gemfile +7 -0
- data/gemfiles/active_record_32.gemfile +10 -0
- data/gemfiles/active_record_40.gemfile +8 -0
- data/gemfiles/active_record_edge.gemfile +11 -0
- data/gemfiles/data_mapper_12.gemfile +15 -0
- data/gemfiles/mongo_mapper.gemfile +10 -0
- data/gemfiles/mongoid_24.gemfile +7 -0
- data/gemfiles/mongoid_30.gemfile +12 -0
- data/gemfiles/sinatra_13.gemfile +13 -0
- data/gemfiles/sinatra_14.gemfile +13 -0
- data/lib/bootstrap_pager/config.rb +51 -0
- data/lib/bootstrap_pager/grape.rb +4 -0
- data/lib/bootstrap_pager/helpers/action_view_extension.rb +152 -0
- data/lib/bootstrap_pager/helpers/paginator.rb +186 -0
- data/lib/bootstrap_pager/helpers/sinatra_helpers.rb +144 -0
- data/lib/bootstrap_pager/helpers/tags.rb +96 -0
- data/lib/bootstrap_pager/hooks.rb +41 -0
- data/lib/bootstrap_pager/models/active_record_extension.rb +22 -0
- data/lib/bootstrap_pager/models/active_record_model_extension.rb +20 -0
- data/lib/bootstrap_pager/models/active_record_relation_methods.rb +29 -0
- data/lib/bootstrap_pager/models/array_extension.rb +58 -0
- data/lib/bootstrap_pager/models/configuration_methods.rb +48 -0
- data/lib/bootstrap_pager/models/data_mapper_collection_methods.rb +15 -0
- data/lib/bootstrap_pager/models/data_mapper_extension.rb +48 -0
- data/lib/bootstrap_pager/models/mongo_mapper_extension.rb +18 -0
- data/lib/bootstrap_pager/models/mongoid_criteria_methods.rb +23 -0
- data/lib/bootstrap_pager/models/mongoid_extension.rb +33 -0
- data/lib/bootstrap_pager/models/page_scope_methods.rb +70 -0
- data/lib/bootstrap_pager/models/plucky_criteria_methods.rb +18 -0
- data/lib/bootstrap_pager/railtie.rb +7 -0
- data/lib/bootstrap_pager/sinatra.rb +5 -0
- data/lib/bootstrap_pager/version.rb +3 -0
- data/lib/bootstrap_pager.rb +38 -0
- data/lib/generators/pager/config_generator.rb +16 -0
- data/lib/generators/pager/templates/pager_config.rb +10 -0
- data/lib/generators/pager/views_generator.rb +118 -0
- data/spec/config/config_spec.rb +91 -0
- data/spec/fake_app/active_record/config.rb +3 -0
- data/spec/fake_app/active_record/models.rb +57 -0
- data/spec/fake_app/data_mapper/config.rb +7 -0
- data/spec/fake_app/data_mapper/models.rb +27 -0
- data/spec/fake_app/log/development.log +832 -0
- data/spec/fake_app/mongo_mapper/config.rb +2 -0
- data/spec/fake_app/mongo_mapper/models.rb +9 -0
- data/spec/fake_app/mongoid/config.rb +16 -0
- data/spec/fake_app/mongoid/models.rb +22 -0
- data/spec/fake_app/rails_app.rb +67 -0
- data/spec/fake_app/sinatra_app.rb +22 -0
- data/spec/fake_gem.rb +4 -0
- data/spec/helpers/action_view_extension_spec.rb +292 -0
- data/spec/helpers/helpers_spec.rb +135 -0
- data/spec/helpers/sinatra_helpers_spec.rb +170 -0
- data/spec/helpers/tags_spec.rb +140 -0
- data/spec/models/active_record/active_record_relation_methods_spec.rb +47 -0
- data/spec/models/active_record/default_per_page_spec.rb +32 -0
- data/spec/models/active_record/max_pages_spec.rb +23 -0
- data/spec/models/active_record/max_per_page_spec.rb +32 -0
- data/spec/models/active_record/scopes_spec.rb +242 -0
- data/spec/models/array_spec.rb +150 -0
- data/spec/models/data_mapper/data_mapper_spec.rb +207 -0
- data/spec/models/mongo_mapper/mongo_mapper_spec.rb +84 -0
- data/spec/models/mongoid/mongoid_spec.rb +126 -0
- data/spec/requests/users_spec.rb +53 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/spec_helper_for_sinatra.rb +34 -0
- data/spec/support/database_cleaner.rb +16 -0
- data/spec/support/matchers.rb +52 -0
- data/vendor/assets/javascripts/jquery.infinitescroll.js +814 -0
- data/vendor/assets/javascripts/jquery.infinitescroll.min.js +1 -0
- metadata +311 -0
|
@@ -0,0 +1,814 @@
|
|
|
1
|
+
/*jshint undef: true */
|
|
2
|
+
/*global jQuery: true */
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
--------------------------------
|
|
6
|
+
Infinite Scroll
|
|
7
|
+
--------------------------------
|
|
8
|
+
+ https://github.com/paulirish/infinite-scroll
|
|
9
|
+
+ version 2.0b2.120519
|
|
10
|
+
+ Copyright 2011/12 Paul Irish & Luke Shumard
|
|
11
|
+
+ Licensed under the MIT license
|
|
12
|
+
|
|
13
|
+
+ Documentation: http://infinite-scroll.com/
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
(function (window, $, undefined) {
|
|
17
|
+
"use strict";
|
|
18
|
+
|
|
19
|
+
$.infinitescroll = function infscr(options, callback, element) {
|
|
20
|
+
this.element = $(element);
|
|
21
|
+
|
|
22
|
+
// Flag the object in the event of a failed creation
|
|
23
|
+
if (!this._create(options, callback)) {
|
|
24
|
+
this.failed = true;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
$.infinitescroll.defaults = {
|
|
29
|
+
loading: {
|
|
30
|
+
finished: undefined,
|
|
31
|
+
finishedMsg: "<em>Congratulations, you've reached the end of the internet.</em>",
|
|
32
|
+
img: "data:image/gif;base64,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",
|
|
33
|
+
msg: null,
|
|
34
|
+
msgText: "<em>Loading the next set of posts...</em>",
|
|
35
|
+
selector: null,
|
|
36
|
+
speed: 'fast',
|
|
37
|
+
start: undefined
|
|
38
|
+
},
|
|
39
|
+
state: {
|
|
40
|
+
isDuringAjax: false,
|
|
41
|
+
isInvalidPage: false,
|
|
42
|
+
isDestroyed: false,
|
|
43
|
+
isDone: false, // For when it goes all the way through the archive.
|
|
44
|
+
isPaused: false,
|
|
45
|
+
isBeyondMaxPage: false,
|
|
46
|
+
currPage: 1
|
|
47
|
+
},
|
|
48
|
+
debug: false,
|
|
49
|
+
behavior: undefined,
|
|
50
|
+
binder: $(window), // used to cache the selector
|
|
51
|
+
nextSelector: "div.navigation a:first",
|
|
52
|
+
navSelector: "div.navigation",
|
|
53
|
+
contentSelector: null, // rename to pageFragment
|
|
54
|
+
extraScrollPx: 150,
|
|
55
|
+
itemSelector: "div.post",
|
|
56
|
+
animate: false,
|
|
57
|
+
pathParse: undefined,
|
|
58
|
+
dataType: 'html',
|
|
59
|
+
appendCallback: true,
|
|
60
|
+
bufferPx: 40,
|
|
61
|
+
errorCallback: function () { },
|
|
62
|
+
infid: 0, //Instance ID
|
|
63
|
+
pixelsFromNavToBottom: undefined,
|
|
64
|
+
path: undefined, // Either parts of a URL as an array (e.g. ["/page/", "/"] or a function that takes in the page number and returns a URL
|
|
65
|
+
prefill: false, // When the document is smaller than the window, load data until the document is larger or links are exhausted
|
|
66
|
+
maxPage: undefined // to manually control maximum page (when maxPage is undefined, maximum page limitation is not work)
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
$.infinitescroll.prototype = {
|
|
70
|
+
|
|
71
|
+
/*
|
|
72
|
+
----------------------------
|
|
73
|
+
Private methods
|
|
74
|
+
----------------------------
|
|
75
|
+
*/
|
|
76
|
+
|
|
77
|
+
// Bind or unbind from scroll
|
|
78
|
+
_binding: function infscr_binding(binding) {
|
|
79
|
+
|
|
80
|
+
var instance = this,
|
|
81
|
+
opts = instance.options;
|
|
82
|
+
|
|
83
|
+
opts.v = '2.0b2.120520';
|
|
84
|
+
|
|
85
|
+
// if behavior is defined and this function is extended, call that instead of default
|
|
86
|
+
if (!!opts.behavior && this['_binding_'+opts.behavior] !== undefined) {
|
|
87
|
+
this['_binding_'+opts.behavior].call(this);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (binding !== 'bind' && binding !== 'unbind') {
|
|
92
|
+
this._debug('Binding value ' + binding + ' not valid');
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (binding === 'unbind') {
|
|
97
|
+
(this.options.binder).unbind('smartscroll.infscr.' + instance.options.infid);
|
|
98
|
+
} else {
|
|
99
|
+
(this.options.binder)[binding]('smartscroll.infscr.' + instance.options.infid, function () {
|
|
100
|
+
instance.scroll();
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
this._debug('Binding', binding);
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
// Fundamental aspects of the plugin are initialized
|
|
108
|
+
_create: function infscr_create(options, callback) {
|
|
109
|
+
|
|
110
|
+
// Add custom options to defaults
|
|
111
|
+
var opts = $.extend(true, {}, $.infinitescroll.defaults, options);
|
|
112
|
+
this.options = opts;
|
|
113
|
+
var $window = $(window);
|
|
114
|
+
var instance = this;
|
|
115
|
+
|
|
116
|
+
// Validate selectors
|
|
117
|
+
if (!instance._validate(options)) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Validate page fragment path
|
|
122
|
+
var path = $(opts.nextSelector).attr('href');
|
|
123
|
+
if (!path) {
|
|
124
|
+
this._debug('Navigation selector not found');
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Set the path to be a relative URL from root.
|
|
129
|
+
opts.path = opts.path || this._determinepath(path);
|
|
130
|
+
|
|
131
|
+
// contentSelector is 'page fragment' option for .load() / .ajax() calls
|
|
132
|
+
opts.contentSelector = opts.contentSelector || this.element;
|
|
133
|
+
|
|
134
|
+
// loading.selector - if we want to place the load message in a specific selector, defaulted to the contentSelector
|
|
135
|
+
opts.loading.selector = opts.loading.selector || opts.contentSelector;
|
|
136
|
+
|
|
137
|
+
// Define loading.msg
|
|
138
|
+
opts.loading.msg = opts.loading.msg || $('<div id="infscr-loading"><img alt="Loading..." src="' + opts.loading.img + '" /><div>' + opts.loading.msgText + '</div></div>');
|
|
139
|
+
|
|
140
|
+
// Preload loading.img
|
|
141
|
+
(new Image()).src = opts.loading.img;
|
|
142
|
+
|
|
143
|
+
// distance from nav links to bottom
|
|
144
|
+
// computed as: height of the document + top offset of container - top offset of nav link
|
|
145
|
+
if(opts.pixelsFromNavToBottom === undefined) {
|
|
146
|
+
opts.pixelsFromNavToBottom = $(document).height() - $(opts.navSelector).offset().top;
|
|
147
|
+
this._debug("pixelsFromNavToBottom: " + opts.pixelsFromNavToBottom);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
var self = this;
|
|
151
|
+
|
|
152
|
+
// determine loading.start actions
|
|
153
|
+
opts.loading.start = opts.loading.start || function() {
|
|
154
|
+
$(opts.navSelector).hide();
|
|
155
|
+
opts.loading.msg
|
|
156
|
+
.appendTo(opts.loading.selector)
|
|
157
|
+
.show(opts.loading.speed, $.proxy(function() {
|
|
158
|
+
this.beginAjax(opts);
|
|
159
|
+
}, self));
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// determine loading.finished actions
|
|
163
|
+
opts.loading.finished = opts.loading.finished || function() {
|
|
164
|
+
if (!opts.state.isBeyondMaxPage)
|
|
165
|
+
opts.loading.msg.fadeOut(opts.loading.speed);
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// callback loading
|
|
169
|
+
opts.callback = function(instance, data, url) {
|
|
170
|
+
if (!!opts.behavior && instance['_callback_'+opts.behavior] !== undefined) {
|
|
171
|
+
instance['_callback_'+opts.behavior].call($(opts.contentSelector)[0], data, url);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (callback) {
|
|
175
|
+
callback.call($(opts.contentSelector)[0], data, opts, url);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (opts.prefill) {
|
|
179
|
+
$window.bind("resize.infinite-scroll", instance._prefill);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
if (options.debug) {
|
|
184
|
+
// Tell IE9 to use its built-in console
|
|
185
|
+
if (Function.prototype.bind && (typeof console === 'object' || typeof console === 'function') && typeof console.log === "object") {
|
|
186
|
+
["log","info","warn","error","assert","dir","clear","profile","profileEnd"]
|
|
187
|
+
.forEach(function (method) {
|
|
188
|
+
console[method] = this.call(console[method], console);
|
|
189
|
+
}, Function.prototype.bind);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
this._setup();
|
|
194
|
+
|
|
195
|
+
// Setups the prefill method for use
|
|
196
|
+
if (opts.prefill) {
|
|
197
|
+
this._prefill();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Return true to indicate successful creation
|
|
201
|
+
return true;
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
_prefill: function infscr_prefill() {
|
|
205
|
+
var instance = this;
|
|
206
|
+
var $window = $(window);
|
|
207
|
+
|
|
208
|
+
function needsPrefill() {
|
|
209
|
+
return (instance.options.contentSelector.height() <= $window.height());
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
this._prefill = function() {
|
|
213
|
+
if (needsPrefill()) {
|
|
214
|
+
instance.scroll();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
$window.bind("resize.infinite-scroll", function() {
|
|
218
|
+
if (needsPrefill()) {
|
|
219
|
+
$window.unbind("resize.infinite-scroll");
|
|
220
|
+
instance.scroll();
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
// Call self after setting up the new function
|
|
226
|
+
this._prefill();
|
|
227
|
+
},
|
|
228
|
+
|
|
229
|
+
// Console log wrapper
|
|
230
|
+
_debug: function infscr_debug() {
|
|
231
|
+
if (true !== this.options.debug) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (typeof console !== 'undefined' && typeof console.log === 'function') {
|
|
236
|
+
// Modern browsers
|
|
237
|
+
// Single argument, which is a string
|
|
238
|
+
if ((Array.prototype.slice.call(arguments)).length === 1 && typeof Array.prototype.slice.call(arguments)[0] === 'string') {
|
|
239
|
+
console.log( (Array.prototype.slice.call(arguments)).toString() );
|
|
240
|
+
} else {
|
|
241
|
+
console.log( Array.prototype.slice.call(arguments) );
|
|
242
|
+
}
|
|
243
|
+
} else if (!Function.prototype.bind && typeof console !== 'undefined' && typeof console.log === 'object') {
|
|
244
|
+
// IE8
|
|
245
|
+
Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments));
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
// find the number to increment in the path.
|
|
250
|
+
_determinepath: function infscr_determinepath(path) {
|
|
251
|
+
|
|
252
|
+
var opts = this.options;
|
|
253
|
+
|
|
254
|
+
// if behavior is defined and this function is extended, call that instead of default
|
|
255
|
+
if (!!opts.behavior && this['_determinepath_'+opts.behavior] !== undefined) {
|
|
256
|
+
return this['_determinepath_'+opts.behavior].call(this,path);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (!!opts.pathParse) {
|
|
260
|
+
|
|
261
|
+
this._debug('pathParse manual');
|
|
262
|
+
return opts.pathParse(path, this.options.state.currPage+1);
|
|
263
|
+
|
|
264
|
+
} else if (path.match(/^(.*?)\b2\b(.*?$)/)) {
|
|
265
|
+
path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1);
|
|
266
|
+
|
|
267
|
+
// if there is any 2 in the url at all.
|
|
268
|
+
} else if (path.match(/^(.*?)2(.*?$)/)) {
|
|
269
|
+
|
|
270
|
+
// page= is used in django:
|
|
271
|
+
// http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127
|
|
272
|
+
if (path.match(/^(.*?page=)2(\/.*|$)/)) {
|
|
273
|
+
path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1);
|
|
274
|
+
return path;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
path = path.match(/^(.*?)2(.*?$)/).slice(1);
|
|
278
|
+
|
|
279
|
+
} else {
|
|
280
|
+
|
|
281
|
+
// page= is used in drupal too but second page is page=1 not page=2:
|
|
282
|
+
// thx Jerod Fritz, vladikoff
|
|
283
|
+
if (path.match(/^(.*?page=)1(\/.*|$)/)) {
|
|
284
|
+
path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1);
|
|
285
|
+
return path;
|
|
286
|
+
} else {
|
|
287
|
+
this._debug('Sorry, we couldn\'t parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.');
|
|
288
|
+
// Get rid of isInvalidPage to allow permalink to state
|
|
289
|
+
opts.state.isInvalidPage = true; //prevent it from running on this page.
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
this._debug('determinePath', path);
|
|
293
|
+
return path;
|
|
294
|
+
|
|
295
|
+
},
|
|
296
|
+
|
|
297
|
+
// Custom error
|
|
298
|
+
_error: function infscr_error(xhr) {
|
|
299
|
+
|
|
300
|
+
var opts = this.options;
|
|
301
|
+
|
|
302
|
+
// if behavior is defined and this function is extended, call that instead of default
|
|
303
|
+
if (!!opts.behavior && this['_error_'+opts.behavior] !== undefined) {
|
|
304
|
+
this['_error_'+opts.behavior].call(this,xhr);
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (xhr !== 'destroy' && xhr !== 'end') {
|
|
309
|
+
xhr = 'unknown';
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
this._debug('Error', xhr);
|
|
313
|
+
|
|
314
|
+
if (xhr === 'end' || opts.state.isBeyondMaxPage) {
|
|
315
|
+
this._showdonemsg();
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
opts.state.isDone = true;
|
|
319
|
+
opts.state.currPage = 1; // if you need to go back to this instance
|
|
320
|
+
opts.state.isPaused = false;
|
|
321
|
+
opts.state.isBeyondMaxPage = false;
|
|
322
|
+
this._binding('unbind');
|
|
323
|
+
|
|
324
|
+
},
|
|
325
|
+
|
|
326
|
+
// Load Callback
|
|
327
|
+
_loadcallback: function infscr_loadcallback(box, data, url) {
|
|
328
|
+
var opts = this.options,
|
|
329
|
+
callback = this.options.callback, // GLOBAL OBJECT FOR CALLBACK
|
|
330
|
+
result = (opts.state.isDone) ? 'done' : (!opts.appendCallback) ? 'no-append' : 'append',
|
|
331
|
+
frag;
|
|
332
|
+
|
|
333
|
+
// if behavior is defined and this function is extended, call that instead of default
|
|
334
|
+
if (!!opts.behavior && this['_loadcallback_'+opts.behavior] !== undefined) {
|
|
335
|
+
this['_loadcallback_'+opts.behavior].call(this,box,data);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
switch (result) {
|
|
340
|
+
case 'done':
|
|
341
|
+
this._showdonemsg();
|
|
342
|
+
return false;
|
|
343
|
+
|
|
344
|
+
case 'no-append':
|
|
345
|
+
if (opts.dataType === 'html') {
|
|
346
|
+
data = '<div>' + data + '</div>';
|
|
347
|
+
data = $(data).find(opts.itemSelector);
|
|
348
|
+
}
|
|
349
|
+
break;
|
|
350
|
+
|
|
351
|
+
case 'append':
|
|
352
|
+
var children = box.children();
|
|
353
|
+
// if it didn't return anything
|
|
354
|
+
if (children.length === 0) {
|
|
355
|
+
return this._error('end');
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// use a documentFragment because it works when content is going into a table or UL
|
|
359
|
+
frag = document.createDocumentFragment();
|
|
360
|
+
while (box[0].firstChild) {
|
|
361
|
+
frag.appendChild(box[0].firstChild);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
this._debug('contentSelector', $(opts.contentSelector)[0]);
|
|
365
|
+
$(opts.contentSelector)[0].appendChild(frag);
|
|
366
|
+
// previously, we would pass in the new DOM element as context for the callback
|
|
367
|
+
// however we're now using a documentfragment, which doesn't have parents or children,
|
|
368
|
+
// so the context is the contentContainer guy, and we pass in an array
|
|
369
|
+
// of the elements collected as the first argument.
|
|
370
|
+
|
|
371
|
+
data = children.get();
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// loadingEnd function
|
|
376
|
+
opts.loading.finished.call($(opts.contentSelector)[0],opts);
|
|
377
|
+
|
|
378
|
+
// smooth scroll to ease in the new content
|
|
379
|
+
if (opts.animate) {
|
|
380
|
+
var scrollTo = $(window).scrollTop() + $(opts.loading.msg).height() + opts.extraScrollPx + 'px';
|
|
381
|
+
$('html,body').animate({ scrollTop: scrollTo }, 800, function () { opts.state.isDuringAjax = false; });
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (!opts.animate) {
|
|
385
|
+
// once the call is done, we can allow it again.
|
|
386
|
+
opts.state.isDuringAjax = false;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
callback(this, data, url);
|
|
390
|
+
|
|
391
|
+
if (opts.prefill) {
|
|
392
|
+
this._prefill();
|
|
393
|
+
}
|
|
394
|
+
},
|
|
395
|
+
|
|
396
|
+
_nearbottom: function infscr_nearbottom() {
|
|
397
|
+
|
|
398
|
+
var opts = this.options,
|
|
399
|
+
pixelsFromWindowBottomToBottom = 0 + $(document).height() - (opts.binder.scrollTop()) - $(window).height();
|
|
400
|
+
|
|
401
|
+
// if behavior is defined and this function is extended, call that instead of default
|
|
402
|
+
if (!!opts.behavior && this['_nearbottom_'+opts.behavior] !== undefined) {
|
|
403
|
+
return this['_nearbottom_'+opts.behavior].call(this);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
this._debug('math:', pixelsFromWindowBottomToBottom, opts.pixelsFromNavToBottom);
|
|
407
|
+
|
|
408
|
+
// if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom....
|
|
409
|
+
return (pixelsFromWindowBottomToBottom - opts.bufferPx < opts.pixelsFromNavToBottom);
|
|
410
|
+
|
|
411
|
+
},
|
|
412
|
+
|
|
413
|
+
// Pause / temporarily disable plugin from firing
|
|
414
|
+
_pausing: function infscr_pausing(pause) {
|
|
415
|
+
|
|
416
|
+
var opts = this.options;
|
|
417
|
+
|
|
418
|
+
// if behavior is defined and this function is extended, call that instead of default
|
|
419
|
+
if (!!opts.behavior && this['_pausing_'+opts.behavior] !== undefined) {
|
|
420
|
+
this['_pausing_'+opts.behavior].call(this,pause);
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// If pause is not 'pause' or 'resume', toggle it's value
|
|
425
|
+
if (pause !== 'pause' && pause !== 'resume' && pause !== null) {
|
|
426
|
+
this._debug('Invalid argument. Toggling pause value instead');
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
pause = (pause && (pause === 'pause' || pause === 'resume')) ? pause : 'toggle';
|
|
430
|
+
|
|
431
|
+
switch (pause) {
|
|
432
|
+
case 'pause':
|
|
433
|
+
opts.state.isPaused = true;
|
|
434
|
+
break;
|
|
435
|
+
|
|
436
|
+
case 'resume':
|
|
437
|
+
opts.state.isPaused = false;
|
|
438
|
+
break;
|
|
439
|
+
|
|
440
|
+
case 'toggle':
|
|
441
|
+
opts.state.isPaused = !opts.state.isPaused;
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
this._debug('Paused', opts.state.isPaused);
|
|
446
|
+
return false;
|
|
447
|
+
|
|
448
|
+
},
|
|
449
|
+
|
|
450
|
+
// Behavior is determined
|
|
451
|
+
// If the behavior option is undefined, it will set to default and bind to scroll
|
|
452
|
+
_setup: function infscr_setup() {
|
|
453
|
+
|
|
454
|
+
var opts = this.options;
|
|
455
|
+
|
|
456
|
+
// if behavior is defined and this function is extended, call that instead of default
|
|
457
|
+
if (!!opts.behavior && this['_setup_'+opts.behavior] !== undefined) {
|
|
458
|
+
this['_setup_'+opts.behavior].call(this);
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
this._binding('bind');
|
|
463
|
+
|
|
464
|
+
return false;
|
|
465
|
+
|
|
466
|
+
},
|
|
467
|
+
|
|
468
|
+
// Show done message
|
|
469
|
+
_showdonemsg: function infscr_showdonemsg() {
|
|
470
|
+
|
|
471
|
+
var opts = this.options;
|
|
472
|
+
|
|
473
|
+
// if behavior is defined and this function is extended, call that instead of default
|
|
474
|
+
if (!!opts.behavior && this['_showdonemsg_'+opts.behavior] !== undefined) {
|
|
475
|
+
this['_showdonemsg_'+opts.behavior].call(this);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
opts.loading.msg
|
|
480
|
+
.find('img')
|
|
481
|
+
.hide()
|
|
482
|
+
.parent()
|
|
483
|
+
.find('div').html(opts.loading.finishedMsg).animate({ opacity: 1 }, 2000, function () {
|
|
484
|
+
$(this).parent().fadeOut(opts.loading.speed);
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
// user provided callback when done
|
|
488
|
+
opts.errorCallback.call($(opts.contentSelector)[0],'done');
|
|
489
|
+
},
|
|
490
|
+
|
|
491
|
+
// grab each selector option and see if any fail
|
|
492
|
+
_validate: function infscr_validate(opts) {
|
|
493
|
+
for (var key in opts) {
|
|
494
|
+
if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0) {
|
|
495
|
+
this._debug('Your ' + key + ' found no elements.');
|
|
496
|
+
return false;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return true;
|
|
501
|
+
},
|
|
502
|
+
|
|
503
|
+
/*
|
|
504
|
+
----------------------------
|
|
505
|
+
Public methods
|
|
506
|
+
----------------------------
|
|
507
|
+
*/
|
|
508
|
+
|
|
509
|
+
// Bind to scroll
|
|
510
|
+
bind: function infscr_bind() {
|
|
511
|
+
this._binding('bind');
|
|
512
|
+
},
|
|
513
|
+
|
|
514
|
+
// Destroy current instance of plugin
|
|
515
|
+
destroy: function infscr_destroy() {
|
|
516
|
+
this.options.state.isDestroyed = true;
|
|
517
|
+
this.options.loading.finished();
|
|
518
|
+
return this._error('destroy');
|
|
519
|
+
},
|
|
520
|
+
|
|
521
|
+
// Set pause value to false
|
|
522
|
+
pause: function infscr_pause() {
|
|
523
|
+
this._pausing('pause');
|
|
524
|
+
},
|
|
525
|
+
|
|
526
|
+
// Set pause value to false
|
|
527
|
+
resume: function infscr_resume() {
|
|
528
|
+
this._pausing('resume');
|
|
529
|
+
},
|
|
530
|
+
|
|
531
|
+
beginAjax: function infscr_ajax(opts) {
|
|
532
|
+
var instance = this,
|
|
533
|
+
path = opts.path,
|
|
534
|
+
box, desturl, method, condition;
|
|
535
|
+
|
|
536
|
+
// increment the URL bit. e.g. /page/3/
|
|
537
|
+
opts.state.currPage++;
|
|
538
|
+
|
|
539
|
+
// Manually control maximum page
|
|
540
|
+
if ( opts.maxPage != undefined && opts.state.currPage > opts.maxPage ){
|
|
541
|
+
opts.state.isBeyondMaxPage = true;
|
|
542
|
+
this.destroy();
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// if we're dealing with a table we can't use DIVs
|
|
547
|
+
box = $(opts.contentSelector).is('table, tbody') ? $('<tbody/>') : $('<div/>');
|
|
548
|
+
|
|
549
|
+
desturl = (typeof path === 'function') ? path(opts.state.currPage) : path.join(opts.state.currPage);
|
|
550
|
+
instance._debug('heading into ajax', desturl);
|
|
551
|
+
|
|
552
|
+
method = (opts.dataType === 'html' || opts.dataType === 'json' ) ? opts.dataType : 'html+callback';
|
|
553
|
+
if (opts.appendCallback && opts.dataType === 'html') {
|
|
554
|
+
method += '+callback';
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
switch (method) {
|
|
558
|
+
case 'html+callback':
|
|
559
|
+
instance._debug('Using HTML via .load() method');
|
|
560
|
+
box.load(desturl + ' ' + opts.itemSelector, undefined, function infscr_ajax_callback(responseText) {
|
|
561
|
+
instance._loadcallback(box, responseText, desturl);
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
break;
|
|
565
|
+
|
|
566
|
+
case 'html':
|
|
567
|
+
instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method');
|
|
568
|
+
$.ajax({
|
|
569
|
+
// params
|
|
570
|
+
url: desturl,
|
|
571
|
+
dataType: opts.dataType,
|
|
572
|
+
complete: function infscr_ajax_callback(jqXHR, textStatus) {
|
|
573
|
+
condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === "success" || textStatus === "notmodified");
|
|
574
|
+
if (condition) {
|
|
575
|
+
instance._loadcallback(box, jqXHR.responseText, desturl);
|
|
576
|
+
} else {
|
|
577
|
+
instance._error('end');
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
break;
|
|
583
|
+
case 'json':
|
|
584
|
+
instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method');
|
|
585
|
+
$.ajax({
|
|
586
|
+
dataType: 'json',
|
|
587
|
+
type: 'GET',
|
|
588
|
+
url: desturl,
|
|
589
|
+
success: function (data, textStatus, jqXHR) {
|
|
590
|
+
condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === "success" || textStatus === "notmodified");
|
|
591
|
+
if (opts.appendCallback) {
|
|
592
|
+
// if appendCallback is true, you must defined template in options.
|
|
593
|
+
// note that data passed into _loadcallback is already an html (after processed in opts.template(data)).
|
|
594
|
+
if (opts.template !== undefined) {
|
|
595
|
+
var theData = opts.template(data);
|
|
596
|
+
box.append(theData);
|
|
597
|
+
if (condition) {
|
|
598
|
+
instance._loadcallback(box, theData);
|
|
599
|
+
} else {
|
|
600
|
+
instance._error('end');
|
|
601
|
+
}
|
|
602
|
+
} else {
|
|
603
|
+
instance._debug("template must be defined.");
|
|
604
|
+
instance._error('end');
|
|
605
|
+
}
|
|
606
|
+
} else {
|
|
607
|
+
// if appendCallback is false, we will pass in the JSON object. you should handle it yourself in your callback.
|
|
608
|
+
if (condition) {
|
|
609
|
+
instance._loadcallback(box, data, desturl);
|
|
610
|
+
} else {
|
|
611
|
+
instance._error('end');
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
},
|
|
615
|
+
error: function() {
|
|
616
|
+
instance._debug("JSON ajax request failed.");
|
|
617
|
+
instance._error('end');
|
|
618
|
+
}
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
break;
|
|
622
|
+
}
|
|
623
|
+
},
|
|
624
|
+
|
|
625
|
+
// Retrieve next set of content items
|
|
626
|
+
retrieve: function infscr_retrieve(pageNum) {
|
|
627
|
+
pageNum = pageNum || null;
|
|
628
|
+
|
|
629
|
+
var instance = this,
|
|
630
|
+
opts = instance.options;
|
|
631
|
+
|
|
632
|
+
// if behavior is defined and this function is extended, call that instead of default
|
|
633
|
+
if (!!opts.behavior && this['retrieve_'+opts.behavior] !== undefined) {
|
|
634
|
+
this['retrieve_'+opts.behavior].call(this,pageNum);
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// for manual triggers, if destroyed, get out of here
|
|
639
|
+
if (opts.state.isDestroyed) {
|
|
640
|
+
this._debug('Instance is destroyed');
|
|
641
|
+
return false;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// we dont want to fire the ajax multiple times
|
|
645
|
+
opts.state.isDuringAjax = true;
|
|
646
|
+
|
|
647
|
+
opts.loading.start.call($(opts.contentSelector)[0],opts);
|
|
648
|
+
},
|
|
649
|
+
|
|
650
|
+
// Check to see next page is needed
|
|
651
|
+
scroll: function infscr_scroll() {
|
|
652
|
+
|
|
653
|
+
var opts = this.options,
|
|
654
|
+
state = opts.state;
|
|
655
|
+
|
|
656
|
+
// if behavior is defined and this function is extended, call that instead of default
|
|
657
|
+
if (!!opts.behavior && this['scroll_'+opts.behavior] !== undefined) {
|
|
658
|
+
this['scroll_'+opts.behavior].call(this);
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
if (state.isDuringAjax || state.isInvalidPage || state.isDone || state.isDestroyed || state.isPaused) {
|
|
663
|
+
return;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
if (!this._nearbottom()) {
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
this.retrieve();
|
|
671
|
+
|
|
672
|
+
},
|
|
673
|
+
|
|
674
|
+
// Toggle pause value
|
|
675
|
+
toggle: function infscr_toggle() {
|
|
676
|
+
this._pausing();
|
|
677
|
+
},
|
|
678
|
+
|
|
679
|
+
// Unbind from scroll
|
|
680
|
+
unbind: function infscr_unbind() {
|
|
681
|
+
this._binding('unbind');
|
|
682
|
+
},
|
|
683
|
+
|
|
684
|
+
// update options
|
|
685
|
+
update: function infscr_options(key) {
|
|
686
|
+
if ($.isPlainObject(key)) {
|
|
687
|
+
this.options = $.extend(true,this.options,key);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
/*
|
|
694
|
+
----------------------------
|
|
695
|
+
Infinite Scroll function
|
|
696
|
+
----------------------------
|
|
697
|
+
|
|
698
|
+
Borrowed logic from the following...
|
|
699
|
+
|
|
700
|
+
jQuery UI
|
|
701
|
+
- https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js
|
|
702
|
+
|
|
703
|
+
jCarousel
|
|
704
|
+
- https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js
|
|
705
|
+
|
|
706
|
+
Masonry
|
|
707
|
+
- https://github.com/desandro/masonry/blob/master/jquery.masonry.js
|
|
708
|
+
|
|
709
|
+
*/
|
|
710
|
+
|
|
711
|
+
$.fn.infinitescroll = function infscr_init(options, callback) {
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
var thisCall = typeof options;
|
|
715
|
+
|
|
716
|
+
switch (thisCall) {
|
|
717
|
+
|
|
718
|
+
// method
|
|
719
|
+
case 'string':
|
|
720
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
|
721
|
+
|
|
722
|
+
this.each(function () {
|
|
723
|
+
var instance = $.data(this, 'infinitescroll');
|
|
724
|
+
|
|
725
|
+
if (!instance) {
|
|
726
|
+
// not setup yet
|
|
727
|
+
// return $.error('Method ' + options + ' cannot be called until Infinite Scroll is setup');
|
|
728
|
+
return false;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
if (!$.isFunction(instance[options]) || options.charAt(0) === "_") {
|
|
732
|
+
// return $.error('No such method ' + options + ' for Infinite Scroll');
|
|
733
|
+
return false;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// no errors!
|
|
737
|
+
instance[options].apply(instance, args);
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
break;
|
|
741
|
+
|
|
742
|
+
// creation
|
|
743
|
+
case 'object':
|
|
744
|
+
|
|
745
|
+
this.each(function () {
|
|
746
|
+
|
|
747
|
+
var instance = $.data(this, 'infinitescroll');
|
|
748
|
+
|
|
749
|
+
if (instance) {
|
|
750
|
+
|
|
751
|
+
// update options of current instance
|
|
752
|
+
instance.update(options);
|
|
753
|
+
|
|
754
|
+
} else {
|
|
755
|
+
|
|
756
|
+
// initialize new instance
|
|
757
|
+
instance = new $.infinitescroll(options, callback, this);
|
|
758
|
+
|
|
759
|
+
// don't attach if instantiation failed
|
|
760
|
+
if (!instance.failed) {
|
|
761
|
+
$.data(this, 'infinitescroll', instance);
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
break;
|
|
769
|
+
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
return this;
|
|
773
|
+
};
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
/*
|
|
778
|
+
* smartscroll: debounced scroll event for jQuery *
|
|
779
|
+
* https://github.com/lukeshumard/smartscroll
|
|
780
|
+
* Based on smartresize by @louis_remi: https://github.com/lrbabe/jquery.smartresize.js *
|
|
781
|
+
* Copyright 2011 Louis-Remi & Luke Shumard * Licensed under the MIT license. *
|
|
782
|
+
*/
|
|
783
|
+
|
|
784
|
+
var event = $.event,
|
|
785
|
+
scrollTimeout;
|
|
786
|
+
|
|
787
|
+
event.special.smartscroll = {
|
|
788
|
+
setup: function () {
|
|
789
|
+
$(this).bind("scroll", event.special.smartscroll.handler);
|
|
790
|
+
},
|
|
791
|
+
teardown: function () {
|
|
792
|
+
$(this).unbind("scroll", event.special.smartscroll.handler);
|
|
793
|
+
},
|
|
794
|
+
handler: function (event, execAsap) {
|
|
795
|
+
// Save the context
|
|
796
|
+
var context = this,
|
|
797
|
+
args = arguments;
|
|
798
|
+
|
|
799
|
+
// set correct event type
|
|
800
|
+
event.type = "smartscroll";
|
|
801
|
+
|
|
802
|
+
if (scrollTimeout) { clearTimeout(scrollTimeout); }
|
|
803
|
+
scrollTimeout = setTimeout(function () {
|
|
804
|
+
$(context).trigger('smartscroll', args);
|
|
805
|
+
}, execAsap === "execAsap" ? 0 : 100);
|
|
806
|
+
}
|
|
807
|
+
};
|
|
808
|
+
|
|
809
|
+
$.fn.smartscroll = function (fn) {
|
|
810
|
+
return fn ? this.bind("smartscroll", fn) : this.trigger("smartscroll", ["execAsap"]);
|
|
811
|
+
};
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
})(window, jQuery);
|