rails_stackview 1.0.0 → 1.0.1
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 +4 -4
- data/README.md +2 -4
- data/lib/rails_stackview/version.rb +1 -1
- data/vendor/assets/README.md +16 -0
- data/vendor/assets/images/stackview/bookEnd-next.png +0 -0
- data/vendor/assets/images/stackview/bookEnd-prev.png +0 -0
- data/vendor/assets/images/stackview/gloss.png +0 -0
- data/vendor/assets/images/stackview/highGloss.png +0 -0
- data/vendor/assets/images/stackview/icon-globe.png +0 -0
- data/vendor/assets/images/stackview/icon-note.png +0 -0
- data/vendor/assets/images/stackview/nav.png +0 -0
- data/vendor/assets/images/stackview/placeholder.gif +0 -0
- data/vendor/assets/images/stackview/ribbonTab.png +0 -0
- data/vendor/assets/images/stackview/serials-edge.png +0 -0
- data/vendor/assets/images/stackview/serials.png +0 -0
- data/vendor/assets/images/stackview/superGloss.png +0 -0
- data/vendor/assets/javascripts/jquery.stackview.js +21 -0
- data/vendor/assets/javascripts/stackview/jquery.easing.1.3.js +205 -0
- data/vendor/assets/javascripts/stackview/jquery.stackview.base.js +561 -0
- data/vendor/assets/javascripts/stackview/jquery.stackview.infinite.js +46 -0
- data/vendor/assets/javascripts/stackview/jquery.stackview.ministack.js +33 -0
- data/vendor/assets/javascripts/stackview/jquery.stackview.navigation.js +71 -0
- data/vendor/assets/javascripts/stackview/jquery.stackview.stackcache.js +74 -0
- data/vendor/assets/javascripts/stackview/jquery.stackview.templates.js +31 -0
- data/vendor/assets/javascripts/stackview/microtemplating.js +40 -0
- data/vendor/assets/javascripts/stackview/types/book.js +184 -0
- data/vendor/assets/javascripts/stackview/types/my_plain.js +183 -0
- data/vendor/assets/javascripts/stackview/types/serial.js +40 -0
- data/vendor/assets/javascripts/stackview/types/soundrecording.js +42 -0
- data/vendor/assets/javascripts/stackview/types/videofilm.js +56 -0
- data/vendor/assets/javascripts/stackview/types/webpage.js +42 -0
- data/vendor/assets/stackview.sha +1 -0
- data/vendor/assets/stylesheets/stackview/_book.scss +66 -0
- data/vendor/assets/stylesheets/stackview/_heatmap.scss +154 -0
- data/vendor/assets/stylesheets/stackview/_ministack.scss +43 -0
- data/vendor/assets/stylesheets/stackview/_mixins.scss +100 -0
- data/vendor/assets/stylesheets/stackview/_navigation.scss +52 -0
- data/vendor/assets/stylesheets/stackview/_plain.scss +71 -0
- data/vendor/assets/stylesheets/stackview/_serial.scss +50 -0
- data/vendor/assets/stylesheets/stackview/_soundrecording.scss +83 -0
- data/vendor/assets/stylesheets/stackview/_videofilm.scss +74 -0
- data/vendor/assets/stylesheets/stackview/_webpage.scss +82 -0
- data/vendor/assets/stylesheets/stackview/jquery.stackview.scss +171 -0
- metadata +41 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f90b15df352fff73c0c6ec5db8241438fcdca875
|
4
|
+
data.tar.gz: 4d8e7e3d5e59c6d9b9230a25974948a6802df5d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9f76890644194095bb344aa0bc6fdb6c94df10f3e31d375d39191a090d40eb30a98e56da750768bb93db88147962df151ed85f55c13b062871661d9f4758cd5
|
7
|
+
data.tar.gz: 00bc0f53ebfa77f1402549e4e5639a4f23eedcf943abed79b9a0e1138546f67a0e0ac3d4e3c356434075af2f3dbc2f348dad5f3b857b46ae3b26dd652b753b1c
|
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
IN PROGRESS UNDER DEVELOPMENT NOT USABLE YET
|
1
|
+
[](https://travis-ci.org/jrochkind/rails_stackview) [](http://badge.fury.io/rb/rails_stackview)
|
4
2
|
|
5
|
-
|
3
|
+
# RailsStackview
|
6
4
|
|
7
5
|
This is not an out of the box solution, integrating it into your app will require some development.
|
8
6
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Asset files from stackview source are included in rails_stackview under
|
2
|
+
`./vendor/assets` subdirs.
|
3
|
+
|
4
|
+
To refresh with recent source, do a git checkout of stackview somewhere, then
|
5
|
+
from rails_stackview root dir, run:
|
6
|
+
|
7
|
+
RUBYLIB=./source_tools/ rails generate copy_stackview_assets path_to_stackview_source -f
|
8
|
+
|
9
|
+
The git SHA of stackview source that was copied into rails_stackview will be
|
10
|
+
saved at ./vendor/assets/stackview.sha
|
11
|
+
|
12
|
+
Part of the routine for copying stackview assets will also replace all
|
13
|
+
CSS `url()` in stackview CSS source with rails-sass `asset-url` calls, to
|
14
|
+
play well with the asset pipeline. To support this, the stackview
|
15
|
+
CSS will be copied as a `.sass` file, even though we are copying generated
|
16
|
+
stackview CSS, and it's not otherwise sass.
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,21 @@
|
|
1
|
+
// Not copied from stackview directly, our own rails_stackview
|
2
|
+
// file to use sprockets to include JS src copied from stackview
|
3
|
+
//
|
4
|
+
// The list of assets is explicit below to preserve any neccesary ordering.
|
5
|
+
// If stackview adds more JS source files, you will have to update
|
6
|
+
// this list below, to keep it in sync with the list in stackview's
|
7
|
+
// own Makefile.
|
8
|
+
//
|
9
|
+
//= require ./stackview/microtemplating.js
|
10
|
+
//= require ./stackview/jquery.easing.1.3.js
|
11
|
+
//= require ./stackview/jquery.stackview.base.js
|
12
|
+
//= require ./stackview/jquery.stackview.infinite.js
|
13
|
+
//= require ./stackview/jquery.stackview.navigation.js
|
14
|
+
//= require ./stackview/jquery.stackview.ministack.js
|
15
|
+
//= require ./stackview/jquery.stackview.stackcache.js
|
16
|
+
//= require ./stackview/jquery.stackview.templates.js
|
17
|
+
//= require ./stackview/types/book.js
|
18
|
+
//= require ./stackview/types/serial.js
|
19
|
+
//= require ./stackview/types/soundrecording.js
|
20
|
+
//= require ./stackview/types/videofilm.js
|
21
|
+
//= require ./stackview/types/webpage.js
|
@@ -0,0 +1,205 @@
|
|
1
|
+
/*
|
2
|
+
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
|
3
|
+
*
|
4
|
+
* Uses the built in easing capabilities added In jQuery 1.1
|
5
|
+
* to offer multiple easing options
|
6
|
+
*
|
7
|
+
* TERMS OF USE - jQuery Easing
|
8
|
+
*
|
9
|
+
* Open source under the BSD License.
|
10
|
+
*
|
11
|
+
* Copyright © 2008 George McGinley Smith
|
12
|
+
* All rights reserved.
|
13
|
+
*
|
14
|
+
* Redistribution and use in source and binary forms, with or without modification,
|
15
|
+
* are permitted provided that the following conditions are met:
|
16
|
+
*
|
17
|
+
* Redistributions of source code must retain the above copyright notice, this list of
|
18
|
+
* conditions and the following disclaimer.
|
19
|
+
* Redistributions in binary form must reproduce the above copyright notice, this list
|
20
|
+
* of conditions and the following disclaimer in the documentation and/or other materials
|
21
|
+
* provided with the distribution.
|
22
|
+
*
|
23
|
+
* Neither the name of the author nor the names of contributors may be used to endorse
|
24
|
+
* or promote products derived from this software without specific prior written permission.
|
25
|
+
*
|
26
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
27
|
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
28
|
+
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
29
|
+
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
30
|
+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
31
|
+
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
32
|
+
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
33
|
+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
34
|
+
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
35
|
+
*
|
36
|
+
*/
|
37
|
+
|
38
|
+
// t: current time, b: begInnIng value, c: change In value, d: duration
|
39
|
+
jQuery.easing['jswing'] = jQuery.easing['swing'];
|
40
|
+
|
41
|
+
jQuery.extend( jQuery.easing,
|
42
|
+
{
|
43
|
+
def: 'easeOutQuad',
|
44
|
+
swing: function (x, t, b, c, d) {
|
45
|
+
//alert(jQuery.easing.default);
|
46
|
+
return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
|
47
|
+
},
|
48
|
+
easeInQuad: function (x, t, b, c, d) {
|
49
|
+
return c*(t/=d)*t + b;
|
50
|
+
},
|
51
|
+
easeOutQuad: function (x, t, b, c, d) {
|
52
|
+
return -c *(t/=d)*(t-2) + b;
|
53
|
+
},
|
54
|
+
easeInOutQuad: function (x, t, b, c, d) {
|
55
|
+
if ((t/=d/2) < 1) return c/2*t*t + b;
|
56
|
+
return -c/2 * ((--t)*(t-2) - 1) + b;
|
57
|
+
},
|
58
|
+
easeInCubic: function (x, t, b, c, d) {
|
59
|
+
return c*(t/=d)*t*t + b;
|
60
|
+
},
|
61
|
+
easeOutCubic: function (x, t, b, c, d) {
|
62
|
+
return c*((t=t/d-1)*t*t + 1) + b;
|
63
|
+
},
|
64
|
+
easeInOutCubic: function (x, t, b, c, d) {
|
65
|
+
if ((t/=d/2) < 1) return c/2*t*t*t + b;
|
66
|
+
return c/2*((t-=2)*t*t + 2) + b;
|
67
|
+
},
|
68
|
+
easeInQuart: function (x, t, b, c, d) {
|
69
|
+
return c*(t/=d)*t*t*t + b;
|
70
|
+
},
|
71
|
+
easeOutQuart: function (x, t, b, c, d) {
|
72
|
+
return -c * ((t=t/d-1)*t*t*t - 1) + b;
|
73
|
+
},
|
74
|
+
easeInOutQuart: function (x, t, b, c, d) {
|
75
|
+
if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
|
76
|
+
return -c/2 * ((t-=2)*t*t*t - 2) + b;
|
77
|
+
},
|
78
|
+
easeInQuint: function (x, t, b, c, d) {
|
79
|
+
return c*(t/=d)*t*t*t*t + b;
|
80
|
+
},
|
81
|
+
easeOutQuint: function (x, t, b, c, d) {
|
82
|
+
return c*((t=t/d-1)*t*t*t*t + 1) + b;
|
83
|
+
},
|
84
|
+
easeInOutQuint: function (x, t, b, c, d) {
|
85
|
+
if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
|
86
|
+
return c/2*((t-=2)*t*t*t*t + 2) + b;
|
87
|
+
},
|
88
|
+
easeInSine: function (x, t, b, c, d) {
|
89
|
+
return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
|
90
|
+
},
|
91
|
+
easeOutSine: function (x, t, b, c, d) {
|
92
|
+
return c * Math.sin(t/d * (Math.PI/2)) + b;
|
93
|
+
},
|
94
|
+
easeInOutSine: function (x, t, b, c, d) {
|
95
|
+
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
|
96
|
+
},
|
97
|
+
easeInExpo: function (x, t, b, c, d) {
|
98
|
+
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
|
99
|
+
},
|
100
|
+
easeOutExpo: function (x, t, b, c, d) {
|
101
|
+
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
|
102
|
+
},
|
103
|
+
easeInOutExpo: function (x, t, b, c, d) {
|
104
|
+
if (t==0) return b;
|
105
|
+
if (t==d) return b+c;
|
106
|
+
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
|
107
|
+
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
|
108
|
+
},
|
109
|
+
easeInCirc: function (x, t, b, c, d) {
|
110
|
+
return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
|
111
|
+
},
|
112
|
+
easeOutCirc: function (x, t, b, c, d) {
|
113
|
+
return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
|
114
|
+
},
|
115
|
+
easeInOutCirc: function (x, t, b, c, d) {
|
116
|
+
if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
|
117
|
+
return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
|
118
|
+
},
|
119
|
+
easeInElastic: function (x, t, b, c, d) {
|
120
|
+
var s=1.70158;var p=0;var a=c;
|
121
|
+
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
122
|
+
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
123
|
+
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
124
|
+
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
125
|
+
},
|
126
|
+
easeOutElastic: function (x, t, b, c, d) {
|
127
|
+
var s=1.70158;var p=0;var a=c;
|
128
|
+
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
129
|
+
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
130
|
+
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
131
|
+
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
|
132
|
+
},
|
133
|
+
easeInOutElastic: function (x, t, b, c, d) {
|
134
|
+
var s=1.70158;var p=0;var a=c;
|
135
|
+
if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
|
136
|
+
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
137
|
+
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
138
|
+
if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
139
|
+
return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
|
140
|
+
},
|
141
|
+
easeInBack: function (x, t, b, c, d, s) {
|
142
|
+
if (s == undefined) s = 1.70158;
|
143
|
+
return c*(t/=d)*t*((s+1)*t - s) + b;
|
144
|
+
},
|
145
|
+
easeOutBack: function (x, t, b, c, d, s) {
|
146
|
+
if (s == undefined) s = 1.70158;
|
147
|
+
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
|
148
|
+
},
|
149
|
+
easeInOutBack: function (x, t, b, c, d, s) {
|
150
|
+
if (s == undefined) s = 1.70158;
|
151
|
+
if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
|
152
|
+
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
|
153
|
+
},
|
154
|
+
easeInBounce: function (x, t, b, c, d) {
|
155
|
+
return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
|
156
|
+
},
|
157
|
+
easeOutBounce: function (x, t, b, c, d) {
|
158
|
+
if ((t/=d) < (1/2.75)) {
|
159
|
+
return c*(7.5625*t*t) + b;
|
160
|
+
} else if (t < (2/2.75)) {
|
161
|
+
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
|
162
|
+
} else if (t < (2.5/2.75)) {
|
163
|
+
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
|
164
|
+
} else {
|
165
|
+
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
|
166
|
+
}
|
167
|
+
},
|
168
|
+
easeInOutBounce: function (x, t, b, c, d) {
|
169
|
+
if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
|
170
|
+
return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
|
171
|
+
}
|
172
|
+
});
|
173
|
+
|
174
|
+
/*
|
175
|
+
*
|
176
|
+
* TERMS OF USE - EASING EQUATIONS
|
177
|
+
*
|
178
|
+
* Open source under the BSD License.
|
179
|
+
*
|
180
|
+
* Copyright © 2001 Robert Penner
|
181
|
+
* All rights reserved.
|
182
|
+
*
|
183
|
+
* Redistribution and use in source and binary forms, with or without modification,
|
184
|
+
* are permitted provided that the following conditions are met:
|
185
|
+
*
|
186
|
+
* Redistributions of source code must retain the above copyright notice, this list of
|
187
|
+
* conditions and the following disclaimer.
|
188
|
+
* Redistributions in binary form must reproduce the above copyright notice, this list
|
189
|
+
* of conditions and the following disclaimer in the documentation and/or other materials
|
190
|
+
* provided with the distribution.
|
191
|
+
*
|
192
|
+
* Neither the name of the author nor the names of contributors may be used to endorse
|
193
|
+
* or promote products derived from this software without specific prior written permission.
|
194
|
+
*
|
195
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
196
|
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
197
|
+
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
198
|
+
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
199
|
+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
200
|
+
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
201
|
+
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
202
|
+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
203
|
+
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
204
|
+
*
|
205
|
+
*/
|
@@ -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);
|