stackview_acorn_tester 2.0.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.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +291 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/javascripts/rails_stackview/auto_init.js +15 -0
  6. data/app/assets/javascripts/rails_stackview/browser.js +161 -0
  7. data/app/assets/javascripts/rails_stackview/plain.js +128 -0
  8. data/app/assets/javascripts/rails_stackview.js +11 -0
  9. data/app/assets/stylesheets/rails_stackview/_plain.scss +119 -0
  10. data/app/assets/stylesheets/rails_stackview/browser.scss +116 -0
  11. data/app/assets/stylesheets/rails_stackview.scss +10 -0
  12. data/app/controllers/stackview_data_controller.rb +91 -0
  13. data/app/fetch_adapters/rails_stackview/db_window_fetcher.rb +88 -0
  14. data/app/fetch_adapters/rails_stackview/mock_fetcher.rb +27 -0
  15. data/app/models/stackview_call_number.rb +2 -0
  16. data/app/views/rails_stackview/browser.html.erb +42 -0
  17. data/config/routes.rb +2 -0
  18. data/db/migrate/20150602210254_create_stackview_call_numbers.rb +34 -0
  19. data/lib/rails_stackview/engine.rb +7 -0
  20. data/lib/rails_stackview/version.rb +3 -0
  21. data/lib/rails_stackview.rb +20 -0
  22. data/lib/tasks/rails_stackview_tasks.rake +4 -0
  23. data/test/controllers/stackview_data_controller_test.rb +55 -0
  24. data/test/dummy/README.rdoc +28 -0
  25. data/test/dummy/Rakefile +6 -0
  26. data/test/dummy/app/assets/javascripts/application.js +17 -0
  27. data/test/dummy/app/assets/stylesheets/application.css +20 -0
  28. data/test/dummy/app/controllers/application_controller.rb +5 -0
  29. data/test/dummy/app/controllers/demo_controller.rb +14 -0
  30. data/test/dummy/app/helpers/application_helper.rb +2 -0
  31. data/test/dummy/app/views/demo/index.html.erb +14 -0
  32. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  33. data/test/dummy/bin/bundle +3 -0
  34. data/test/dummy/bin/rails +4 -0
  35. data/test/dummy/bin/rake +4 -0
  36. data/test/dummy/bin/setup +29 -0
  37. data/test/dummy/config/application.rb +26 -0
  38. data/test/dummy/config/boot.rb +5 -0
  39. data/test/dummy/config/database.yml +25 -0
  40. data/test/dummy/config/environment.rb +5 -0
  41. data/test/dummy/config/environments/development.rb +41 -0
  42. data/test/dummy/config/environments/production.rb +79 -0
  43. data/test/dummy/config/environments/test.rb +42 -0
  44. data/test/dummy/config/initializers/assets.rb +11 -0
  45. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  46. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  47. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  48. data/test/dummy/config/initializers/inflections.rb +16 -0
  49. data/test/dummy/config/initializers/mime_types.rb +4 -0
  50. data/test/dummy/config/initializers/session_store.rb +3 -0
  51. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  52. data/test/dummy/config/locales/en.yml +23 -0
  53. data/test/dummy/config/routes.rb +67 -0
  54. data/test/dummy/config/secrets.yml +22 -0
  55. data/test/dummy/config.ru +4 -0
  56. data/test/dummy/public/404.html +67 -0
  57. data/test/dummy/public/422.html +67 -0
  58. data/test/dummy/public/500.html +66 -0
  59. data/test/dummy/public/favicon.ico +0 -0
  60. data/test/dummy/test_fixture.yaml +433 -0
  61. data/test/fetch_adapters/db_window_fetcher_test.rb +106 -0
  62. data/test/fixtures/stackview_call_numbers.yml +473 -0
  63. data/test/integration/navigation_test.rb +10 -0
  64. data/test/rails_stackview_test.rb +7 -0
  65. data/test/test_helper.rb +42 -0
  66. data/vendor/assets/README.md +16 -0
  67. data/vendor/assets/images/stackview/bookEnd-next.png +0 -0
  68. data/vendor/assets/images/stackview/bookEnd-prev.png +0 -0
  69. data/vendor/assets/images/stackview/gloss.png +0 -0
  70. data/vendor/assets/images/stackview/highGloss.png +0 -0
  71. data/vendor/assets/images/stackview/icon-globe.png +0 -0
  72. data/vendor/assets/images/stackview/icon-note.png +0 -0
  73. data/vendor/assets/images/stackview/nav.png +0 -0
  74. data/vendor/assets/images/stackview/placeholder.gif +0 -0
  75. data/vendor/assets/images/stackview/ribbonTab.png +0 -0
  76. data/vendor/assets/images/stackview/serials-edge.png +0 -0
  77. data/vendor/assets/images/stackview/serials.png +0 -0
  78. data/vendor/assets/images/stackview/superGloss.png +0 -0
  79. data/vendor/assets/javascripts/jquery.stackview.js +21 -0
  80. data/vendor/assets/javascripts/stackview/jquery.easing.1.3.js +205 -0
  81. data/vendor/assets/javascripts/stackview/jquery.stackview.base.js +561 -0
  82. data/vendor/assets/javascripts/stackview/jquery.stackview.infinite.js +46 -0
  83. data/vendor/assets/javascripts/stackview/jquery.stackview.ministack.js +33 -0
  84. data/vendor/assets/javascripts/stackview/jquery.stackview.navigation.js +71 -0
  85. data/vendor/assets/javascripts/stackview/jquery.stackview.stackcache.js +74 -0
  86. data/vendor/assets/javascripts/stackview/jquery.stackview.templates.js +31 -0
  87. data/vendor/assets/javascripts/stackview/microtemplating.js +40 -0
  88. data/vendor/assets/javascripts/stackview/types/book.js +184 -0
  89. data/vendor/assets/javascripts/stackview/types/my_plain.js +183 -0
  90. data/vendor/assets/javascripts/stackview/types/serial.js +40 -0
  91. data/vendor/assets/javascripts/stackview/types/soundrecording.js +42 -0
  92. data/vendor/assets/javascripts/stackview/types/videofilm.js +56 -0
  93. data/vendor/assets/javascripts/stackview/types/webpage.js +42 -0
  94. data/vendor/assets/stackview.sha +1 -0
  95. data/vendor/assets/stylesheets/stackview/_book.scss +66 -0
  96. data/vendor/assets/stylesheets/stackview/_heatmap.scss +154 -0
  97. data/vendor/assets/stylesheets/stackview/_ministack.scss +43 -0
  98. data/vendor/assets/stylesheets/stackview/_mixins.scss +100 -0
  99. data/vendor/assets/stylesheets/stackview/_navigation.scss +52 -0
  100. data/vendor/assets/stylesheets/stackview/_plain.scss +71 -0
  101. data/vendor/assets/stylesheets/stackview/_serial.scss +50 -0
  102. data/vendor/assets/stylesheets/stackview/_soundrecording.scss +83 -0
  103. data/vendor/assets/stylesheets/stackview/_videofilm.scss +74 -0
  104. data/vendor/assets/stylesheets/stackview/_webpage.scss +82 -0
  105. data/vendor/assets/stylesheets/stackview/jquery.stackview.scss +171 -0
  106. metadata +233 -0
@@ -0,0 +1,561 @@
1
+ /*!
2
+ Stack View - The jQuery virtual stack plugin
3
+ by The Harvard Library Innovation Lab
4
+
5
+ Dual licensed under MIT and GPL.
6
+ */
7
+ (function($, window, document, undefined) {
8
+ var events,
9
+ plugin = 'stackView',
10
+ StackView,
11
+ types = {};
12
+
13
+ events = {
14
+ init: 'stackview.init',
15
+ item_added: 'stackview.itemadded',
16
+ item_removed: 'stackview.itemremoved',
17
+ page_load: 'stackview.pageload'
18
+ };
19
+
20
+ /*
21
+ #get_type
22
+ */
23
+ var get_type = function(item) {
24
+ var type;
25
+
26
+ $.each(types, function(key, val) {
27
+ if (val.match(item)) {
28
+ type = val;
29
+ return false;
30
+ }
31
+ });
32
+
33
+ return type;
34
+ };
35
+
36
+ /*
37
+ #render_items(StackView, array [, jQuery]) - Private
38
+
39
+ Takes a StackView instance, an array of result items, and an optional
40
+ jQuery object. Renders a DOM element for each of the items and
41
+ appends it to the stack's item list. If [placeholder] is passed in the
42
+ items take the its spot in the DOM.
43
+ */
44
+ var render_items = function(stack, docs, $placeholder) {
45
+ var action = $placeholder ? 'before' : 'append',
46
+ $pivot = $placeholder ?
47
+ $placeholder :
48
+ stack.$element.find(stack.options.selectors.item_list);
49
+
50
+ $.each(docs, function(i, item) {
51
+ var type = get_type(item),
52
+ $item;
53
+
54
+ if (type == null) {
55
+ return true;
56
+ }
57
+
58
+ $item = $(tmpl(type.template, type.adapter(item, stack.options)));
59
+ $item.data('stackviewItem', item);
60
+ $pivot[action]($item);
61
+ });
62
+
63
+ if ($placeholder) {
64
+ $placeholder.remove();
65
+ }
66
+
67
+ };
68
+
69
+ /*
70
+ #calculate_params(StackView) - Private
71
+
72
+ Takes a StackView instance and returns the parameters for the next page.
73
+ If the Stack uses loc_sort_order, this adjusts the query for that case.
74
+ Returns a plain object with key:value params to be used by $.param.
75
+ */
76
+ var calculate_params = function(stack) {
77
+ var opts = stack.options,
78
+ params;
79
+
80
+ params = {
81
+ start: stack.page * stack.options.items_per_page,
82
+ limit: stack.options.items_per_page,
83
+ search_type: stack.options.search_type,
84
+ query: stack.options.query
85
+ };
86
+
87
+ if (params.search_type === 'loc_sort_order') {
88
+ params.start = 0;
89
+
90
+ if (stack.page === 0) {
91
+ stack.loc = {
92
+ low: opts.id - Math.floor(opts.items_per_page / 2),
93
+ high: opts.id + Math.floor(opts.items_per_page / 2)
94
+ };
95
+ params.query = [
96
+ '[',
97
+ stack.loc.low,
98
+ ' TO ',
99
+ stack.loc.high,
100
+ ']'
101
+ ].join('');
102
+ }
103
+ else if (stack.direction === 'down') {
104
+ params.query = [
105
+ '[',
106
+ stack.loc.high + 1,
107
+ ' TO ',
108
+ stack.loc.high + opts.items_per_page + 1,
109
+ ']'
110
+ ].join('');
111
+ stack.loc.high = stack.loc.high + opts.items_per_page + 1;
112
+ }
113
+ else if (stack.direction === 'up') {
114
+ params.query = [
115
+ '[',
116
+ stack.loc.low - opts.items_per_page - 1,
117
+ ' TO ',
118
+ stack.loc.low - 1,
119
+ ']'
120
+ ].join('');
121
+ stack.loc.low = stack.loc.low - opts.items_per_page - 1;
122
+ }
123
+ }
124
+
125
+ return params;
126
+ };
127
+
128
+ /*
129
+ #fetch_page(StackView, function) - Private
130
+
131
+ Takes a StackView instance and a callback function. Retrieves the
132
+ next page according to the URL and other options of the StackView
133
+ instance. When the page is finished fetching, the callback is
134
+ invoked, passing in the array of items.
135
+ */
136
+ var fetch_page = function(stack, callback) {
137
+ var params = calculate_params(stack),
138
+ querystring = $.param(params),
139
+ cachedResult;
140
+
141
+ stack.page++;
142
+ cachedResult = window.stackCache.get(stack.options.url + querystring);
143
+
144
+ if (cachedResult) {
145
+ callback(cachedResult);
146
+ }
147
+ else {
148
+ $.ajax({
149
+ url: stack.options.url,
150
+ data: querystring,
151
+ dataType: stack.options.jsonp ? 'jsonp' : 'json',
152
+ success: function(data) {
153
+ window.stackCache.set(
154
+ stack.options.url + params,
155
+ data,
156
+ stack.options.cache_ttl
157
+ );
158
+ callback(data);
159
+ }
160
+ });
161
+ }
162
+ };
163
+
164
+
165
+
166
+
167
+ /* StackView constructor, set up instance properties and call init. */
168
+ StackView = function(elem, opts) {
169
+ this.element = elem;
170
+ this.$element = $(elem);
171
+ this.options = $.extend(true, {}, StackView.defaults, opts);
172
+ this.page = 0;
173
+ this.finished = {
174
+ up: false,
175
+ down: false
176
+ };
177
+ this.loc = {
178
+ low: null,
179
+ high: null
180
+ };
181
+ this.direction = 'down';
182
+ this.init();
183
+ };
184
+
185
+ /* Static properties and functions */
186
+ $.extend(true, StackView, {
187
+
188
+ /*
189
+ The default options for a StackView instance.
190
+
191
+ cache_ttl
192
+ How long a request will stay in cache.
193
+
194
+ data
195
+ An alternative to URL, used for static data. Accepts a typical
196
+ URL response object or a simple array of item objects.
197
+
198
+ id
199
+ When using a search type of loc_sort_order, this is the id of
200
+ the item that the search centers around.
201
+
202
+ items_per_page
203
+ The number of items to request each page.
204
+
205
+ jsonp
206
+ If true, the URL will expect a JSONP request. callback=? will be
207
+ added to the request parameters.
208
+
209
+ query
210
+ The query passed to the script at URL. Passed as the
211
+ query parameter.
212
+
213
+ ribbon
214
+ The text of the ribbon at the top of the stack.
215
+
216
+ search_type
217
+ The type of search to be performed by the script at URL. This is
218
+ passed to the script as the search_type parameter.
219
+
220
+ selectors
221
+ A number of selectors that are frequently used by the code to
222
+ identify key structures.
223
+
224
+ item
225
+ A single item in the stack.
226
+
227
+ item_list
228
+ Container around all of the stack items.
229
+
230
+ ribbon
231
+ The text ribbon at the top of the stack.
232
+
233
+ url
234
+ The URL to send requests to for item data.
235
+ */
236
+ defaults: {
237
+ cache_ttl: 60,
238
+ data: '',
239
+ id: null,
240
+ items_per_page: 10,
241
+ jsonp: false,
242
+ query: '',
243
+ ribbon: 'Stack View',
244
+ search_type: 'keyword',
245
+ selectors: {
246
+ item: '.stack-item',
247
+ item_list: '.stack-items',
248
+ ribbon: '.ribbon'
249
+ },
250
+ url: 'basic.json'
251
+ },
252
+
253
+ /*
254
+ StackView.get_heat(number)
255
+
256
+ Takes a value between 0 and 100 and returns a number to be used with
257
+ heat classes to indicate popularity.
258
+ */
259
+ utils: {
260
+ get_heat: function(scaled_value) {
261
+ return scaled_value === 100 ? 10 : Math.floor(scaled_value / 10) + 1;
262
+ }
263
+ },
264
+
265
+ /*
266
+ StackView.register_type(object)
267
+
268
+ Registers an item type to be used by the stack. A Type object
269
+ has the following properties:
270
+
271
+ name: string
272
+ A unique, identifying name of the item type.
273
+
274
+ match: function(obj) -> obj
275
+ A function that takes a stack item and returns true if the
276
+ item matches this type. Example:
277
+
278
+ match: function(item) { return item.type === 'book' }
279
+
280
+ adapter: function(obj, obj) -> obj
281
+ This function allows the user to make transformations to the
282
+ item data before rendering it to the template. It takes as
283
+ parameters a raw item that matches the match function and the
284
+ options from the StackView instance. It should return an object
285
+ to render against "template." If no changes to the raw data need
286
+ to be made, the simplest value for this can be:
287
+
288
+ adapter: function(item) { return item; }
289
+
290
+ template: string
291
+ A microtemplating template to render for this type in the stack.
292
+ Receives as its data the return value from "adapter."
293
+
294
+ */
295
+ register_type: function(obj) {
296
+ types[obj.name] = obj;
297
+ },
298
+
299
+ /*
300
+ StackView.get_types()
301
+
302
+ Returns the hash of item types.
303
+ */
304
+ get_types: function() {
305
+ return types;
306
+ }
307
+ });
308
+
309
+ /*
310
+ StackView public methods
311
+ */
312
+ $.extend(true, StackView.prototype, {
313
+
314
+ /*
315
+ #init()
316
+
317
+ Sets up the initial states of a stack. Including:
318
+ - Creating the HTML skeleton.
319
+ - Binding zIndex ordering to the pageload event.
320
+ - Loading the first page.
321
+ - Firing the init event.
322
+ */
323
+ init: function() {
324
+ var that = this;
325
+
326
+ this.$element
327
+ .html(tmpl(StackView.templates.scaffold, {
328
+ ribbon: this.options.ribbon
329
+ }))
330
+ .addClass('stackview')
331
+ .bind(events.page_load, function() {
332
+ that.zIndex();
333
+ });
334
+
335
+ this.$element.data('stackviewObject', this);
336
+ this.$element.trigger(events.init);
337
+ this.next_page();
338
+ },
339
+
340
+ /*
341
+ #next_page()
342
+
343
+ Loads the next page of stack items. If we've already hit the
344
+ last page, this function does nothing.
345
+ */
346
+ next_page: function() {
347
+ var $placeholder = $(tmpl(StackView.templates.placeholder, {})),
348
+ that = this,
349
+ opts = this.options;
350
+
351
+ if (this.finished.down) {
352
+ return;
353
+ }
354
+
355
+ this.direction = 'down';
356
+ if (opts.data) {
357
+ render_items(this, opts.data.docs ? opts.data.docs : opts.data);
358
+ this.finished.down = true;
359
+ this.$element.trigger(events.page_load, [opts.data]);
360
+ }
361
+ else if (opts.url) {
362
+ this.$element
363
+ .find(opts.selectors.item_list)
364
+ .append($placeholder);
365
+ fetch_page(this, function(data) {
366
+ render_items(that, data.docs, $placeholder);
367
+ if (parseInt(data.start, 10) === -1) {
368
+ that.finished.down = true;
369
+ }
370
+ that.$element.trigger(events.page_load, [data]);
371
+ });
372
+ }
373
+ },
374
+
375
+ /*
376
+ #prev_page()
377
+
378
+ Loads the previous page of stack items. If we've already hit the
379
+ first page this function does nothing. This function only works
380
+ for stacks using the loc_sort_order search type.
381
+ */
382
+ prev_page: function() {
383
+ var $placeholder = $(tmpl(StackView.templates.placeholder, {})),
384
+ opts = this.options,
385
+ that = this,
386
+ $oldMarker = that.$element.find(opts.selectors.item).first();
387
+
388
+ if (opts.search_type !== 'loc_sort_order' || this.finished.up) {
389
+ return;
390
+ }
391
+
392
+ this.direction = 'up';
393
+ this.$element.find(opts.selectors.item_list).prepend($placeholder);
394
+ fetch_page(this, function(data) {
395
+ var oldTop = $oldMarker.position().top;
396
+
397
+ render_items(that, data.docs, $placeholder);
398
+ if (that.page > 1) {
399
+ that.$element.find(opts.selectors.item_list).animate({
400
+ 'scrollTop': '+=' + ($oldMarker.position().top - oldTop)
401
+ }, 0);
402
+ }
403
+ if (parseInt(data.start, 10) === -1) {
404
+ that.finished.up = true;
405
+ }
406
+ that.$element.trigger(events.page_load, [data]);
407
+ });
408
+ },
409
+
410
+ /*
411
+ #add([number,] object)
412
+
413
+ Adds the specified item object to the stack, at the given index if
414
+ provided or at the end (bottom) of the stack if index is not given.
415
+ */
416
+ add: function() {
417
+ var $items = this.$element.find(this.options.selectors.item),
418
+ index, item, type, action, $pivot, $item;
419
+
420
+ if (typeof(arguments[0]) === 'number') {
421
+ index = arguments[0];
422
+ item = arguments[1];
423
+ }
424
+ else {
425
+ index = $items.length;
426
+ item = arguments[0];
427
+ }
428
+
429
+ if (index > $items.length || index < 0) {
430
+ return;
431
+ }
432
+ else if (index === $items.length) {
433
+ $pivot = $items.last();
434
+ action = 'after';
435
+ }
436
+ else {
437
+ $pivot = $items.eq(index);
438
+ action = 'before';
439
+ }
440
+
441
+ type = get_type(item);
442
+ if (type == null) {
443
+ return;
444
+ }
445
+ $item = $(tmpl(type.template, type.adapter(item, this.options)));
446
+
447
+ $item.data('stackviewItem', item);
448
+ $pivot[action]($item);
449
+ this.zIndex();
450
+ this.$element.trigger(events.item_added);
451
+ },
452
+
453
+ /*
454
+ #remove(number | object)
455
+
456
+ If a number is given, it removes the item at that index. If an
457
+ object is given, this method finds the element that represents that
458
+ item and removes it.
459
+ */
460
+ remove: function(arg) {
461
+ var $items = this.$element.find(this.options.selectors.item),
462
+ $found, data, index;
463
+
464
+ if (typeof(arg) === 'number') {
465
+ $found = $items.eq(arg);
466
+ }
467
+ else if (arg.nodeType || arg.jquery){
468
+ $found = $(arg);
469
+ }
470
+ else {
471
+ $items.each(function(i, el) {
472
+ var $el = $(el);
473
+
474
+ if ($el.data('stackviewItem') === arg) {
475
+ $found = $el;
476
+ return false;
477
+ }
478
+ });
479
+ }
480
+
481
+ if ($found == null || !$found.length) {
482
+ return;
483
+ }
484
+
485
+ $found.detach();
486
+ data = $found.data('stackviewItem');
487
+ this.$element.trigger(events.item_removed, [data]);
488
+ return $found;
489
+ },
490
+
491
+
492
+ /*
493
+ #getData()
494
+
495
+ Returns an array of all the item objects currently in the stack.
496
+ */
497
+ getData: function() {
498
+ var data = [];
499
+
500
+ this.$element.find(this.options.selectors.item).each(function() {
501
+ data.push($(this).data('stackviewItem'));
502
+ });
503
+
504
+ return data;
505
+ },
506
+
507
+ /*
508
+ #zIndex(boolean)
509
+
510
+ Reverses the natural flow order of the stack items by giving those
511
+ earlier in the source (higher on the stack) a higher z-index. If
512
+ passed true, it will instead assign z-indexes in normal flow order.
513
+ */
514
+ zIndex: function(reverse) {
515
+ var $items = this.$element.find(this.options.selectors.item),
516
+ length = $items.length,
517
+ i = 0,
518
+ z = reverse ? 0 : $items.length - 1;
519
+
520
+ while (i < length) {
521
+ $items.eq(i).css('z-index', z);
522
+ z = z + (reverse ? 1 : -1);
523
+ i++;
524
+ }
525
+ }
526
+ });
527
+
528
+ /*
529
+ If .stackView has not been called on an element, the first call will
530
+ initialize the plugin. Subsequent calls expect a method from the
531
+ StackView class. Any method that returns undefined is assumed to
532
+ chain. If the method returns a value, only the value from the first
533
+ element in the jQuery set will be returned, the same as other getters
534
+ in jQuery.
535
+ */
536
+ $.fn[plugin] = function(method) {
537
+ var response,
538
+ args = Array.prototype.slice.call(arguments, 1);
539
+
540
+ this.each(function(i, el) {
541
+ var $el = $(el),
542
+ obj = $el.data('stackviewObject');
543
+
544
+ if (!obj) {
545
+ new StackView(el, method);
546
+ }
547
+ else if (obj[method]) {
548
+ var methodResponse = obj[method].apply(obj, args);
549
+
550
+ if (response === undefined && methodResponse !== undefined) {
551
+ response = methodResponse;
552
+ }
553
+ }
554
+ });
555
+
556
+ return response === undefined ? this : response;
557
+ };
558
+
559
+ /* Expose the StackView class for extension */
560
+ window.StackView = StackView;
561
+ })(jQuery, window, document);
@@ -0,0 +1,46 @@
1
+ /*
2
+ Stack View infinite scroll module:
3
+
4
+ This module uses the scroll position of a stack to determine when
5
+ to fire the base methods of next_page and prev_page.
6
+ */
7
+ (function($, undefined) {
8
+ var $d = $(document),
9
+ infinite;
10
+
11
+ /* Extend defaults */
12
+ $.extend(StackView.defaults, {
13
+ infiniteScrollDistance: 100
14
+ });
15
+
16
+ infinite = function(event) {
17
+ var $stack = $(event.target),
18
+ stack = $stack.data('stackviewObject'),
19
+ opts = stack.options,
20
+ $itemList, $items, opts, lastItemTop, triggerPoint, scrollCheck;
21
+
22
+ $itemList = $stack.find(opts.selectors.item_list);
23
+ $items = $stack.find(opts.selectors.item);
24
+
25
+ lastItemTop = $items.length ? $items.last().position().top : 0;
26
+ lastItemTop += $itemList.scrollTop();
27
+ triggerPoint = lastItemTop - $stack.height() - opts.infiniteScrollDistance;
28
+
29
+ scrollCheck = function() {
30
+ if (opts.search_type === 'loc_sort_order' &&
31
+ $itemList.scrollTop() <= opts.infiniteScrollDistance) {
32
+ $itemList.unbind('scroll.stackview');
33
+ $stack.stackView('prev_page');
34
+ }
35
+ else if ($itemList.scrollTop() >= triggerPoint) {
36
+ $itemList.unbind('scroll.stackview');
37
+ $stack.stackView('next_page');
38
+ }
39
+ };
40
+
41
+ $itemList.bind('scroll.stackview', scrollCheck);
42
+ scrollCheck();
43
+ };
44
+
45
+ $d.delegate('.stackview', 'stackview.pageload', infinite);
46
+ })(jQuery);
@@ -0,0 +1,33 @@
1
+ (function($, undefined) {
2
+ var $d = $(document),
3
+ StackView = window.StackView;
4
+
5
+ $.extend(true, StackView.defaults, {
6
+ classes: {
7
+ ministack: 'stackview-mini'
8
+ },
9
+
10
+ ministack: {
11
+ breakpoint: 220,
12
+ max_height_percentage: 100,
13
+ min_height_percentage: 80,
14
+ page_multiple: .08
15
+ }
16
+ });
17
+
18
+ $d.delegate('.stackview', 'stackview.init', function(event) {
19
+ var $stack = $(event.target),
20
+ stack = $stack.data('stackviewObject');
21
+
22
+ if ($stack.width() <= stack.options.ministack.breakpoint) {
23
+ $stack.addClass(stack.options.classes.ministack);
24
+ $.each([
25
+ 'max_height_percentage',
26
+ 'min_height_percentage',
27
+ 'page_multiple'
28
+ ], function(i, el) {
29
+ stack.options.book[el] = stack.options.ministack[el];
30
+ });
31
+ }
32
+ });
33
+ })(jQuery);
@@ -0,0 +1,71 @@
1
+ /*
2
+ Stack View navigation module
3
+
4
+ Adds clickable navigation to scroll through the stack, as well as
5
+ a # of items indicator.
6
+ */
7
+ (function($, undefined) {
8
+ var $d = $(document),
9
+ StackView = window.StackView;
10
+
11
+ $.extend(true, StackView.defaults, {
12
+ transitionDuration: 500,
13
+ transitionEasing: 'easeOutQuad',
14
+ navigationPercent: 80,
15
+ selectors: {
16
+ downstream: '.downstream',
17
+ upstream: '.upstream',
18
+ num_items: '.num-found span'
19
+ }
20
+ });
21
+
22
+ $d.delegate('.stackview', 'stackview.init', function(event) {
23
+ var $stack = $(event.target),
24
+ stack = $stack.data('stackviewObject'),
25
+ $items = $stack.find(stack.options.selectors.item_list),
26
+ delta = $stack.height() * stack.options.navigationPercent / 100;
27
+
28
+ stack.num_found_delta = 0;
29
+ $stack.prepend(tmpl(StackView.templates.navigation, {
30
+ empty: stack.options.search_type === 'loc_sort_order'
31
+ }));
32
+
33
+ $stack
34
+ .delegate(stack.options.selectors.downstream, 'click', function() {
35
+ $items.animate({
36
+ scrollTop: '+=' + delta
37
+ }, stack.options.transitionDuration, stack.options.transitionEasing);
38
+ return false;
39
+ })
40
+ .delegate(stack.options.selectors.upstream, 'click', function() {
41
+ $items.animate({
42
+ scrollTop: '-=' + delta
43
+ }, stack.options.transitionDuration, stack.options.transitionEasing);
44
+ return false;
45
+ });
46
+
47
+ }).delegate('.stackview', 'stackview.pageload', function(event, data) {
48
+ var $stack = $(event.target),
49
+ stack = $stack.data('stackviewObject'),
50
+ num_found = data.num_found ? parseInt(data.num_found, 10) : data.length,
51
+ num;
52
+
53
+ stack.num_found = num_found;
54
+ num = num_found + stack.num_found_delta;
55
+ $stack.find(stack.options.selectors.num_items).text(num);
56
+
57
+ }).delegate(
58
+ '.stackview',
59
+ 'stackview.itemadded stackview.itemremoved',
60
+ function(event) {
61
+ var $stack = $(event.target),
62
+ stack = $stack.data('stackviewObject'),
63
+ $items = $stack.find(stack.options.selectors.item),
64
+ num;
65
+
66
+ stack.num_found_delta += (event.namespace === 'itemadded' ? 1 : -1);
67
+ num = stack.num_found + stack.num_found_delta;
68
+ $stack.find(stack.options.selectors.num_items).text(num);
69
+ }
70
+ );
71
+ })(jQuery);