├── css ├── base.css └── style.css ├── fonts └── ostrich-sans-fontfacekit │ ├── SIL Open Font License 1.1.txt │ ├── demo.html │ ├── ostrich-black-webfont.eot │ ├── ostrich-black-webfont.svg │ ├── ostrich-black-webfont.ttf │ ├── ostrich-black-webfont.woff │ ├── ostrich-bold-webfont.eot │ ├── ostrich-bold-webfont.svg │ ├── ostrich-bold-webfont.ttf │ ├── ostrich-bold-webfont.woff │ ├── ostrich-dashed-webfont.eot │ ├── ostrich-dashed-webfont.svg │ ├── ostrich-dashed-webfont.ttf │ ├── ostrich-dashed-webfont.woff │ ├── ostrich-light-webfont.eot │ ├── ostrich-light-webfont.svg │ ├── ostrich-light-webfont.ttf │ ├── ostrich-light-webfont.woff │ ├── ostrich-regular-webfont.eot │ ├── ostrich-regular-webfont.svg │ ├── ostrich-regular-webfont.ttf │ ├── ostrich-regular-webfont.woff │ ├── ostrich-rounded-webfont.eot │ ├── ostrich-rounded-webfont.svg │ ├── ostrich-rounded-webfont.ttf │ ├── ostrich-rounded-webfont.woff │ └── stylesheet.css ├── index.html ├── js ├── libs │ ├── jquery-1.6.2.js │ ├── jquery.ba-dotimeout.js │ ├── jquery.mockjax.js │ ├── jquery.tmpl.js │ └── modernizr-1.7.min.js └── script.js ├── mocks ├── johnneiner.js └── mocks.js └── readme.md /css/base.css: -------------------------------------------------------------------------------- 1 | /* HTML5 ✰ Boilerplate */ 2 | 3 | html, body, div, span, object, iframe, 4 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 5 | abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, 6 | small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, 7 | fieldset, form, label, legend, 8 | table, caption, tbody, tfoot, thead, tr, th, td, 9 | article, aside, canvas, details, figcaption, figure, 10 | footer, header, hgroup, menu, nav, section, summary, 11 | time, mark, audio, video { 12 | margin: 0; 13 | padding: 0; 14 | border: 0; 15 | font-size: 100%; 16 | font: inherit; 17 | vertical-align: baseline; 18 | } 19 | 20 | article, aside, details, figcaption, figure, 21 | footer, header, hgroup, menu, nav, section { 22 | display: block; 23 | } 24 | 25 | blockquote, q { quotes: none; } 26 | blockquote:before, blockquote:after, 27 | q:before, q:after { content: ""; content: none; } 28 | ins { background-color: #ff9; color: #000; text-decoration: none; } 29 | mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; } 30 | del { text-decoration: line-through; } 31 | abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; } 32 | table { border-collapse: collapse; border-spacing: 0; } 33 | hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; } 34 | input, select { vertical-align: middle; } 35 | 36 | body { font:13px/1.231 sans-serif; *font-size:small; } 37 | select, input, textarea, button { font:99% sans-serif; } 38 | pre, code, kbd, samp { font-family: monospace, sans-serif; } 39 | 40 | html { overflow-y: scroll; } 41 | a:hover, a:active { outline: none; } 42 | ul, ol { margin-left: 2em; } 43 | ol { list-style-type: decimal; } 44 | nav ul, nav li { margin: 0; list-style:none; list-style-image: none; } 45 | small { font-size: 85%; } 46 | strong, th { font-weight: bold; } 47 | td { vertical-align: top; } 48 | sub, sup { font-size: 75%; line-height: 0; position: relative; } 49 | sup { top: -0.5em; } 50 | sub { bottom: -0.25em; } 51 | 52 | pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; padding: 15px; } 53 | textarea { overflow: auto; } 54 | .ie6 legend, .ie7 legend { margin-left: -7px; } 55 | input[type="radio"] { vertical-align: text-bottom; } 56 | input[type="checkbox"] { vertical-align: bottom; } 57 | .ie7 input[type="checkbox"] { vertical-align: baseline; } 58 | .ie6 input { vertical-align: text-bottom; } 59 | label, input[type="button"], input[type="submit"], input[type="image"], button { cursor: pointer; } 60 | button, input, select, textarea { margin: 0; } 61 | input:valid, textarea:valid { } 62 | input:invalid, textarea:invalid { border-radius: 1px; -moz-box-shadow: 0px 0px 5px red; -webkit-box-shadow: 0px 0px 5px red; box-shadow: 0px 0px 5px red; } 63 | .no-boxshadow input:invalid, .no-boxshadow textarea:invalid { background-color: #f0dddd; } 64 | 65 | 66 | /*::-moz-selection{ background: #FF5E99; color:#fff; text-shadow: none; } 67 | ::selection { background:#FF5E99; color:#fff; text-shadow: none; } 68 | a:link { -webkit-tap-highlight-color: #FF5E99; }*/ 69 | button { width: auto; overflow: visible; } 70 | .ie7 img { -ms-interpolation-mode: bicubic; } 71 | 72 | body, select, input, textarea { color: #444; } 73 | h1, h2, h3, h4, h5, h6 { font-weight: bold; } 74 | a, a:active, a:visited { color: #607890; } 75 | a:hover { color: #036; } 76 | 77 | 78 | /** 79 | * Primary styles 80 | * 81 | * Author: 82 | */ 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | .ir { display: block; text-indent: -999em; overflow: hidden; background-repeat: no-repeat; text-align: left; direction: ltr; } 98 | .hidden { display: none; visibility: hidden; } 99 | .visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; } 100 | .visuallyhidden.focusable:active, 101 | .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; } 102 | .invisible { visibility: hidden; } 103 | .clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; } 104 | .clearfix:after { clear: both; } 105 | .clearfix { zoom: 1; } 106 | 107 | 108 | @media all and (orientation:portrait) { 109 | 110 | } 111 | 112 | @media all and (orientation:landscape) { 113 | 114 | } 115 | 116 | @media screen and (max-device-width: 480px) { 117 | 118 | /* html { -webkit-text-size-adjust:none; -ms-text-size-adjust:none; } */ 119 | } 120 | 121 | 122 | @media print { 123 | * { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important; 124 | -ms-filter: none !important; } 125 | a, a:visited { color: #444 !important; text-decoration: underline; } 126 | a[href]:after { content: " (" attr(href) ")"; } 127 | abbr[title]:after { content: " (" attr(title) ")"; } 128 | .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; } 129 | pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } 130 | thead { display: table-header-group; } 131 | tr, img { page-break-inside: avoid; } 132 | @page { margin: 0.5cm; } 133 | p, h2, h3 { orphans: 3; widows: 3; } 134 | h2, h3{ page-break-after: avoid; } 135 | } 136 | 137 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | @import url( "base.css" ); 2 | @import url( "../fonts/ostrich-sans-fontfacekit/stylesheet.css" ); 3 | 4 | html, body { width: 100%; min-height: 100%; } 5 | 6 | html { 7 | height: 100%; 8 | background-color: #70300a; 9 | background: -webkit-gradient(radial, 50% 0%, 0, 50% 0%, 700, from(#CB7317), color-stop(0.5, #984D10), to(#70300A)); 10 | background: -moz-radial-gradient(50% 0%, farthest-side, #CB7317, #984D10, #70300A); 11 | background-attachment: fixed; 12 | } 13 | 14 | body { 15 | background: transparent; 16 | padding: 1px 0; 17 | } 18 | 19 | header { 20 | text-align: center; 21 | margin: 30px 0 20px 0; 22 | text-shadow: 2px 2px 4px rgba(0,0,0,0.2); 23 | } 24 | 25 | header h1 { 26 | font-size: 80px; 27 | font-family: "OstrichSansBlack", sans-serif; 28 | color: rgb(255,191,59); 29 | } 30 | 31 | header p { 32 | font-family: "Gill Sans", serif; 33 | text-transform: uppercase; 34 | font-size: 24px; 35 | color: #fff; 36 | } 37 | 38 | .portfolio { 39 | width: 690px; 40 | margin: 40px auto; 41 | list-style: none; 42 | padding: 0; 43 | position: relative; 44 | left: 10px; 45 | } 46 | 47 | .portfolio li { 48 | float: left; 49 | margin-right: 20px; 50 | margin-bottom: 20px; 51 | padding: 5px; 52 | background: #fff; 53 | -webkit-box-shadow: 2px 2px 3px rgba(0,0,0,0.2); /* Saf3.0+, Chrome */ 54 | -moz-box-shadow: 2px 2px 3px rgba(0,0,0,0.2); /* FF3.5+ */ 55 | box-shadow: 2px 2px 3px rgba(0,0,0,0.2); /* Opera 10.5, IE 9.0 */ 56 | position: relative; 57 | } 58 | 59 | .portfolio li img, 60 | .portfolio li span.placeholder-image { 61 | width: 200px; 62 | height: 150px; 63 | background: #3b1702; 64 | margin: 0; 65 | padding: 0; 66 | display: block; 67 | } 68 | 69 | .portfolio-info-panel { 70 | background: rgba(0,0,0,0.9); 71 | position: absolute; 72 | color: #fff; 73 | padding: 10px; 74 | width: 160px; 75 | -webkit-border-radius: 5px; /* Saf3+, Chrome */ 76 | -moz-border-radius: 5px; /* FF1+ */ 77 | border-radius: 5px; /* Opera 10.5, IE 9 */ 78 | text-align: center; 79 | left: 15px; 80 | bottom: 140px; 81 | display: none; 82 | } 83 | 84 | .no-js li:hover .portfolio-info-panel { 85 | display: block; 86 | } 87 | 88 | .portfolio li:nth-child(1n+4) .portfolio-info-panel { 89 | bottom: auto; 90 | top: 140px; 91 | } 92 | 93 | .portfolio-info-panel h2 { 94 | font-weight: normal; 95 | font-family: "OstrichSansBlack", serif; 96 | text-rendering: optimizeLegibility; 97 | font-size: 24px; 98 | color: rgb(255,191,59); 99 | } 100 | 101 | .portfolio-info-panel a { 102 | color: #ccc; 103 | text-decoration: none; 104 | } 105 | 106 | .portfolio-info-panel a:hover { 107 | text-decoration: underline; 108 | } 109 | 110 | 111 | footer { 112 | clear: left; 113 | width: 700px; 114 | border-top: solid 1px rgba(0,0,0,0.4); 115 | padding-top: 30px; 116 | position: relative; 117 | margin: 0 auto; 118 | top: 20px; 119 | text-align: center; 120 | color: rgba(255,255,255,0.4); 121 | } 122 | 123 | footer a { 124 | color: #fff; 125 | } -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/SIL Open Font License 1.1.txt: -------------------------------------------------------------------------------- 1 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 2 | This license is copied below, and is also available with a FAQ at: 3 | http://scripts.sil.org/OFL 4 | 5 | 6 | ----------------------------------------------------------- 7 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 8 | ----------------------------------------------------------- 9 | 10 | PREAMBLE 11 | The goals of the Open Font License (OFL) are to stimulate worldwide 12 | development of collaborative font projects, to support the font creation 13 | efforts of academic and linguistic communities, and to provide a free and 14 | open framework in which fonts may be shared and improved in partnership 15 | with others. 16 | 17 | The OFL allows the licensed fonts to be used, studied, modified and 18 | redistributed freely as long as they are not sold by themselves. The 19 | fonts, including any derivative works, can be bundled, embedded, 20 | redistributed and/or sold with any software provided that any reserved 21 | names are not used by derivative works. The fonts and derivatives, 22 | however, cannot be released under any other type of license. The 23 | requirement for fonts to remain under this license does not apply 24 | to any document created using the fonts or their derivatives. 25 | 26 | DEFINITIONS 27 | "Font Software" refers to the set of files released by the Copyright 28 | Holder(s) under this license and clearly marked as such. This may 29 | include source files, build scripts and documentation. 30 | 31 | "Reserved Font Name" refers to any names specified as such after the 32 | copyright statement(s). 33 | 34 | "Original Version" refers to the collection of Font Software components as 35 | distributed by the Copyright Holder(s). 36 | 37 | "Modified Version" refers to any derivative made by adding to, deleting, 38 | or substituting -- in part or in whole -- any of the components of the 39 | Original Version, by changing formats or by porting the Font Software to a 40 | new environment. 41 | 42 | "Author" refers to any designer, engineer, programmer, technical 43 | writer or other person who contributed to the Font Software. 44 | 45 | PERMISSION & CONDITIONS 46 | Permission is hereby granted, free of charge, to any person obtaining 47 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 48 | redistribute, and sell modified and unmodified copies of the Font 49 | Software, subject to the following conditions: 50 | 51 | 1) Neither the Font Software nor any of its individual components, 52 | in Original or Modified Versions, may be sold by itself. 53 | 54 | 2) Original or Modified Versions of the Font Software may be bundled, 55 | redistributed and/or sold with any software, provided that each copy 56 | contains the above copyright notice and this license. These can be 57 | included either as stand-alone text files, human-readable headers or 58 | in the appropriate machine-readable metadata fields within text or 59 | binary files as long as those fields can be easily viewed by the user. 60 | 61 | 3) No Modified Version of the Font Software may use the Reserved Font 62 | Name(s) unless explicit written permission is granted by the corresponding 63 | Copyright Holder. This restriction only applies to the primary font name as 64 | presented to the users. 65 | 66 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 67 | Software shall not be used to promote, endorse or advertise any 68 | Modified Version, except to acknowledge the contribution(s) of the 69 | Copyright Holder(s) and the Author(s) or with their explicit written 70 | permission. 71 | 72 | 5) The Font Software, modified or unmodified, in part or in whole, 73 | must be distributed entirely under this license, and must not be 74 | distributed under any other license. The requirement for fonts to 75 | remain under this license does not apply to any document created 76 | using the Font Software. 77 | 78 | TERMINATION 79 | This license becomes null and void if any of the above conditions are 80 | not met. 81 | 82 | DISCLAIMER 83 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 84 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 85 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 86 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 87 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 88 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 89 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 90 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 91 | OTHER DEALINGS IN THE FONT SOFTWARE. -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/demo.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | Font Face Demo 9 | 10 | 26 | 27 | 28 | 29 |
30 |

FONT-FACE DEMO FOR THE OSTRICH SANS FONT

31 | 32 | 33 | 34 |

Ostrich Sans Light - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

35 | 36 | 37 | 38 |

Ostrich Sans Regular - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

39 | 40 | 41 | 42 |

Ostrich Sans Bold - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

43 | 44 | 45 | 46 |

Ostrich Sans Black - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

47 | 48 | 49 | 50 |

Ostrich Sans Rounded - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

51 | 52 | 53 | 54 |

Ostrich Sans Dashed - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

55 | 56 |
57 | 58 | 59 | -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-black-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-black-webfont.eot -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-black-webfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a custom SVG webfont generated by Font Squirrel. 6 | Copyright : Copyright c 2011 by Tyler Finck All rights reserved 7 | Designer : Tyler Finck 8 | Foundry : Tyler Finck 9 | Foundry URL : httpwwwsurslycom 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-black-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-black-webfont.ttf -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-black-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-black-webfont.woff -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-bold-webfont.eot -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-bold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-bold-webfont.ttf -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-bold-webfont.woff -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-dashed-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-dashed-webfont.eot -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-dashed-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-dashed-webfont.ttf -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-dashed-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-dashed-webfont.woff -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-light-webfont.eot -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-light-webfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a custom SVG webfont generated by Font Squirrel. 6 | Copyright : Copyright c 2011 by Tyler Finck All rights reserved 7 | Designer : Tyler Finck 8 | Foundry : Tyler Finck 9 | Foundry URL : httpwwwsurslycom 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-light-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-light-webfont.ttf -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-light-webfont.woff -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-regular-webfont.eot -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-regular-webfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a custom SVG webfont generated by Font Squirrel. 6 | Copyright : Copyright c 2011 by Tyler Finck All rights reserved 7 | Designer : Tyler Finck 8 | Foundry : Tyler Finck 9 | Foundry URL : httpwwwsurslycom 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-regular-webfont.ttf -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-regular-webfont.woff -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-rounded-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-rounded-webfont.eot -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-rounded-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-rounded-webfont.ttf -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/ostrich-rounded-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dcneiner/jQuery-Bling/494da66d2c854fcfd5bcf67e22857284abc2d9c1/fonts/ostrich-sans-fontfacekit/ostrich-rounded-webfont.woff -------------------------------------------------------------------------------- /fonts/ostrich-sans-fontfacekit/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* Generated by Font Squirrel (http://www.fontsquirrel.com) on July 22, 2011 07:15:32 AM America/New_York */ 2 | 3 | 4 | 5 | @font-face { 6 | font-family: 'OstrichSansCondensedLight'; 7 | src: url('ostrich-light-webfont.eot'); 8 | src: url('ostrich-light-webfont.eot?#iefix') format('embedded-opentype'), 9 | url('ostrich-light-webfont.woff') format('woff'), 10 | url('ostrich-light-webfont.ttf') format('truetype'), 11 | url('ostrich-light-webfont.svg#OstrichSansCondensedLight') format('svg'); 12 | font-weight: normal; 13 | font-style: normal; 14 | 15 | } 16 | 17 | @font-face { 18 | font-family: 'OstrichSansMedium'; 19 | src: url('ostrich-regular-webfont.eot'); 20 | src: url('ostrich-regular-webfont.eot?#iefix') format('embedded-opentype'), 21 | url('ostrich-regular-webfont.woff') format('woff'), 22 | url('ostrich-regular-webfont.ttf') format('truetype'), 23 | url('ostrich-regular-webfont.svg#OstrichSansMedium') format('svg'); 24 | font-weight: normal; 25 | font-style: normal; 26 | 27 | } 28 | 29 | @font-face { 30 | font-family: 'OstrichSansBold'; 31 | src: url('ostrich-bold-webfont.eot'); 32 | src: url('ostrich-bold-webfont.eot?#iefix') format('embedded-opentype'), 33 | url('ostrich-bold-webfont.woff') format('woff'), 34 | url('ostrich-bold-webfont.ttf') format('truetype'), 35 | url('ostrich-bold-webfont.svg#OstrichSansBold') format('svg'); 36 | font-weight: normal; 37 | font-style: normal; 38 | 39 | } 40 | 41 | @font-face { 42 | font-family: 'OstrichSansBlack'; 43 | src: url('ostrich-black-webfont.eot'); 44 | src: url('ostrich-black-webfont.eot?#iefix') format('embedded-opentype'), 45 | url('ostrich-black-webfont.woff') format('woff'), 46 | url('ostrich-black-webfont.ttf') format('truetype'), 47 | url('ostrich-black-webfont.svg#OstrichSansBlack') format('svg'); 48 | font-weight: normal; 49 | font-style: normal; 50 | 51 | } 52 | 53 | @font-face { 54 | font-family: 'OstrichSansRoundedMedium'; 55 | src: url('ostrich-rounded-webfont.eot'); 56 | src: url('ostrich-rounded-webfont.eot?#iefix') format('embedded-opentype'), 57 | url('ostrich-rounded-webfont.woff') format('woff'), 58 | url('ostrich-rounded-webfont.ttf') format('truetype'), 59 | url('ostrich-rounded-webfont.svg#OstrichSansRoundedMedium') format('svg'); 60 | font-weight: normal; 61 | font-style: normal; 62 | 63 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | My Portfolio | John Neiner 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 |
24 |

John Neiner

25 |

Check out some of my Dribbble shots:

26 |
27 | 29 | 32 |
33 | 34 | 35 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /js/libs/jquery.ba-dotimeout.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery doTimeout: Like setTimeout, but better! - v1.0 - 3/3/2010 3 | * http://benalman.com/projects/jquery-dotimeout-plugin/ 4 | * 5 | * Copyright (c) 2010 "Cowboy" Ben Alman 6 | * Dual licensed under the MIT and GPL licenses. 7 | * http://benalman.com/about/license/ 8 | */ 9 | 10 | // Script: jQuery doTimeout: Like setTimeout, but better! 11 | // 12 | // *Version: 1.0, Last updated: 3/3/2010* 13 | // 14 | // Project Home - http://benalman.com/projects/jquery-dotimeout-plugin/ 15 | // GitHub - http://github.com/cowboy/jquery-dotimeout/ 16 | // Source - http://github.com/cowboy/jquery-dotimeout/raw/master/jquery.ba-dotimeout.js 17 | // (Minified) - http://github.com/cowboy/jquery-dotimeout/raw/master/jquery.ba-dotimeout.min.js (1.0kb) 18 | // 19 | // About: License 20 | // 21 | // Copyright (c) 2010 "Cowboy" Ben Alman, 22 | // Dual licensed under the MIT and GPL licenses. 23 | // http://benalman.com/about/license/ 24 | // 25 | // About: Examples 26 | // 27 | // These working examples, complete with fully commented code, illustrate a few 28 | // ways in which this plugin can be used. 29 | // 30 | // Debouncing - http://benalman.com/code/projects/jquery-dotimeout/examples/debouncing/ 31 | // Delays, Polling - http://benalman.com/code/projects/jquery-dotimeout/examples/delay-poll/ 32 | // Hover Intent - http://benalman.com/code/projects/jquery-dotimeout/examples/hoverintent/ 33 | // 34 | // About: Support and Testing 35 | // 36 | // Information about what version or versions of jQuery this plugin has been 37 | // tested with, what browsers it has been tested in, and where the unit tests 38 | // reside (so you can test it yourself). 39 | // 40 | // jQuery Versions - 1.3.2, 1.4.2 41 | // Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome 4-5, Opera 9.6-10.1. 42 | // Unit Tests - http://benalman.com/code/projects/jquery-dotimeout/unit/ 43 | // 44 | // About: Release History 45 | // 46 | // 1.0 - (3/3/2010) Callback can now be a string, in which case it will call 47 | // the appropriate $.method or $.fn.method, depending on where .doTimeout 48 | // was called. Callback must now return `true` (not just a truthy value) 49 | // to poll. 50 | // 0.4 - (7/15/2009) Made the "id" argument optional, some other minor tweaks 51 | // 0.3 - (6/25/2009) Initial release 52 | 53 | (function($){ 54 | '$:nomunge'; // Used by YUI compressor. 55 | 56 | var cache = {}, 57 | 58 | // Reused internal string. 59 | doTimeout = 'doTimeout', 60 | 61 | // A convenient shortcut. 62 | aps = Array.prototype.slice; 63 | 64 | // Method: jQuery.doTimeout 65 | // 66 | // Initialize, cancel, or force execution of a callback after a delay. 67 | // 68 | // If delay and callback are specified, a doTimeout is initialized. The 69 | // callback will execute, asynchronously, after the delay. If an id is 70 | // specified, this doTimeout will override and cancel any existing doTimeout 71 | // with the same id. Any additional arguments will be passed into callback 72 | // when it is executed. 73 | // 74 | // If the callback returns true, the doTimeout loop will execute again, after 75 | // the delay, creating a polling loop until the callback returns a non-true 76 | // value. 77 | // 78 | // Note that if an id is not passed as the first argument, this doTimeout will 79 | // NOT be able to be manually canceled or forced. (for debouncing, be sure to 80 | // specify an id). 81 | // 82 | // If id is specified, but delay and callback are not, the doTimeout will be 83 | // canceled without executing the callback. If force_mode is specified, the 84 | // callback will be executed, synchronously, but will only be allowed to 85 | // continue a polling loop if force_mode is true (provided the callback 86 | // returns true, of course). If force_mode is false, no polling loop will 87 | // continue, even if the callback returns true. 88 | // 89 | // Usage: 90 | // 91 | // > jQuery.doTimeout( [ id, ] delay, callback [, arg ... ] ); 92 | // > jQuery.doTimeout( id [, force_mode ] ); 93 | // 94 | // Arguments: 95 | // 96 | // id - (String) An optional unique identifier for this doTimeout. If id is 97 | // not specified, the doTimeout will NOT be able to be manually canceled or 98 | // forced. 99 | // delay - (Number) A zero-or-greater delay in milliseconds after which 100 | // callback will be executed. 101 | // callback - (Function) A function to be executed after delay milliseconds. 102 | // callback - (String) A jQuery method to be executed after delay 103 | // milliseconds. This method will only poll if it explicitly returns 104 | // true. 105 | // force_mode - (Boolean) If true, execute that id's doTimeout callback 106 | // immediately and synchronously, continuing any callback return-true 107 | // polling loop. If false, execute the callback immediately and 108 | // synchronously but do NOT continue a callback return-true polling loop. 109 | // If omitted, cancel that id's doTimeout. 110 | // 111 | // Returns: 112 | // 113 | // If force_mode is true, false or undefined and there is a 114 | // yet-to-be-executed callback to cancel, true is returned, but if no 115 | // callback remains to be executed, undefined is returned. 116 | 117 | $[doTimeout] = function() { 118 | return p_doTimeout.apply( window, [ 0 ].concat( aps.call( arguments ) ) ); 119 | }; 120 | 121 | // Method: jQuery.fn.doTimeout 122 | // 123 | // Initialize, cancel, or force execution of a callback after a delay. 124 | // Operates like , but the passed callback executes in the 125 | // context of the jQuery collection of elements, and the id is stored as data 126 | // on the first element in that collection. 127 | // 128 | // If delay and callback are specified, a doTimeout is initialized. The 129 | // callback will execute, asynchronously, after the delay. If an id is 130 | // specified, this doTimeout will override and cancel any existing doTimeout 131 | // with the same id. Any additional arguments will be passed into callback 132 | // when it is executed. 133 | // 134 | // If the callback returns true, the doTimeout loop will execute again, after 135 | // the delay, creating a polling loop until the callback returns a non-true 136 | // value. 137 | // 138 | // Note that if an id is not passed as the first argument, this doTimeout will 139 | // NOT be able to be manually canceled or forced (for debouncing, be sure to 140 | // specify an id). 141 | // 142 | // If id is specified, but delay and callback are not, the doTimeout will be 143 | // canceled without executing the callback. If force_mode is specified, the 144 | // callback will be executed, synchronously, but will only be allowed to 145 | // continue a polling loop if force_mode is true (provided the callback 146 | // returns true, of course). If force_mode is false, no polling loop will 147 | // continue, even if the callback returns true. 148 | // 149 | // Usage: 150 | // 151 | // > jQuery('selector').doTimeout( [ id, ] delay, callback [, arg ... ] ); 152 | // > jQuery('selector').doTimeout( id [, force_mode ] ); 153 | // 154 | // Arguments: 155 | // 156 | // id - (String) An optional unique identifier for this doTimeout, stored as 157 | // jQuery data on the element. If id is not specified, the doTimeout will 158 | // NOT be able to be manually canceled or forced. 159 | // delay - (Number) A zero-or-greater delay in milliseconds after which 160 | // callback will be executed. 161 | // callback - (Function) A function to be executed after delay milliseconds. 162 | // callback - (String) A jQuery.fn method to be executed after delay 163 | // milliseconds. This method will only poll if it explicitly returns 164 | // true (most jQuery.fn methods return a jQuery object, and not `true`, 165 | // which allows them to be chained and prevents polling). 166 | // force_mode - (Boolean) If true, execute that id's doTimeout callback 167 | // immediately and synchronously, continuing any callback return-true 168 | // polling loop. If false, execute the callback immediately and 169 | // synchronously but do NOT continue a callback return-true polling loop. 170 | // If omitted, cancel that id's doTimeout. 171 | // 172 | // Returns: 173 | // 174 | // When creating a , the initial jQuery collection of 175 | // elements is returned. Otherwise, if force_mode is true, false or undefined 176 | // and there is a yet-to-be-executed callback to cancel, true is returned, 177 | // but if no callback remains to be executed, undefined is returned. 178 | 179 | $.fn[doTimeout] = function() { 180 | var args = aps.call( arguments ), 181 | result = p_doTimeout.apply( this, [ doTimeout + args[0] ].concat( args ) ); 182 | 183 | return typeof args[0] === 'number' || typeof args[1] === 'number' 184 | ? this 185 | : result; 186 | }; 187 | 188 | function p_doTimeout( jquery_data_key ) { 189 | var that = this, 190 | elem, 191 | data = {}, 192 | 193 | // Allows the plugin to call a string callback method. 194 | method_base = jquery_data_key ? $.fn : $, 195 | 196 | // Any additional arguments will be passed to the callback. 197 | args = arguments, 198 | slice_args = 4, 199 | 200 | id = args[1], 201 | delay = args[2], 202 | callback = args[3]; 203 | 204 | if ( typeof id !== 'string' ) { 205 | slice_args--; 206 | 207 | id = jquery_data_key = 0; 208 | delay = args[1]; 209 | callback = args[2]; 210 | } 211 | 212 | // If id is passed, store a data reference either as .data on the first 213 | // element in a jQuery collection, or in the internal cache. 214 | if ( jquery_data_key ) { // Note: key is 'doTimeout' + id 215 | 216 | // Get id-object from the first element's data, otherwise initialize it to {}. 217 | elem = that.eq(0); 218 | elem.data( jquery_data_key, data = elem.data( jquery_data_key ) || {} ); 219 | 220 | } else if ( id ) { 221 | // Get id-object from the cache, otherwise initialize it to {}. 222 | data = cache[ id ] || ( cache[ id ] = {} ); 223 | } 224 | 225 | // Clear any existing timeout for this id. 226 | data.id && clearTimeout( data.id ); 227 | delete data.id; 228 | 229 | // Clean up when necessary. 230 | function cleanup() { 231 | if ( jquery_data_key ) { 232 | elem.removeData( jquery_data_key ); 233 | } else if ( id ) { 234 | delete cache[ id ]; 235 | } 236 | }; 237 | 238 | // Yes, there actually is a setTimeout call in here! 239 | function actually_setTimeout() { 240 | data.id = setTimeout( function(){ data.fn(); }, delay ); 241 | }; 242 | 243 | if ( callback ) { 244 | // A callback (and delay) were specified. Store the callback reference for 245 | // possible later use, and then setTimeout. 246 | data.fn = function( no_polling_loop ) { 247 | 248 | // If the callback value is a string, it is assumed to be the name of a 249 | // method on $ or $.fn depending on where doTimeout was executed. 250 | if ( typeof callback === 'string' ) { 251 | callback = method_base[ callback ]; 252 | } 253 | 254 | callback.apply( that, aps.call( args, slice_args ) ) === true && !no_polling_loop 255 | 256 | // Since the callback returned true, and we're not specifically 257 | // canceling a polling loop, do it again! 258 | ? actually_setTimeout() 259 | 260 | // Otherwise, clean up and quit. 261 | : cleanup(); 262 | }; 263 | 264 | // Set that timeout! 265 | actually_setTimeout(); 266 | 267 | } else if ( data.fn ) { 268 | // No callback passed. If force_mode (delay) is true, execute the data.fn 269 | // callback immediately, continuing any callback return-true polling loop. 270 | // If force_mode is false, execute the data.fn callback immediately but do 271 | // NOT continue a callback return-true polling loop. If force_mode is 272 | // undefined, simply clean up. Since data.fn was still defined, whatever 273 | // was supposed to happen hadn't yet, so return true. 274 | delay === undefined ? cleanup() : data.fn( delay === false ); 275 | return true; 276 | 277 | } else { 278 | // Since no callback was passed, and data.fn isn't defined, it looks like 279 | // whatever was supposed to happen already did. Clean up and quit! 280 | cleanup(); 281 | } 282 | 283 | }; 284 | 285 | })(jQuery); 286 | -------------------------------------------------------------------------------- /js/libs/jquery.mockjax.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * MockJax - jQuery Plugin to Mock Ajax requests 3 | * 4 | * Version: 1.4.0 5 | * Released: 2011-02-04 6 | * Source: http://github.com/appendto/jquery-mockjax 7 | * Docs: http://enterprisejquery.com/2010/07/mock-your-ajax-requests-with-mockjax-for-rapid-development 8 | * Plugin: mockjax 9 | * Author: Jonathan Sharp (http://jdsharp.com) 10 | * License: MIT,GPL 11 | * 12 | * Copyright (c) 2010 appendTo LLC. 13 | * Dual licensed under the MIT or GPL licenses. 14 | * http://appendto.com/open-source-licenses 15 | */ 16 | (function($) { 17 | var _ajax = $.ajax, 18 | mockHandlers = []; 19 | 20 | function parseXML(xml) { 21 | if ( window['DOMParser'] == undefined && window.ActiveXObject ) { 22 | DOMParser = function() { }; 23 | DOMParser.prototype.parseFromString = function( xmlString ) { 24 | var doc = new ActiveXObject('Microsoft.XMLDOM'); 25 | doc.async = 'false'; 26 | doc.loadXML( xmlString ); 27 | return doc; 28 | }; 29 | } 30 | 31 | try { 32 | var xmlDoc = ( new DOMParser() ).parseFromString( xml, 'text/xml' ); 33 | if ( $.isXMLDoc( xmlDoc ) ) { 34 | var err = $('parsererror', xmlDoc); 35 | if ( err.length == 1 ) { 36 | throw('Error: ' + $(xmlDoc).text() ); 37 | } 38 | } else { 39 | throw('Unable to parse XML'); 40 | } 41 | } catch( e ) { 42 | var msg = ( e.name == undefined ? e : e.name + ': ' + e.message ); 43 | $(document).trigger('xmlParseError', [ msg ]); 44 | return undefined; 45 | } 46 | return xmlDoc; 47 | } 48 | 49 | $.extend({ 50 | ajax: function(origSettings) { 51 | var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings), 52 | mock = false; 53 | // Iterate over our mock handlers (in registration order) until we find 54 | // one that is willing to intercept the request 55 | $.each(mockHandlers, function(k, v) { 56 | if ( !mockHandlers[k] ) { 57 | return; 58 | } 59 | var m = null; 60 | // If the mock was registered with a function, let the function decide if we 61 | // want to mock this request 62 | if ( $.isFunction(mockHandlers[k]) ) { 63 | m = mockHandlers[k](s); 64 | } else { 65 | m = mockHandlers[k]; 66 | // Inspect the URL of the request and check if the mock handler's url 67 | // matches the url for this ajax request 68 | if ( $.isFunction(m.url.test) ) { 69 | // The user provided a regex for the url, test it 70 | if ( !m.url.test( s.url ) ) { 71 | m = null; 72 | } 73 | } else { 74 | // Look for a simple wildcard '*' or a direct URL match 75 | var star = m.url.indexOf('*'); 76 | if ( ( m.url != '*' && m.url != s.url && star == -1 ) || 77 | ( star > -1 && m.url.substr(0, star) != s.url.substr(0, star) ) ) { 78 | // The url we tested did not match the wildcard * 79 | m = null; 80 | } 81 | } 82 | if ( m ) { 83 | // Inspect the data submitted in the request (either POST body or GET query string) 84 | if ( m.data && s.data ) { 85 | var identical = false; 86 | // Deep inspect the identity of the objects 87 | (function ident(mock, live) { 88 | // Test for situations where the data is a querystring (not an object) 89 | if (typeof live === 'string') { 90 | // Querystring may be a regex 91 | identical = $.isFunction( mock.test ) ? mock.test(live) : mock == live; 92 | return identical; 93 | } 94 | $.each(mock, function(k, v) { 95 | if ( live[k] === undefined ) { 96 | identical = false; 97 | return false; 98 | } else { 99 | identical = true; 100 | if ( typeof live[k] == 'object' ) { 101 | return ident(mock[k], live[k]); 102 | } else { 103 | if ( $.isFunction( mock[k].test ) ) { 104 | identical = mock[k].test(live[k]); 105 | } else { 106 | identical = ( mock[k] == live[k] ); 107 | } 108 | return identical; 109 | } 110 | } 111 | }); 112 | })(m.data, s.data); 113 | // They're not identical, do not mock this request 114 | if ( identical == false ) { 115 | m = null; 116 | } 117 | } 118 | // Inspect the request type 119 | if ( m && m.type && m.type != s.type ) { 120 | // The request type doesn't match (GET vs. POST) 121 | m = null; 122 | } 123 | } 124 | } 125 | if ( m ) { 126 | mock = true; 127 | 128 | // Handle console logging 129 | var c = $.extend({}, $.mockjaxSettings, m); 130 | if ( c.log && $.isFunction(c.log) ) { 131 | c.log('MOCK ' + s.type.toUpperCase() + ': ' + s.url, $.extend({}, s)); 132 | } 133 | 134 | var jsre = /=\?(&|$)/, jsc = (new Date()).getTime(); 135 | 136 | // Handle JSONP Parameter Callbacks, we need to replicate some of the jQuery core here 137 | // because there isn't an easy hook for the cross domain script tag of jsonp 138 | if ( s.dataType === "jsonp" ) { 139 | if ( s.type.toUpperCase() === "GET" ) { 140 | if ( !jsre.test( s.url ) ) { 141 | s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?"; 142 | } 143 | } else if ( !s.data || !jsre.test(s.data) ) { 144 | s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; 145 | } 146 | s.dataType = "json"; 147 | } 148 | 149 | // Build temporary JSONP function 150 | if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) { 151 | jsonp = s.jsonpCallback || ("jsonp" + jsc++); 152 | 153 | // Replace the =? sequence both in the query string and the data 154 | if ( s.data ) { 155 | s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1"); 156 | } 157 | 158 | s.url = s.url.replace(jsre, "=" + jsonp + "$1"); 159 | 160 | // We need to make sure 161 | // that a JSONP style response is executed properly 162 | s.dataType = "script"; 163 | 164 | // Handle JSONP-style loading 165 | window[ jsonp ] = window[ jsonp ] || function( tmp ) { 166 | data = tmp; 167 | success(); 168 | complete(); 169 | // Garbage collect 170 | window[ jsonp ] = undefined; 171 | 172 | try { 173 | delete window[ jsonp ]; 174 | } catch(e) {} 175 | 176 | if ( head ) { 177 | head.removeChild( script ); 178 | } 179 | }; 180 | } 181 | 182 | var rurl = /^(\w+:)?\/\/([^\/?#]+)/, 183 | parts = rurl.exec( s.url ), 184 | remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host); 185 | 186 | // Test if we are going to create a script tag (if so, intercept & mock) 187 | if ( s.dataType === "script" && s.type.toUpperCase() === "GET" && remote ) { 188 | // Synthesize the mock request for adding a script tag 189 | var callbackContext = origSettings && origSettings.context || s; 190 | 191 | function success() { 192 | // If a local callback was specified, fire it and pass it the data 193 | if ( s.success ) { 194 | s.success.call( callbackContext, ( m.response ? m.response.toString() : m.responseText || ''), status, {} ); 195 | } 196 | 197 | // Fire the global callback 198 | if ( s.global ) { 199 | trigger( "ajaxSuccess", [{}, s] ); 200 | } 201 | } 202 | 203 | function complete() { 204 | // Process result 205 | if ( s.complete ) { 206 | s.complete.call( callbackContext, {} , status ); 207 | } 208 | 209 | // The request was completed 210 | if ( s.global ) { 211 | trigger( "ajaxComplete", [{}, s] ); 212 | } 213 | 214 | // Handle the global AJAX counter 215 | if ( s.global && ! --jQuery.active ) { 216 | jQuery.event.trigger( "ajaxStop" ); 217 | } 218 | } 219 | 220 | function trigger(type, args) { 221 | (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args); 222 | } 223 | 224 | if ( m.response && $.isFunction(m.response) ) { 225 | m.response(origSettings); 226 | } else { 227 | $.globalEval(m.responseText); 228 | } 229 | success(); 230 | complete(); 231 | return false; 232 | } 233 | mock = _ajax.call($, $.extend(true, {}, origSettings, { 234 | // Mock the XHR object 235 | xhr: function() { 236 | // Extend with our default mockjax settings 237 | m = $.extend({}, $.mockjaxSettings, m); 238 | 239 | if ( m.contentType ) { 240 | m.headers['content-type'] = m.contentType; 241 | } 242 | 243 | // Return our mock xhr object 244 | return { 245 | status: m.status, 246 | readyState: 1, 247 | open: function() { }, 248 | send: function() { 249 | // This is a substitute for < 1.4 which lacks $.proxy 250 | var process = (function(that) { 251 | return function() { 252 | return (function() { 253 | // The request has returned 254 | this.status = m.status; 255 | this.readyState = 4; 256 | 257 | // We have an executable function, call it to give 258 | // the mock handler a chance to update it's data 259 | if ( $.isFunction(m.response) ) { 260 | m.response(origSettings); 261 | } 262 | // Copy over our mock to our xhr object before passing control back to 263 | // jQuery's onreadystatechange callback 264 | if ( s.dataType == 'json' && ( typeof m.responseText == 'object' ) ) { 265 | this.responseText = JSON.stringify(m.responseText); 266 | } else if ( s.dataType == 'xml' ) { 267 | if ( typeof m.responseXML == 'string' ) { 268 | this.responseXML = parseXML(m.responseXML); 269 | } else { 270 | this.responseXML = m.responseXML; 271 | } 272 | } else { 273 | this.responseText = m.responseText; 274 | } 275 | // jQuery < 1.4 doesn't have onreadystate change for xhr 276 | if ( $.isFunction(this.onreadystatechange) ) { 277 | this.onreadystatechange( m.isTimeout ? 'timeout' : undefined ); 278 | } 279 | }).apply(that); 280 | }; 281 | })(this); 282 | 283 | if ( m.proxy ) { 284 | // We're proxying this request and loading in an external file instead 285 | _ajax({ 286 | global: false, 287 | url: m.proxy, 288 | type: m.proxyType, 289 | data: m.data, 290 | dataType: s.dataType, 291 | complete: function(xhr, txt) { 292 | m.responseXML = xhr.responseXML; 293 | m.responseText = xhr.responseText; 294 | this.responseTimer = setTimeout(process, m.responseTime || 0); 295 | } 296 | }); 297 | } else { 298 | // type == 'POST' || 'GET' || 'DELETE' 299 | if ( s.async === false ) { 300 | // TODO: Blocking delay 301 | process(); 302 | } else { 303 | this.responseTimer = setTimeout(process, m.responseTime || 50); 304 | } 305 | } 306 | }, 307 | abort: function() { 308 | clearTimeout(this.responseTimer); 309 | }, 310 | setRequestHeader: function() { }, 311 | getResponseHeader: function(header) { 312 | // 'Last-modified', 'Etag', 'content-type' are all checked by jQuery 313 | if ( m.headers && m.headers[header] ) { 314 | // Return arbitrary headers 315 | return m.headers[header]; 316 | } else if ( header.toLowerCase() == 'last-modified' ) { 317 | return m.lastModified || (new Date()).toString(); 318 | } else if ( header.toLowerCase() == 'etag' ) { 319 | return m.etag || ''; 320 | } else if ( header.toLowerCase() == 'content-type' ) { 321 | return m.contentType || 'text/plain'; 322 | } 323 | }, 324 | getAllResponseHeaders: function() { 325 | var headers = ''; 326 | $.each(m.headers, function(k, v) { 327 | headers += k + ': ' + v + "\n"; 328 | }); 329 | return headers; 330 | } 331 | }; 332 | } 333 | })); 334 | return false; 335 | } 336 | }); 337 | // We don't have a mock request, trigger a normal request 338 | if ( !mock ) { 339 | return _ajax.apply($, arguments); 340 | } else { 341 | return mock; 342 | } 343 | } 344 | }); 345 | 346 | $.mockjaxSettings = { 347 | //url: null, 348 | //type: 'GET', 349 | log: function(msg) { 350 | window['console'] && window.console.log && window.console.log(msg); 351 | }, 352 | status: 200, 353 | responseTime: 500, 354 | isTimeout: false, 355 | contentType: 'text/plain', 356 | response: '', 357 | responseText: '', 358 | responseXML: '', 359 | proxy: '', 360 | proxyType: 'GET', 361 | 362 | lastModified: null, 363 | etag: '', 364 | headers: { 365 | etag: 'IJF@H#@923uf8023hFO@I#H#', 366 | 'content-type' : 'text/plain' 367 | } 368 | }; 369 | 370 | $.mockjax = function(settings) { 371 | var i = mockHandlers.length; 372 | mockHandlers[i] = settings; 373 | return i; 374 | }; 375 | $.mockjaxClear = function(i) { 376 | if ( arguments.length == 1 ) { 377 | mockHandlers[i] = null; 378 | } else { 379 | mockHandlers = []; 380 | } 381 | }; 382 | })(jQuery); 383 | -------------------------------------------------------------------------------- /js/libs/jquery.tmpl.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Templates Plugin 3 | * http://github.com/jquery/jquery-tmpl 4 | * 5 | * Copyright Software Freedom Conservancy, Inc. 6 | * Dual licensed under the MIT or GPL Version 2 licenses. 7 | * http://jquery.org/license 8 | */ 9 | (function( jQuery, undefined ){ 10 | var oldManip = jQuery.fn.domManip, tmplItmAtt = "_tmplitem", htmlExpr = /^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /, 11 | newTmplItems = {}, wrappedItems = {}, appendToTmplItems, topTmplItem = { key: 0, data: {} }, itemKey = 0, cloneIndex = 0, stack = []; 12 | 13 | function newTmplItem( options, parentItem, fn, data ) { 14 | // Returns a template item data structure for a new rendered instance of a template (a 'template item'). 15 | // The content field is a hierarchical array of strings and nested items (to be 16 | // removed and replaced by nodes field of dom elements, once inserted in DOM). 17 | var newItem = { 18 | data: data || (parentItem ? parentItem.data : {}), 19 | _wrap: parentItem ? parentItem._wrap : null, 20 | tmpl: null, 21 | parent: parentItem || null, 22 | nodes: [], 23 | calls: tiCalls, 24 | nest: tiNest, 25 | wrap: tiWrap, 26 | html: tiHtml, 27 | update: tiUpdate 28 | }; 29 | if ( options ) { 30 | jQuery.extend( newItem, options, { nodes: [], parent: parentItem } ); 31 | } 32 | if ( fn ) { 33 | // Build the hierarchical content to be used during insertion into DOM 34 | newItem.tmpl = fn; 35 | newItem._ctnt = newItem._ctnt || newItem.tmpl( jQuery, newItem ); 36 | newItem.key = ++itemKey; 37 | // Keep track of new template item, until it is stored as jQuery Data on DOM element 38 | (stack.length ? wrappedItems : newTmplItems)[itemKey] = newItem; 39 | } 40 | return newItem; 41 | } 42 | 43 | // Override appendTo etc., in order to provide support for targeting multiple elements. (This code would disappear if integrated in jquery core). 44 | jQuery.each({ 45 | appendTo: "append", 46 | prependTo: "prepend", 47 | insertBefore: "before", 48 | insertAfter: "after", 49 | replaceAll: "replaceWith" 50 | }, function( name, original ) { 51 | jQuery.fn[ name ] = function( selector ) { 52 | var ret = [], insert = jQuery( selector ), elems, i, l, tmplItems, 53 | parent = this.length === 1 && this[0].parentNode; 54 | 55 | appendToTmplItems = newTmplItems || {}; 56 | if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) { 57 | insert[ original ]( this[0] ); 58 | ret = this; 59 | } else { 60 | for ( i = 0, l = insert.length; i < l; i++ ) { 61 | cloneIndex = i; 62 | elems = (i > 0 ? this.clone(true) : this).get(); 63 | jQuery.fn[ original ].apply( jQuery(insert[i]), elems ); 64 | ret = ret.concat( elems ); 65 | } 66 | cloneIndex = 0; 67 | ret = this.pushStack( ret, name, insert.selector ); 68 | } 69 | tmplItems = appendToTmplItems; 70 | appendToTmplItems = null; 71 | jQuery.tmpl.complete( tmplItems ); 72 | return ret; 73 | }; 74 | }); 75 | 76 | jQuery.fn.extend({ 77 | // Use first wrapped element as template markup. 78 | // Return wrapped set of template items, obtained by rendering template against data. 79 | tmpl: function( data, options, parentItem ) { 80 | return jQuery.tmpl( this[0], data, options, parentItem ); 81 | }, 82 | 83 | // Find which rendered template item the first wrapped DOM element belongs to 84 | tmplItem: function() { 85 | return jQuery.tmplItem( this[0] ); 86 | }, 87 | 88 | // Consider the first wrapped element as a template declaration, and get the compiled template or store it as a named template. 89 | template: function( name ) { 90 | return jQuery.template( name, this[0] ); 91 | }, 92 | 93 | domManip: function( args, table, callback, options ) { 94 | // This appears to be a bug in the appendTo, etc. implementation 95 | // it should be doing .call() instead of .apply(). See #6227 96 | if ( args[0] && args[0].nodeType ) { 97 | var dmArgs = jQuery.makeArray( arguments ), argsLength = args.length, i = 0, tmplItem; 98 | while ( i < argsLength && !(tmplItem = jQuery.data( args[i++], "tmplItem" ))) {} 99 | if ( argsLength > 1 ) { 100 | dmArgs[0] = [jQuery.makeArray( args )]; 101 | } 102 | if ( tmplItem && cloneIndex ) { 103 | dmArgs[2] = function( fragClone ) { 104 | // Handler called by oldManip when rendered template has been inserted into DOM. 105 | jQuery.tmpl.afterManip( this, fragClone, callback ); 106 | }; 107 | } 108 | oldManip.apply( this, dmArgs ); 109 | } else { 110 | oldManip.apply( this, arguments ); 111 | } 112 | cloneIndex = 0; 113 | if ( !appendToTmplItems ) { 114 | jQuery.tmpl.complete( newTmplItems ); 115 | } 116 | return this; 117 | } 118 | }); 119 | 120 | jQuery.extend({ 121 | // Return wrapped set of template items, obtained by rendering template against data. 122 | tmpl: function( tmpl, data, options, parentItem ) { 123 | var ret, topLevel = !parentItem; 124 | if ( topLevel ) { 125 | // This is a top-level tmpl call (not from a nested template using {{tmpl}}) 126 | parentItem = topTmplItem; 127 | tmpl = jQuery.template[tmpl] || jQuery.template( null, tmpl ); 128 | wrappedItems = {}; // Any wrapped items will be rebuilt, since this is top level 129 | } else if ( !tmpl ) { 130 | // The template item is already associated with DOM - this is a refresh. 131 | // Re-evaluate rendered template for the parentItem 132 | tmpl = parentItem.tmpl; 133 | newTmplItems[parentItem.key] = parentItem; 134 | parentItem.nodes = []; 135 | if ( parentItem.wrapped ) { 136 | updateWrapped( parentItem, parentItem.wrapped ); 137 | } 138 | // Rebuild, without creating a new template item 139 | return jQuery( build( parentItem, null, parentItem.tmpl( jQuery, parentItem ) )); 140 | } 141 | if ( !tmpl ) { 142 | return []; // Could throw... 143 | } 144 | if ( typeof data === "function" ) { 145 | data = data.call( parentItem || {} ); 146 | } 147 | if ( options && options.wrapped ) { 148 | updateWrapped( options, options.wrapped ); 149 | } 150 | ret = jQuery.isArray( data ) ? 151 | jQuery.map( data, function( dataItem ) { 152 | return dataItem ? newTmplItem( options, parentItem, tmpl, dataItem ) : null; 153 | }) : 154 | [ newTmplItem( options, parentItem, tmpl, data ) ]; 155 | return topLevel ? jQuery( build( parentItem, null, ret ) ) : ret; 156 | }, 157 | 158 | // Return rendered template item for an element. 159 | tmplItem: function( elem ) { 160 | var tmplItem; 161 | if ( elem instanceof jQuery ) { 162 | elem = elem[0]; 163 | } 164 | while ( elem && elem.nodeType === 1 && !(tmplItem = jQuery.data( elem, "tmplItem" )) && (elem = elem.parentNode) ) {} 165 | return tmplItem || topTmplItem; 166 | }, 167 | 168 | // Set: 169 | // Use $.template( name, tmpl ) to cache a named template, 170 | // where tmpl is a template string, a script element or a jQuery instance wrapping a script element, etc. 171 | // Use $( "selector" ).template( name ) to provide access by name to a script block template declaration. 172 | 173 | // Get: 174 | // Use $.template( name ) to access a cached template. 175 | // Also $( selectorToScriptBlock ).template(), or $.template( null, templateString ) 176 | // will return the compiled template, without adding a name reference. 177 | // If templateString includes at least one HTML tag, $.template( templateString ) is equivalent 178 | // to $.template( null, templateString ) 179 | template: function( name, tmpl ) { 180 | if (tmpl) { 181 | // Compile template and associate with name 182 | if ( typeof tmpl === "string" ) { 183 | // This is an HTML string being passed directly in. 184 | tmpl = buildTmplFn( tmpl ) 185 | } else if ( tmpl instanceof jQuery ) { 186 | tmpl = tmpl[0] || {}; 187 | } 188 | if ( tmpl.nodeType ) { 189 | // If this is a template block, use cached copy, or generate tmpl function and cache. 190 | tmpl = jQuery.data( tmpl, "tmpl" ) || jQuery.data( tmpl, "tmpl", buildTmplFn( tmpl.innerHTML )); 191 | } 192 | return typeof name === "string" ? (jQuery.template[name] = tmpl) : tmpl; 193 | } 194 | // Return named compiled template 195 | return name ? (typeof name !== "string" ? jQuery.template( null, name ): 196 | (jQuery.template[name] || 197 | // If not in map, treat as a selector. (If integrated with core, use quickExpr.exec) 198 | jQuery.template( null, htmlExpr.test( name ) ? name : jQuery( name )))) : null; 199 | }, 200 | 201 | encode: function( text ) { 202 | // Do HTML encoding replacing < > & and ' and " by corresponding entities. 203 | return ("" + text).split("<").join("<").split(">").join(">").split('"').join(""").split("'").join("'"); 204 | } 205 | }); 206 | 207 | jQuery.extend( jQuery.tmpl, { 208 | tag: { 209 | "tmpl": { 210 | _default: { $2: "null" }, 211 | open: "if($notnull_1){_=_.concat($item.nest($1,$2));}" 212 | // tmpl target parameter can be of type function, so use $1, not $1a (so not auto detection of functions) 213 | // This means that {{tmpl foo}} treats foo as a template (which IS a function). 214 | // Explicit parens can be used if foo is a function that returns a template: {{tmpl foo()}}. 215 | }, 216 | "wrap": { 217 | _default: { $2: "null" }, 218 | open: "$item.calls(_,$1,$2);_=[];", 219 | close: "call=$item.calls();_=call._.concat($item.wrap(call,_));" 220 | }, 221 | "each": { 222 | _default: { $2: "$index, $value" }, 223 | open: "if($notnull_1){$.each($1a,function($2){with(this){", 224 | close: "}});}" 225 | }, 226 | "if": { 227 | open: "if(($notnull_1) && $1a){", 228 | close: "}" 229 | }, 230 | "else": { 231 | _default: { $1: "true" }, 232 | open: "}else if(($notnull_1) && $1a){" 233 | }, 234 | "html": { 235 | // Unecoded expression evaluation. 236 | open: "if($notnull_1){_.push($1a);}" 237 | }, 238 | "=": { 239 | // Encoded expression evaluation. Abbreviated form is ${}. 240 | _default: { $1: "$data" }, 241 | open: "if($notnull_1){_.push($.encode($1a));}" 242 | }, 243 | "!": { 244 | // Comment tag. Skipped by parser 245 | open: "" 246 | } 247 | }, 248 | 249 | // This stub can be overridden, e.g. in jquery.tmplPlus for providing rendered events 250 | complete: function( items ) { 251 | newTmplItems = {}; 252 | }, 253 | 254 | // Call this from code which overrides domManip, or equivalent 255 | // Manage cloning/storing template items etc. 256 | afterManip: function afterManip( elem, fragClone, callback ) { 257 | // Provides cloned fragment ready for fixup prior to and after insertion into DOM 258 | var content = fragClone.nodeType === 11 ? 259 | jQuery.makeArray(fragClone.childNodes) : 260 | fragClone.nodeType === 1 ? [fragClone] : []; 261 | 262 | // Return fragment to original caller (e.g. append) for DOM insertion 263 | callback.call( elem, fragClone ); 264 | 265 | // Fragment has been inserted:- Add inserted nodes to tmplItem data structure. Replace inserted element annotations by jQuery.data. 266 | storeTmplItems( content ); 267 | cloneIndex++; 268 | } 269 | }); 270 | 271 | //========================== Private helper functions, used by code above ========================== 272 | 273 | function build( tmplItem, nested, content ) { 274 | // Convert hierarchical content into flat string array 275 | // and finally return array of fragments ready for DOM insertion 276 | var frag, ret = content ? jQuery.map( content, function( item ) { 277 | return (typeof item === "string") ? 278 | // Insert template item annotations, to be converted to jQuery.data( "tmplItem" ) when elems are inserted into DOM. 279 | (tmplItem.key ? item.replace( /(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g, "$1 " + tmplItmAtt + "=\"" + tmplItem.key + "\" $2" ) : item) : 280 | // This is a child template item. Build nested template. 281 | build( item, tmplItem, item._ctnt ); 282 | }) : 283 | // If content is not defined, insert tmplItem directly. Not a template item. May be a string, or a string array, e.g. from {{html $item.html()}}. 284 | tmplItem; 285 | if ( nested ) { 286 | return ret; 287 | } 288 | 289 | // top-level template 290 | ret = ret.join(""); 291 | 292 | // Support templates which have initial or final text nodes, or consist only of text 293 | // Also support HTML entities within the HTML markup. 294 | ret.replace( /^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/, function( all, before, middle, after) { 295 | frag = jQuery( middle ).get(); 296 | 297 | storeTmplItems( frag ); 298 | if ( before ) { 299 | frag = unencode( before ).concat(frag); 300 | } 301 | if ( after ) { 302 | frag = frag.concat(unencode( after )); 303 | } 304 | }); 305 | return frag ? frag : unencode( ret ); 306 | } 307 | 308 | function unencode( text ) { 309 | // Use createElement, since createTextNode will not render HTML entities correctly 310 | var el = document.createElement( "div" ); 311 | el.innerHTML = text; 312 | return jQuery.makeArray(el.childNodes); 313 | } 314 | 315 | // Generate a reusable function that will serve to render a template against data 316 | function buildTmplFn( markup ) { 317 | return new Function("jQuery","$item", 318 | "var $=jQuery,call,_=[],$data=$item.data;" + 319 | 320 | // Introduce the data as local variables using with(){} 321 | "with($data){_.push('" + 322 | 323 | // Convert the template into pure JavaScript 324 | jQuery.trim(markup) 325 | .replace( /([\\'])/g, "\\$1" ) 326 | .replace( /[\r\t\n]/g, " " ) 327 | .replace( /\$\{([^\}]*)\}/g, "{{= $1}}" ) 328 | .replace( /\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g, 329 | function( all, slash, type, fnargs, target, parens, args ) { 330 | var tag = jQuery.tmpl.tag[ type ], def, expr, exprAutoFnDetect; 331 | if ( !tag ) { 332 | throw "Template command not found: " + type; 333 | } 334 | def = tag._default || []; 335 | if ( parens && !/\w$/.test(target)) { 336 | target += parens; 337 | parens = ""; 338 | } 339 | if ( target ) { 340 | target = unescape( target ); 341 | args = args ? ("," + unescape( args ) + ")") : (parens ? ")" : ""); 342 | // Support for target being things like a.toLowerCase(); 343 | // In that case don't call with template item as 'this' pointer. Just evaluate... 344 | expr = parens ? (target.indexOf(".") > -1 ? target + parens : ("(" + target + ").call($item" + args)) : target; 345 | exprAutoFnDetect = parens ? expr : "(typeof(" + target + ")==='function'?(" + target + ").call($item):(" + target + "))"; 346 | } else { 347 | exprAutoFnDetect = expr = def.$1 || "null"; 348 | } 349 | fnargs = unescape( fnargs ); 350 | return "');" + 351 | tag[ slash ? "close" : "open" ] 352 | .split( "$notnull_1" ).join( target ? "typeof(" + target + ")!=='undefined' && (" + target + ")!=null" : "true" ) 353 | .split( "$1a" ).join( exprAutoFnDetect ) 354 | .split( "$1" ).join( expr ) 355 | .split( "$2" ).join( fnargs ? 356 | fnargs.replace( /\s*([^\(]+)\s*(\((.*?)\))?/g, function( all, name, parens, params ) { 357 | params = params ? ("," + params + ")") : (parens ? ")" : ""); 358 | return params ? ("(" + name + ").call($item" + params) : all; 359 | }) 360 | : (def.$2||"") 361 | ) + 362 | "_.push('"; 363 | }) + 364 | "');}return _;" 365 | ); 366 | } 367 | function updateWrapped( options, wrapped ) { 368 | // Build the wrapped content. 369 | options._wrap = build( options, true, 370 | // Suport imperative scenario in which options.wrapped can be set to a selector or an HTML string. 371 | jQuery.isArray( wrapped ) ? wrapped : [htmlExpr.test( wrapped ) ? wrapped : jQuery( wrapped ).html()] 372 | ).join(""); 373 | } 374 | 375 | function unescape( args ) { 376 | return args ? args.replace( /\\'/g, "'").replace(/\\\\/g, "\\" ) : null; 377 | } 378 | function outerHtml( elem ) { 379 | var div = document.createElement("div"); 380 | div.appendChild( elem.cloneNode(true) ); 381 | return div.innerHTML; 382 | } 383 | 384 | // Store template items in jQuery.data(), ensuring a unique tmplItem data data structure for each rendered template instance. 385 | function storeTmplItems( content ) { 386 | var keySuffix = "_" + cloneIndex, elem, elems, newClonedItems = {}, i, l, m; 387 | for ( i = 0, l = content.length; i < l; i++ ) { 388 | if ( (elem = content[i]).nodeType !== 1 ) { 389 | continue; 390 | } 391 | elems = elem.getElementsByTagName("*"); 392 | for ( m = elems.length - 1; m >= 0; m-- ) { 393 | processItemKey( elems[m] ); 394 | } 395 | processItemKey( elem ); 396 | } 397 | function processItemKey( el ) { 398 | var pntKey, pntNode = el, pntItem, tmplItem, key; 399 | // Ensure that each rendered template inserted into the DOM has its own template item, 400 | if ( (key = el.getAttribute( tmplItmAtt ))) { 401 | while ( pntNode.parentNode && (pntNode = pntNode.parentNode).nodeType === 1 && !(pntKey = pntNode.getAttribute( tmplItmAtt ))) { } 402 | if ( pntKey !== key ) { 403 | // The next ancestor with a _tmplitem expando is on a different key than this one. 404 | // So this is a top-level element within this template item 405 | // Set pntNode to the key of the parentNode, or to 0 if pntNode.parentNode is null, or pntNode is a fragment. 406 | pntNode = pntNode.parentNode ? (pntNode.nodeType === 11 ? 0 : (pntNode.getAttribute( tmplItmAtt ) || 0)) : 0; 407 | if ( !(tmplItem = newTmplItems[key]) ) { 408 | // The item is for wrapped content, and was copied from the temporary parent wrappedItem. 409 | tmplItem = wrappedItems[key]; 410 | tmplItem = newTmplItem( tmplItem, newTmplItems[pntNode]||wrappedItems[pntNode], null, true ); 411 | tmplItem.key = ++itemKey; 412 | newTmplItems[itemKey] = tmplItem; 413 | } 414 | if ( cloneIndex ) { 415 | cloneTmplItem( key ); 416 | } 417 | } 418 | el.removeAttribute( tmplItmAtt ); 419 | } else if ( cloneIndex && (tmplItem = jQuery.data( el, "tmplItem" )) ) { 420 | // This was a rendered element, cloned during append or appendTo etc. 421 | // TmplItem stored in jQuery data has already been cloned in cloneCopyEvent. We must replace it with a fresh cloned tmplItem. 422 | cloneTmplItem( tmplItem.key ); 423 | newTmplItems[tmplItem.key] = tmplItem; 424 | pntNode = jQuery.data( el.parentNode, "tmplItem" ); 425 | pntNode = pntNode ? pntNode.key : 0; 426 | } 427 | if ( tmplItem ) { 428 | pntItem = tmplItem; 429 | // Find the template item of the parent element. 430 | // (Using !=, not !==, since pntItem.key is number, and pntNode may be a string) 431 | while ( pntItem && pntItem.key != pntNode ) { 432 | // Add this element as a top-level node for this rendered template item, as well as for any 433 | // ancestor items between this item and the item of its parent element 434 | pntItem.nodes.push( el ); 435 | pntItem = pntItem.parent; 436 | } 437 | // Delete content built during rendering - reduce API surface area and memory use, and avoid exposing of stale data after rendering... 438 | delete tmplItem._ctnt; 439 | delete tmplItem._wrap; 440 | // Store template item as jQuery data on the element 441 | jQuery.data( el, "tmplItem", tmplItem ); 442 | } 443 | function cloneTmplItem( key ) { 444 | key = key + keySuffix; 445 | tmplItem = newClonedItems[key] = 446 | (newClonedItems[key] || newTmplItem( tmplItem, newTmplItems[tmplItem.parent.key + keySuffix] || tmplItem.parent, null, true )); 447 | } 448 | } 449 | } 450 | 451 | //---- Helper functions for template item ---- 452 | 453 | function tiCalls( content, tmpl, data, options ) { 454 | if ( !content ) { 455 | return stack.pop(); 456 | } 457 | stack.push({ _: content, tmpl: tmpl, item:this, data: data, options: options }); 458 | } 459 | 460 | function tiNest( tmpl, data, options ) { 461 | // nested template, using {{tmpl}} tag 462 | return jQuery.tmpl( jQuery.template( tmpl ), data, options, this ); 463 | } 464 | 465 | function tiWrap( call, wrapped ) { 466 | // nested template, using {{wrap}} tag 467 | var options = call.options || {}; 468 | options.wrapped = wrapped; 469 | // Apply the template, which may incorporate wrapped content, 470 | return jQuery.tmpl( jQuery.template( call.tmpl ), call.data, options, call.item ); 471 | } 472 | 473 | function tiHtml( filter, textOnly ) { 474 | var wrapped = this._wrap; 475 | return jQuery.map( 476 | jQuery( jQuery.isArray( wrapped ) ? wrapped.join("") : wrapped ).filter( filter || "*" ), 477 | function(e) { 478 | return textOnly ? 479 | e.innerText || e.textContent : 480 | e.outerHTML || outerHtml(e); 481 | }); 482 | } 483 | 484 | function tiUpdate() { 485 | var coll = this.nodes; 486 | jQuery.tmpl( null, null, null, this).insertBefore( coll[0] ); 487 | jQuery( coll ).remove(); 488 | } 489 | })( jQuery ); 490 | -------------------------------------------------------------------------------- /js/libs/modernizr-1.7.min.js: -------------------------------------------------------------------------------- 1 | // Modernizr v1.7 www.modernizr.com 2 | window.Modernizr=function(a,b,c){function G(){e.input=function(a){for(var b=0,c=a.length;b7)},r.history=function(){return !!(a.history&&history.pushState)},r.draganddrop=function(){return x("dragstart")&&x("drop")},r.websockets=function(){return"WebSocket"in a},r.rgba=function(){A("background-color:rgba(150,255,150,.5)");return D(k.backgroundColor,"rgba")},r.hsla=function(){A("background-color:hsla(120,40%,100%,.5)");return D(k.backgroundColor,"rgba")||D(k.backgroundColor,"hsla")},r.multiplebgs=function(){A("background:url(//:),url(//:),red url(//:)");return(new RegExp("(url\\s*\\(.*?){3}")).test(k.background)},r.backgroundsize=function(){return F("backgroundSize")},r.borderimage=function(){return F("borderImage")},r.borderradius=function(){return F("borderRadius","",function(a){return D(a,"orderRadius")})},r.boxshadow=function(){return F("boxShadow")},r.textshadow=function(){return b.createElement("div").style.textShadow===""},r.opacity=function(){B("opacity:.55");return/^0.55$/.test(k.opacity)},r.cssanimations=function(){return F("animationName")},r.csscolumns=function(){return F("columnCount")},r.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";A((a+o.join(b+a)+o.join(c+a)).slice(0,-a.length));return D(k.backgroundImage,"gradient")},r.cssreflections=function(){return F("boxReflect")},r.csstransforms=function(){return!!E(["transformProperty","WebkitTransform","MozTransform","OTransform","msTransform"])},r.csstransforms3d=function(){var a=!!E(["perspectiveProperty","WebkitPerspective","MozPerspective","OPerspective","msPerspective"]);a&&"webkitPerspective"in g.style&&(a=w("@media ("+o.join("transform-3d),(")+"modernizr)"));return a},r.csstransitions=function(){return F("transitionProperty")},r.fontface=function(){var a,c,d=h||g,e=b.createElement("style"),f=b.implementation||{hasFeature:function(){return!1}};e.type="text/css",d.insertBefore(e,d.firstChild),a=e.sheet||e.styleSheet;var i=f.hasFeature("CSS2","")?function(b){if(!a||!b)return!1;var c=!1;try{a.insertRule(b,0),c=/src/i.test(a.cssRules[0].cssText),a.deleteRule(a.cssRules.length-1)}catch(d){}return c}:function(b){if(!a||!b)return!1;a.cssText=b;return a.cssText.length!==0&&/src/i.test(a.cssText)&&a.cssText.replace(/\r+|\n+/g,"").indexOf(b.split(" ")[0])===0};c=i('@font-face { font-family: "font"; src: url(data:,); }'),d.removeChild(e);return c},r.video=function(){var a=b.createElement("video"),c=!!a.canPlayType;if(c){c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"');var d='video/mp4; codecs="avc1.42E01E';c.h264=a.canPlayType(d+'"')||a.canPlayType(d+', mp4a.40.2"'),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"')}return c},r.audio=function(){var a=b.createElement("audio"),c=!!a.canPlayType;c&&(c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"'),c.mp3=a.canPlayType("audio/mpeg;"),c.wav=a.canPlayType('audio/wav; codecs="1"'),c.m4a=a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;"));return c},r.localstorage=function(){try{return!!localStorage.getItem}catch(a){return!1}},r.sessionstorage=function(){try{return!!sessionStorage.getItem}catch(a){return!1}},r.webWorkers=function(){return!!a.Worker},r.applicationcache=function(){return!!a.applicationCache},r.svg=function(){return!!b.createElementNS&&!!b.createElementNS(q.svg,"svg").createSVGRect},r.inlinesvg=function(){var a=b.createElement("div");a.innerHTML="";return(a.firstChild&&a.firstChild.namespaceURI)==q.svg},r.smil=function(){return!!b.createElementNS&&/SVG/.test(n.call(b.createElementNS(q.svg,"animate")))},r.svgclippaths=function(){return!!b.createElementNS&&/SVG/.test(n.call(b.createElementNS(q.svg,"clipPath")))};for(var H in r)z(r,H)&&(v=H.toLowerCase(),e[v]=r[H](),u.push((e[v]?"":"no-")+v));e.input||G(),e.crosswindowmessaging=e.postmessage,e.historymanagement=e.history,e.addTest=function(a,b){a=a.toLowerCase();if(!e[a]){b=!!b(),g.className+=" "+(b?"":"no-")+a,e[a]=b;return e}},A(""),j=l=null,f&&a.attachEvent&&function(){var a=b.createElement("div");a.innerHTML="";return a.childNodes.length!==1}()&&function(a,b){function p(a,b){var c=-1,d=a.length,e,f=[];while(++c` tags from `index.html`. 32 | 33 | ## jQuery Tmpl 34 | 35 | The point of showing [this plugin](https://github.com/jquery/jquery-tmpl) was not to say this is the end-all of templating libraries for JS, but instead to show the concept of separating HTML from JavaScript in a clear way. This code is also in its final state from the presentation, but you can see the important pieces in the `script#shot-template` in `index.html`, and also in the first section of code in `js/script.js`. 36 | 37 | ## jQuery doTimeout 38 | 39 | Ben Alman's [jQuery.doTimeout] plugin makes dealing with timers almost effortless. During the live coding session, we looked at how to implement this plugin to get some great results. 40 | 41 | If you want to follow along on the progression we took during the live coding session, visit the bottom of `js/script.js` and one by one uncomment `first_try`, `second_try`, etc. Be sure to only have one uncommented at a time. Don't leave `first_try` and `third_try` running at the same time, for instance. 42 | 43 | `final_try` is of course the final working interaction. The comments in the `script.js` file explain about the expected interactions at each stage, and any problems you might see during that time. 44 | 45 | 46 | ## Font License 47 | 48 | Please see the `SIL Open Font License 1.1.txt` file in the `fonts/ostrich-sans-fontfacekit` directory for information on the license for the Ostrich Sans web font used in this project. `@font-face` kit used was downloaded from [Font Squirrel](http://fontsquirrel.com). 49 | 50 | ## Included Libraries and Assets 51 | * Website theme built on a stripped down version of [HTML5 Boilerplate](http://html5boilerplate.com) 52 | * [Modernizr](http://modernizr.com) 53 | * [jQuery](http://jquery.com) 54 | * [jQuery Mockjax](http://code.appendto.com/plugins/jquery-mockjax) 55 | * [jQuery doTimeout](http://benalman.com/projects/jquery-dotimeout-plugin/) 56 | * [jQuery Tmpl](https://github.com/jquery/jquery-tmpl) 57 | 58 | ## Code License (MIT) 59 | 60 | All code not mentioned in the **Font** or **Included Libraries** section (excluding the data returned from the Dribbble API) uses the following license: 61 | 62 | Copyright (c) 2011 Douglas C. Neiner 63 | 64 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 65 | 66 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 67 | 68 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------------