Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'develop' of github.com:harvard-lil/stackview into develop

  • Loading branch information...
commit 8bac1e6715225fdb6110e2148554ca5ae6c18d7b 2 parents e76f670 + 6584aad
@anniejocain anniejocain authored
Showing with 2,488 additions and 543 deletions.
  1. +8 −1 Makefile
  2. BIN  lib/images/icon-globe.png
  3. BIN  lib/images/icon-note.png
  4. BIN  lib/images/serials-edge.png
  5. BIN  lib/images/serials.png
  6. +745 −117 lib/jquery.stackview.css
  7. +2 −2 lib/jquery.stackview.min.js
  8. +205 −0 src/js/jquery.easing.1.3.js
  9. +150 −206 src/js/jquery.stackview.base.js
  10. +11 −9 src/js/jquery.stackview.infinite.js
  11. +33 −0 src/js/jquery.stackview.ministack.js
  12. +4 −3 src/js/jquery.stackview.navigation.js
  13. +184 −0 src/js/types/book.js
  14. +40 −0 src/js/types/serial.js
  15. +42 −0 src/js/types/soundrecording.js
  16. +56 −0 src/js/types/videofilm.js
  17. +42 −0 src/js/types/webpage.js
  18. +66 −0 src/scss/_book.scss
  19. +123 −112 src/scss/_heatmap.scss
  20. +43 −0 src/scss/_ministack.scss
  21. +54 −8 src/scss/_mixins.scss
  22. +50 −0 src/scss/_serial.scss
  23. +82 −0 src/scss/_soundrecording.scss
  24. +74 −0 src/scss/_videofilm.scss
  25. +82 −0 src/scss/_webpage.scss
  26. +16 −60 src/scss/jquery.stackview.scss
  27. +10 −0 test/index.html
  28. +162 −0 test/mocks/types.js
  29. +23 −6 test/preview.html
  30. +0 −19 test/spec/stackview.base.spec.js
  31. +40 −0 test/spec/stackview.ministack.spec.js
  32. +141 −0 test/spec/stackview.types.spec.js
View
9 Makefile
@@ -1,9 +1,16 @@
JS_SOURCES = src/js/microtemplating.js\
+ src/js/jquery.easing.1.3.js\
src/js/jquery.stackview.base.js \
src/js/jquery.stackview.infinite.js\
src/js/jquery.stackview.navigation.js\
+ src/js/jquery.stackview.ministack.js\
src/js/jquery.stackview.stackcache.js\
- src/js/jquery.stackview.templates.js
+ src/js/jquery.stackview.templates.js\
+ src/js/types/book.js\
+ src/js/types/serial.js\
+ src/js/types/soundrecording.js\
+ src/js/types/videofilm.js\
+ src/js/types/webpage.js
SCSS_SOURCE = src/scss/jquery.stackview.scss
JS_OUTPUT = lib/jquery.stackview.min.js
View
BIN  lib/images/icon-globe.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  lib/images/icon-note.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  lib/images/serials-edge.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  lib/images/serials.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
862 lib/jquery.stackview.css
@@ -57,35 +57,27 @@
.stack-item {
position: relative;
display: block;
- margin: 0 0 2px 0;
-webkit-transform: translate3d(0, 0, 0);
}
-.stack-item a {
+.stack-item > a {
display: block;
text-decoration: none;
height: 100%;
- background: url("images/gloss.png") repeat-x 0 47%;
color: #fff;
- border-width: 1px 2px;
- border-style: solid;
white-space: nowrap;
- overflow: hidden;
- border-radius: 3px/20px;
+ background: url("images/gloss.png") repeat-x 0 47%;
}
-.stack-item a:hover, .stack-item a:focus {
+.stack-item > a:hover, .stack-item > a:focus {
background-image: url("images/highGloss.png");
text-decoration: none;
}
+.stack-item > a:visited, .stack-item > a:hover, .stack-item > a:active {
+ color: #fff;
+}
.spine-text {
position: absolute;
z-index: 2;
- height: 40px;
- line-height: 40px;
- top: 50%;
- margin-top: -7px;
- left: 15px;
- right: 24px;
overflow: hidden;
display: block;
}
@@ -124,70 +116,6 @@
border-color: #e6dec4;
text-shadow: none;
color: #555;
- -webkit-transform: rotate(-90deg);
- -moz-transform: rotate(-90deg);
- -o-transform: rotate(-90deg);
- -ms-transform: rotate(-90deg);
- transform: rotate(-90deg);
-}
-
-.stack-pages {
- position: absolute;
- z-index: 4;
- display: block;
- width: 10px;
- right: -6px;
- top: 0;
- bottom: -4px;
- border-width: 3px 0 3px 2px;
- border-style: solid;
- border-radius: 4px 0 0 4px/20px 0 0 20px;
- -o-transform-origin: 0 100%;
- -ms-transform-origin: 0 100%;
- -moz-transform-origin: 0 100%;
- -webkit-transform-origin: 0 100%;
- transform-origin: 0 100%;
- -webkit-transform: skew(0deg, -20deg);
- -moz-transform: skew(0deg, -20deg);
- -o-transform: skew(0deg, -20deg);
- -ms-transform: skew(0deg, -20deg);
- transform: skew(0deg, -20deg);
-}
-.stack-pages:after {
- position: absolute;
- content: "";
- left: 0;
- right: 2px;
- top: 0;
- bottom: 0;
- background: #f5f2e8;
- border-radius: 3px 0 0 3px/20px 0 0 20px;
- border-width: 2px 1px 2px 0px;
- border-style: solid;
- border-color: #aaa #e5e5e5 #007acc #ddd;
-}
-
-.stack-cover {
- position: absolute;
- z-index: 4;
- height: 2px;
- border-width: 1px;
- border-style: solid;
- border-right-width: 2px;
- top: -4px;
- left: 0;
- right: 5px;
- border-radius: 4px 0 0 50px;
- -o-transform-origin: 0 100%;
- -ms-transform-origin: 0 100%;
- -moz-transform-origin: 0 100%;
- -webkit-transform-origin: 0 100%;
- transform-origin: 0 100%;
- -webkit-transform: skew(-70deg, 0deg);
- -moz-transform: skew(-70deg, 0deg);
- -o-transform: skew(-70deg, 0deg);
- -ms-transform: skew(-70deg, 0deg);
- transform: skew(-70deg, 0deg);
}
.stackview .ribbon {
@@ -225,141 +153,389 @@
hottest = heat10
coldest = heat1
*******************/
-.stackview .heat1 a {
+.heat1 a {
background-color: #ccebff;
background-image: url("images/superGloss.png");
color: #222;
text-shadow: 0 1px 0 #fff;
border-color: #aaddff;
}
-.stackview .heat1 .stack-pages {
+.heat1 a:visited, .heat1 a:hover, .heat1 a:active {
+ color: #222;
+}
+.heat1 .stack-pages {
+ border-color: #aaddff;
+}
+.heat1 .stack-cover {
+ border-color: #aaddff;
+ background: #ccebff;
+}
+.heat1 .videofilm-cover {
+ background: #ccebff;
+ border-color: #aaddff;
+}
+.heat1 .serial-edge {
+ background-color: #ccebff;
+ border-color: #aaddff;
+}
+.heat1 .serial-cover {
+ background: #ccebff;
border-color: #aaddff;
}
-.stackview .heat1 .stack-cover {
+.heat1 .sound-edge {
+ background-color: #ccebff;
+}
+.heat1 .sound-cover {
+ background: #ccebff;
border-color: #aaddff;
+}
+.heat1 .webpage-top, .heat1 .webpage-edge {
background: #ccebff;
+ border-color: #aaddff;
}
-.stackview .heat2 a {
+
+.heat2 a {
background-color: #aaddff;
background-image: url("images/superGloss.png");
color: #222;
text-shadow: 0 1px 0 #ddf1ff;
border-color: #88cfff;
}
-.stackview .heat2 .stack-pages {
+.heat2 a:visited, .heat2 a:hover, .heat2 a:active {
+ color: #222;
+}
+.heat2 .stack-pages {
+ border-color: #88cfff;
+}
+.heat2 .stack-cover {
+ border-color: #88cfff;
+ background: #aaddff;
+}
+.heat2 .videofilm-cover {
+ background: #aaddff;
+ border-color: #88cfff;
+}
+.heat2 .serial-edge {
+ background-color: #aaddff;
+ border-color: #88cfff;
+}
+.heat2 .serial-cover {
+ background: #aaddff;
border-color: #88cfff;
}
-.stackview .heat2 .stack-cover {
+.heat2 .sound-edge {
+ background-color: #aaddff;
+}
+.heat2 .sound-cover {
+ background: #aaddff;
border-color: #88cfff;
+}
+.heat2 .webpage-top, .heat2 .webpage-edge {
background: #aaddff;
+ border-color: #88cfff;
}
-.stackview .heat3 a {
+
+.heat3 a {
background-color: #77c9ff;
background-image: url("images/highGloss.png");
color: #111;
text-shadow: 0 1px 0 #adf;
border-color: #59b6ef;
}
-.stackview .heat3 .stack-pages {
+.heat3 a:visited, .heat3 a:hover, .heat3 a:active {
+ color: #111;
+}
+.heat3 .stack-pages {
+ border-color: #59b6ef;
+}
+.heat3 .stack-cover {
+ border-color: #59b6ef;
+ background: #77c9ff;
+}
+.heat3 .videofilm-cover {
+ background: #77c9ff;
+ border-color: #59b6ef;
+}
+.heat3 .serial-edge {
+ background-color: #77c9ff;
+ border-color: #59b6ef;
+}
+.heat3 .serial-cover {
+ background: #77c9ff;
border-color: #59b6ef;
}
-.stackview .heat3 .stack-cover {
+.heat3 .sound-edge {
+ background-color: #77c9ff;
+}
+.heat3 .sound-cover {
+ background: #77c9ff;
border-color: #59b6ef;
+}
+.heat3 .webpage-top, .heat3 .webpage-edge {
background: #77c9ff;
+ border-color: #59b6ef;
}
-.stackview .heat4 a {
+
+.heat4 a {
background-color: #44b4ff;
text-shadow: 0 -1px 0 #11a0ff;
border-color: #11a0ff;
}
-.stackview .heat4 .stack-pages {
+.heat4 .stack-pages {
+ border-color: #11a0ff;
+}
+.heat4 .stack-cover {
+ border-color: #11a0ff;
+ background: #44b4ff;
+}
+.heat4 .videofilm-cover {
+ background: #44b4ff;
+ border-color: #11a0ff;
+}
+.heat4 .serial-edge {
+ background-color: #44b4ff;
+ border-color: #11a0ff;
+}
+.heat4 .serial-cover {
+ background: #44b4ff;
border-color: #11a0ff;
}
-.stackview .heat4 .stack-cover {
+.heat4 .sound-edge {
+ background-color: #44b4ff;
+}
+.heat4 .sound-cover {
+ background: #44b4ff;
border-color: #11a0ff;
+}
+.heat4 .webpage-top, .heat4 .webpage-edge {
background: #44b4ff;
+ border-color: #11a0ff;
}
-.stackview .heat5 a {
+
+.heat5 a {
background-color: #22a7ff;
text-shadow: 0 -1px 0 #008fee;
border-color: #008fee;
}
-.stackview .heat5 .stack-pages {
+.heat5 .stack-pages {
+ border-color: #008fee;
+}
+.heat5 .stack-cover {
+ border-color: #008fee;
+ background: #22a7ff;
+}
+.heat5 .videofilm-cover {
+ background: #22a7ff;
+ border-color: #008fee;
+}
+.heat5 .serial-edge {
+ background-color: #22a7ff;
+ border-color: #008fee;
+}
+.heat5 .serial-cover {
+ background: #22a7ff;
border-color: #008fee;
}
-.stackview .heat5 .stack-cover {
+.heat5 .sound-edge {
+ background-color: #22a7ff;
+}
+.heat5 .sound-cover {
+ background: #22a7ff;
border-color: #008fee;
+}
+.heat5 .webpage-top, .heat5 .webpage-edge {
background: #22a7ff;
+ border-color: #008fee;
}
-.stackview .heat6 a {
+
+.heat6 a {
background-color: #0099ff;
text-shadow: 0 -1px 0 #0085dd;
border-color: #007acc;
}
-.stackview .heat6 .stack-pages {
+.heat6 .stack-pages {
+ border-color: #007acc;
+}
+.heat6 .stack-cover {
+ border-color: #007acc;
+ background: #0099ff;
+}
+.heat6 .videofilm-cover {
+ background: #0099ff;
+ border-color: #007acc;
+}
+.heat6 .serial-edge {
+ background-color: #0099ff;
+ border-color: #007acc;
+}
+.heat6 .serial-cover {
+ background: #0099ff;
border-color: #007acc;
}
-.stackview .heat6 .stack-cover {
+.heat6 .sound-edge {
+ background-color: #0099ff;
+}
+.heat6 .sound-cover {
+ background: #0099ff;
border-color: #007acc;
+}
+.heat6 .webpage-top, .heat6 .webpage-edge {
background: #0099ff;
+ border-color: #007acc;
}
-.stackview .heat7 a {
+
+.heat7 a {
background-color: #0085dd;
text-shadow: 0 -1px 0 #0070bb;
border-color: #0066aa;
}
-.stackview .heat7 .stack-pages {
+.heat7 .stack-pages {
+ border-color: #0066aa;
+}
+.heat7 .stack-cover {
+ border-color: #0066aa;
+ background: #0085dd;
+}
+.heat7 .videofilm-cover {
+ background: #0085dd;
+ border-color: #0066aa;
+}
+.heat7 .serial-edge {
+ background-color: #0085dd;
+ border-color: #0066aa;
+}
+.heat7 .serial-cover {
+ background: #0085dd;
border-color: #0066aa;
}
-.stackview .heat7 .stack-cover {
+.heat7 .sound-edge {
+ background-color: #0085dd;
+}
+.heat7 .sound-cover {
+ background: #0085dd;
border-color: #0066aa;
+}
+.heat7 .webpage-top, .heat7 .webpage-edge {
background: #0085dd;
+ border-color: #0066aa;
}
-.stackview .heat8 a {
+
+.heat8 a {
background-color: #0070bb;
text-shadow: 0 -1px 0 #005c99;
border-color: #004777;
}
-.stackview .heat8 .stack-pages {
+.heat8 .stack-pages {
+ border-color: #004777;
+}
+.heat8 .stack-cover {
+ border-color: #004777;
+ background: #0070bb;
+}
+.heat8 .videofilm-cover {
+ background: #0070bb;
+ border-color: #004777;
+}
+.heat8 .serial-edge {
+ background-color: #0070bb;
+ border-color: #004777;
+}
+.heat8 .serial-cover {
+ background: #0070bb;
border-color: #004777;
}
-.stackview .heat8 .stack-cover {
+.heat8 .sound-edge {
+ background-color: #0070bb;
+}
+.heat8 .sound-cover {
+ background: #0070bb;
border-color: #004777;
+}
+.heat8 .webpage-top, .heat8 .webpage-edge {
background: #0070bb;
+ border-color: #004777;
}
-.stackview .heat9 a {
+
+.heat9 a {
background-color: #005c99;
text-shadow: 0 -1px 0 #004777;
border-color: #002944;
}
-.stackview .heat9 .stack-pages {
+.heat9 .stack-pages {
+ border-color: #002944;
+}
+.heat9 .stack-cover {
+ border-color: #002944;
+ background: #005c99;
+}
+.heat9 .videofilm-cover {
+ background: #005c99;
+ border-color: #002944;
+}
+.heat9 .serial-edge {
+ background-color: #005c99;
+ border-color: #002944;
+}
+.heat9 .serial-cover {
+ background: #005c99;
border-color: #002944;
}
-.stackview .heat9 .stack-cover {
+.heat9 .sound-edge {
+ background-color: #005c99;
+}
+.heat9 .sound-cover {
+ background: #005c99;
border-color: #002944;
+}
+.heat9 .webpage-top, .heat9 .webpage-edge {
background: #005c99;
+ border-color: #002944;
}
-.stackview .heat10 a {
+
+.heat10 a {
background-color: #004777;
text-shadow: 0 -1px 0 #003355;
border-color: #001522;
}
-.stackview .heat10 .stack-pages {
+.heat10 .stack-pages {
border-color: #001522;
}
-.stackview .heat10 .stack-cover {
+.heat10 .stack-cover {
border-color: #001522;
background: #004777;
}
-
-/**************
- NAVIGATION
-***************/
-.stack-navigation {
- position: absolute;
- left: 5px;
- top: 5px;
- width: 41px;
+.heat10 .videofilm-cover {
+ background: #004777;
+ border-color: #001522;
+}
+.heat10 .serial-edge {
+ background-color: #004777;
+ border-color: #001522;
+}
+.heat10 .serial-cover {
+ background: #004777;
+ border-color: #001522;
+}
+.heat10 .sound-edge {
+ background-color: #004777;
+}
+.heat10 .sound-cover {
+ background: #004777;
+ border-color: #001522;
+}
+.heat10 .webpage-top, .heat10 .webpage-edge {
+ background: #004777;
+ border-color: #001522;
+}
+
+/**************
+ NAVIGATION
+***************/
+.stack-navigation {
+ position: absolute;
+ left: 5px;
+ top: 5px;
+ width: 41px;
text-align: center;
}
.stack-navigation .upstream, .stack-navigation .downstream {
@@ -395,3 +571,455 @@
.stack-navigation.empty .num-found {
visibility: hidden;
}
+
+/* Types */
+.stack-book {
+ margin: 0 0 2px 0;
+}
+.stack-book > a {
+ border-width: 1px 2px;
+ border-style: solid;
+ border-radius: 3px/20px;
+}
+.stack-book .spine-text {
+ height: 40px;
+ line-height: 40px;
+ top: 50%;
+ margin-top: -7px;
+ left: 15px;
+ right: 24px;
+}
+.stack-book .spine-year {
+ -webkit-transform: rotate(-90deg);
+ -moz-transform: rotate(-90deg);
+ -o-transform: rotate(-90deg);
+ -ms-transform: rotate(-90deg);
+ transform: rotate(-90deg);
+}
+
+.stack-pages {
+ position: absolute;
+ z-index: 4;
+ display: block;
+ width: 10px;
+ right: -6px;
+ top: 0;
+ bottom: -4px;
+ border-width: 3px 0 3px 2px;
+ border-style: solid;
+ border-radius: 4px 0 0 4px/20px 0 0 20px;
+ -o-transform-origin: 0 100%;
+ -ms-transform-origin: 0 100%;
+ -moz-transform-origin: 0 100%;
+ -webkit-transform-origin: 0 100%;
+ transform-origin: 0 100%;
+ -webkit-transform: skew(0deg, -20deg);
+ -moz-transform: skew(0deg, -20deg);
+ -o-transform: skew(0deg, -20deg);
+ -ms-transform: skew(0deg, -20deg);
+ transform: skew(0deg, -20deg);
+}
+.stack-pages:after {
+ position: absolute;
+ content: "";
+ left: 0;
+ right: 2px;
+ top: 0;
+ bottom: 0;
+ background: #f5f2e8;
+ border-radius: 3px 0 0 3px/20px 0 0 20px;
+ border-width: 2px 1px 2px 0px;
+ border-style: solid;
+ border-color: #aaa #e5e5e5 #007acc #ddd;
+}
+
+.stack-cover {
+ position: absolute;
+ z-index: 4;
+ height: 2px;
+ border-width: 1px;
+ border-style: solid;
+ border-right-width: 2px;
+ top: -4px;
+ left: 0;
+ right: 5px;
+ border-radius: 4px 0 0 50px;
+ -o-transform-origin: 0 100%;
+ -ms-transform-origin: 0 100%;
+ -moz-transform-origin: 0 100%;
+ -webkit-transform-origin: 0 100%;
+ transform-origin: 0 100%;
+ -webkit-transform: skew(-70deg, 0deg);
+ -moz-transform: skew(-70deg, 0deg);
+ -o-transform: skew(-70deg, 0deg);
+ -ms-transform: skew(-70deg, 0deg);
+ transform: skew(-70deg, 0deg);
+}
+
+.stack-serial {
+ width: 343px;
+ height: 39px;
+ margin: 0;
+}
+.stack-serial > a {
+ border-radius: 3px 0 0 3px;
+}
+.stack-serial > a, .stack-serial > a:hover, .stack-serial > a:focus {
+ background-image: url(images/serials.png);
+}
+.stack-serial .spine-text {
+ left: 15px;
+ top: 0;
+ bottom: 0;
+ width: 200px;
+}
+.stack-serial .spine-title {
+ height: 39px;
+ line-height: 39px;
+ font-size: 12px;
+}
+
+.serial-edge {
+ position: absolute;
+ right: -17px;
+ bottom: 0;
+ width: 17px;
+ height: 38px;
+ background: url(images/serials-edge.png) 0 0 no-repeat;
+ border-width: 2px 0;
+ -o-transform-origin: 0 100%;
+ -ms-transform-origin: 0 100%;
+ -moz-transform-origin: 0 100%;
+ -webkit-transform-origin: 0 100%;
+ transform-origin: 0 100%;
+ -webkit-transform: skew(0deg, -20deg);
+ -moz-transform: skew(0deg, -20deg);
+ -o-transform: skew(0deg, -20deg);
+ -ms-transform: skew(0deg, -20deg);
+ transform: skew(0deg, -20deg);
+}
+
+.serial-cover {
+ position: absolute;
+ top: -5px;
+ left: 0;
+ right: -2px;
+ height: 3px;
+ border-width: 1px;
+ border-style: solid;
+ -o-transform-origin: 0 100%;
+ -ms-transform-origin: 0 100%;
+ -moz-transform-origin: 0 100%;
+ -webkit-transform-origin: 0 100%;
+ transform-origin: 0 100%;
+ -webkit-transform: skew(-70deg, 0);
+ -moz-transform: skew(-70deg, 0);
+ -o-transform: skew(-70deg, 0);
+ -ms-transform: skew(-70deg, 0);
+ transform: skew(-70deg, 0);
+}
+
+.stack-soundrecording {
+ height: 25px;
+ width: 280px;
+ margin: 0 0 1px 0;
+}
+.stack-soundrecording:before {
+ content: url("images/icon-note.png");
+ position: absolute;
+ left: 10px;
+ top: 4px;
+}
+.stack-soundrecording > a {
+ border-width: 1px;
+ border-style: solid;
+ border-left: 3px solid rgba(225, 225, 225, 0.6);
+ border-right: 3px solid rgba(225, 225, 225, 0.6);
+}
+.stack-soundrecording .spine-text {
+ left: 35px;
+}
+.stack-soundrecording .spine-title {
+ height: 25px;
+ line-height: 25px;
+ font-size: 12px;
+}
+.stack-soundrecording .spine-year {
+ right: 7px;
+}
+
+.sound-edge {
+ position: absolute;
+ top: 0;
+ bottom: -2px;
+ left: 100%;
+ width: 5px;
+ border: 2px solid rgba(225, 225, 225, 0.6);
+ border-radius: 0 2px 2px 0;
+ -o-transform-origin: 0 100%;
+ -ms-transform-origin: 0 100%;
+ -moz-transform-origin: 0 100%;
+ -webkit-transform-origin: 0 100%;
+ transform-origin: 0 100%;
+ -webkit-transform: skew(0, -20deg);
+ -moz-transform: skew(0, -20deg);
+ -o-transform: skew(0, -20deg);
+ -ms-transform: skew(0, -20deg);
+ transform: skew(0, -20deg);
+}
+.sound-edge:before {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 1px;
+ display: block;
+ content: "";
+ z-index: 5;
+ width: 1px;
+ background: rgba(250, 250, 250, 0.5);
+}
+.sound-edge:after {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 3px;
+ display: block;
+ content: "";
+ z-index: 5;
+ width: 1px;
+ background: rgba(250, 250, 250, 0.5);
+}
+
+.sound-cover {
+ position: absolute;
+ top: -3px;
+ left: 0;
+ right: -1px;
+ height: 1px;
+ border-width: 1px;
+ border-style: solid;
+ border-radius: 4px;
+ -o-transform-origin: 0 100%;
+ -ms-transform-origin: 0 100%;
+ -moz-transform-origin: 0 100%;
+ -webkit-transform-origin: 0 100%;
+ transform-origin: 0 100%;
+ -webkit-transform: skew(-70deg, 0);
+ -moz-transform: skew(-70deg, 0);
+ -o-transform: skew(-70deg, 0);
+ -ms-transform: skew(-70deg, 0);
+ transform: skew(-70deg, 0);
+}
+
+.stack-videofilm {
+ height: 28px;
+ margin: 0 0 1px 0;
+}
+.stack-videofilm > a {
+ border-left: 4px solid #444;
+ border-right: 4px solid #444;
+ border-top-width: 1px;
+ border-bottom-width: 1px;
+ border-style: solid;
+}
+.stack-videofilm .spine-text {
+ left: 15px;
+ top: 0;
+ bottom: 0;
+ right: 24px;
+ font-size: 12px;
+ font-weight: bold;
+}
+.stack-videofilm .spine-title {
+ height: 28px;
+ line-height: 28px;
+}
+.stack-videofilm .spine-year {
+ -webkit-transform: rotate(-90deg);
+ -moz-transform: rotate(-90deg);
+ -o-transform: rotate(-90deg);
+ -ms-transform: rotate(-90deg);
+ transform: rotate(-90deg);
+ width: 24px;
+ height: 12px;
+ line-height: 12px;
+ font-size: 9px;
+ text-align: center;
+ margin-top: -6px;
+}
+
+.videofilm-edge {
+ position: absolute;
+ display: block;
+ z-index: 2;
+ left: 100%;
+ top: 0;
+ bottom: -2px;
+ width: 7px;
+ background: #444;
+ -o-transform-origin: 0 100%;
+ -ms-transform-origin: 0 100%;
+ -moz-transform-origin: 0 100%;
+ -webkit-transform-origin: 0 100%;
+ transform-origin: 0 100%;
+ -webkit-transform: skew(0deg, -20deg);
+ -moz-transform: skew(0deg, -20deg);
+ -o-transform: skew(0deg, -20deg);
+ -ms-transform: skew(0deg, -20deg);
+ transform: skew(0deg, -20deg);
+ border-radius: 0 2px 2px 0;
+}
+.videofilm-edge:after {
+ content: '';
+ position: absolute;
+ top: 50%;
+ right: 0;
+ left: 0;
+ height: 1px;
+ background: #000;
+ border-top: 1px solid #ccc;
+}
+
+.videofilm-cover {
+ position: absolute;
+ top: -4px;
+ height: 2px;
+ left: 0;
+ right: 0;
+ border-style: solid;
+ border-width: 1px;
+ border-radius: 4px 4px 0 0;
+ -o-transform-origin: 0 100%;
+ -ms-transform-origin: 0 100%;
+ -moz-transform-origin: 0 100%;
+ -webkit-transform-origin: 0 100%;
+ transform-origin: 0 100%;
+ -webkit-transform: skew(-70deg, 0deg);
+ -moz-transform: skew(-70deg, 0deg);
+ -o-transform: skew(-70deg, 0deg);
+ -ms-transform: skew(-70deg, 0deg);
+ transform: skew(-70deg, 0deg);
+}
+
+.stack-webpage {
+ height: 38px;
+ max-width: 75%;
+}
+.stack-webpage > a {
+ display: inline-block;
+ position: relative;
+ border-radius: 6px 0 1px 0;
+ border-width: 1px;
+ border-style: solid;
+ color: #555;
+ text-shadow: none;
+ font-size: 11px;
+ padding: 0 10px;
+ max-width: 100%;
+}
+.stack-webpage > a:visited, .stack-webpage > a:hover, .stack-webpage > a:active {
+ color: #555;
+}
+
+.url-bar {
+ display: block;
+ margin: 7px 0 0 0;
+ height: 24px;
+ line-height: 24px;
+ background: #fff;
+ padding: 0 10px 0 10px;
+ border-radius: 3px;
+ border: 1px inset #ccc;
+ box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.url-bar:before {
+ content: url("images/icon-globe.png");
+ vertical-align: middle;
+ position: relative;
+ top: 1px;
+ left: -3px;
+}
+
+.url-publisher {
+ font-variant: small-caps;
+}
+
+.url-title {
+ white-space: nowrap;
+}
+
+.webpage-top {
+ content: '';
+ display: block;
+ position: absolute;
+ top: -5px;
+ left: 4px;
+ right: -5px;
+ height: 3px;
+ border-width: 1px;
+ border-style: solid;
+ -webkit-transform: skew(-70deg, 0);
+ -moz-transform: skew(-70deg, 0);
+ -o-transform: skew(-70deg, 0);
+ -ms-transform: skew(-70deg, 0);
+ transform: skew(-70deg, 0);
+ border-radius: 0 5px 0 5px;
+ z-index: 2;
+}
+
+.webpage-edge {
+ content: '';
+ display: block;
+ position: absolute;
+ top: -3px;
+ bottom: 1px;
+ right: -8px;
+ width: 6px;
+ -webkit-transform: skew(0, -20deg);
+ -moz-transform: skew(0, -20deg);
+ -o-transform: skew(0, -20deg);
+ -ms-transform: skew(0, -20deg);
+ transform: skew(0, -20deg);
+ border-width: 0 1px 1px 0;
+ border-style: solid;
+}
+
+.stackview-mini .spine-text {
+ left: 5px;
+ margin-top: -5px;
+}
+.stackview-mini .spine-title {
+ font-size: 11px;
+}
+.stackview-mini .spine-author {
+ display: none;
+}
+.stackview-mini .spine-year {
+ font-size: 8px;
+ padding: 0;
+ line-height: 12px;
+ height: 12px;
+ margin-top: -6px;
+ width: 24px;
+ -webkit-transform: rotate(0deg);
+ -moz-transform: rotate(0deg);
+ -o-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ transform: rotate(0deg);
+}
+.stackview-mini .stack-items:before, .stackview-mini .stack-items:after {
+ width: 106px;
+ height: 57px;
+ background-size: contain;
+}
+.stackview-mini .stack-items:after {
+ margin-top: -4px;
+}
+.stackview-mini .ribbon {
+ top: 20px;
+ padding: 4px 5px 4px 14px;
+ min-height: 20px;
+ font-size: 16px;
+}
View
4 lib/jquery.stackview.min.js
@@ -5,11 +5,11 @@
http://west-wind.com/weblog/posts/2008/Oct/13/Client-Templating-with-jQuery
MIT Licensed
*/
-(function(){var b={};this.tmpl=function a(e,d){var c=!/\W/.test(e)?b[e]=b[e]||a(document.getElementById(e).innerHTML):new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+e.replace(/[\r\t\n]/g," ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return d?c(d):c}})();
+(function(){var b={};this.tmpl=function a(e,d){var c=!/\W/.test(e)?b[e]=b[e]||a(document.getElementById(e).innerHTML):new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+e.replace(/[\r\t\n]/g," ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return d?c(d):c}})();jQuery.easing.jswing=jQuery.easing.swing;jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(e,f,a,h,g){return jQuery.easing[jQuery.easing.def](e,f,a,h,g)},easeInQuad:function(e,f,a,h,g){return h*(f/=g)*f+a},easeOutQuad:function(e,f,a,h,g){return -h*(f/=g)*(f-2)+a},easeInOutQuad:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f+a}return -h/2*((--f)*(f-2)-1)+a},easeInCubic:function(e,f,a,h,g){return h*(f/=g)*f*f+a},easeOutCubic:function(e,f,a,h,g){return h*((f=f/g-1)*f*f+1)+a},easeInOutCubic:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f+a}return h/2*((f-=2)*f*f+2)+a},easeInQuart:function(e,f,a,h,g){return h*(f/=g)*f*f*f+a},easeOutQuart:function(e,f,a,h,g){return -h*((f=f/g-1)*f*f*f-1)+a},easeInOutQuart:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f*f+a}return -h/2*((f-=2)*f*f*f-2)+a},easeInQuint:function(e,f,a,h,g){return h*(f/=g)*f*f*f*f+a},easeOutQuint:function(e,f,a,h,g){return h*((f=f/g-1)*f*f*f*f+1)+a},easeInOutQuint:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f*f*f+a}return h/2*((f-=2)*f*f*f*f+2)+a},easeInSine:function(e,f,a,h,g){return -h*Math.cos(f/g*(Math.PI/2))+h+a},easeOutSine:function(e,f,a,h,g){return h*Math.sin(f/g*(Math.PI/2))+a},easeInOutSine:function(e,f,a,h,g){return -h/2*(Math.cos(Math.PI*f/g)-1)+a},easeInExpo:function(e,f,a,h,g){return(f==0)?a:h*Math.pow(2,10*(f/g-1))+a},easeOutExpo:function(e,f,a,h,g){return(f==g)?a+h:h*(-Math.pow(2,-10*f/g)+1)+a},easeInOutExpo:function(e,f,a,h,g){if(f==0){return a}if(f==g){return a+h}if((f/=g/2)<1){return h/2*Math.pow(2,10*(f-1))+a}return h/2*(-Math.pow(2,-10*--f)+2)+a},easeInCirc:function(e,f,a,h,g){return -h*(Math.sqrt(1-(f/=g)*f)-1)+a},easeOutCirc:function(e,f,a,h,g){return h*Math.sqrt(1-(f=f/g-1)*f)+a},easeInOutCirc:function(e,f,a,h,g){if((f/=g/2)<1){return -h/2*(Math.sqrt(1-f*f)-1)+a}return h/2*(Math.sqrt(1-(f-=2)*f)+1)+a},easeInElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k)==1){return e+l}if(!j){j=k*0.3}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}return -(g*Math.pow(2,10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j))+e},easeOutElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k)==1){return e+l}if(!j){j=k*0.3}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}return g*Math.pow(2,-10*h)*Math.sin((h*k-i)*(2*Math.PI)/j)+l+e},easeInOutElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k/2)==2){return e+l}if(!j){j=k*(0.3*1.5)}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}if(h<1){return -0.5*(g*Math.pow(2,10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j))+e}return g*Math.pow(2,-10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j)*0.5+l+e},easeInBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}return i*(f/=h)*f*((g+1)*f-g)+a},easeOutBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}return i*((f=f/h-1)*f*((g+1)*f+g)+1)+a},easeInOutBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}if((f/=h/2)<1){return i/2*(f*f*(((g*=(1.525))+1)*f-g))+a}return i/2*((f-=2)*f*(((g*=(1.525))+1)*f+g)+2)+a},easeInBounce:function(e,f,a,h,g){return h-jQuery.easing.easeOutBounce(e,g-f,0,h,g)+a},easeOutBounce:function(e,f,a,h,g){if((f/=g)<(1/2.75)){return h*(7.5625*f*f)+a}else{if(f<(2/2.75)){return h*(7.5625*(f-=(1.5/2.75))*f+0.75)+a}else{if(f<(2.5/2.75)){return h*(7.5625*(f-=(2.25/2.75))*f+0.9375)+a}else{return h*(7.5625*(f-=(2.625/2.75))*f+0.984375)+a}}}},easeInOutBounce:function(e,f,a,h,g){if(f<g/2){return jQuery.easing.easeInBounce(e,f*2,0,h,g)*0.5+a}return jQuery.easing.easeOutBounce(e,f*2-g,0,h,g)*0.5+h*0.5+a}});
/*!
Stack View - The jQuery virtual stack plugin
by The Harvard Library Innovation Lab
Dual licensed under MIT and GPL.
*/
-(function(g,f,a,h){var d,e="stackView",c,b={};d={init:"stackview.init",item_added:"stackview.itemadded",item_removed:"stackview.itemremoved",page_load:"stackview.pageload"};b.translate=function(n,m,j,k,p){var i=j-m,l=p-k,o=(n-m)/(i);return k+o*l};b.get_heat=function(i){return i===100?10:Math.floor(i/10)+1};b.get_height=function(k,l){var n=k.options,j=parseInt(l.measurement_height_numeric,10),m=n.min_item_height,i=n.max_item_height;if(isNaN(j)){j=m}j=Math.min(Math.max(j,m),i);j=b.translate(j,n.min_item_height,n.max_item_height,n.min_height_percentage,n.max_height_percentage);return j+"%"};b.get_thickness=function(k,l){var n=parseInt(l.measurement_page_numeric,10),m=k.options.min_pages,j=k.options.max_pages,i=k.options.page_multiple;if(isNaN(n)){n=m}n=Math.min(Math.max(n,m),j)*i;return n+"px"};b.normalize_link=function(i){return i.title_link_friendly?"../shelflife/book/"+i.title_link_friendly+"/"+i.id:i.link};b.get_author=function(j){var i=j.creator&&j.creator.length?j.creator[0]:"";if(/^([^,]*)/.test(i)){i=i.match(/^[^,]*/)}return i};b.normalize_item=function(i,j){return{heat:b.get_heat(j.shelfrank),book_height:b.get_height(i,j),book_thickness:b.get_thickness(i,j),link:b.normalize_link(j),title:j.title,author:b.get_author(j),year:j.pub_date}};b.render_items=function(i,m,j){var k=j?"before":"append",l=j?j:i.$element.find(i.options.selectors.item_list);g.each(m,function(o,p){var n=g(tmpl(c.templates.book,b.normalize_item(i,p)));n.data("stackviewItem",p);l[k](n)});if(j){j.remove()}};b.calculate_params=function(i){var j=i.options,k;k={start:i.page*i.options.items_per_page,limit:i.options.items_per_page,search_type:i.options.search_type,query:i.options.query};if(k.search_type==="loc_sort_order"){k.start=0;if(i.page===0){i.loc={low:j.id-Math.floor(j.items_per_page/2),high:j.id+Math.floor(j.items_per_page/2)};k.query=["[",i.loc.low,"%20TO%20",i.loc.high,"]"].join("")}else{if(i.direction==="down"){k.query=["[",i.loc.high+1,"%20TO%20",i.loc.high+j.items_per_page+1,"]"].join("");i.loc.high=i.loc.high+j.items_per_page+1}else{if(i.direction==="up"){k.query=["[",i.loc.low-j.items_per_page-1,"%20TO%20",i.loc.low-1,"]"].join("");i.loc.low=i.loc.low-j.items_per_page-1}}}}return k};b.fetch_page=function(j,m){var l=b.calculate_params(j),i=g.param(l),k;j.page++;k=f.stackCache.get(j.options.url+i);if(k){m(k)}else{g.ajax({url:j.options.url,data:i,dataType:j.options.jsonp?"jsonp":"json",success:function(n){f.stackCache.set(j.options.url+l,n,j.options.cache_ttl);m(n)}})}};c=function(j,i){this.element=j;this.$element=g(j);this.options=g.extend({},c.defaults,i);this.page=0;this.finished={up:false,down:false};this.loc={low:null,high:null};this.direction="down";this.init()};g.extend(c,{defaults:{url:"basic.json",data:"",jsonp:false,items_per_page:10,page_multiple:0.2,height_multiple:12.5,search_type:"keyword",query:"",ribbon:"Stack View",id:null,min_pages:200,max_pages:540,min_item_height:20,max_item_height:39,min_height_percentage:59,max_height_percentage:100,cache_ttl:60,selectors:{item:".stack-item",item_list:".stack-items",ribbon:".ribbon"}}});g.extend(true,c.prototype,{init:function(){var i=this;this.$element.html(tmpl(c.templates.scaffold,{ribbon:this.options.ribbon})).addClass("stackview").bind(d.page_load,function(){i.zIndex()});this.$element.data("stackviewObject",this);this.$element.trigger(d.init);this.next_page()},next_page:function(){var i=g(tmpl(c.templates.placeholder,{})),k=this,j=this.options;if(this.finished.down){return}this.direction="down";if(j.data){b.render_items(this,j.data.docs?j.data.docs:j.data);this.finished.down=true;this.$element.trigger(d.page_load,[j.data])}else{if(j.url){this.$element.find(j.selectors.item_list).append(i);b.fetch_page(this,function(l){b.render_items(k,l.docs,i);if(parseInt(l.start,10)===-1){k.finished.down=true}k.$element.trigger(d.page_load,[l])})}}},prev_page:function(){var i=g(tmpl(c.templates.placeholder,{})),k=this.options,j=this,l=j.$element.find(k.selectors.item).first();if(k.search_type!=="loc_sort_order"||this.finished.up){return}this.direction="up";this.$element.find(k.selectors.item_list).prepend(i);b.fetch_page(this,function(n){var m=l.position().top;b.render_items(j,n.docs,i);if(j.page>1){j.$element.find(k.selectors.item_list).animate({scrollTop:"+="+(l.position().top-m)},0)}if(parseInt(n.start,10)===-1){j.finished.up=true}j.$element.trigger(d.page_load,[n])})},add:function(){var n=this.$element.find(this.options.selectors.item),j,k,l,m,i;if(typeof(arguments[0])==="number"){j=arguments[0];k=arguments[1]}else{j=n.length;k=arguments[0]}if(j>n.length||j<0){return}else{if(j===n.length){m=n.last();l="after"}else{m=n.eq(j);l="before"}}i=g(tmpl(c.templates.book,b.normalize_item(this,k)));i.data("stackviewItem",k);m[l](i);this.zIndex();this.$element.trigger(d.item_added)},remove:function(i){var m=this.$element.find(this.options.selectors.item),k,l,j;if(typeof(i)==="number"){k=m.eq(i)}else{if(i.nodeType||i.jquery){k=g(i)}else{m.each(function(o,p){var n=g(p);if(n.data("stackviewItem")===i){k=n;return false}})}}if(k==null||!k.length){return}k.detach();l=k.data("stackviewItem");this.$element.trigger(d.item_removed,[l]);return k},getData:function(){var i=[];this.$element.find(this.options.selectors.item).each(function(){i.push(g(this).data("stackviewItem"))});return i},zIndex:function(j){var n=this.$element.find(this.options.selectors.item),l=n.length,k=0,m=j?0:n.length-1;while(k<l){n.eq(k).css("z-index",m);m=m+(j?1:-1);k++}}});g.fn[e]=function(k){var i,j=Array.prototype.slice.call(arguments,1);this.each(function(m,o){var l=g(o),p=l.data("stackviewObject");if(!p){new c(o,k)}else{if(p[k]){var n=p[k].apply(p,j);if(i===h&&n!==h){i=n}}}});return i===h?this:i};f.StackView=c})(jQuery,window,document);(function(c,d){var a=c(document),b;c.extend(StackView.defaults,{infiniteScrollDistance:100});b=function(h){var i=c(h.target),e=i.data("stackviewObject"),g=e.options,l,g,j,f,k;l=i.find(g.selectors.item_list);j=l.find(g.selectors.item).last().position().top;j+=l.scrollTop();f=j-i.height()-g.infiniteScrollDistance;k=function(){if(g.search_type==="loc_sort_order"&&l.scrollTop()<=g.infiniteScrollDistance){l.unbind("scroll.stackview");i.stackView("prev_page")}else{if(l.scrollTop()>=f){l.unbind("scroll.stackview");i.stackView("next_page")}}};l.bind("scroll.stackview",k);k()};a.delegate(".stackview","stackview.pageload",b)})(jQuery);(function(c,d){var b=c(document),a=window.StackView;c.extend(true,a.defaults,{transitionDuration:200,navigationPercent:80,selectors:{downstream:".downstream",upstream:".upstream",num_items:".num-found span"}});b.delegate(".stackview","stackview.init",function(f){var g=c(f.target),e=g.data("stackviewObject"),i=g.find(e.options.selectors.item_list),h=g.height()*e.options.navigationPercent/100;e.num_found_delta=0;g.prepend(tmpl(a.templates.navigation,{empty:e.options.search_type==="loc_sort_order"}));g.delegate(e.options.selectors.downstream,"click",function(){i.animate({scrollTop:"+="+h},e.options.transitionDuration);return false}).delegate(e.options.selectors.upstream,"click",function(){i.animate({scrollTop:"-="+h},e.options.transitionDuration);return false})}).delegate(".stackview","stackview.pageload",function(h,i){var j=c(h.target),e=j.data("stackviewObject"),g=i.num_found?parseInt(i.num_found,10):i.length,f;e.num_found=g;f=g+e.num_found_delta;j.find(e.options.selectors.num_items).text(f)}).delegate(".stackview","stackview.itemadded stackview.itemremoved",function(g){var h=c(g.target),e=h.data("stackviewObject"),i=h.find(e.options.selectors.item),f;e.num_found_delta+=(g.namespace==="itemadded"?1:-1);f=e.num_found+e.num_found_delta;h.find(e.options.selectors.num_items).text(f)})})(jQuery);window.stackCache=(function(d,f){var b={},e=d.JSON&&(function(){try{return("localStorage" in d)&&d.localStorage!==null}catch(h){return false}})();return{set:g,get:c,remove:a};function g(j,k,h){var i=h&&new Date(+new Date()+h*1000),m={expires:+i,value:k};if(e){try{localStorage[j]=JSON.stringify(m)}catch(l){return l}}else{b[j]=m}}function c(h){var i,j;if(e){i=localStorage[h];if(i){i=JSON.parse(i)}}else{i=b[h]}if(i){if(i.expires&&i.expires<+new Date()){a(h)}else{j=i.value}}return j}function a(h){if(e){localStorage.removeItem(h)}else{delete b[h]}}})(window);(function(a){StackView.templates={scaffold:' <div class="ribbon"><%= ribbon %></div> <ul class="stack-items" />',navigation:' <div class="stack-navigation<%= empty ? " empty" : ""%>"> <div class="upstream">Up</div> <div class="num-found"> <span></span><br />items </div> <div class="downstream">Down</div> </div>',book:' <li class="stack-item stack-book heat<%= heat %>" style="width:<%= book_height %>; height:<%= book_thickness %>;"> <a href="<%= link %>" target="_newtab"> <span class="spine-text"> <span class="spine-title"><%= title %></span> <span class="spine-author"><%= author %></span> </span> <span class="spine-year"><%= year %></span> <span class="stack-pages" /> <span class="stack-cover" /> </a> </li>',placeholder:'<li class="stackview-placeholder"></li>'}})();
+(function(e,h,i,c){var l,f="stackView",j,g={};l={init:"stackview.init",item_added:"stackview.itemadded",item_removed:"stackview.itemremoved",page_load:"stackview.pageload"};var b=function(n){var m;e.each(g,function(o,p){if(p.match(n)){m=p;return false}});return m};var d=function(m,q,n){var o=n?"before":"append",p=n?n:m.$element.find(m.options.selectors.item_list);e.each(q,function(s,u){var t=b(u),r;if(t==null){return true}r=e(tmpl(t.template,t.adapter(u,m.options)));r.data("stackviewItem",u);p[o](r)});if(n){n.remove()}};var a=function(m){var n=m.options,o;o={start:m.page*m.options.items_per_page,limit:m.options.items_per_page,search_type:m.options.search_type,query:m.options.query};if(o.search_type==="loc_sort_order"){o.start=0;if(m.page===0){m.loc={low:n.id-Math.floor(n.items_per_page/2),high:n.id+Math.floor(n.items_per_page/2)};o.query=["[",m.loc.low,"%20TO%20",m.loc.high,"]"].join("")}else{if(m.direction==="down"){o.query=["[",m.loc.high+1,"%20TO%20",m.loc.high+n.items_per_page+1,"]"].join("");m.loc.high=m.loc.high+n.items_per_page+1}else{if(m.direction==="up"){o.query=["[",m.loc.low-n.items_per_page-1,"%20TO%20",m.loc.low-1,"]"].join("");m.loc.low=m.loc.low-n.items_per_page-1}}}}return o};var k=function(n,q){var p=a(n),m=e.param(p),o;n.page++;o=h.stackCache.get(n.options.url+m);if(o){q(o)}else{e.ajax({url:n.options.url,data:m,dataType:n.options.jsonp?"jsonp":"json",success:function(r){h.stackCache.set(n.options.url+p,r,n.options.cache_ttl);q(r)}})}};j=function(n,m){this.element=n;this.$element=e(n);this.options=e.extend({},j.defaults,m);this.page=0;this.finished={up:false,down:false};this.loc={low:null,high:null};this.direction="down";this.init()};e.extend(true,j,{defaults:{cache_ttl:60,data:"",id:null,items_per_page:10,jsonp:false,query:"",ribbon:"Stack View",search_type:"keyword",selectors:{item:".stack-item",item_list:".stack-items",ribbon:".ribbon"},url:"basic.json"},utils:{get_heat:function(m){return m===100?10:Math.floor(m/10)+1}},register_type:function(m){g[m.name]=m},get_types:function(){return g}});e.extend(true,j.prototype,{init:function(){var m=this;this.$element.html(tmpl(j.templates.scaffold,{ribbon:this.options.ribbon})).addClass("stackview").bind(l.page_load,function(){m.zIndex()});this.$element.data("stackviewObject",this);this.$element.trigger(l.init);this.next_page()},next_page:function(){var m=e(tmpl(j.templates.placeholder,{})),o=this,n=this.options;if(this.finished.down){return}this.direction="down";if(n.data){d(this,n.data.docs?n.data.docs:n.data);this.finished.down=true;this.$element.trigger(l.page_load,[n.data])}else{if(n.url){this.$element.find(n.selectors.item_list).append(m);k(this,function(p){d(o,p.docs,m);if(parseInt(p.start,10)===-1){o.finished.down=true}o.$element.trigger(l.page_load,[p])})}}},prev_page:function(){var m=e(tmpl(j.templates.placeholder,{})),o=this.options,n=this,p=n.$element.find(o.selectors.item).first();if(o.search_type!=="loc_sort_order"||this.finished.up){return}this.direction="up";this.$element.find(o.selectors.item_list).prepend(m);k(this,function(r){var q=p.position().top;d(n,r.docs,m);if(n.page>1){n.$element.find(o.selectors.item_list).animate({scrollTop:"+="+(p.position().top-q)},0)}if(parseInt(r.start,10)===-1){n.finished.up=true}n.$element.trigger(l.page_load,[r])})},add:function(){var s=this.$element.find(this.options.selectors.item),n,p,o,q,r,m;if(typeof(arguments[0])==="number"){n=arguments[0];p=arguments[1]}else{n=s.length;p=arguments[0]}if(n>s.length||n<0){return}else{if(n===s.length){r=s.last();q="after"}else{r=s.eq(n);q="before"}}o=b(p);if(o==null){return}m=e(tmpl(o.template,o.adapter(p,this.options)));m.data("stackviewItem",p);r[q](m);this.zIndex();this.$element.trigger(l.item_added)},remove:function(m){var q=this.$element.find(this.options.selectors.item),o,p,n;if(typeof(m)==="number"){o=q.eq(m)}else{if(m.nodeType||m.jquery){o=e(m)}else{q.each(function(s,t){var r=e(t);if(r.data("stackviewItem")===m){o=r;return false}})}}if(o==null||!o.length){return}o.detach();p=o.data("stackviewItem");this.$element.trigger(l.item_removed,[p]);return o},getData:function(){var m=[];this.$element.find(this.options.selectors.item).each(function(){m.push(e(this).data("stackviewItem"))});return m},zIndex:function(m){var q=this.$element.find(this.options.selectors.item),o=q.length,n=0,p=m?0:q.length-1;while(n<o){q.eq(n).css("z-index",p);p=p+(m?1:-1);n++}}});e.fn[f]=function(o){var m,n=Array.prototype.slice.call(arguments,1);this.each(function(q,s){var p=e(s),t=p.data("stackviewObject");if(!t){new j(s,o)}else{if(t[o]){var r=t[o].apply(t,n);if(m===c&&r!==c){m=r}}}});return m===c?this:m};h.StackView=j})(jQuery,window,document);(function(c,d){var a=c(document),b;c.extend(StackView.defaults,{infiniteScrollDistance:100});b=function(f){var l=c(f.target),m=l.data("stackviewObject"),e=m.options,g,k,e,h,j,i;g=l.find(e.selectors.item_list);k=l.find(e.selectors.item);h=k.length?k.last().position().top:0;h+=g.scrollTop();j=h-l.height()-e.infiniteScrollDistance;i=function(){if(e.search_type==="loc_sort_order"&&g.scrollTop()<=e.infiniteScrollDistance){g.unbind("scroll.stackview");l.stackView("prev_page")}else{if(g.scrollTop()>=j){g.unbind("scroll.stackview");l.stackView("next_page")}}};g.bind("scroll.stackview",i);i()};a.delegate(".stackview","stackview.pageload",b)})(jQuery);(function(c,d){var b=c(document),a=window.StackView;c.extend(true,a.defaults,{transitionDuration:500,transitionEasing:"easeOutQuad",navigationPercent:80,selectors:{downstream:".downstream",upstream:".upstream",num_items:".num-found span"}});b.delegate(".stackview","stackview.init",function(f){var g=c(f.target),e=g.data("stackviewObject"),i=g.find(e.options.selectors.item_list),h=g.height()*e.options.navigationPercent/100;e.num_found_delta=0;g.prepend(tmpl(a.templates.navigation,{empty:e.options.search_type==="loc_sort_order"}));g.delegate(e.options.selectors.downstream,"click",function(){i.animate({scrollTop:"+="+h},e.options.transitionDuration,e.options.transitionEasing);return false}).delegate(e.options.selectors.upstream,"click",function(){i.animate({scrollTop:"-="+h},e.options.transitionDuration,e.options.transitionEasing);return false})}).delegate(".stackview","stackview.pageload",function(h,i){var j=c(h.target),e=j.data("stackviewObject"),g=i.num_found?parseInt(i.num_found,10):i.length,f;e.num_found=g;f=g+e.num_found_delta;j.find(e.options.selectors.num_items).text(f)}).delegate(".stackview","stackview.itemadded stackview.itemremoved",function(g){var h=c(g.target),e=h.data("stackviewObject"),i=h.find(e.options.selectors.item),f;e.num_found_delta+=(g.namespace==="itemadded"?1:-1);f=e.num_found+e.num_found_delta;h.find(e.options.selectors.num_items).text(f)})})(jQuery);(function(c,d){var b=c(document),a=window.StackView;c.extend(true,a.defaults,{classes:{ministack:"stackview-mini"},ministack:{breakpoint:220,max_height_percentage:100,min_height_percentage:80,page_multiple:0.08}});b.delegate(".stackview","stackview.init",function(f){var g=c(f.target),e=g.data("stackviewObject");if(g.width()<=e.options.ministack.breakpoint){g.addClass(e.options.classes.ministack);c.each(["max_height_percentage","min_height_percentage","page_multiple"],function(h,j){e.options.book[j]=e.options.ministack[j]})}})})(jQuery);window.stackCache=(function(d,f){var b={},e=d.JSON&&(function(){try{return("localStorage" in d)&&d.localStorage!==null}catch(h){return false}})();return{set:g,get:c,remove:a};function g(j,k,h){var i=h&&new Date(+new Date()+h*1000),m={expires:+i,value:k};if(e){try{localStorage[j]=JSON.stringify(m)}catch(l){return l}}else{b[j]=m}}function c(h){var i,j;if(e){i=localStorage[h];if(i){i=JSON.parse(i)}}else{i=b[h]}if(i){if(i.expires&&i.expires<+new Date()){a(h)}else{j=i.value}}return j}function a(h){if(e){localStorage.removeItem(h)}else{delete b[h]}}})(window);(function(a){StackView.templates={scaffold:' <div class="ribbon"><%= ribbon %></div> <ul class="stack-items" />',navigation:' <div class="stack-navigation<%= empty ? " empty" : ""%>"> <div class="upstream">Up</div> <div class="num-found"> <span></span><br />items </div> <div class="downstream">Down</div> </div>',book:' <li class="stack-item stack-book heat<%= heat %>" style="width:<%= book_height %>; height:<%= book_thickness %>;"> <a href="<%= link %>" target="_newtab"> <span class="spine-text"> <span class="spine-title"><%= title %></span> <span class="spine-author"><%= author %></span> </span> <span class="spine-year"><%= year %></span> <span class="stack-pages" /> <span class="stack-cover" /> </a> </li>',placeholder:'<li class="stackview-placeholder"></li>'}})();(function(e,d,h){e.extend(true,d.StackView.defaults,{book:{max_height_percentage:100,max_height:39,max_pages:540,min_height_percentage:59,min_height:20,min_pages:200,page_multiple:0.2},selectors:{book:".stack-book"}});var g=function(n,m,j,k,p){var i=j-m,l=p-k,o=(n-m)/(i);return k+o*l};var f=function(l,k){var j=parseInt(k.measurement_height_numeric,10),m=l.book.min_height,i=l.book.max_height;if(isNaN(j)){j=m}j=Math.min(Math.max(j,m),i);j=g(j,l.book.min_height,l.book.max_height,l.book.min_height_percentage,l.book.max_height_percentage);return j+"%"};var b=function(l,k){var n=parseInt(k.measurement_page_numeric,10),m=l.book.min_pages,j=l.book.max_pages,i=l.book.page_multiple;if(isNaN(n)){n=m}n=Math.min(Math.max(n,m),j)*i;return n+"px"};var c=function(i){return i.title_link_friendly?"../shelflife/book/"+i.title_link_friendly+"/"+i.id:i.link};var a=function(j){var i=j.creator&&j.creator.length?j.creator[0]:"";if(/^([^,]*)/.test(i)){i=i.match(/^[^,]*/)}return i};d.StackView.register_type({name:"book",match:function(i){return(i.format&&i.format==="book")||!i.format},adapter:function(j,i){return{heat:d.StackView.utils.get_heat(j.shelfrank),book_height:f(i,j),book_thickness:b(i,j),link:c(j),title:j.title,author:a(j),year:j.pub_date}},template:' <li class="stack-item stack-book heat<%= heat %>" style="width:<%= book_height %>; height:<%= book_thickness %>;"> <a href="<%= link %>" target="_blank"> <span class="spine-text"> <span class="spine-title"><%= title %></span> <span class="spine-author"><%= author %></span> </span> <span class="spine-year"><%= year %></span> <span class="stack-pages" /> <span class="stack-cover" /> </a> </li>'})})(jQuery,window);(function(b,a,c){b.extend(true,a.StackView.defaults,{selectors:{serial:".stack-serial"}});a.StackView.register_type({name:"serial",match:function(d){return d.format==="Serial"},adapter:function(e,d){return{heat:a.StackView.utils.get_heat(e.shelfrank),title:e.title,link:e.link}},template:' <li class="stack-item stack-serial heat<%= heat %>"> <a href="<%= link %>" target="_blank"> <span class="spine-text"> <span class="spine-title"><%= title %></span> </span> <span class="serial-edge" /> <span class="serial-cover" /> </a> </li>'})})(jQuery,window);(function(b,a,c){b.extend(true,a.StackView.defaults,{selectors:{soundrecording:".stack-soundrecording"}});a.StackView.register_type({name:"soundrecording",match:function(d){return d.format==="Sound Recording"},adapter:function(e,d){return{heat:a.StackView.utils.get_heat(e.shelfrank),link:"#",title:e.title,year:e.pub_date}},template:' <li class="stack-item stack-soundrecording heat<%= heat %>"> <a href="<%= link %>" target="_blank"> <span class="spine-text"> <span class="spine-title"><%= title %></span> </span> <span class="spine-year"><%= year %></span> <span class="sound-edge"></span> <span class="sound-cover"></span> </a> </li>'})})(jQuery,window);(function(c,b,d){c.extend(true,b.StackView.defaults,{selectors:{videofilm:".stack-videofilm"}});var a=function(e){return e.title?e.title:"#"};b.StackView.register_type({name:"videofilm",match:function(e){return e.format==="Video/Film"},adapter:function(f,e){return{heat:b.StackView.utils.get_heat(f.shelfrank),height:"65%",title:f.title,year:f.pub_date,link:a(f)}},template:' <li class="stack-item stack-videofilm heat<%= heat %>" style="width:<%= height %>;"> <a href="<%= link %>" target="_blank"> <span class="spine-text"> <span class="spine-title"><%= title %></span> </span> <span class="spine-year"><%= year %></span> <span class="videofilm-edge" /> <span class="videofilm-cover" /> </a> </li>'})})(jQuery,window);(function(b,a,c){b.extend(true,a.StackView.defaults,{selectors:{webpage:".stack-webpage"}});a.StackView.register_type({name:"webpage",match:function(d){return d.format==="webpage"},adapter:function(e,d){return{heat:a.StackView.utils.get_heat(e.shelfrank),link:e.rsrc_value,publisher:e.publisher,title:e.title}},template:' <li class="stack-item stack-webpage heat<%= heat %>"> <a href="<%= link %>" target="_blank"> <span class="url-bar"> <span class="url-publisher"><%= publisher %>:</span> <span class="url-title"><%= title %></span> </span> <span class="webpage-top"></span> <span class="webpage-edge"></span> </a> </li>'})})(jQuery,window);
View
205 src/js/jquery.easing.1.3.js
@@ -0,0 +1,205 @@
+/*
+ * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
+ *
+ * Uses the built in easing capabilities added In jQuery 1.1
+ * to offer multiple easing options
+ *
+ * TERMS OF USE - jQuery Easing
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright © 2008 George McGinley Smith
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * Neither the name of the author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+*/
+
+// t: current time, b: begInnIng value, c: change In value, d: duration
+jQuery.easing['jswing'] = jQuery.easing['swing'];
+
+jQuery.extend( jQuery.easing,
+{
+ def: 'easeOutQuad',
+ swing: function (x, t, b, c, d) {
+ //alert(jQuery.easing.default);
+ return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
+ },
+ easeInQuad: function (x, t, b, c, d) {
+ return c*(t/=d)*t + b;
+ },
+ easeOutQuad: function (x, t, b, c, d) {
+ return -c *(t/=d)*(t-2) + b;
+ },
+ easeInOutQuad: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t + b;
+ return -c/2 * ((--t)*(t-2) - 1) + b;
+ },
+ easeInCubic: function (x, t, b, c, d) {
+ return c*(t/=d)*t*t + b;
+ },
+ easeOutCubic: function (x, t, b, c, d) {
+ return c*((t=t/d-1)*t*t + 1) + b;
+ },
+ easeInOutCubic: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t + b;
+ return c/2*((t-=2)*t*t + 2) + b;
+ },
+ easeInQuart: function (x, t, b, c, d) {
+ return c*(t/=d)*t*t*t + b;
+ },
+ easeOutQuart: function (x, t, b, c, d) {
+ return -c * ((t=t/d-1)*t*t*t - 1) + b;
+ },
+ easeInOutQuart: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
+ return -c/2 * ((t-=2)*t*t*t - 2) + b;
+ },
+ easeInQuint: function (x, t, b, c, d) {
+ return c*(t/=d)*t*t*t*t + b;
+ },
+ easeOutQuint: function (x, t, b, c, d) {
+ return c*((t=t/d-1)*t*t*t*t + 1) + b;
+ },
+ easeInOutQuint: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
+ return c/2*((t-=2)*t*t*t*t + 2) + b;
+ },
+ easeInSine: function (x, t, b, c, d) {
+ return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
+ },
+ easeOutSine: function (x, t, b, c, d) {
+ return c * Math.sin(t/d * (Math.PI/2)) + b;
+ },
+ easeInOutSine: function (x, t, b, c, d) {
+ return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
+ },
+ easeInExpo: function (x, t, b, c, d) {
+ return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
+ },
+ easeOutExpo: function (x, t, b, c, d) {
+ return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
+ },
+ easeInOutExpo: function (x, t, b, c, d) {
+ if (t==0) return b;
+ if (t==d) return b+c;
+ if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
+ return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
+ },
+ easeInCirc: function (x, t, b, c, d) {
+ return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
+ },
+ easeOutCirc: function (x, t, b, c, d) {
+ return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
+ },
+ easeInOutCirc: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
+ return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
+ },
+ easeInElastic: function (x, t, b, c, d) {
+ var s=1.70158;var p=0;var a=c;
+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
+ return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
+ },
+ easeOutElastic: function (x, t, b, c, d) {
+ var s=1.70158;var p=0;var a=c;
+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
+ return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
+ },
+ easeInOutElastic: function (x, t, b, c, d) {
+ var s=1.70158;var p=0;var a=c;
+ if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
+ if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
+ return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
+ },
+ easeInBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ return c*(t/=d)*t*((s+1)*t - s) + b;
+ },
+ easeOutBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
+ },
+ easeInOutBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
+ return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
+ },
+ easeInBounce: function (x, t, b, c, d) {
+ return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
+ },
+ easeOutBounce: function (x, t, b, c, d) {
+ if ((t/=d) < (1/2.75)) {
+ return c*(7.5625*t*t) + b;
+ } else if (t < (2/2.75)) {
+ return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
+ } else if (t < (2.5/2.75)) {
+ return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
+ } else {
+ return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
+ }
+ },
+ easeInOutBounce: function (x, t, b, c, d) {
+ if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
+ return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
+ }
+});
+
+/*
+ *
+ * TERMS OF USE - EASING EQUATIONS
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright © 2001 Robert Penner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * Neither the name of the author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
View
356 src/js/jquery.stackview.base.js
@@ -8,7 +8,7 @@
var events,
plugin = 'stackView',
StackView,
- utils = {};
+ types = {};
events = {
init: 'stackview.init',
@@ -18,127 +18,19 @@
};
/*
- #translate(number, number, number, number, number) - Private
-
- Takes a value (the first argument) and two ranges of numbers. Translates
- this value from the first range to the second range. E.g.:
-
- translate(0, 0, 10, 50, 100) returns 50.
- translate(10, 0, 10, 50, 100) returns 100.
- translate(5, 0, 10, 50, 100) returns 75.
-
- http://stackoverflow.com/questions/1969240/mapping-a-range-of-values-to-another
+ #get_type
*/
- utils.translate = function(value, start_min, start_max, end_min, end_max) {
- var start_range = start_max - start_min,
- end_range = end_max - end_min,
- scale = (value - start_min) / (start_range);
-
- return end_min + scale * end_range;
- };
-
+ var get_type = function(item) {
+ var type;
- /*
- #get_heat(number) - Private
-
- Takes a value between 0 and 100 and returns a number to be used with
- heat classes to indicate popularity.
- */
- utils.get_heat = function(scaled_value) {
- return scaled_value === 100 ? 10 : Math.floor(scaled_value / 10) + 1;
- };
-
- /*
- #get_height(StackView, object) - Private
-
- Takes a StackView instance and a book object. Returns a normalized
- book height percentage, taking into account the minimum height,
- maximum height, height multiple, and translating them onto the
- percentage range specified in the stack options.
- */
- utils.get_height = function(stack, book) {
- var opts = stack.options,
- height = parseInt(book.measurement_height_numeric, 10),
- min = opts.min_item_height,
- max = opts.max_item_height;
-
- if (isNaN(height)) {
- height = min;
- }
- height = Math.min(Math.max(height, min), max);
- height = utils.translate(
- height,
- opts.min_item_height, opts.max_item_height,
- opts.min_height_percentage, opts.max_height_percentage
- );
- return height + '%';
- };
-
- /*
- #get_thickness(StackView, object) - Private
-
- Takes a StackView instance and a book object. Returns a normalized
- book thickness using the number of book pages, taking into account
- the minimum pages, maximum pages, and pages multiple.
- */
- utils.get_thickness = function(stack, book) {
- var thickness = parseInt(book.measurement_page_numeric, 10),
- min = stack.options.min_pages,
- max = stack.options.max_pages,
- multiple = stack.options.page_multiple;
-
- if (isNaN(thickness)) {
- thickness = min;
- }
- thickness = Math.min(Math.max(thickness, min), max) * multiple;
- return thickness + 'px';
- };
-
- /*
- #normalize_link(object) - Private
-
- Takes an item and returns the item's link, taking into account
- workarounds that may come from inconsistent data structure.
- */
- utils.normalize_link = function(item) {
- //workaround for link construction from LibraryCloud
- return item.title_link_friendly ?
- '../shelflife/book/' + item.title_link_friendly + '/' + item.id :
- item.link;
- };
-
- /*
- #get_author(object) - Private
-
- Takes an item and returns the item's author, taking the first
- author if an array of authors is defined.
- */
- utils.get_author = function(item) {
- var author = item.creator && item.creator.length ? item.creator[0] : '';
-
- if(/^([^,]*)/.test(author)) {
- author = author.match(/^[^,]*/);
- }
-
- return author;
- };
-
- /*
- #normalize_item(StackView, object)
-
- Takes an item and returns a normalized object suited for rendering to
- the item template.
- */
- utils.normalize_item = function(stack, item) {
- return {
- heat: utils.get_heat(item.shelfrank),
- book_height: utils.get_height(stack, item),
- book_thickness: utils.get_thickness(stack, item),
- link: utils.normalize_link(item),
- title: item.title,
- author: utils.get_author(item),
- year: item.pub_date
- };
+ $.each(types, function(key, val) {
+ if (val.match(item)) {
+ type = val;
+ return false;
+ }
+ });
+
+ return type;
};
/*
@@ -149,25 +41,29 @@
appends it to the stack's item list. If [placeholder] is passed in the
items take the its spot in the DOM.
*/
- utils.render_items = function(stack, docs, $placeholder) {
+ var render_items = function(stack, docs, $placeholder) {
var action = $placeholder ? 'before' : 'append',
$pivot = $placeholder ?
$placeholder :
stack.$element.find(stack.options.selectors.item_list);
-
+
$.each(docs, function(i, item) {
- var $item = $(tmpl(
- StackView.templates.book,
- utils.normalize_item(stack, item)
- ));
-
+ var type = get_type(item),
+ $item;
+
+ if (type == null) {
+ return true;
+ }
+
+ $item = $(tmpl(type.template, type.adapter(item, stack.options)));
$item.data('stackviewItem', item);
$pivot[action]($item);
});
-
+
if ($placeholder) {
$placeholder.remove();
}
+
};
/*
@@ -177,7 +73,7 @@
If the Stack uses loc_sort_order, this adjusts the query for that case.
Returns a plain object with key:value params to be used by $.param.
*/
- utils.calculate_params = function(stack) {
+ var calculate_params = function(stack) {
var opts = stack.options,
params;
@@ -237,8 +133,8 @@
instance. When the page is finished fetching, the callback is
invoked, passing in the array of items.
*/
- utils.fetch_page = function(stack, callback) {
- var params = utils.calculate_params(stack),
+ var fetch_page = function(stack, callback) {
+ var params = calculate_params(stack),
querystring = $.param(params),
cachedResult;
@@ -286,81 +182,127 @@
this.init();
};
- /*
- The default options for a StackView instance.
-
- url
- The URL to send requests to for item data.
- data
- An alternative to URL, used for static data. Accepts a typical
- URL response object or a simple array of item objects.
- jsonp
- If true, the URL will expect a JSONP request. callback=? will be
- added to the request parameters.
- items_per_page
- The number of items to request each page.
- page_multiple
- A number that when multiplied by the number of pages in a book
- gives us the total pixel height to be rendered.
- search_type
- The type of search to be performed by the script at URL. This is
- passed to the script as the search_type parameter.
- query
- The query passed to the script at URL. Passed as the
- query parameter.
- ribbon
- The text of the ribbon at the top of the stack.
- id
- When using a search type of loc_sort_order, this is the id of
- the item that the search centers around.
- min_pages
- The minimum number of pages that a book will render as,
- regardless of the true number of pages.
- max_pages
- The maximum number of pages that a book will render as,
- regardless of the true number of pages.
- min_item_height
- The minimum height in centimeters that an item will render as,
- regardless of the true height of the item.
- max_item_height
- The maximum height in centimeters that an item will render as,
- regardless of the true height of the item.
- min_height_percentage
- Books with the minimum height will render as this percentage
- width in the stack.
- max_height_percentage
- Books with the maximum height will render as this percentage
- width in the stack.
- cache_ttl
- How long a request will stay in cache.
- selectors
- A number of selectors that are frequently used by the code to
- identify key structures.
- */
- $.extend(StackView, {
+ /* Static properties and functions */
+ $.extend(true, StackView, {
+
+ /*
+ The default options for a StackView instance.
+
+ cache_ttl
+ How long a request will stay in cache.
+
+ data
+ An alternative to URL, used for static data. Accepts a typical
+ URL response object or a simple array of item objects.
+
+ id
+ When using a search type of loc_sort_order, this is the id of
+ the item that the search centers around.
+
+ items_per_page
+ The number of items to request each page.
+
+ jsonp
+ If true, the URL will expect a JSONP request. callback=? will be
+ added to the request parameters.
+
+ query
+ The query passed to the script at URL. Passed as the
+ query parameter.
+
+ ribbon
+ The text of the ribbon at the top of the stack.
+
+ search_type
+ The type of search to be performed by the script at URL. This is
+ passed to the script as the search_type parameter.
+
+ selectors
+ A number of selectors that are frequently used by the code to
+ identify key structures.
+
+ item
+ A single item in the stack.
+
+ item_list
+ Container around all of the stack items.
+
+ ribbon
+ The text ribbon at the top of the stack.
+
+ url
+ The URL to send requests to for item data.
+ */
defaults: {
- url: 'basic.json',
+ cache_ttl: 60,
data: '',
- jsonp: false,
+ id: null,
items_per_page: 10,
- page_multiple: 0.20,
- height_multiple: 12.5,
- search_type: 'keyword',
+ jsonp: false,
query: '',
ribbon: 'Stack View',
- id: null,
- min_pages: 200,
- max_pages: 540,
- min_item_height: 20,
- max_item_height: 39,
- min_height_percentage: 59,
- max_height_percentage: 100,
- cache_ttl: 60,
+ search_type: 'keyword',
selectors: {
item: '.stack-item',
item_list: '.stack-items',
ribbon: '.ribbon'
+ },
+ url: 'basic.json'
+ },
+
+ /*
+ StackView.get_heat(number)
+
+ Takes a value between 0 and 100 and returns a number to be used with
+ heat classes to indicate popularity.
+ */
+ utils: {
+ get_heat: function(scaled_value) {
+ return scaled_value === 100 ? 10 : Math.floor(scaled_value / 10) + 1;
}
+ },
+
+ /*
+ StackView.register_type(object)
+
+ Registers an item type to be used by the stack. A Type object
+ has the following properties:
+
+ name: string
+ A unique, identifying name of the item type.
+
+ match: function(obj) -> obj
+ A function that takes a stack item and returns true if the
+ item matches this type. Example:
+
+ match: function(item) { return item.type === 'book' }
+
+ adapter: function(obj, obj) -> obj
+ This function allows the user to make transformations to the
+ item data before rendering it to the template. It takes as
+ parameters a raw item that matches the match function and the
+ options from the StackView instance. It should return an object
+ to render against "template." If no changes to the raw data need
+ to be made, the simplest value for this can be:
+
+ adapter: function(item) { return item; }
+
+ template: string
+ A microtemplating template to render for this type in the stack.
+ Receives as its data the return value from "adapter."
+
+ */
+ register_type: function(obj) {
+ types[obj.name] = obj;
+ },
+
+ /*
+ StackView.get_types()
+
+ Returns the hash of item types.
+ */
+ get_types: function() {
+ return types;
}
});
@@ -412,7 +354,7 @@
this.direction = 'down';
if (opts.data) {
- utils.render_items(this, opts.data.docs ? opts.data.docs : opts.data);
+ render_items(this, opts.data.docs ? opts.data.docs : opts.data);
this.finished.down = true;
this.$element.trigger(events.page_load, [opts.data]);
}
@@ -420,8 +362,8 @@
this.$element
.find(opts.selectors.item_list)
.append($placeholder);
- utils.fetch_page(this, function(data) {
- utils.render_items(that, data.docs, $placeholder);
+ fetch_page(this, function(data) {
+ render_items(that, data.docs, $placeholder);
if (parseInt(data.start, 10) === -1) {
that.finished.down = true;
}
@@ -449,10 +391,10 @@
this.direction = 'up';
this.$element.find(opts.selectors.item_list).prepend($placeholder);
- utils.fetch_page(this, function(data) {
+ fetch_page(this, function(data) {
var oldTop = $oldMarker.position().top;
- utils.render_items(that, data.docs, $placeholder);
+ render_items(that, data.docs, $placeholder);
if (that.page > 1) {
that.$element.find(opts.selectors.item_list).animate({
'scrollTop': '+=' + ($oldMarker.position().top - oldTop)
@@ -473,7 +415,7 @@
*/
add: function() {
var $items = this.$element.find(this.options.selectors.item),
- index, item, action, $pivot, $item;
+ index, item, type, action, $pivot, $item;
if (typeof(arguments[0]) === 'number') {
index = arguments[0];
@@ -496,10 +438,12 @@
action = 'before';
}
- $item = $(tmpl(
- StackView.templates.book,
- utils.normalize_item(this, item)
- ));
+ type = get_type(item);
+ if (type == null) {
+ return;
+ }
+ $item = $(tmpl(type.template, type.adapter(item, this.options)));
+
$item.data('stackviewItem', item);
$pivot[action]($item);
this.zIndex();
View
20 src/js/jquery.stackview.infinite.js
@@ -17,26 +17,28 @@
var $stack = $(event.target),
stack = $stack.data('stackviewObject'),
opts = stack.options,
- $items, opts, lastItemTop, triggerPoint, scrollCheck;
+ $itemList, $items, opts, lastItemTop, triggerPoint, scrollCheck;
- $items = $stack.find(opts.selectors.item_list);
- lastItemTop = $items.find(opts.selectors.item).last().position().top;
- lastItemTop += $items.scrollTop();
+ $itemList = $stack.find(opts.selectors.item_list);
+ $items = $stack.find(opts.selectors.item);
+
+ lastItemTop = $items.length ? $items.last().position().top : 0;
+ lastItemTop += $itemList.scrollTop();
triggerPoint = lastItemTop - $stack.height() - opts.infiniteScrollDistance;
scrollCheck = function() {
if (opts.search_type === 'loc_sort_order' &&
- $items.scrollTop() <= opts.infiniteScrollDistance) {
- $items.unbind('scroll.stackview');
+ $itemList.scrollTop() <= opts.infiniteScrollDistance) {
+ $itemList.unbind('scroll.stackview');
$stack.stackView('prev_page');
}
- else if ($items.scrollTop() >= triggerPoint) {
- $items.unbind('scroll.stackview');
+ else if ($itemList.scrollTop() >= triggerPoint) {
+ $itemList.unbind('scroll.stackview');
$stack.stackView('next_page');
}
};
- $items.bind('scroll.stackview', scrollCheck);
+ $itemList.bind('scroll.stackview', scrollCheck);
scrollCheck();
};
View
33 src/js/jquery.stackview.ministack.js
@@ -0,0 +1,33 @@
+(function($, undefined) {
+ var $d = $(document),
+ StackView = window.StackView;
+
+ $.extend(true, StackView.defaults, {
+ classes: {
+ ministack: 'stackview-mini'
+ },
+
+ ministack: {
+ breakpoint: 220,
+ max_height_percentage: 100,
+ min_height_percentage: 80,
+ page_multiple: .08
+ }
+ });
+
+ $d.delegate('.stackview', 'stackview.init', function(event) {
+ var $stack = $(event.target),
+ stack = $stack.data('stackviewObject');
+
+ if ($stack.width() <= stack.options.ministack.breakpoint) {
+ $stack.addClass(stack.options.classes.ministack);
+ $.each([
+ 'max_height_percentage',
+ 'min_height_percentage',
+ 'page_multiple'
+ ], function(i, el) {
+ stack.options.book[el] = stack.options.ministack[el];
+ });
+ }
+ });
+})(jQuery);
View
7 src/js/jquery.stackview.navigation.js
@@ -9,7 +9,8 @@
StackView = window.StackView;
$.extend(true, StackView.defaults, {
- transitionDuration: 200,
+ transitionDuration: 500,
+ transitionEasing: 'easeOutQuad',
navigationPercent: 80,
selectors: {
downstream: '.downstream',
@@ -33,13 +34,13 @@
.delegate(stack.options.selectors.downstream, 'click', function() {
$items.animate({
scrollTop: '+=' + delta
- }, stack.options.transitionDuration);
+ }, stack.options.transitionDuration, stack.options.transitionEasing);
return false;
})
.delegate(stack.options.selectors.upstream, 'click', function() {
$items.animate({
scrollTop: '-=' + delta
- }, stack.options.transitionDuration);
+ }, stack.options.transitionDuration, stack.options.transitionEasing);
return false;
});
View
184 src/js/types/book.js
@@ -0,0 +1,184 @@
+(function($, window, undefined) {
+ /*
+ Extend StackView defaults to include options for this item type.
+
+ max_height_percentage
+ Books with the maximum height will render as this percentage
+ width in the stack.
+
+ max_height
+ The maximum height in centimeters that an item will render as,
+ regardless of the true height of the item.
+
+ max_pages
+ The maximum number of pages that a book will render as,
+ regardless of the true number of pages.
+
+ min_height_percentage
+ Books with the minimum height will render as this percentage
+ width in the stack.
+
+ min_height
+ The minimum height in centimeters that an item will render as,
+ regardless of the true height of the item.
+
+ min_pages
+ The minimum number of pages that a book will render as,
+ regardless of the true number of pages.
+
+ page_multiple
+ A number that when multiplied by the number of pages in a book
+ gives us the total pixel height to be rendered.
+
+ selectors.book
+ Item selector specific to the book type.
+ */
+ $.extend(true, window.StackView.defaults, {
+ book: {
+ max_height_percentage: 100,
+ max_height: 39,
+ max_pages: 540,
+ min_height_percentage: 59,
+ min_height: 20,
+ min_pages: 200,
+ page_multiple: 0.20
+ },
+
+ selectors: {
+ book: '.stack-book'
+ }
+ });
+
+ /*
+ #translate(number, number, number, number, number) - Private
+
+ Takes a value (the first argument) and two ranges of numbers. Translates
+ this value from the first range to the second range. E.g.:
+
+ translate(0, 0, 10, 50, 100) returns 50.
+ translate(10, 0, 10, 50, 100) returns 100.
+ translate(5, 0, 10, 50, 100) returns 75.
+
+ http://stackoverflow.com/questions/1969240/mapping-a-range-of-values-to-another
+ */
+ var translate = function(value, start_min, start_max, end_min, end_max) {
+ var start_range = start_max - start_min,
+ end_range = end_max - end_min,
+ scale = (value - start_min) / (start_range);
+
+ return end_min + scale * end_range;
+ };
+
+ /*
+ #get_height(StackView, object) - Private
+
+ Takes a StackView options object and a book object. Returns a
+ normalized book height percentage, taking into account the minimum
+ height, maximum height, height multiple, and translating them onto
+ the percentage range specified in the stack options.
+ */
+ var get_height = function(options, book) {
+ var height = parseInt(book.measurement_height_numeric, 10),
+ min = options.book.min_height,
+ max = options.book.max_height;
+
+ if (isNaN(height)) {
+ height = min;
+ }
+ height = Math.min(Math.max(height, min), max);
+ height = translate(
+ height,
+ options.book.min_height,
+ options.book.max_height,
+ options.book.min_height_percentage,
+ options.book.max_height_percentage
+ );
+ return height + '%';
+ };
+
+ /*
+ #get_thickness(StackView, object) - Private
+
+ Takes a StackView instance and a book object. Returns a normalized
+ book thickness using the number of book pages, taking into account
+ the minimum pages, maximum pages, and pages multiple.
+ */
+ var get_thickness = function(options, book) {
+ var thickness = parseInt(book.measurement_page_numeric, 10),
+ min = options.book.min_pages,
+ max = options.book.max_pages,
+ multiple = options.book.page_multiple;
+
+ if (isNaN(thickness)) {
+ thickness = min;
+ }
+ thickness = Math.min(Math.max(thickness, min), max) * multiple;
+ return thickness + 'px';
+ };
+
+ /*
+ #normalize_link(object) - Private
+
+ Takes an item and returns the item's link, taking into account
+ workarounds that may come from inconsistent data structure.
+ */
+ var normalize_link = function(item) {
+ //workaround for link construction from LibraryCloud
+ return item.title_link_friendly ?
+ '../shelflife/book/' + item.title_link_friendly + '/' + item.id :
+ item.link;
+ };
+
+ /*
+ #get_author(object) - Private
+
+ Takes an item and returns the item's author, taking the first
+ author if an array of authors is defined.
+ */
+ var get_author = function(item) {
+ var author = item.creator && item.creator.length ? item.creator[0] : '';
+
+ if(/^([^,]*)/.test(author)) {
+ author = author.match(/^[^,]*/);
+ }
+
+ return author;
+ };
+
+
+ /*
+ Book type definition.
+ */
+ window.StackView.register_type({
+ name: 'book',
+
+ match: function(item) {
+ return (item.format && item.format === 'book') || !item.format;
+ },
+
+ adapter: function(item, options) {
+ return {
+ heat: window.StackView.utils.get_heat(item.shelfrank),
+ book_height: get_height(options, item),
+ book_thickness: get_thickness(options, item),
+ link: normalize_link(item),
+ title: item.title,
+ author: get_author(item),
+ year: item.pub_date
+ };
+ },
+
+ template: '\
+ <li class="stack-item stack-book heat<%= heat %>" style="width:<%= book_height %>; height:<%= book_thickness %>;">\
+ <a href="<%= link %>" target="_blank">\
+ <span class="spine-text">\
+ <span class="spine-title"><%= title %></span>\
+ <span class="spine-author"><%= author %></span>\
+ </span>\
+ <span class="spine-year"><%= year %></span>\
+ <span class="stack-pages" />\
+ <span class="stack-cover" />\
+ </a>\
+ </li>'
+ });
+})(jQuery, window);
View
40 src/js/types/serial.js
@@ -0,0 +1,40 @@
+(function($, window, undefined) {
+ /*
+ Extend StackView defaults to include options for this item type.
+
+ selectors.serial
+ Item selector specific to the serial type.
+ */
+ $.extend(true, window.StackView.defaults, {
+ selectors: {
+ serial: '.stack-serial'
+ }
+ });
+
+ window.StackView.register_type({
+ name: 'serial',
+
+ match: function(item) {
+ return item.format === 'Serial';
+ },
+
+ adapter: function(item, options) {
+ return {
+ heat: window.StackView.utils.get_heat(item.shelfrank),
+ title: item.title,
+ link: item.link
+ };
+ },
+
+ template: '\
+ <li class="stack-item stack-serial heat<%= heat %>">\
+ <a href="<%= link %>" target="_blank">\
+ <span class="spine-text">\
+ <span class="spine-title"><%= title %></span>\
+ </span>\
+ <span class="serial-edge" />\
+ <span class="serial-cover" />\
+ </a>\
+ </li>'
+ });
+})(jQuery, window);
View
42 src/js/types/soundrecording.js
@@ -0,0 +1,42 @@
+(function($, window, undefined) {
+ /*
+ Extend StackView defaults to include options for this item type.
+
+ selectors.soundrecording
+ Item selector specific to the soundrecording type.
+ */
+ $.extend(true, window.StackView.defaults, {
+ selectors: {
+ soundrecording: '.stack-soundrecording'
+ }
+ });
+
+ window.StackView.register_type({
+ name: 'soundrecording',
+
+ match: function(item) {
+ return item.format === 'Sound Recording';
+ },
+
+ adapter: function(item, options) {
+ return {
+ heat: window.StackView.utils.get_heat(item.shelfrank),
+ link: '#',
+ title: item.title,
+ year: item.pub_date
+ };
+ },
+
+ template: '\
+ <li class="stack-item stack-soundrecording heat<%= heat %>">\
+ <a href="<%= link %>" target="_blank">\
+ <span class="spine-text">\
+ <span class="spine-title"><%= title %></span>\
+ </span>\
+ <span class="spine-year"><%= year %></span>\
+ <span class="sound-edge"></span>\
+ <span class="sound-cover"></span>\
+ </a>\
+ </li>'
+ });
+})(jQuery, window);
View
56 src/js/types/videofilm.js
@@ -0,0 +1,56 @@
+(function($, window, undefined) {
+ /*
+ Extend StackView defaults to include options for this item type.
+
+ selectors.videofilm
+ Item selector specific to the videofilm type.
+ */
+ $.extend(true, window.StackView.defaults, {
+ selectors: {
+ videofilm: '.stack-videofilm'
+ }
+ });
+
+ /*
+ #normalize_link(object) - Private
+
+ Takes an item and returns the item's link, taking into account
+ workarounds that may come from inconsistent data structure.
+ */
+ var normalize_link = function(item) {
+ // TODO: How should this be normalized? Can we just drop normalization
+ // in favor of other systems modifying or redefining types?
+ return item.title ? item.title : '#'
+ };
+
+ window.StackView.register_type({
+ name: 'videofilm',
+
+ match: function(item) {
+ return item.format === 'Video\/Film';
+ },
+
+ adapter: function(item, options) {
+ return {
+ heat: window.StackView.utils.get_heat(item.shelfrank),
+ /* TODO: How should video widths be calculated? */
+ height: '65%',
+ title: item.title,
+ year: item.pub_date,
+ link: normalize_link(item)
+ };
+ },
+
+ template: '\
+ <li class="stack-item stack-videofilm heat<%= heat %>" style="width:<%= height %>;">\
+ <a href="<%= link %>" target="_blank">\
+ <span class="spine-text">\
+ <span class="spine-title"><%= title %></span>\
+ </span>\
+ <span class="spine-year"><%= year %></span>\
+ <span class="videofilm-edge" />\
+ <span class="videofilm-cover" />\
+ </a>\
+ </li>'
+ });
+})(jQuery, window);
View
42 src/js/types/webpage.js
@@ -0,0 +1,42 @@
+(function($, window, undefined) {
+ /*
+ Extend StackView defaults to include options for this item type.
+
+ selectors.webpage
+ Item selector specific to the webpage type.
+ */
+ $.extend(true, window.StackView.defaults, {
+ selectors: {
+ webpage: '.stack-webpage'
+ }
+ });
+
+ window.StackView.register_type({
+ name: 'webpage',
+
+ match: function(item) {
+ return item.format === 'webpage';
+ },
+
+ adapter: function(item, options) {
+ return {
+ heat: window.StackView.utils.get_heat(item.shelfrank),
+ link: item.rsrc_value,
+ publisher: item.publisher,
+ title: item.title
+ };
+ },
+
+ template: '\