├── .gitignore
├── Gruntfile.js
├── MIT-LICENSE.txt
├── README.md
├── example
├── css
│ ├── prism.css
│ └── style.css
├── fonts
│ ├── proximanova-light-webfont.eot
│ ├── proximanova-light-webfont.svg
│ ├── proximanova-light-webfont.ttf
│ ├── proximanova-light-webfont.woff
│ ├── proximanova-regular-webfont.eot
│ ├── proximanova-regular-webfont.svg
│ ├── proximanova-regular-webfont.ttf
│ └── proximanova-regular-webfont.woff
├── img
│ └── gray_jean.png
├── index.html
├── less
│ ├── buttons.less
│ ├── elements.less
│ ├── fonts.less
│ ├── forms.less
│ ├── reset.less
│ └── style.less
└── lib
│ ├── jquery-ui
│ ├── css
│ │ └── ui-lightness
│ │ │ ├── images
│ │ │ ├── animated-overlay.gif
│ │ │ ├── ui-bg_diagonals-thick_18_b81900_40x40.png
│ │ │ ├── ui-bg_diagonals-thick_20_666666_40x40.png
│ │ │ ├── ui-bg_flat_10_000000_40x100.png
│ │ │ ├── ui-bg_glass_100_f6f6f6_1x400.png
│ │ │ ├── ui-bg_glass_100_fdf5ce_1x400.png
│ │ │ ├── ui-bg_glass_65_ffffff_1x400.png
│ │ │ ├── ui-bg_gloss-wave_35_f6a828_500x100.png
│ │ │ ├── ui-bg_highlight-soft_100_eeeeee_1x100.png
│ │ │ ├── ui-bg_highlight-soft_75_ffe45c_1x100.png
│ │ │ ├── ui-icons_222222_256x240.png
│ │ │ ├── ui-icons_228ef1_256x240.png
│ │ │ ├── ui-icons_ef8c08_256x240.png
│ │ │ ├── ui-icons_ffd27a_256x240.png
│ │ │ └── ui-icons_ffffff_256x240.png
│ │ │ ├── jquery-ui-1.10.2.custom.css
│ │ │ └── jquery-ui-1.10.2.custom.min.css
│ └── js
│ │ └── jquery-ui-1.10.2.custom.min.js
│ ├── jquery.min.js
│ ├── less.js
│ └── prism.js
├── jquery.timeAutocomplete.min.js
├── package.json
├── src
├── formatters
│ ├── 24hr.js
│ ├── ampm.js
│ └── french.js
└── jquery.timeAutocomplete.js
├── tests
├── index.html
├── lib
│ ├── jasmine-1.3.1
│ │ ├── MIT.LICENSE
│ │ ├── jasmine-html.js
│ │ ├── jasmine.css
│ │ └── jasmine.js
│ └── jasmine-affix.js
└── spec
│ ├── formatters
│ ├── 24hr.spec.js
│ ├── ampm.spec.js
│ └── french.spec.js
│ └── timeAutocomplete.spec.js
└── timeAutocomplete.jquery.json
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .DS_Store
3 | node_modules
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(grunt) {
4 |
5 | grunt.initConfig({
6 | uglify: {
7 | build: {
8 | files: {
9 | 'jquery.timeAutocomplete.min.js': [
10 | 'src/jquery.timeAutocomplete.js',
11 | 'src/formatters/ampm.js',
12 | 'src/formatters/24hr.js',
13 | 'src/formatters/french.js'
14 | ]
15 | }
16 | }
17 | }
18 | });
19 |
20 | grunt.loadNpmTasks('grunt-contrib-uglify');
21 | grunt.registerTask('default', ['uglify']);
22 |
23 | };
--------------------------------------------------------------------------------
/MIT-LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2013 7shifts Online Employee Scheduling,
2 | http://www.7shifts.com
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # jQuery timeAutocomplete Plugin
2 |
3 | ### What is this?
4 |
5 | It's a time picker similar to how Google Calendar's time picker works for events. It's meant to be smart, sexy and intuitive.
6 |
7 | Some things that make is super duper fantastic:
8 |
9 | * Start time defaults to users current time (within your set increment).
10 | * Tabbing out of the field without selecting a time will cause it to make an educated guess. Try typing a badly formatted time like 115 or 1 or 1pm or 28 then tabbing out.
11 | * If the end time is less than the start time, evaluate it to the opposite am/pm of the start time. Example: 7:00AM - 5... 5 will default to PM.
12 | * Fetch time in H:i:s format (13:30:00) for comparing/validating. Done so by calling $(input).data('timeAutocomplete').getTime()
13 | * Uses placeholder attribute if detected, if not, it uses our own placeholder text.
14 | * Oh, and it's tested :) - see tests/index.html to run tests
15 |
16 | ### Basic Usage
17 | ```
18 | $('#basic-example').timeAutocomplete();
19 | ```
20 |
21 | ### Advanced usage #1
22 |
23 | Injecting an existing value and using 24hr as the formatter.
24 |
25 | ```
26 | $('#from-24hr').timeAutocomplete({
27 | formatter: '24hr',
28 | value: '07:00:00'
29 | });
30 | ```
31 | or
32 | ```
33 | $('#to-24hr').val('09:30:00').timeAutocomplete({
34 | formatter: '24hr'
35 | });
36 | ```
37 |
38 | ### More documentation and examples
39 | * http://7shifts.com/blog/better-time-drop-downs-for-scheduling-jquery-timeautocomplete/
40 |
41 | ### Contributing
42 | * Run ```npm install``` to install dependencies (requires NodeJS).
43 | * Make changes to any of the .js files
44 | * Run ```grunt``` from the project root to compile
45 | * Commit and submit pull request
--------------------------------------------------------------------------------
/example/css/prism.css:
--------------------------------------------------------------------------------
1 | /**
2 | * prism.js default theme for JavaScript, CSS and HTML
3 | * Based on dabblet (http://dabblet.com)
4 | * @author Lea Verou
5 | */
6 |
7 | code[class*="language-"],
8 | pre[class*="language-"] {
9 | color: black;
10 | text-shadow: 0 1px white;
11 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
12 | direction: ltr;
13 | text-align: left;
14 | white-space: pre;
15 | word-spacing: normal;
16 |
17 | -moz-tab-size: 4;
18 | -o-tab-size: 4;
19 | tab-size: 4;
20 |
21 | -webkit-hyphens: none;
22 | -moz-hyphens: none;
23 | -ms-hyphens: none;
24 | hyphens: none;
25 | }
26 |
27 | @media print {
28 | code[class*="language-"],
29 | pre[class*="language-"] {
30 | text-shadow: none;
31 | }
32 | }
33 |
34 | /* Code blocks */
35 | pre[class*="language-"] {
36 | padding: 1em;
37 | margin: .5em 0;
38 | overflow: auto;
39 | }
40 |
41 | :not(pre) > code[class*="language-"],
42 | pre[class*="language-"] {
43 | background: #f5f2f0;
44 | }
45 |
46 | /* Inline code */
47 | :not(pre) > code[class*="language-"] {
48 | padding: .1em;
49 | border-radius: .3em;
50 | }
51 |
52 | .token.comment,
53 | .token.prolog,
54 | .token.doctype,
55 | .token.cdata {
56 | color: slategray;
57 | }
58 |
59 | .token.punctuation {
60 | color: #999;
61 | }
62 |
63 | .namespace {
64 | opacity: .7;
65 | }
66 |
67 | .token.property,
68 | .token.tag,
69 | .token.boolean,
70 | .token.number {
71 | color: #905;
72 | }
73 |
74 | .token.selector,
75 | .token.attr-name,
76 | .token.string {
77 | color: #690;
78 | }
79 |
80 | .token.operator,
81 | .token.entity,
82 | .token.url,
83 | .language-css .token.string,
84 | .style .token.string {
85 | color: #a67f59;
86 | background: hsla(0,0%,100%,.5);
87 | }
88 |
89 | .token.atrule,
90 | .token.attr-value,
91 | .token.keyword {
92 | color: #07a;
93 | }
94 |
95 |
96 | .token.regex,
97 | .token.important {
98 | color: #e90;
99 | }
100 |
101 | .token.important {
102 | font-weight: bold;
103 | }
104 |
105 | .token.entity {
106 | cursor: help;
107 | }
--------------------------------------------------------------------------------
/example/css/style.css:
--------------------------------------------------------------------------------
1 | .clear {
2 | clear: both;
3 | }
4 | .clearfix:after {
5 | content: ".";
6 | display: block;
7 | clear: both;
8 | visibility: hidden;
9 | line-height: 0;
10 | height: 0;
11 | }
12 | .clearfix {
13 | display: inline-block;
14 | }
15 | html[xmlns] .clearfix {
16 | display: block;
17 | }
18 | * html .clearfix {
19 | height: 1%;
20 | }
21 | article,
22 | aside,
23 | details,
24 | figcaption,
25 | figure,
26 | footer,
27 | header,
28 | hgroup,
29 | nav,
30 | section {
31 | display: block;
32 | }
33 | table {
34 | width: 100%;
35 | font-size: 13px;
36 | }
37 | table thead th {
38 | background: #fff;
39 | border-bottom: 1px solid #ccc;
40 | }
41 | table th,
42 | table td {
43 | padding: 5px;
44 | }
45 | table tr td {
46 | border: 1px solid #ccc;
47 | }
48 | audio,
49 | canvas,
50 | video {
51 | display: inline-block;
52 | *display: inline;
53 | *zoom: 1;
54 | }
55 | audio:not([controls]) {
56 | display: none;
57 | }
58 | html {
59 | font-size: 100%;
60 | -webkit-text-size-adjust: 100%;
61 | -ms-text-size-adjust: 100%;
62 | }
63 | a:hover,
64 | a:active {
65 | outline: 0;
66 | }
67 | sub,
68 | sup {
69 | position: relative;
70 | font-size: 75%;
71 | line-height: 0;
72 | vertical-align: baseline;
73 | }
74 | sup {
75 | top: -0.5em;
76 | }
77 | sub {
78 | bottom: -0.25em;
79 | }
80 | img {
81 | /* Responsive images (ensure images don't scale beyond their parents) */
82 |
83 | max-width: 100%;
84 | /* Part 1: Set a maxium relative to the parent */
85 |
86 | width: auto\9;
87 | /* IE7-8 need help adjusting responsive images */
88 |
89 | height: auto;
90 | /* Part 2: Scale the height according to the width, otherwise you get stretching */
91 |
92 | vertical-align: middle;
93 | border: 0;
94 | -ms-interpolation-mode: bicubic;
95 | }
96 | #map_canvas img,
97 | .google-maps img {
98 | max-width: none;
99 | }
100 | button,
101 | input,
102 | select,
103 | textarea {
104 | margin: 0;
105 | font-size: 100%;
106 | vertical-align: middle;
107 | }
108 | button,
109 | input {
110 | *overflow: visible;
111 | line-height: normal;
112 | }
113 | button::-moz-focus-inner,
114 | input::-moz-focus-inner {
115 | padding: 0;
116 | border: 0;
117 | }
118 | button,
119 | html input[type="button"],
120 | input[type="reset"],
121 | input[type="submit"] {
122 | -webkit-appearance: button;
123 | cursor: pointer;
124 | }
125 | label,
126 | select,
127 | button,
128 | input[type="button"],
129 | input[type="reset"],
130 | input[type="submit"],
131 | input[type="radio"],
132 | input[type="checkbox"] {
133 | cursor: pointer;
134 | }
135 | input[type="search"] {
136 | -webkit-appearance: textfield;
137 | }
138 | input[type="search"]::-webkit-search-decoration,
139 | input[type="search"]::-webkit-search-cancel-button {
140 | -webkit-appearance: none;
141 | }
142 | textarea {
143 | overflow: auto;
144 | vertical-align: top;
145 | }
146 | @media print {
147 | * {
148 | text-shadow: none !important;
149 | color: #000 !important;
150 | background: transparent !important;
151 | box-shadow: none !important;
152 | }
153 | a,
154 | a:visited {
155 | text-decoration: underline;
156 | }
157 | a[href]:after {
158 | content: " (" attr(href) ")";
159 | }
160 | abbr[title]:after {
161 | content: " (" attr(title) ")";
162 | }
163 | .ir a:after,
164 | a[href^="javascript:"]:after,
165 | a[href^="#"]:after {
166 | content: "";
167 | }
168 | pre,
169 | blockquote {
170 | border: 1px solid #999;
171 | page-break-inside: avoid;
172 | }
173 | thead {
174 | display: table-header-group;
175 | }
176 | tr,
177 | img {
178 | page-break-inside: avoid;
179 | }
180 | img {
181 | max-width: 100% !important;
182 | }
183 | @page {
184 | margin: 0.5cm;
185 | }
186 | p,
187 | h2,
188 | h3 {
189 | orphans: 3;
190 | widows: 3;
191 | }
192 | h2,
193 | h3 {
194 | page-break-after: avoid;
195 | }
196 | }
197 | /*---------------------------------------------------
198 | LESS Elements 0.9
199 | ---------------------------------------------------
200 | A set of useful LESS mixins
201 | More info at: http://lesselements.com
202 | ---------------------------------------------------*/
203 | /* This file was created to be share between the main site and marketing pages (restaurants.php, coffee.php etc) */
204 | @font-face {
205 | font-family: 'ProximaNovaLight';
206 | src: url('../fonts/proximanova-light-webfont.eot');
207 | src: url('../fonts/proximanova-light-webfont.eot') format('embedded-opentype'), url('../fonts/proximanova-light-webfont.woff') format('woff'), url('../fonts/proximanova-light-webfont.ttf') format('truetype'), url('../fonts/proximanova-light-webfont.svg#proxima_novalight') format('svg');
208 | font-weight: normal;
209 | font-style: normal;
210 | }
211 | @font-face {
212 | font-family: 'ProximaNovaRegular';
213 | src: url('../fonts/proximanova-regular-webfont.eot');
214 | src: url('../fonts/proximanova-regular-webfont.eot') format('embedded-opentype'), url('../fonts/proximanova-regular-webfont.woff') format('woff'), url('../proximanova-regular-webfont.ttf') format('truetype'), url('../proximanova-regular-webfont.svg#proxima_nova_rgregular') format('svg');
215 | font-weight: normal;
216 | font-style: normal;
217 | }
218 | input[type="text"],
219 | button {
220 | margin: 5px 0;
221 | font-family: 'ProximaNovaLight', 'Helvetica Neue', 'Helvetica', 'Arial';
222 | font-size: 15px;
223 | padding: 10px;
224 | -webkit-border-radius: 5px;
225 | -moz-border-radius: 5px;
226 | border-radius: 5px;
227 | border: 1px solid #ccc;
228 | }
229 | button {
230 | background: #aaaaaa;
231 | background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
232 | background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
233 | background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
234 | background: -o-linear-gradient(#ffffff, #eeeeee);
235 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
236 | }
237 | button:active {
238 | background: #ffffff;
239 | background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #eeeeee));
240 | background: -ms-linear-gradient(bottom, #eeeeee, #eeeeee);
241 | background: -moz-linear-gradient(center bottom, #eeeeee 0%, #eeeeee 100%);
242 | background: -o-linear-gradient(#eeeeee, #eeeeee);
243 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#eeeeee', GradientType=0);
244 | }
245 | button.green {
246 | background-color: #7fbf4d;
247 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #7fbf4d), color-stop(100%, #63a62f));
248 | background-image: -webkit-linear-gradient(top, #7fbf4d, #63a62f);
249 | background-image: -moz-linear-gradient(top, #7fbf4d, #63a62f);
250 | background-image: -ms-linear-gradient(top, #7fbf4d, #63a62f);
251 | background-image: -o-linear-gradient(top, #7fbf4d, #63a62f);
252 | background-image: linear-gradient(top, #7fbf4d, #63a62f);
253 | border: 1px solid #63a62f;
254 | border-bottom: 1px solid #66a039;
255 | border-radius: 3px;
256 | -webkit-box-shadow: inset 0 1px 0 0 #9acc73;
257 | box-shadow: inset 0 1px 0 0 #9acc73;
258 | color: #fff;
259 | padding: 7px 0 8px 0;
260 | text-align: center;
261 | text-shadow: 0 -1px 0 #66a039;
262 | width: 100%;
263 | margin: 10px 0;
264 | }
265 | button.green:hover {
266 | background-color: #72b240;
267 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #72b240), color-stop(100%, #579229));
268 | background-image: -webkit-linear-gradient(top, #72b240, #579229);
269 | background-image: -moz-linear-gradient(top, #72b240, #579229);
270 | background-image: -ms-linear-gradient(top, #72b240, #579229);
271 | background-image: -o-linear-gradient(top, #72b240, #579229);
272 | background-image: linear-gradient(top, #72b240, #579229);
273 | -webkit-box-shadow: inset 0 1px 0 0 #8cc660;
274 | box-shadow: inset 0 1px 0 0 #8cc660;
275 | cursor: pointer;
276 | }
277 | button.green:active {
278 | border: 1px solid #53822f;
279 | border-bottom: 1px solid #5a8d33;
280 | -webkit-box-shadow: inset 0 0 8px 4px #649c38, 0 1px 0 0 #eeeeee;
281 | box-shadow: inset 0 0 8px 4px #649c38, 0 1px 0 0 #eeeeee;
282 | }
283 | button.green[disabled="disabled"] {
284 | opacity: .5;
285 | }
286 | button.blue {
287 | background-color: #67a4e9;
288 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #67a4e9), color-stop(100%, #3587e4));
289 | background-image: -webkit-linear-gradient(top, #67a4e9, #3587e4);
290 | background-image: -moz-linear-gradient(top, #67a4e9, #3587e4);
291 | background-image: -ms-linear-gradient(top, #67a4e9, #3587e4);
292 | background-image: -o-linear-gradient(top, #67a4e9, #3587e4);
293 | background-image: linear-gradient(top, #67a4e9, #3587e4);
294 | border: 1px solid #3587e4;
295 | border-bottom: 1px solid #3a89e3;
296 | border-radius: 3px;
297 | -webkit-box-shadow: inset 0 1px 0 0 #94bfef;
298 | box-shadow: inset 0 1px 0 0 #94bfef;
299 | color: #fff;
300 | padding: 7px 0 8px 0;
301 | text-align: center;
302 | text-shadow: 0 -1px 0 #3a89e3;
303 | width: 100%;
304 | }
305 | button.blue:hover {
306 | background-color: #5197e6;
307 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #5197e6), color-stop(100%, #1f7ae1));
308 | background-image: -webkit-linear-gradient(top, #5197e6, #1f7ae1);
309 | background-image: -moz-linear-gradient(top, #5197e6, #1f7ae1);
310 | background-image: -ms-linear-gradient(top, #5197e6, #1f7ae1);
311 | background-image: -o-linear-gradient(top, #5197e6, #1f7ae1);
312 | background-image: linear-gradient(top, #5197e6, #1f7ae1);
313 | -webkit-box-shadow: inset 0 1px 0 0 #7db1ec;
314 | box-shadow: inset 0 1px 0 0 #7db1ec;
315 | cursor: pointer;
316 | }
317 | button.blue:active {
318 | border: 1px solid #1f74d5;
319 | border-bottom: 1px solid #247cdf;
320 | -webkit-box-shadow: inset 0 0 8px 4px #3687e2, 0 1px 0 0 #eeeeee;
321 | box-shadow: inset 0 0 8px 4px #3687e2, 0 1px 0 0 #eeeeee;
322 | }
323 | button.blue[disabled="disabled"] {
324 | opacity: .5;
325 | }
326 | body {
327 | background: #ffffff url(../img/gray_jean.png);
328 | color: #333;
329 | font-size: 15px;
330 | line-height: 170%;
331 | font-family: 'ProximaNovaLight', 'Helvetica Neue', 'Helvetica', 'Arial';
332 | margin: 0;
333 | text-shadow: 1px 1px 0 #fff;
334 | }
335 | a {
336 | color: #333;
337 | }
338 | #container {
339 | width: 700px;
340 | margin: 30px auto 50px auto;
341 | }
342 | h1 {
343 | text-align: center;
344 | }
345 | h1 span {
346 | display: block;
347 | margin: 10px 0;
348 | font-style: italic;
349 | font-size: 16px;
350 | }
351 | h3.grey-line {
352 | position: relative;
353 | text-align: center;
354 | z-index: 1;
355 | }
356 | h3.grey-line:before {
357 | border-top: 1px solid #ccc;
358 | content: "";
359 | margin: 0 auto;
360 | position: absolute;
361 | top: 15px;
362 | left: 0;
363 | right: 0;
364 | bottom: 0;
365 | width: 100%;
366 | z-index: -1;
367 | }
368 | h3.grey-line span {
369 | background: url(../img/gray_jean.png);
370 | padding: 0 10px;
371 | }
372 |
--------------------------------------------------------------------------------
/example/fonts/proximanova-light-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/fonts/proximanova-light-webfont.eot
--------------------------------------------------------------------------------
/example/fonts/proximanova-light-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/fonts/proximanova-light-webfont.ttf
--------------------------------------------------------------------------------
/example/fonts/proximanova-light-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/fonts/proximanova-light-webfont.woff
--------------------------------------------------------------------------------
/example/fonts/proximanova-regular-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/fonts/proximanova-regular-webfont.eot
--------------------------------------------------------------------------------
/example/fonts/proximanova-regular-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/fonts/proximanova-regular-webfont.ttf
--------------------------------------------------------------------------------
/example/fonts/proximanova-regular-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/fonts/proximanova-regular-webfont.woff
--------------------------------------------------------------------------------
/example/img/gray_jean.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/img/gray_jean.png
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | jQuery TimeAutocomplete Example
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
jQuery timeAutocomplete Plugin by 7shifts.com
25 |
26 |
What is this?
27 |
28 |
It's a time picker similar to how Google Calendar's time picker works for events. It's meant to be smart, sexy and intuitive.
29 |
30 |
Some things that make is super duper fantastic:
31 |
32 | Start time defaults to users current time (within your set increment ).
33 | Tabbing out of the field without selecting a time will cause it to make an educated guess. Try typing a badly formatted time like 115 or 1 or 1pm or 28 then tabbing out.
34 | If the end time is less than the start time, evaluate it to the opposite am/pm of the start time. Example: 7:00AM - 5... 5 will default to PM.
35 | Fetch time in H:i:s format (13:30:00) for comparing/validating. Done so by calling $(input).data('timeAutocomplete').getTime()
36 | Uses placeholder attribute if detected, if not, it uses our own placeholder text.
37 | Oh, and it's tested :) - see tests/index.html to run tests
38 |
39 |
40 |
Basic usage
41 |
$('#basic-example').timeAutocomplete();
42 |
43 |
44 |
45 |
Advanced usage #1
46 |
Injecting an existing value and using 24hr as the formatter.
47 |
$('#from-24hr').timeAutocomplete({
48 | formatter: '24hr',
49 | value: '07:00:00'
50 | });
51 |
52 | $('#to-24hr').timeAutocomplete({
53 | formatter: '24hr',
54 | value: '09:30:00'
55 | });
56 |
57 | From
58 | To
Show getTime() value (H:i:s format)
59 |
60 |
61 |
Advanced usage #2
62 |
Using a 'from' and 'to' input. We use a 'from_selector' argument in the set of options on the 'to' field. This makes the time autocomplete aware of the time in the other
63 | field. If the 'from' field is '8:00 AM' and we start typing into the 'to' field with '4', it will show us a list of 4 'PM' instead of 4 'AM' options.
64 |
$('#from-ampm').timeAutocomplete({
65 | increment: 5,
66 | value: '08:00:00'
67 | });
68 |
69 | $('#to-ampm').timeAutocomplete({
70 | increment: 5,
71 | from_selector: '#from-ampm',
72 | value: '17:30:00' // likely populated from your database.
73 | });
74 |
75 | From
76 | To
Show getTime() value (H:i:s format)
77 |
78 |
Advanced usage #3
79 |
80 |
$('#from-french').timeAutocomplete({
81 | formatter: 'french'
82 | });
83 |
84 | $('#to-french').timeAutocomplete({
85 | formatter: 'french',
86 | value: '17:00:00'
87 | });
88 |
89 | From
90 | To
Show getTime() value (H:i:s format)
91 |
92 |
Initialization options
93 |
Below is a set of options you can pass when you call $('#my-input').timeAutocomplete(options);
94 |
95 |
options = {
96 |
97 |
98 |
99 | Option key
100 | Default value
101 | Possible values
102 | Description
103 |
104 |
105 |
106 |
107 | auto_complete
108 | { delay: 0, autoFocus: true, minLength: 0 } (object)
109 | View here .
110 | Any options to over-ride jQuery UI autocomplete plugin.
111 |
112 |
113 | formatter
114 | ampm (string)
115 | ampm | 24hr | french
116 | The formatter we want to use
117 |
118 |
119 | value
120 | '' (string)
121 | '13:30:00'
122 | Allows you to pass in a 24hr (H:i:s) time to be formatted and displayed in the field. It's the same as calling $('#from').data('timeAutocomplete').setTime('13:30:00');
123 |
124 |
125 | from_selector
126 | '' (string)
127 | #from
128 | You'll want to use this option on the #to element if you're using the
129 | 'ampm' formatter. It applies a level of
130 | "smartness" when dealing with both from/to inputs. If your #from input is 8:00 AM then the user types in "5" into the #to input, it will give them possible increments in PM.
131 |
132 |
133 | increment
134 | 15 (int)
135 | 5, 10, 15, 30, 60
136 |
137 | The increment you want the time dropdown to appear in. A 15 minute increment would produce: ['7:15 AM', '7:30 AM', '7:45 AM'].
138 |
139 |
140 |
141 | start_hour
142 | 0 (int)
143 | Any number on or between 0 and 24
144 | What hour you want start the selectable time list to start at.
145 |
146 |
147 | end_hour
148 | 24 (int)
149 | Any number on or between 0 and 24
150 | What hour you want the end of the selectable time list to end at.
151 |
152 |
153 | blur_empty_populate
154 | true
155 | true | false
156 | If we blur from the input field and it's empty, populate it with our empty default value (see next line).
157 |
158 |
159 | auto_value
160 | true
161 | true | false
162 | If false, it will not inject the current time as a value. Your input will be empty.
163 |
164 |
165 | empty
166 | {
167 | h: '12',
168 | m: '00',
169 | sep: ':',
170 | postfix: ' PM'
171 | } (object)
172 |
173 | The default empty value
174 |
175 |
176 |
177 |
178 |
}
179 |
180 |
API
181 |
Once you initialize timeAutocomplete() on an element, you have access to methods via data('timeAutocomplete').
182 |
183 |
184 |
185 | Method
186 | Arguments
187 | Description
188 |
189 |
190 |
191 |
192 |
193 | destroy()
194 | None
195 | Completely removes timeAutocomplete plugin from the input
196 |
197 |
198 | $('#my-input').data('timeAutocomplete').destroy();
199 |
200 |
201 | getTime()
202 | None
203 | Gets the time in H:i:s (13:30:00) format.
204 |
205 |
206 | $('#my-input').data('timeAutocomplete').getTime();
207 |
208 |
209 | setTime(time)
210 | time: '13:30:00'
211 | Sets the time by passing in a 24hr format. This will be formatted appropriately before being displayed.
212 |
213 |
214 | $('#my-input').data('timeAutocomplete').setTime('13:30:00');
215 |
216 |
217 | setFormatter(formatter)
218 | formatter: 'ampm' or '24hr' or 'french'
219 | Changes the formatter type on the fly.
220 |
221 |
222 | $('#my-input').data('timeAutocomplete').setFormatter('24hr');
223 |
224 |
225 |
226 |
227 |
228 |
Requirements
229 |
230 | jQuery (only tested with 1.9)
231 | jQuery UI w/ Autocomplete plugin (only tested with 1.10.2)
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
307 |
308 |
309 |
--------------------------------------------------------------------------------
/example/less/buttons.less:
--------------------------------------------------------------------------------
1 | .button (@color1, @color2) {
2 | background-color: @color1;
3 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, @color1), color-stop(100%, @color2));
4 | background-image: -webkit-linear-gradient(top, @color1, @color2);
5 | background-image: -moz-linear-gradient(top, @color1, @color2);
6 | background-image: -ms-linear-gradient(top, @color1, @color2);
7 | background-image: -o-linear-gradient(top, @color1, @color2);
8 | background-image: linear-gradient(top, @color1, @color2);
9 | border: 1px solid @color2;
10 | border-bottom: 1px solid darken(@color1, 10%);
11 | border-radius: 3px;
12 | -webkit-box-shadow: inset 0 1px 0 0 lighten(@color1, 10%);
13 | box-shadow: inset 0 1px 0 0 lighten(@color1, 10%);
14 | color: #fff;
15 | padding: 7px 0 8px 0;
16 | text-align: center;
17 | text-shadow: 0 -1px 0 darken(@color1, 10%);
18 | width: 100%;
19 |
20 | &:hover {
21 | background-color: darken(@color1, 5%);
22 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, darken(@color1, 5%)), color-stop(100%, darken(@color2, 5%)));
23 | background-image: -webkit-linear-gradient(top, darken(@color1, 5%), darken(@color2, 5%));
24 | background-image: -moz-linear-gradient(top, darken(@color1, 5%), darken(@color2, 5%));
25 | background-image: -ms-linear-gradient(top, darken(@color1, 5%), darken(@color2, 5%));
26 | background-image: -o-linear-gradient(top, darken(@color1, 5%), darken(@color2, 5%));
27 | background-image: linear-gradient(top, darken(@color1, 5%), darken(@color2, 5%));
28 | -webkit-box-shadow: inset 0 1px 0 0 lighten(@color1, 5%);
29 | box-shadow: inset 0 1px 0 0 lighten(@color1, 5%);
30 | cursor: pointer;
31 | }
32 |
33 | &:active {
34 | border: 1px solid darken(@color1, 18%);
35 | border-bottom: 1px solid darken(@color1, 15%);
36 | -webkit-box-shadow: inset 0 0 8px 4px darken(@color1, 11%), 0 1px 0 0 #eeeeee;
37 | box-shadow: inset 0 0 8px 4px darken(@color1, 11%), 0 1px 0 0 #eeeeee;
38 | }
39 |
40 | &[disabled="disabled"] {
41 | opacity: .5;
42 | }
43 |
44 | }
45 |
46 | button.green {
47 | .button(#7fbf4d, #63a62f);
48 |
49 | margin: 10px 0;
50 | }
51 | button.blue {
52 | .button(#67a4e9, #3587e4);
53 | }
--------------------------------------------------------------------------------
/example/less/elements.less:
--------------------------------------------------------------------------------
1 | /*---------------------------------------------------
2 | LESS Elements 0.9
3 | ---------------------------------------------------
4 | A set of useful LESS mixins
5 | More info at: http://lesselements.com
6 | ---------------------------------------------------*/
7 |
8 | .gradient(@color: #F5F5F5, @start: #EEE, @stop: #FFF) {
9 | background: @color;
10 | background: -webkit-gradient(linear,
11 | left bottom,
12 | left top,
13 | color-stop(0, @start),
14 | color-stop(1, @stop));
15 | background: -ms-linear-gradient(bottom,
16 | @start,
17 | @stop);
18 | background: -moz-linear-gradient(center bottom,
19 | @start 0%,
20 | @stop 100%);
21 | background: -o-linear-gradient(@stop,
22 | @start);
23 | filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",@stop,@start));
24 | }
25 | .bw-gradient(@color: #F5F5F5, @start: 0, @stop: 255) {
26 | background: @color;
27 | background: -webkit-gradient(linear,
28 | left bottom,
29 | left top,
30 | color-stop(0, rgb(@start,@start,@start)),
31 | color-stop(1, rgb(@stop,@stop,@stop)));
32 | background: -ms-linear-gradient(bottom,
33 | rgb(@start,@start,@start) 0%,
34 | rgb(@stop,@stop,@stop) 100%);
35 | background: -moz-linear-gradient(center bottom,
36 | rgb(@start,@start,@start) 0%,
37 | rgb(@stop,@stop,@stop) 100%);
38 | background: -o-linear-gradient(rgb(@stop,@stop,@stop),
39 | rgb(@start,@start,@start));
40 | filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",rgb(@stop,@stop,@stop),rgb(@start,@start,@start)));
41 | }
42 | .bordered(@top-color: #EEE, @right-color: #EEE, @bottom-color: #EEE, @left-color: #EEE) {
43 | border-top: solid 1px @top-color;
44 | border-left: solid 1px @left-color;
45 | border-right: solid 1px @right-color;
46 | border-bottom: solid 1px @bottom-color;
47 | }
48 | .drop-shadow(@x-axis: 0, @y-axis: 1px, @blur: 2px, @alpha: 0.1) {
49 | -webkit-box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha);
50 | -moz-box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha);
51 | box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha);
52 | }
53 | .rounded(@radius: 2px) {
54 | -webkit-border-radius: @radius;
55 | -moz-border-radius: @radius;
56 | border-radius: @radius;
57 | }
58 | .border-radius(@topright: 0, @bottomright: 0, @bottomleft: 0, @topleft: 0) {
59 | -webkit-border-top-right-radius: @topright;
60 | -webkit-border-bottom-right-radius: @bottomright;
61 | -webkit-border-bottom-left-radius: @bottomleft;
62 | -webkit-border-top-left-radius: @topleft;
63 | -moz-border-radius-topright: @topright;
64 | -moz-border-radius-bottomright: @bottomright;
65 | -moz-border-radius-bottomleft: @bottomleft;
66 | -moz-border-radius-topleft: @topleft;
67 | border-top-right-radius: @topright;
68 | border-bottom-right-radius: @bottomright;
69 | border-bottom-left-radius: @bottomleft;
70 | border-top-left-radius: @topleft;
71 | .background-clip(padding-box);
72 | }
73 | .opacity(@opacity: 0.5) {
74 | -moz-opacity: @opacity;
75 | -khtml-opacity: @opacity;
76 | -webkit-opacity: @opacity;
77 | opacity: @opacity;
78 | @opperc: @opacity * 100;
79 | -ms-filter: ~"progid:DXImageTransform.Microsoft.Alpha(opacity=@{opperc})";
80 | filter: ~"alpha(opacity=@{opperc})";
81 | }
82 | .transition-duration(@duration: 0.2s) {
83 | -moz-transition-duration: @duration;
84 | -webkit-transition-duration: @duration;
85 | -o-transition-duration: @duration;
86 | transition-duration: @duration;
87 | }
88 | .transform(...) {
89 | -webkit-transform: @arguments;
90 | -moz-transform: @arguments;
91 | -o-transform: @arguments;
92 | -ms-transform: @arguments;
93 | transform: @arguments;
94 | }
95 | .rotation(@deg:5deg){
96 | .transform(rotate(@deg));
97 | }
98 | .scale(@ratio:1.5){
99 | .transform(scale(@ratio));
100 | }
101 | .transition(@duration:0.2s, @ease:ease-out) {
102 | -webkit-transition: all @duration @ease;
103 | -moz-transition: all @duration @ease;
104 | -o-transition: all @duration @ease;
105 | transition: all @duration @ease;
106 | }
107 | .inner-shadow(@horizontal:0, @vertical:1px, @blur:2px, @alpha: 0.4) {
108 | -webkit-box-shadow: inset @horizontal @vertical @blur rgba(0, 0, 0, @alpha);
109 | -moz-box-shadow: inset @horizontal @vertical @blur rgba(0, 0, 0, @alpha);
110 | box-shadow: inset @horizontal @vertical @blur rgba(0, 0, 0, @alpha);
111 | }
112 | .box-shadow(@arguments) {
113 | -webkit-box-shadow: @arguments;
114 | -moz-box-shadow: @arguments;
115 | box-shadow: @arguments;
116 | }
117 | .box-sizing(@sizing: border-box) {
118 | -ms-box-sizing: @sizing;
119 | -moz-box-sizing: @sizing;
120 | -webkit-box-sizing: @sizing;
121 | box-sizing: @sizing;
122 | }
123 | .user-select(@argument: none) {
124 | -webkit-user-select: @argument;
125 | -moz-user-select: @argument;
126 | -ms-user-select: @argument;
127 | user-select: @argument;
128 | }
129 | .columns(@colwidth: 250px, @colcount: 0, @colgap: 50px, @columnRuleColor: #EEE, @columnRuleStyle: solid, @columnRuleWidth: 1px) {
130 | -moz-column-width: @colwidth;
131 | -moz-column-count: @colcount;
132 | -moz-column-gap: @colgap;
133 | -moz-column-rule-color: @columnRuleColor;
134 | -moz-column-rule-style: @columnRuleStyle;
135 | -moz-column-rule-width: @columnRuleWidth;
136 | -webkit-column-width: @colwidth;
137 | -webkit-column-count: @colcount;
138 | -webkit-column-gap: @colgap;
139 | -webkit-column-rule-color: @columnRuleColor;
140 | -webkit-column-rule-style: @columnRuleStyle;
141 | -webkit-column-rule-width: @columnRuleWidth;
142 | column-width: @colwidth;
143 | column-count: @colcount;
144 | column-gap: @colgap;
145 | column-rule-color: @columnRuleColor;
146 | column-rule-style: @columnRuleStyle;
147 | column-rule-width: @columnRuleWidth;
148 | }
149 | .translate(@x:0, @y:0) {
150 | .transform(translate(@x, @y));
151 | }
152 | .background-clip(@argument: padding-box) {
153 | -moz-background-clip: @argument;
154 | -webkit-background-clip: @argument;
155 | background-clip: @argument;
156 | }
--------------------------------------------------------------------------------
/example/less/fonts.less:
--------------------------------------------------------------------------------
1 | /* This file was created to be share between the main site and marketing pages (restaurants.php, coffee.php etc) */
2 | @font-face {
3 | font-family: 'ProximaNovaLight';
4 | src: url('../fonts/proximanova-light-webfont.eot');
5 | src: url('../fonts/proximanova-light-webfont.eot?#iefix') format('embedded-opentype'),
6 | url('../fonts/proximanova-light-webfont.woff') format('woff'),
7 | url('../fonts/proximanova-light-webfont.ttf') format('truetype'),
8 | url('../fonts/proximanova-light-webfont.svg#proxima_novalight') format('svg');
9 | font-weight: normal;
10 | font-style: normal;
11 |
12 | }
13 | @font-face {
14 | font-family: 'ProximaNovaRegular';
15 | src: url('../fonts/proximanova-regular-webfont.eot');
16 | src: url('../fonts/proximanova-regular-webfont.eot?#iefix') format('embedded-opentype'),
17 | url('../fonts/proximanova-regular-webfont.woff') format('woff'),
18 | url('../proximanova-regular-webfont.ttf') format('truetype'),
19 | url('../proximanova-regular-webfont.svg#proxima_nova_rgregular') format('svg');
20 | font-weight: normal;
21 | font-style: normal;
22 | }
--------------------------------------------------------------------------------
/example/less/forms.less:
--------------------------------------------------------------------------------
1 | input[type="text"],
2 | button {
3 | margin: 5px 0;
4 | font-family: @font_family;
5 | font-size: @font_size;
6 | padding: 10px;
7 | .rounded(5px);
8 | border: 1px solid #ccc;
9 | }
10 |
11 | button {
12 | .gradient(#aaa, #eee, #fff);
13 | }
14 | button:active {
15 | .gradient(#fff, #eee, #eee);
16 | }
--------------------------------------------------------------------------------
/example/less/reset.less:
--------------------------------------------------------------------------------
1 | //
2 | // Reset CSS
3 | // Adapted from http://github.com/necolas/normalize.css
4 | // --------------------------------------------------
5 | .clear {
6 | clear: both;
7 | }
8 |
9 | .clearfix:after {
10 | content: ".";
11 | display: block;
12 | clear: both;
13 | visibility: hidden;
14 | line-height: 0;
15 | height: 0;
16 | }
17 |
18 | .clearfix {
19 | display: inline-block;
20 | }
21 |
22 | html[xmlns] .clearfix {
23 | display: block;
24 | }
25 |
26 | * html .clearfix {
27 | height: 1%;
28 | }
29 |
30 | // Display in IE6-9 and FF3
31 | // -------------------------
32 |
33 | article,
34 | aside,
35 | details,
36 | figcaption,
37 | figure,
38 | footer,
39 | header,
40 | hgroup,
41 | nav,
42 | section {
43 | display: block;
44 | }
45 |
46 | table {
47 | width: 100%;
48 | font-size: 13px;
49 | }
50 | table thead th {
51 | background: #fff;
52 | border-bottom: 1px solid #ccc;
53 | }
54 | table th,
55 | table td {
56 | padding: 5px;
57 | }
58 | table tr td {
59 | border: 1px solid #ccc;
60 | }
61 |
62 | // Display block in IE6-9 and FF3
63 | // -------------------------
64 |
65 | audio,
66 | canvas,
67 | video {
68 | display: inline-block;
69 | *display: inline;
70 | *zoom: 1;
71 | }
72 |
73 | // Prevents modern browsers from displaying 'audio' without controls
74 | // -------------------------
75 |
76 | audio:not([controls]) {
77 | display: none;
78 | }
79 |
80 | // Base settings
81 | // -------------------------
82 |
83 | html {
84 | font-size: 100%;
85 | -webkit-text-size-adjust: 100%;
86 | -ms-text-size-adjust: 100%;
87 | }
88 | // Hover & Active
89 | a:hover,
90 | a:active {
91 | outline: 0;
92 | }
93 |
94 | // Prevents sub and sup affecting line-height in all browsers
95 | // -------------------------
96 |
97 | sub,
98 | sup {
99 | position: relative;
100 | font-size: 75%;
101 | line-height: 0;
102 | vertical-align: baseline;
103 | }
104 | sup {
105 | top: -0.5em;
106 | }
107 | sub {
108 | bottom: -0.25em;
109 | }
110 |
111 | // Img border in a's and image quality
112 | // -------------------------
113 |
114 | img {
115 | /* Responsive images (ensure images don't scale beyond their parents) */
116 | max-width: 100%; /* Part 1: Set a maxium relative to the parent */
117 | width: auto\9; /* IE7-8 need help adjusting responsive images */
118 | height: auto; /* Part 2: Scale the height according to the width, otherwise you get stretching */
119 |
120 | vertical-align: middle;
121 | border: 0;
122 | -ms-interpolation-mode: bicubic;
123 | }
124 |
125 | // Prevent max-width from affecting Google Maps
126 | #map_canvas img,
127 | .google-maps img {
128 | max-width: none;
129 | }
130 |
131 | // Forms
132 | // -------------------------
133 |
134 | // Font size in all browsers, margin changes, misc consistency
135 | button,
136 | input,
137 | select,
138 | textarea {
139 | margin: 0;
140 | font-size: 100%;
141 | vertical-align: middle;
142 | }
143 | button,
144 | input {
145 | *overflow: visible; // Inner spacing ie IE6/7
146 | line-height: normal; // FF3/4 have !important on line-height in UA stylesheet
147 | }
148 | button::-moz-focus-inner,
149 | input::-moz-focus-inner { // Inner padding and border oddities in FF3/4
150 | padding: 0;
151 | border: 0;
152 | }
153 | button,
154 | html input[type="button"], // Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls.
155 | input[type="reset"],
156 | input[type="submit"] {
157 | -webkit-appearance: button; // Corrects inability to style clickable `input` types in iOS.
158 | cursor: pointer; // Improves usability and consistency of cursor style between image-type `input` and others.
159 | }
160 | label,
161 | select,
162 | button,
163 | input[type="button"],
164 | input[type="reset"],
165 | input[type="submit"],
166 | input[type="radio"],
167 | input[type="checkbox"] {
168 | cursor: pointer; // Improves usability and consistency of cursor style between image-type `input` and others.
169 | }
170 | input[type="search"] { // Appearance in Safari/Chrome
171 | -webkit-appearance: textfield;
172 | }
173 | input[type="search"]::-webkit-search-decoration,
174 | input[type="search"]::-webkit-search-cancel-button {
175 | -webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5
176 | }
177 | textarea {
178 | overflow: auto; // Remove vertical scrollbar in IE6-9
179 | vertical-align: top; // Readability and alignment cross-browser
180 | }
181 |
182 |
183 | // Printing
184 | // -------------------------
185 | // Source: https://github.com/h5bp/html5-boilerplate/blob/master/css/main.css
186 |
187 | @media print {
188 |
189 | * {
190 | text-shadow: none !important;
191 | color: #000 !important; // Black prints faster: h5bp.com/s
192 | background: transparent !important;
193 | box-shadow: none !important;
194 | }
195 |
196 | a,
197 | a:visited {
198 | text-decoration: underline;
199 | }
200 |
201 | a[href]:after {
202 | content: " (" attr(href) ")";
203 | }
204 |
205 | abbr[title]:after {
206 | content: " (" attr(title) ")";
207 | }
208 |
209 | // Don't show links for images, or javascript/internal links
210 | .ir a:after,
211 | a[href^="javascript:"]:after,
212 | a[href^="#"]:after {
213 | content: "";
214 | }
215 |
216 | pre,
217 | blockquote {
218 | border: 1px solid #999;
219 | page-break-inside: avoid;
220 | }
221 |
222 | thead {
223 | display: table-header-group; // h5bp.com/t
224 | }
225 |
226 | tr,
227 | img {
228 | page-break-inside: avoid;
229 | }
230 |
231 | img {
232 | max-width: 100% !important;
233 | }
234 |
235 | @page {
236 | margin: 0.5cm;
237 | }
238 |
239 | p,
240 | h2,
241 | h3 {
242 | orphans: 3;
243 | widows: 3;
244 | }
245 |
246 | h2,
247 | h3 {
248 | page-break-after: avoid;
249 | }
250 | }
--------------------------------------------------------------------------------
/example/less/style.less:
--------------------------------------------------------------------------------
1 | @font_size: 15px;
2 | @font_family: 'ProximaNovaLight', 'Helvetica Neue', 'Helvetica', 'Arial';
3 | @width: 700px;
4 |
5 | @import "reset.less";
6 | @import "elements.less";
7 | @import "fonts.less";
8 | @import "forms.less";
9 | @import "buttons.less";
10 |
11 | body {
12 | background: #fff url(../img/gray_jean.png);
13 | color: #333;
14 | font-size: @font_size;
15 | line-height: 170%;
16 | font-family: @font_family;
17 | margin: 0;
18 | text-shadow: 1px 1px 0 #fff;
19 | }
20 |
21 | a {
22 | color: #333;
23 | }
24 |
25 | #container {
26 | width: @width;
27 | margin: 30px auto 50px auto;
28 | }
29 |
30 | h1 {
31 | text-align: center;
32 |
33 | span {
34 | display: block;
35 | margin: 10px 0;
36 | font-style: italic;
37 | font-size: 16px;
38 | }
39 | }
40 |
41 | h3.grey-line {
42 | position: relative;
43 | text-align: center;
44 | z-index: 1;
45 | }
46 | h3.grey-line:before {
47 | border-top: 1px solid #ccc;
48 | content:"";
49 | margin: 0 auto;
50 | position: absolute;
51 | top: 15px; left: 0; right: 0; bottom: 0;
52 | width: 100%;
53 | z-index: -1;
54 | }
55 | h3.grey-line span {
56 | background: url(../img/gray_jean.png);
57 | padding: 0 10px;
58 | }
59 |
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/animated-overlay.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/animated-overlay.gif
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/ui-icons_222222_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/ui-icons_222222_256x240.png
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/ui-icons_228ef1_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/ui-icons_228ef1_256x240.png
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/ui-icons_ef8c08_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/ui-icons_ef8c08_256x240.png
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/ui-icons_ffd27a_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/ui-icons_ffd27a_256x240.png
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/images/ui-icons_ffffff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/example/lib/jquery-ui/css/ui-lightness/images/ui-icons_ffffff_256x240.png
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/jquery-ui-1.10.2.custom.css:
--------------------------------------------------------------------------------
1 | /*! jQuery UI - v1.10.2 - 2013-03-22
2 | * http://jqueryui.com
3 | * Includes: jquery.ui.core.css, jquery.ui.autocomplete.css, jquery.ui.menu.css
4 | * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=gloss_wave&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=highlight_soft&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=glass&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=glass&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=highlight_soft&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=diagonals_thick&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=diagonals_thick&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=flat&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
5 | * Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
6 |
7 | /* Layout helpers
8 | ----------------------------------*/
9 | .ui-helper-hidden {
10 | display: none;
11 | }
12 | .ui-helper-hidden-accessible {
13 | border: 0;
14 | clip: rect(0 0 0 0);
15 | height: 1px;
16 | margin: -1px;
17 | overflow: hidden;
18 | padding: 0;
19 | position: absolute;
20 | width: 1px;
21 | }
22 | .ui-helper-reset {
23 | margin: 0;
24 | padding: 0;
25 | border: 0;
26 | outline: 0;
27 | line-height: 1.3;
28 | text-decoration: none;
29 | font-size: 100%;
30 | list-style: none;
31 | }
32 | .ui-helper-clearfix:before,
33 | .ui-helper-clearfix:after {
34 | content: "";
35 | display: table;
36 | border-collapse: collapse;
37 | }
38 | .ui-helper-clearfix:after {
39 | clear: both;
40 | }
41 | .ui-helper-clearfix {
42 | min-height: 0; /* support: IE7 */
43 | }
44 | .ui-helper-zfix {
45 | width: 100%;
46 | height: 100%;
47 | top: 0;
48 | left: 0;
49 | position: absolute;
50 | opacity: 0;
51 | filter:Alpha(Opacity=0);
52 | }
53 |
54 | .ui-front {
55 | z-index: 100;
56 | }
57 |
58 |
59 | /* Interaction Cues
60 | ----------------------------------*/
61 | .ui-state-disabled {
62 | cursor: default !important;
63 | }
64 |
65 |
66 | /* Icons
67 | ----------------------------------*/
68 |
69 | /* states and images */
70 | .ui-icon {
71 | display: block;
72 | text-indent: -99999px;
73 | overflow: hidden;
74 | background-repeat: no-repeat;
75 | }
76 |
77 |
78 | /* Misc visuals
79 | ----------------------------------*/
80 |
81 | /* Overlays */
82 | .ui-widget-overlay {
83 | position: fixed;
84 | top: 0;
85 | left: 0;
86 | width: 100%;
87 | height: 100%;
88 | }
89 | .ui-autocomplete {
90 | position: absolute;
91 | top: 0;
92 | left: 0;
93 | cursor: default;
94 | }
95 | .ui-menu {
96 | list-style: none;
97 | padding: 2px;
98 | margin: 0;
99 | display: block;
100 | outline: none;
101 | }
102 | .ui-menu .ui-menu {
103 | margin-top: -3px;
104 | position: absolute;
105 | }
106 | .ui-menu .ui-menu-item {
107 | margin: 0;
108 | padding: 0;
109 | width: 100%;
110 | }
111 | .ui-menu .ui-menu-divider {
112 | margin: 5px -2px 5px -2px;
113 | height: 0;
114 | font-size: 0;
115 | line-height: 0;
116 | border-width: 1px 0 0 0;
117 | }
118 | .ui-menu .ui-menu-item a {
119 | text-decoration: none;
120 | display: block;
121 | padding: 2px .4em;
122 | line-height: 1.5;
123 | min-height: 0; /* support: IE7 */
124 | font-weight: normal;
125 | }
126 | .ui-menu .ui-menu-item a.ui-state-focus,
127 | .ui-menu .ui-menu-item a.ui-state-active {
128 | font-weight: normal;
129 | margin: -1px;
130 | }
131 |
132 | .ui-menu .ui-state-disabled {
133 | font-weight: normal;
134 | margin: .4em 0 .2em;
135 | line-height: 1.5;
136 | }
137 | .ui-menu .ui-state-disabled a {
138 | cursor: default;
139 | }
140 |
141 | /* icon support */
142 | .ui-menu-icons {
143 | position: relative;
144 | }
145 | .ui-menu-icons .ui-menu-item a {
146 | position: relative;
147 | padding-left: 2em;
148 | }
149 |
150 | /* left-aligned */
151 | .ui-menu .ui-icon {
152 | position: absolute;
153 | top: .2em;
154 | left: .2em;
155 | }
156 |
157 | /* right-aligned */
158 | .ui-menu .ui-menu-icon {
159 | position: static;
160 | float: right;
161 | }
162 |
163 | /* Component containers
164 | ----------------------------------*/
165 | .ui-widget {
166 | font-family: Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;
167 | font-size: 1.1em;
168 | }
169 | .ui-widget .ui-widget {
170 | font-size: 1em;
171 | }
172 | .ui-widget input,
173 | .ui-widget select,
174 | .ui-widget textarea,
175 | .ui-widget button {
176 | font-family: Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;
177 | font-size: 1em;
178 | }
179 | .ui-widget-content {
180 | border: 1px solid #dddddd;
181 | background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;
182 | color: #333333;
183 | }
184 | .ui-widget-content a {
185 | color: #333333;
186 | }
187 | .ui-widget-header {
188 | border: 1px solid #e78f08;
189 | background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x;
190 | color: #ffffff;
191 | font-weight: bold;
192 | }
193 | .ui-widget-header a {
194 | color: #ffffff;
195 | }
196 |
197 | /* Interaction states
198 | ----------------------------------*/
199 | .ui-state-default,
200 | .ui-widget-content .ui-state-default,
201 | .ui-widget-header .ui-state-default {
202 | border: 1px solid #cccccc;
203 | background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x;
204 | font-weight: bold;
205 | color: #1c94c4;
206 | }
207 | .ui-state-default a,
208 | .ui-state-default a:link,
209 | .ui-state-default a:visited {
210 | color: #1c94c4;
211 | text-decoration: none;
212 | }
213 | .ui-state-hover,
214 | .ui-widget-content .ui-state-hover,
215 | .ui-widget-header .ui-state-hover,
216 | .ui-state-focus,
217 | .ui-widget-content .ui-state-focus,
218 | .ui-widget-header .ui-state-focus {
219 | border: 1px solid #fbcb09;
220 | background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x;
221 | font-weight: bold;
222 | color: #c77405;
223 | }
224 | .ui-state-hover a,
225 | .ui-state-hover a:hover,
226 | .ui-state-hover a:link,
227 | .ui-state-hover a:visited {
228 | color: #c77405;
229 | text-decoration: none;
230 | }
231 | .ui-state-active,
232 | .ui-widget-content .ui-state-active,
233 | .ui-widget-header .ui-state-active {
234 | border: 1px solid #fbd850;
235 | background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;
236 | font-weight: bold;
237 | color: #eb8f00;
238 | }
239 | .ui-state-active a,
240 | .ui-state-active a:link,
241 | .ui-state-active a:visited {
242 | color: #eb8f00;
243 | text-decoration: none;
244 | }
245 |
246 | /* Interaction Cues
247 | ----------------------------------*/
248 | .ui-state-highlight,
249 | .ui-widget-content .ui-state-highlight,
250 | .ui-widget-header .ui-state-highlight {
251 | border: 1px solid #fed22f;
252 | background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x;
253 | color: #363636;
254 | }
255 | .ui-state-highlight a,
256 | .ui-widget-content .ui-state-highlight a,
257 | .ui-widget-header .ui-state-highlight a {
258 | color: #363636;
259 | }
260 | .ui-state-error,
261 | .ui-widget-content .ui-state-error,
262 | .ui-widget-header .ui-state-error {
263 | border: 1px solid #cd0a0a;
264 | background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat;
265 | color: #ffffff;
266 | }
267 | .ui-state-error a,
268 | .ui-widget-content .ui-state-error a,
269 | .ui-widget-header .ui-state-error a {
270 | color: #ffffff;
271 | }
272 | .ui-state-error-text,
273 | .ui-widget-content .ui-state-error-text,
274 | .ui-widget-header .ui-state-error-text {
275 | color: #ffffff;
276 | }
277 | .ui-priority-primary,
278 | .ui-widget-content .ui-priority-primary,
279 | .ui-widget-header .ui-priority-primary {
280 | font-weight: bold;
281 | }
282 | .ui-priority-secondary,
283 | .ui-widget-content .ui-priority-secondary,
284 | .ui-widget-header .ui-priority-secondary {
285 | opacity: .7;
286 | filter:Alpha(Opacity=70);
287 | font-weight: normal;
288 | }
289 | .ui-state-disabled,
290 | .ui-widget-content .ui-state-disabled,
291 | .ui-widget-header .ui-state-disabled {
292 | opacity: .35;
293 | filter:Alpha(Opacity=35);
294 | background-image: none;
295 | }
296 | .ui-state-disabled .ui-icon {
297 | filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
298 | }
299 |
300 | /* Icons
301 | ----------------------------------*/
302 |
303 | /* states and images */
304 | .ui-icon {
305 | width: 16px;
306 | height: 16px;
307 | }
308 | .ui-icon,
309 | .ui-widget-content .ui-icon {
310 | background-image: url(images/ui-icons_222222_256x240.png);
311 | }
312 | .ui-widget-header .ui-icon {
313 | background-image: url(images/ui-icons_ffffff_256x240.png);
314 | }
315 | .ui-state-default .ui-icon {
316 | background-image: url(images/ui-icons_ef8c08_256x240.png);
317 | }
318 | .ui-state-hover .ui-icon,
319 | .ui-state-focus .ui-icon {
320 | background-image: url(images/ui-icons_ef8c08_256x240.png);
321 | }
322 | .ui-state-active .ui-icon {
323 | background-image: url(images/ui-icons_ef8c08_256x240.png);
324 | }
325 | .ui-state-highlight .ui-icon {
326 | background-image: url(images/ui-icons_228ef1_256x240.png);
327 | }
328 | .ui-state-error .ui-icon,
329 | .ui-state-error-text .ui-icon {
330 | background-image: url(images/ui-icons_ffd27a_256x240.png);
331 | }
332 |
333 | /* positioning */
334 | .ui-icon-blank { background-position: 16px 16px; }
335 | .ui-icon-carat-1-n { background-position: 0 0; }
336 | .ui-icon-carat-1-ne { background-position: -16px 0; }
337 | .ui-icon-carat-1-e { background-position: -32px 0; }
338 | .ui-icon-carat-1-se { background-position: -48px 0; }
339 | .ui-icon-carat-1-s { background-position: -64px 0; }
340 | .ui-icon-carat-1-sw { background-position: -80px 0; }
341 | .ui-icon-carat-1-w { background-position: -96px 0; }
342 | .ui-icon-carat-1-nw { background-position: -112px 0; }
343 | .ui-icon-carat-2-n-s { background-position: -128px 0; }
344 | .ui-icon-carat-2-e-w { background-position: -144px 0; }
345 | .ui-icon-triangle-1-n { background-position: 0 -16px; }
346 | .ui-icon-triangle-1-ne { background-position: -16px -16px; }
347 | .ui-icon-triangle-1-e { background-position: -32px -16px; }
348 | .ui-icon-triangle-1-se { background-position: -48px -16px; }
349 | .ui-icon-triangle-1-s { background-position: -64px -16px; }
350 | .ui-icon-triangle-1-sw { background-position: -80px -16px; }
351 | .ui-icon-triangle-1-w { background-position: -96px -16px; }
352 | .ui-icon-triangle-1-nw { background-position: -112px -16px; }
353 | .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
354 | .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
355 | .ui-icon-arrow-1-n { background-position: 0 -32px; }
356 | .ui-icon-arrow-1-ne { background-position: -16px -32px; }
357 | .ui-icon-arrow-1-e { background-position: -32px -32px; }
358 | .ui-icon-arrow-1-se { background-position: -48px -32px; }
359 | .ui-icon-arrow-1-s { background-position: -64px -32px; }
360 | .ui-icon-arrow-1-sw { background-position: -80px -32px; }
361 | .ui-icon-arrow-1-w { background-position: -96px -32px; }
362 | .ui-icon-arrow-1-nw { background-position: -112px -32px; }
363 | .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
364 | .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
365 | .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
366 | .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
367 | .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
368 | .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
369 | .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
370 | .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
371 | .ui-icon-arrowthick-1-n { background-position: 0 -48px; }
372 | .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
373 | .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
374 | .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
375 | .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
376 | .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
377 | .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
378 | .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
379 | .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
380 | .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
381 | .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
382 | .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
383 | .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
384 | .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
385 | .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
386 | .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
387 | .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
388 | .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
389 | .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
390 | .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
391 | .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
392 | .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
393 | .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
394 | .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
395 | .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
396 | .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
397 | .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
398 | .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
399 | .ui-icon-arrow-4 { background-position: 0 -80px; }
400 | .ui-icon-arrow-4-diag { background-position: -16px -80px; }
401 | .ui-icon-extlink { background-position: -32px -80px; }
402 | .ui-icon-newwin { background-position: -48px -80px; }
403 | .ui-icon-refresh { background-position: -64px -80px; }
404 | .ui-icon-shuffle { background-position: -80px -80px; }
405 | .ui-icon-transfer-e-w { background-position: -96px -80px; }
406 | .ui-icon-transferthick-e-w { background-position: -112px -80px; }
407 | .ui-icon-folder-collapsed { background-position: 0 -96px; }
408 | .ui-icon-folder-open { background-position: -16px -96px; }
409 | .ui-icon-document { background-position: -32px -96px; }
410 | .ui-icon-document-b { background-position: -48px -96px; }
411 | .ui-icon-note { background-position: -64px -96px; }
412 | .ui-icon-mail-closed { background-position: -80px -96px; }
413 | .ui-icon-mail-open { background-position: -96px -96px; }
414 | .ui-icon-suitcase { background-position: -112px -96px; }
415 | .ui-icon-comment { background-position: -128px -96px; }
416 | .ui-icon-person { background-position: -144px -96px; }
417 | .ui-icon-print { background-position: -160px -96px; }
418 | .ui-icon-trash { background-position: -176px -96px; }
419 | .ui-icon-locked { background-position: -192px -96px; }
420 | .ui-icon-unlocked { background-position: -208px -96px; }
421 | .ui-icon-bookmark { background-position: -224px -96px; }
422 | .ui-icon-tag { background-position: -240px -96px; }
423 | .ui-icon-home { background-position: 0 -112px; }
424 | .ui-icon-flag { background-position: -16px -112px; }
425 | .ui-icon-calendar { background-position: -32px -112px; }
426 | .ui-icon-cart { background-position: -48px -112px; }
427 | .ui-icon-pencil { background-position: -64px -112px; }
428 | .ui-icon-clock { background-position: -80px -112px; }
429 | .ui-icon-disk { background-position: -96px -112px; }
430 | .ui-icon-calculator { background-position: -112px -112px; }
431 | .ui-icon-zoomin { background-position: -128px -112px; }
432 | .ui-icon-zoomout { background-position: -144px -112px; }
433 | .ui-icon-search { background-position: -160px -112px; }
434 | .ui-icon-wrench { background-position: -176px -112px; }
435 | .ui-icon-gear { background-position: -192px -112px; }
436 | .ui-icon-heart { background-position: -208px -112px; }
437 | .ui-icon-star { background-position: -224px -112px; }
438 | .ui-icon-link { background-position: -240px -112px; }
439 | .ui-icon-cancel { background-position: 0 -128px; }
440 | .ui-icon-plus { background-position: -16px -128px; }
441 | .ui-icon-plusthick { background-position: -32px -128px; }
442 | .ui-icon-minus { background-position: -48px -128px; }
443 | .ui-icon-minusthick { background-position: -64px -128px; }
444 | .ui-icon-close { background-position: -80px -128px; }
445 | .ui-icon-closethick { background-position: -96px -128px; }
446 | .ui-icon-key { background-position: -112px -128px; }
447 | .ui-icon-lightbulb { background-position: -128px -128px; }
448 | .ui-icon-scissors { background-position: -144px -128px; }
449 | .ui-icon-clipboard { background-position: -160px -128px; }
450 | .ui-icon-copy { background-position: -176px -128px; }
451 | .ui-icon-contact { background-position: -192px -128px; }
452 | .ui-icon-image { background-position: -208px -128px; }
453 | .ui-icon-video { background-position: -224px -128px; }
454 | .ui-icon-script { background-position: -240px -128px; }
455 | .ui-icon-alert { background-position: 0 -144px; }
456 | .ui-icon-info { background-position: -16px -144px; }
457 | .ui-icon-notice { background-position: -32px -144px; }
458 | .ui-icon-help { background-position: -48px -144px; }
459 | .ui-icon-check { background-position: -64px -144px; }
460 | .ui-icon-bullet { background-position: -80px -144px; }
461 | .ui-icon-radio-on { background-position: -96px -144px; }
462 | .ui-icon-radio-off { background-position: -112px -144px; }
463 | .ui-icon-pin-w { background-position: -128px -144px; }
464 | .ui-icon-pin-s { background-position: -144px -144px; }
465 | .ui-icon-play { background-position: 0 -160px; }
466 | .ui-icon-pause { background-position: -16px -160px; }
467 | .ui-icon-seek-next { background-position: -32px -160px; }
468 | .ui-icon-seek-prev { background-position: -48px -160px; }
469 | .ui-icon-seek-end { background-position: -64px -160px; }
470 | .ui-icon-seek-start { background-position: -80px -160px; }
471 | /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
472 | .ui-icon-seek-first { background-position: -80px -160px; }
473 | .ui-icon-stop { background-position: -96px -160px; }
474 | .ui-icon-eject { background-position: -112px -160px; }
475 | .ui-icon-volume-off { background-position: -128px -160px; }
476 | .ui-icon-volume-on { background-position: -144px -160px; }
477 | .ui-icon-power { background-position: 0 -176px; }
478 | .ui-icon-signal-diag { background-position: -16px -176px; }
479 | .ui-icon-signal { background-position: -32px -176px; }
480 | .ui-icon-battery-0 { background-position: -48px -176px; }
481 | .ui-icon-battery-1 { background-position: -64px -176px; }
482 | .ui-icon-battery-2 { background-position: -80px -176px; }
483 | .ui-icon-battery-3 { background-position: -96px -176px; }
484 | .ui-icon-circle-plus { background-position: 0 -192px; }
485 | .ui-icon-circle-minus { background-position: -16px -192px; }
486 | .ui-icon-circle-close { background-position: -32px -192px; }
487 | .ui-icon-circle-triangle-e { background-position: -48px -192px; }
488 | .ui-icon-circle-triangle-s { background-position: -64px -192px; }
489 | .ui-icon-circle-triangle-w { background-position: -80px -192px; }
490 | .ui-icon-circle-triangle-n { background-position: -96px -192px; }
491 | .ui-icon-circle-arrow-e { background-position: -112px -192px; }
492 | .ui-icon-circle-arrow-s { background-position: -128px -192px; }
493 | .ui-icon-circle-arrow-w { background-position: -144px -192px; }
494 | .ui-icon-circle-arrow-n { background-position: -160px -192px; }
495 | .ui-icon-circle-zoomin { background-position: -176px -192px; }
496 | .ui-icon-circle-zoomout { background-position: -192px -192px; }
497 | .ui-icon-circle-check { background-position: -208px -192px; }
498 | .ui-icon-circlesmall-plus { background-position: 0 -208px; }
499 | .ui-icon-circlesmall-minus { background-position: -16px -208px; }
500 | .ui-icon-circlesmall-close { background-position: -32px -208px; }
501 | .ui-icon-squaresmall-plus { background-position: -48px -208px; }
502 | .ui-icon-squaresmall-minus { background-position: -64px -208px; }
503 | .ui-icon-squaresmall-close { background-position: -80px -208px; }
504 | .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
505 | .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
506 | .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
507 | .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
508 | .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
509 | .ui-icon-grip-diagonal-se { background-position: -80px -224px; }
510 |
511 |
512 | /* Misc visuals
513 | ----------------------------------*/
514 |
515 | /* Corner radius */
516 | .ui-corner-all,
517 | .ui-corner-top,
518 | .ui-corner-left,
519 | .ui-corner-tl {
520 | border-top-left-radius: 4px;
521 | }
522 | .ui-corner-all,
523 | .ui-corner-top,
524 | .ui-corner-right,
525 | .ui-corner-tr {
526 | border-top-right-radius: 4px;
527 | }
528 | .ui-corner-all,
529 | .ui-corner-bottom,
530 | .ui-corner-left,
531 | .ui-corner-bl {
532 | border-bottom-left-radius: 4px;
533 | }
534 | .ui-corner-all,
535 | .ui-corner-bottom,
536 | .ui-corner-right,
537 | .ui-corner-br {
538 | border-bottom-right-radius: 4px;
539 | }
540 |
541 | /* Overlays */
542 | .ui-widget-overlay {
543 | background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat;
544 | opacity: .5;
545 | filter: Alpha(Opacity=50);
546 | }
547 | .ui-widget-shadow {
548 | margin: -5px 0 0 -5px;
549 | padding: 5px;
550 | background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x;
551 | opacity: .2;
552 | filter: Alpha(Opacity=20);
553 | border-radius: 5px;
554 | }
555 |
--------------------------------------------------------------------------------
/example/lib/jquery-ui/css/ui-lightness/jquery-ui-1.10.2.custom.min.css:
--------------------------------------------------------------------------------
1 | /*! jQuery UI - v1.10.2 - 2013-03-22
2 | * http://jqueryui.com
3 | * Includes: jquery.ui.core.css, jquery.ui.autocomplete.css, jquery.ui.menu.css
4 | * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=gloss_wave&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=highlight_soft&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=glass&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=glass&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=highlight_soft&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=diagonals_thick&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=diagonals_thick&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=flat&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
5 | * Copyright 2013 jQuery Foundation and other contributors Licensed MIT */.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:0}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;width:100%}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;min-height:0;font-weight:400}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:400;margin:-1px}.ui-menu .ui-state-disabled{font-weight:400;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-widget{font-family:Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #ddd;background:#eee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #e78f08;background:#f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x;color:#fff;font-weight:bold}.ui-widget-header a{color:#fff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #ccc;background:#f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#1c94c4}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#1c94c4;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #fbcb09;background:#fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#c77405}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited{color:#c77405;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #fbd850;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#eb8f00}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#eb8f00;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fed22f;background:#ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat;color:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_ffffff_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_ef8c08_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_ef8c08_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_ef8c08_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_228ef1_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_ffd27a_256x240.png)}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat;opacity:.5;filter:Alpha(Opacity=50)}.ui-widget-shadow{margin:-5px 0 0 -5px;padding:5px;background:#000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x;opacity:.2;filter:Alpha(Opacity=20);border-radius:5px}
--------------------------------------------------------------------------------
/example/lib/prism.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Prism: Lightweight, robust, elegant syntax highlighting
3 | * MIT license http://www.opensource.org/licenses/mit-license.php/
4 | * @author Lea Verou http://lea.verou.me
5 | */(function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},clone:function(e){var n=t.util.type(e);switch(n){case"Object":var r={};for(var i in e)e.hasOwnProperty(i)&&(r[i]=t.util.clone(e[i]));return r;case"Array":return e.slice()}return e}},languages:{extend:function(e,n){var r=t.util.clone(t.languages[e]);for(var i in n)r[i]=n[i];return r},insertBefore:function(e,n,r,i){i=i||t.languages;var s=i[e],o={};for(var u in s)if(s.hasOwnProperty(u)){if(u==n)for(var a in r)r.hasOwnProperty(a)&&(o[a]=r[a]);o[u]=s[u]}return i[e]=o},DFS:function(e,n){for(var r in e){n.call(e,r,e[r]);t.util.type(e)==="Object"&&t.languages.DFS(e[r],n)}}},highlightAll:function(e,n){var r=document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');for(var i=0,s;s=r[i++];)t.highlightElement(s,e===!0,n)},highlightElement:function(r,i,s){var o,u,a=r;while(a&&!e.test(a.className))a=a.parentNode;if(a){o=(a.className.match(e)||[,""])[1];u=t.languages[o]}if(!u)return;r.className=r.className.replace(e,"").replace(/\s+/g," ")+" language-"+o;a=r.parentNode;/pre/i.test(a.nodeName)&&(a.className=a.className.replace(e,"").replace(/\s+/g," ")+" language-"+o);var f=r.textContent;if(!f)return;f=f.replace(/&/g,"&").replace(//g,">").replace(/\u00a0/g," ");var l={element:r,language:o,grammar:u,code:f};t.hooks.run("before-highlight",l);if(i&&self.Worker){var c=new Worker(t.filename);c.onmessage=function(e){l.highlightedCode=n.stringify(JSON.parse(e.data));l.element.innerHTML=l.highlightedCode;s&&s.call(l.element);t.hooks.run("after-highlight",l)};c.postMessage(JSON.stringify({language:l.language,code:l.code}))}else{l.highlightedCode=t.highlight(l.code,l.grammar);l.element.innerHTML=l.highlightedCode;s&&s.call(r);t.hooks.run("after-highlight",l)}},highlight:function(e,r){return n.stringify(t.tokenize(e,r))},tokenize:function(e,n){var r=t.Token,i=[e],s=n.rest;if(s){for(var o in s)n[o]=s[o];delete n.rest}e:for(var o in n){if(!n.hasOwnProperty(o)||!n[o])continue;var u=n[o],a=u.inside,f=!!u.lookbehind||0;u=u.pattern||u;for(var l=0;le.length)break e;if(c instanceof r)continue;u.lastIndex=0;var h=u.exec(c);if(h){f&&(f=h[1].length);var p=h.index-1+f,h=h[0].slice(f),d=h.length,v=p+d,m=c.slice(0,p+1),g=c.slice(v+1),y=[l,1];m&&y.push(m);var b=new r(o,a?t.tokenize(h,a):h);y.push(b);g&&y.push(g);Array.prototype.splice.apply(i,y)}}}return i},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[];r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(!r||!r.length)return;for(var i=0,s;s=r[i++];)s(n)}}},n=t.Token=function(e,t){this.type=e;this.content=t};n.stringify=function(e){if(typeof e=="string")return e;if(Object.prototype.toString.call(e)=="[object Array]")return e.map(n.stringify).join("");var r={type:e.type,content:n.stringify(e.content),tag:"span",classes:["token",e.type],attributes:{}};r.type=="comment"&&(r.attributes.spellcheck="true");t.hooks.run("wrap",r);var i="";for(var s in r.attributes)i+=s+'="'+(r.attributes[s]||"")+'"';return"<"+r.tag+' class="'+r.classes.join(" ")+'" '+i+">"+r.content+""+r.tag+">"};if(!self.document){self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,i=n.code;self.postMessage(JSON.stringify(t.tokenize(i,t.languages[r])));self.close()},!1);return}var r=document.getElementsByTagName("script");r=r[r.length-1];if(r){t.filename=r.src;document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)}})();;
6 | Prism.languages.markup={comment:/<!--[\w\W]*?--(>|>)/g,prolog:/<\?.+?\?>/,doctype:/<!DOCTYPE.+?>/,cdata:/<!\[CDATA\[[\w\W]+?]]>/i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|\w+))?\s*)*\/?>/gi,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi,inside:{punctuation:/=|>|"/g}},punctuation:/\/?>/g,"attr-name":{pattern:/[\w:-]+/g,inside:{namespace:/^[\w-]+?:/}}}},entity:/&#?[\da-z]{1,8};/gi};Prism.hooks.add("wrap",function(e){e.type==="entity"&&(e.attributes.title=e.content.replace(/&/,"&"))});;
7 | Prism.languages.css={comment:/\/\*[\w\W]*?\*\//g,atrule:/@[\w-]+?(\s+[^;{]+)?(?=\s*{|\s*;)/gi,url:/url\((["']?).*?\1\)/gi,selector:/[^\{\}\s][^\{\}]*(?=\s*\{)/g,property:/(\b|\B)[a-z-]+(?=\s*:)/ig,string:/("|')(\\?.)*?\1/g,important:/\B!important\b/gi,ignore:/&(lt|gt|amp);/gi,punctuation:/[\{\};:]/g};Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{style:{pattern:/(<|<)style[\w\W]*?(>|>)[\w\W]*?(<|<)\/style(>|>)/ig,inside:{tag:{pattern:/(<|<)style[\w\W]*?(>|>)|(<|<)\/style(>|>)/ig,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css}}});;
8 | Prism.languages.clike={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|[^:]\/\/.*?(\r?\n|$))/g,lookbehind:!0},string:/("|')(\\?.)*?\1/g,keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,number:/\b-?(0x)?\d*\.?[\da-f]+\b/g,operator:/[-+]{1,2}|!|=?<|=?>|={1,2}|(&){1,2}|\|?\||\?|\*|\//g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};;
9 | Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(var|let|if|else|while|do|for|return|in|instanceof|function|new|with|typeof|try|catch|finally|null|break|continue)\b/g,number:/\b(-?(0x)?\d*\.?[\da-f]+|NaN|-?Infinity)\b/g});Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}});Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/(<|<)script[\w\W]*?(>|>)[\w\W]*?(<|<)\/script(>|>)/ig,inside:{tag:{pattern:/(<|<)script[\w\W]*?(>|>)|(<|<)\/script(>|>)/ig,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});;
10 |
--------------------------------------------------------------------------------
/jquery.timeAutocomplete.min.js:
--------------------------------------------------------------------------------
1 | (function(t){var e="timeAutocomplete",i=e+".time",o=function(){this.initialize.apply(this,arguments)};o.prototype={el:null,_formatter:null,_calling_from_init:!1,default_opts:{auto_complete:{delay:0,autoFocus:!0,minLength:0},auto_value:!0,value:"",formatter:"ampm"},initialize:function(e,i){this.options=t.extend(!0,{},this.default_opts,i),t.timeAutocompleteDefaults!==void 0&&(this.options=t.extend(!0,{},this.options,t.timeAutocompleteDefaults)),this.el=e},_callAutocomplete:function(){if(this.options.auto_complete.source=this._callFormatterMethod("filterSource",[this.el],function(){throw Error("You must set a hook_filterSource method in your formatter.")}),t.fn.autocomplete===void 0)throw Error("You need to include the jQuery UI bundle that has the Autocomplete plugin.");this.el.autocomplete(this.options.auto_complete)},_bindEvents:function(){var i=this,o=!0;t("body").on("click."+e,"ul.ui-autocomplete a",function(){o=!1,setTimeout(function(){o=!0},100)}),this.el.bind("keydown."+e,function(){i._keydownAutocomplete.apply(i,arguments)}).bind("keyup."+e,function(){i._keyupAutocomplete.apply(i,arguments)}).bind("blur."+e,function(){i._blurAutocomplete.apply(i,arguments)}).bind("focus."+e,function(){o&&i._focusAutocomplete.apply(i,arguments)}),this.options.auto_value&&this.el.trigger("blur."+e)},_setupPlaceholder:function(){this.el.attr("placeholder")===void 0&&this.el.attr("placeholder",this._callFormatterMethod("placeholderValue",[],""))},_focusAutocomplete:function(){var e=t.trim(this.el.val()).substr(0,2);this.el.data("uiAutocomplete")&&this.el.autocomplete("search",e)},_keydownAutocomplete:function(e){var i=t.trim(this.el.val()),o=[8,9,13,38,40];if(!~t.inArray(e.which,o)&&(8==e.which||i.length>1&&!~i.indexOf("h")&&!~i.indexOf(":")&&t.isNumeric(i)))try{this.el.autocomplete("close").autocomplete("disable")}catch(e){}},_keyupAutocomplete:function(){""==t.trim(this.el.val())&&this.el.data("uiAutocomplete")&&this.el.autocomplete("enable")},_blurAutocomplete:function(){var e=t.trim(this.el.val());e=this._callFormatterMethod("blur",[e],e);var i="";i=e?this._createStringFromFormat(this._readMind(e)):this._callFormatterMethod("blurEmpty",[e],e),this.el.val(i),this._attacheUsableTimeData()},_attacheUsableTimeData:function(){var e=t.trim(this.el.val());this.el.data(i,this._callFormatterMethod("getUsableTimeValue",[e]))},setFormatter:function(e){if(this.options.formatter=e||this.options.formatter,!t.timeAutocomplete.formatters[this.options.formatter])throw Error("Formatter: '"+e+"' was not found. Make sure you're loading it (formatters/"+this.options.formatter+".js) after you load src/TimeAutocomplete.js");this._formatter=new t.timeAutocomplete.formatters[this.options.formatter](this,this.options),this._calling_from_init||this._callAutocomplete(),this._calling_from_init=!1},getFormatter:function(){return this._formatter},getTime:function(){return this.el.data(i)||""},_callFormatterMethod:function(e,i,o){var s=this.getFormatter();return t.isFunction(s["hook_"+e])?s["hook_"+e].apply(s,i):o},_readMind:function(t){return this._callFormatterMethod("readMind",[t],t)},_createStringFromFormat:function(t){var e=""+t.h+t.sep+(""+t.m);return t.postfix&&(e+=t.postfix),e},_setValueAsTime:function(){var e=t.trim(this.el.val()),i=e.split(":");if(""==e&&this.options.value)this.setTime(this.options.value);else if(3==i.length&&this.isNumber(i[0])&&this.isNumber(i[1])&&this.isNumber(i[2]))this.setTime(e);else{var o=this._getCurrentTimeAsValue();this.el.val(o),this._attacheUsableTimeData()}},isNumber:function(t){return!isNaN(parseFloat(t))&&isFinite(t)},setTime:function(t){var e=t.replace(/[^0-9.]/g,""),i=e.match(/^[0-9]+$/);if(!i||!i.length||5!=i[0].length&&6!=i[0].length)throw Error("Setting a time must be in H:i:s format. Example: 03:30:00");var o=this._callFormatterMethod("getTimeObjectFromHis",[t]);o=this._createStringFromFormat(o),this.el.val(o),this._attacheUsableTimeData()},_getCurrentTimeAsValue:function(){for(var e=this.getFormatter(),i=[1987,1,17],o=this._getCurrentDate(),s=o.getHours(),n=o.getMinutes(),r=new Date(i[0],i[1],i[2],s,n).getTime(),a=e.options.times.slice().concat(e.options.times),p=[],m=0,h=a.length;h>m;m++){var l=this._callFormatterMethod("getTime",[a[m],i]),u=a[m+1]?this._callFormatterMethod("getTime",[a[m+1],i]):!1,c=!(-1===t.inArray(u,p));if(p.push(u),r>l&&(u&&u>=r||c))return a[m+1]}},_getCurrentDate:function(){return new Date},destroy:function(){this.el.removeData(e),this.el.removeData(i),this.el.unbind("."+e),this.el.data("uiAutocomplete")&&this.el.autocomplete("destroy")},render:function(){return this._calling_from_init=!0,this.setFormatter(),this._callAutocomplete(),this.options.auto_value&&this._setValueAsTime(),this._bindEvents(),this._setupPlaceholder(),this}},t.timeAutocomplete={formatters:{},_raw:o},t.fn.timeAutocomplete=function(i){return this.each(function(){var s=t(this);s.data(e)&&s.data(e).destroy();var n=new o(s,i).render();s.data(e,n)})}})(jQuery),function(t){t.timeAutocomplete.formatters.ampm=function(){this.initialize.apply(this,arguments)},t.timeAutocomplete.formatters.ampm.prototype={main_instance:null,options:{},default_opts:{from_selector:"",increment:15,start_hour:0,end_hour:24,pm_text:"PM",am_text:"AM",blur_empty_populate:!0,times:[],empty:{h:"12",m:"00",sep:":",postfix:" PM"}},initialize:function(e,i){this.main_instance=e,this.options=t.extend(!0,{},this.default_opts,i),this.generateTimes()},hook_placeholderValue:function(){return this.main_instance._createStringFromFormat(this.options.empty)},hook_filterSource:function(e){var i=this;return e=e[0],function(i,o){return function(s,n){var r=t.trim(e.value),a=t.ui.autocomplete.escapeRegex(s.term),p=~a.toLowerCase().indexOf("a"),m=~a.toLowerCase().indexOf("p"),h="",l=!(1!=r),u=(p||m)&&2>=a.replace(/a|m|p/gi,"").length;u&&(a=t.trim(a.replace(/a|m|p/gi,""))+":00 ",a+=p?o.options.am_text:o.options.pm_text),o.options.from_selector&&(h=o.detectAMPMFromInstanceOverlap()==o.options.am_text?o.options.pm_text:o.options.am_text);var c=RegExp("^"+a,"i"),f=[];r&&(f=t.grep(i,function(t){var e=h&&RegExp(h,"gi").test(t)||l&&"1:"!=t.substring(0,2)||~r.toLowerCase().indexOf("p")&&!~t.toLowerCase().indexOf("p")||~r.toLowerCase().indexOf("a")&&!~t.toLowerCase().indexOf("a");if(!e)return c.test(t)})),n(f)}}(i.options.times,i)},hook_blur:function(t){return 0==t.charAt(0)&&(t=t.substr(1)),t},hook_blurEmpty:function(){return this.options.blur_empty_populate?this.main_instance._createStringFromFormat(this.options.empty):""},hook_readMind:function(t){var e="";return t=t.toLowerCase(),!this.options.from_selector||~t.indexOf("a")||~t.indexOf("p")||(e=this.detectAMPMFromInstanceOverlap()),this.getTimeObject(t,e)},hook_getUsableTimeValue:function(t){return this.parseTime(t)},hook_getTime:function(t,e){var i=this.parseTime(t).split(this.options.empty.sep),o=i[0],s=i[1];return new Date(e[0],e[1],e[2],o,s).getTime()},hook_getTimeObjectFromHis:function(t){var e=t.split(":"),i=e[0],o=e[1],s=i>=12?this.options.pm_text:this.options.am_text;2==i.length&&10>parseInt(i,10)&&(i=i.substr(1)),i>12&&(i-=12),0==i&&(i=12);var n={h:parseInt(i,10),m:o,sep:this.options.empty.sep,postfix:" "+s};return n},detectAMPMFromInstanceOverlap:function(){var e="",i=this.getTimeObject(t(this.options.from_selector).val()),o=this.getTimeObject(t.trim(this.main_instance.el.val()));if(i.postfix&&(~i.postfix.toLowerCase().indexOf("a")||~i.postfix.toLowerCase().indexOf("p"))){var s=~i.postfix.toLowerCase().indexOf("a")?this.options.am_text:this.options.pm_text,n=o.h,r=i.h;e=12==r&&12!=n?s==this.options.am_text?this.options.am_text:this.options.pm_text:12==n&&12!=r?s==this.options.am_text?this.options.pm_text:this.options.am_text:r>n?s==this.options.am_text?this.options.pm_text:this.options.am_text:s==this.options.am_text?this.options.am_text:this.options.pm_text}return e},getTimeObject:function(t,e){var i,o=this.parseTime(t,"g:i:A").split(":"),s=o[0],n=o[1];return i=s||n?{h:s,m:n,sep:":",postfix:" "+(e?e:o[2])}:this.options.empty},generateTimes:function(){if(!this.options.times.length){var t=60,e=this.options.increment,i=new Date(2012,1,1,this.options.start_hour-1,t-e),o=[],s=60,n=this.options.end_hour,r=n-this.options.start_hour,a=!1;24==r&&(a=!0);for(var p=0,m=r*(s/e);m>=p;p++){i.setMinutes(i.getMinutes()+e);var h=i.getHours(),l=i.getMinutes(),u=h>11?this.options.pm_text:this.options.am_text;0==h&&(h=12),h>12&&(h-=12),1==(""+l).length&&(l="0"+l);var c=h+":"+l+" "+u;o.push(c)}a&&o.pop(),this.options.times=o}},parseTime:function(t,e){var i,o,e=e||"H:i:s",s=null!==t.match(/p/i),n=null!==t.match(/a/i),r=t.replace(/[^0-9]/g,"");switch(r.length){case 4:i=parseInt(r.charAt(0)+r.charAt(1),10),o=parseInt(r.charAt(2)+r.charAt(3),10);break;case 3:i=parseInt(r.charAt(0),10),o=parseInt(r.charAt(1)+r.charAt(2),10);break;case 2:case 1:i=parseInt(r.charAt(0)+(r.charAt(1)||""),10),o=0;break;default:return""}if(12==i&&s===!1&&n===!1?(i=12,s=!0):12==i&&s===!1?i=0:s===!0&&i>0&&12>i&&(i+=12),0>=i&&(i=0),i>=24&&2==(""+i).length){var a=(""+i).split("");i=parseInt(a[0],10),o=parseInt(a[1],10),6>o&&(o+="0")}return(0>o||o>59)&&(o=0),i>=13&&23>=i&&(s=!0),e.replace(/g/g,0===i?"12":"g").replace(/g/g,i>12?i-12:i).replace(/h/g,(""+i).length>1?i>12?i-12:i:"0"+(i>12?i-12:i)).replace(/H/g,(""+i).length>1?i:"0"+i).replace(/i/g,(""+o).length>1?o:"0"+o).replace(/s/g,"00").replace(/A/g,s?this.options.pm_text:this.options.am_text)}}}(jQuery),function(t){t.timeAutocomplete.formatters["24hr"]=function(){this.initialize.apply(this,arguments)},t.timeAutocomplete.formatters["24hr"].prototype={main_instance:null,options:{},default_opts:{increment:15,start_hour:"00",hour_max:24,blur_empty_populate:!0,times:[],empty:{h:"12",m:"00",sep:":",postfix:""}},initialize:function(e,i){this.main_instance=e,this.options=t.extend(!0,{},this.default_opts,i),this.generateTimes()},hook_placeholderValue:function(){return this.main_instance._createStringFromFormat(this.options.empty)},hook_getTime:function(t,e){var i=t.split(this.options.empty.sep),o=i[0],s=i[1];return new Date(e[0],e[1],e[2],o,s).getTime()},hook_getTimeObjectFromHis:function(t){var e=t.split(":"),i=e[0],o=e[1],s={h:i,m:o,sep:this.options.empty.sep};return s},hook_filterSource:function(e){var i=this;return e=e[0],function(i,o){return function(s,n){var r=t.trim(e.value);1==s.term.length&&10>s.term.substr(0,1)&&(s.term="0"+s.term);var a=t.ui.autocomplete.escapeRegex(s.term),p=RegExp("^"+a,"i"),m=[];r&&(m=t.grep(i,function(t){return 0==t.substr(0,1)&&1==t.length&&(t=t.substr(1)),p.test(t)})),n(m);var h=r.toLowerCase();!m.length&&h.length>5&&o.main_instance.el.val(h.substr(0,5))}}(i.options.times,i)},hook_blurEmpty:function(){return this.options.blur_empty_populate?this.main_instance._createStringFromFormat(this.options.empty):""},hook_readMind:function(t){return t=t.toLowerCase(),this.getTimeObject(t)},hook_getUsableTimeValue:function(t){return t+":00"},getTimeObject:function(t){var e="",i="",o="";if(~t.indexOf("h")){var s=t.split("h");e=s[0]?s[0]:this.options.empty.h,i=s[1]?s[1]:this.options.empty.m}else{var n=t.replace(/[^\d]/g,"");n=n.split(""),4==n.length?(e=n[0]+n[1],i=n[2]+n[3]):3==n.length?(e="0"+n[0],i=n[1]+n[2]):2==n.length?(e=n.join(""),i="00"):1==n.length&&(e=n.join(""),i="00")}return e>24&&"00"==i&&(e=e.split(""),i=e[1]+"0",e="0"+e[0]),1==e.length&&(e="0"+e),1==i.length&&(i+="0"),o=e||i?{h:e,m:i,sep:this.options.empty.sep}:this.options.empty},generateTimes:function(){if(!this.options.times.length){for(var t=60,e=this.options.increment,i=new Date(2012,1,1,this.options.start_hour-1,t-e),o=[],s=60,n=this.options.hour_max,r=0,a=n*(s/e);a>r;r++){i.setMinutes(i.getMinutes()+e);var p=i.getHours(),m=i.getMinutes();1==(""+p).length&&(p="0"+p),1==(""+m).length&&(m="0"+m);var h=p+this.options.empty.sep+m;o.push(h)}this.options.times=o}}}}(jQuery),function(t){t.timeAutocomplete.formatters.french=function(){this.initialize.apply(this,arguments)},t.timeAutocomplete.formatters.french.prototype=t.extend(!0,{},t.timeAutocomplete.formatters["24hr"].prototype,{default_opts:{empty:{sep:"h"}},hook_getUsableTimeValue:function(t){return t.replace(this.options.empty.sep,":")+":00"}})}(jQuery);
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jQueryTimeAutocomplete",
3 | "title": "jQueryTimeAutocomplete",
4 | "description": "A time autocomplete plugin similar to how Google Calendar's time autocomplete works.",
5 | "version": "1.0.2",
6 | "homepage": "http://7shifts.com/blog/better-time-drop-downs-for-scheduling-jquery-timeautocomplete/",
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/7shifts/jQueryTimeAutocomplete.git"
10 | },
11 | "devDependencies": {
12 | "grunt": "0.4.1",
13 | "grunt-contrib-uglify": "0.2.0",
14 | "grunt-contrib-concat": "~0.3.0"
15 | }
16 | }
--------------------------------------------------------------------------------
/src/formatters/24hr.js:
--------------------------------------------------------------------------------
1 | (function($){
2 |
3 | $.timeAutocomplete.formatters['24hr'] = function(){
4 | this.initialize.apply(this, arguments);
5 | };
6 |
7 | $.timeAutocomplete.formatters['24hr'].prototype = {
8 |
9 | /*
10 | * The main instance that was created. Found on $('#el').data('timeAutocomplete')
11 | * of that specific element. Gets stuffed in on initialize();
12 | */
13 | main_instance: null,
14 |
15 | /*
16 | * These get merged in later. We take the default_opts and the formatter_opts from
17 | * initialize() and merge them into this options object.
18 | */
19 | options: {},
20 |
21 | /*
22 | * Some defaults to get over-ridden if needed. Can be done using
23 | * $('#el').timeAutocomplete({ formatter: '24hr' } });
24 | */
25 | default_opts: {
26 | increment: 15,
27 | start_hour: '00',
28 | hour_max: 24,
29 | blur_empty_populate: true,
30 | times: [],
31 | empty: {
32 | h: '12',
33 | m: '00',
34 | sep: ':',
35 | postfix: ''
36 | }
37 | },
38 |
39 | /*
40 | * Initialize the formatter
41 | *
42 | * @param {Object} main_instance Instance of timeAutocomplete on that element
43 | * @param {Object} formatter_opts Any options passed... $('#el').timeAutocomplete({ formatter: 'ampm', from_selector: ... });
44 | */
45 | initialize: function(main_instance, formatter_opts){
46 |
47 | this.main_instance = main_instance;
48 | this.options = $.extend(true, {}, this.default_opts, formatter_opts);
49 | this.generateTimes();
50 |
51 | },
52 |
53 | hook_placeholderValue: function(){
54 | return this.main_instance._createStringFromFormat(this.options.empty);
55 | },
56 |
57 | /*
58 | * Get the timestamp on a time value
59 | *
60 | * @param {String} t The time (2:00 PM)
61 | * @param {Array} fake_date_data [1987, 1, 17]
62 | */
63 | hook_getTime: function(t, fake_date_data){
64 |
65 | var time_parts = t.split(this.options.empty.sep);
66 | var h = time_parts[0];
67 | var m = time_parts[1];
68 |
69 | return (new Date(fake_date_data[0], fake_date_data[1], fake_date_data[2], h, m)).getTime();
70 |
71 | },
72 |
73 | /*
74 | * Get the H:is (13:30:00) time format and turn it into a time object
75 | * that we can pass back to the main view.
76 | *
77 | * @param {String} time_his 13:30:00
78 | */
79 | hook_getTimeObjectFromHis: function(time_his){
80 |
81 | var time = time_his.split(':');
82 | var hour = time[0];
83 | var min = time[1];
84 |
85 | var time_obj = {
86 | h: hour,
87 | m: min,
88 | sep: this.options.empty.sep
89 | };
90 |
91 | return time_obj;
92 |
93 | },
94 |
95 | /*
96 | * Setup a filter when we type a key into this input.
97 | *
98 | * @param {Object} el The jQuery element
99 | */
100 | hook_filterSource: function(el){
101 |
102 | var self = this;
103 | el = el[0];
104 |
105 | return (function(times, self){
106 | return function(req, responseFn){
107 |
108 | var self_val = $.trim(el.value);
109 |
110 | if(req.term.length == 1 && req.term.substr(0, 1) < 10){
111 | req.term = '0' + req.term;
112 | }
113 |
114 | var re = $.ui.autocomplete.escapeRegex(req.term);
115 |
116 | var matcher = new RegExp("^" + re, "i");
117 | var a = [];
118 |
119 | if(self_val){
120 | a = $.grep(times, function(item){
121 |
122 | if(item.substr(0, 1) == 0 && item.length == 1){
123 | item = item.substr(1);
124 | }
125 |
126 | return matcher.test(item);
127 | });
128 | }
129 |
130 | responseFn(a);
131 |
132 | var val = self_val.toLowerCase();
133 | if(!a.length && val.length > 5){
134 | // Should never be longer than 5 in french/24hr. Ie. 04h30 (5 characters), if it's longer, truncate it.
135 | self.main_instance.el.val(val.substr(0, 5));
136 | }
137 |
138 | }
139 | })(self.options.times, self);
140 | },
141 |
142 | /*
143 | * If we blurred and it was an empty value.
144 | */
145 | hook_blurEmpty: function(){
146 |
147 | if(this.options.blur_empty_populate){
148 | return this.main_instance._createStringFromFormat(this.options.empty);
149 | }
150 | else {
151 | return '';
152 | }
153 |
154 | },
155 |
156 | /*
157 | * Where our formatting actually happens.
158 | *
159 | * @param {String} val The value we're formatting
160 | */
161 | hook_readMind: function(val){
162 |
163 | val = val.toLowerCase();
164 |
165 | return this.getTimeObject(val);
166 |
167 | },
168 |
169 | hook_getUsableTimeValue: function(val){
170 | return val + ':00'
171 | },
172 |
173 | /**
174 | * Format our numbers.
175 | *
176 | * @param {String} original_val The original value
177 | */
178 | getTimeObject: function(original_val){
179 |
180 | var h = '';
181 | var m = '';
182 | var new_num = '';
183 |
184 | if(~original_val.indexOf('h')){
185 | var parts = original_val.split('h');
186 | h = (parts[0]) ? parts[0] : this.options.empty.h; // really? no hour. Must be jack-assery.
187 | m = (parts[1]) ? parts[1] : this.options.empty.m;
188 | }
189 | else {
190 | var numbers = original_val.replace(/[^\d]/g, "");
191 | numbers = numbers.split('');
192 | if(numbers.length == 4){
193 | h = numbers[0] + numbers[1];
194 | m = numbers[2] + numbers[3];
195 | }
196 | else if(numbers.length == 3){
197 | h = '0' + numbers[0];
198 | m = numbers[1] + numbers[2];
199 | }
200 | else if(numbers.length == 2){
201 | h = numbers.join('');
202 | m = '00';
203 | }
204 | else if(numbers.length == 1){
205 | h = numbers.join('');
206 | m = '00';
207 | }
208 | }
209 |
210 | // 91 entered.. format it to 09h10
211 | if(h > 24 && m == '00'){
212 | h = h.split('');
213 | m = h[1] + '0';
214 | h = '0' + h[0];
215 | }
216 |
217 | if(h.length == 1){
218 | h = '0' + h;
219 | }
220 |
221 | if(m.length == 1){
222 | m = m + '0';
223 | }
224 |
225 | if(!h && !m){
226 | new_num = this.options.empty;
227 | }
228 | else {
229 | new_num = {
230 | h: h,
231 | m: m,
232 | sep: this.options.empty.sep
233 | };
234 | }
235 |
236 | return new_num;
237 |
238 | },
239 |
240 | /*
241 | * Generate an array of times to pass to our autocomplete source.
242 | * ['12h00', '12h15'] etc. Totally depends on the increment options set.
243 | */
244 | generateTimes: function(){
245 |
246 | if(!this.options.times.length){
247 |
248 | var start_minute = 60;
249 | var increment = this.options.increment;
250 | var date = new Date(2012, 1, 1, (this.options.start_hour - 1), (start_minute - increment));
251 | var arr = [];
252 | var hour_len = 60;
253 | var hours = this.options.hour_max;
254 |
255 | for(var i = 0, loop_int = hours * (hour_len/increment); i < loop_int; i++){
256 |
257 | date.setMinutes(date.getMinutes() + increment);
258 | var h = date.getHours();
259 | var m = date.getMinutes();
260 |
261 | if(("" + h).length == 1){
262 | h = '0' + h;
263 | }
264 |
265 | if(("" + m).length == 1){
266 | m = '0' + m;
267 | }
268 |
269 | var label = h + this.options.empty.sep + m;
270 | arr.push(label);
271 | }
272 |
273 | this.options.times = arr;
274 | }
275 |
276 | }
277 |
278 | };
279 |
280 | })(jQuery);
--------------------------------------------------------------------------------
/src/formatters/ampm.js:
--------------------------------------------------------------------------------
1 | (function($){
2 |
3 | $.timeAutocomplete.formatters.ampm = function(){
4 | this.initialize.apply(this, arguments);
5 | };
6 |
7 | $.timeAutocomplete.formatters.ampm.prototype = {
8 |
9 | /*
10 | * The main instance that was created. Found on $('#el').data('timeAutocomplete')
11 | * of that specific element. Gets stuffed in on initialize();
12 | */
13 | main_instance: null,
14 |
15 | /*
16 | * These get merged in later. We take the default_opts and the formatter_opts from
17 | * initialize() and merge them into this options object.
18 | */
19 | options: {},
20 |
21 | /*
22 | * Some defaults to get over-ridden if needed. Can be done using
23 | * $('#el').timeAutocomplete({ formatter: 'ampm', from_selector: ... });
24 | */
25 | default_opts: {
26 | from_selector: '',
27 | increment: 15,
28 | start_hour: 0,
29 | end_hour: 24,
30 | pm_text: 'PM',
31 | am_text: 'AM',
32 | blur_empty_populate: true,
33 | times: [], // over-ride if not using built-in populator
34 | empty: {
35 | h: '12',
36 | m: '00',
37 | sep: ':',
38 | postfix: ' PM'
39 | }
40 | },
41 |
42 | /*
43 | * Initialize the formatter. Called from within TimeAutocomplete file.
44 | *
45 | * @param {Object} main_instance Instance of timeAutocomplete on that element
46 | * @param {Object} formatter_opts Any options passed... $('#el').timeAutocomplete({ formatter: 'ampm', from_selector: ... });
47 | */
48 | initialize: function(main_instance, formatter_opts){
49 |
50 | this.main_instance = main_instance;
51 | this.options = $.extend(true, {}, this.default_opts, formatter_opts);
52 | this.generateTimes();
53 |
54 | },
55 |
56 | hook_placeholderValue: function(){
57 | return this.main_instance._createStringFromFormat(this.options.empty);
58 | },
59 |
60 | /*
61 | * Setup a filter when we type a key into this input.
62 | *
63 | * @param {Object} el The jQuery element
64 | */
65 | hook_filterSource: function(el){
66 |
67 | var self = this;
68 | el = el[0];
69 |
70 | return (function(times, self){
71 | return function(req, responseFn){
72 |
73 | var self_val = $.trim(el.value);
74 | var re = $.ui.autocomplete.escapeRegex(req.term);
75 | var has_am = ~re.toLowerCase().indexOf('a');
76 | var has_pm = ~re.toLowerCase().indexOf('p');
77 | var trim_ampm_possibilities = '';
78 | var is_one = !!(self_val == 1); // if they type "1", don't show "11" and "12".
79 | var do_has_am_pm_mind_read = (has_am || has_pm) && re.replace(/a|m|p/gi, '').length <= 2;
80 |
81 | if(do_has_am_pm_mind_read){
82 | re = $.trim(re.replace(/a|m|p/gi, '')) + ':00 ';
83 | re += (has_am) ? self.options.am_text : self.options.pm_text;
84 | }
85 |
86 | // If the starting (from) time was 9:00 AM, and they start to type
87 | // 2 in the (to) spot, default to 2 PM because 2 is less than 9.
88 | // Only works on english.. not french.
89 | if(self.options.from_selector){
90 | trim_ampm_possibilities = self.detectAMPMFromInstanceOverlap() == self.options.am_text ? self.options.pm_text : self.options.am_text;
91 | }
92 |
93 | var matcher = new RegExp("^" + re, "i");
94 | var a = [];
95 |
96 | if(self_val){
97 | a = $.grep(times, function(item){
98 | var return_nil =
99 | // If we want to trim out some AM/PM slots based on our mind reading
100 | (trim_ampm_possibilities && (new RegExp(trim_ampm_possibilities, "gi")).test(item))
101 | // If we type in "1", don't show "11" and "12" possibilities
102 | || (is_one && item.substring(0, 2) != '1:')
103 | || (~self_val.toLowerCase().indexOf('p') && !~item.toLowerCase().indexOf('p'))
104 | || (~self_val.toLowerCase().indexOf('a') && !~item.toLowerCase().indexOf('a'));
105 | if(return_nil){
106 | return;
107 | }
108 | return matcher.test(item);
109 | });
110 | }
111 |
112 | responseFn(a);
113 |
114 | }
115 | })(self.options.times, self);
116 |
117 | },
118 |
119 | /*
120 | * When we blur on the input field. Make any corrections/modifications to the value
121 | *
122 | * @param {String} val The input value
123 | */
124 | hook_blur: function(val){
125 |
126 | // Clean up 03:00 am
127 | if(val.charAt(0) == 0){
128 | val = val.substr(1);
129 | }
130 |
131 | return val;
132 |
133 | },
134 |
135 | /*
136 | * If we blurred and it was an empty value.
137 | */
138 | hook_blurEmpty: function(){
139 |
140 | if(this.options.blur_empty_populate){
141 | return this.main_instance._createStringFromFormat(this.options.empty);
142 | }
143 | else {
144 | return '';
145 | }
146 |
147 | },
148 |
149 | /*
150 | * Where our formatting actually happens.
151 | *
152 | * @param {String} val The value we're formatting
153 | */
154 | hook_readMind: function(val){
155 |
156 | var am_pm = '';
157 |
158 | val = val.toLowerCase();
159 | if(this.options.from_selector && !~val.indexOf('a') && !~val.indexOf('p'))
160 | {
161 | am_pm = this.detectAMPMFromInstanceOverlap();
162 | }
163 |
164 | return this.getTimeObject(val, am_pm);
165 |
166 | },
167 |
168 | /*
169 | * Convert an '1:00 PM' to H:i:s so it's usable for storing in the DB.
170 | *
171 | * @param {String} val
172 | */
173 | hook_getUsableTimeValue: function(val){
174 | return this.parseTime(val);
175 | },
176 |
177 | /*
178 | * Get the timestamp on a time value
179 | *
180 | * @param {String} t The time (2:00 PM)
181 | * @param {Array} fake_date_data [1987, 1, 17]
182 | */
183 | hook_getTime: function(t, fake_date_data){
184 |
185 | var time_parts = this.parseTime(t).split(this.options.empty.sep);
186 | var h = time_parts[0];
187 | var m = time_parts[1];
188 |
189 | return (new Date(fake_date_data[0], fake_date_data[1], fake_date_data[2], h, m)).getTime();
190 |
191 | },
192 |
193 | /*
194 | * Get the H:is (13:30:00) time format and turn it into a time object
195 | * that we can pass back to the main view.
196 | *
197 | * @param {String} time_his 13:30:00
198 | */
199 | hook_getTimeObjectFromHis: function(time_his){
200 |
201 | var time = time_his.split(':');
202 | var hour = time[0];
203 | var min = time[1];
204 | var ampm = (hour >= 12) ? this.options.pm_text : this.options.am_text;
205 |
206 | if(hour.length == 2 && parseInt(hour, 10) < 10){
207 | hour = hour.substr(1);
208 | }
209 |
210 | if(hour > 12){
211 | hour -= 12;
212 | }
213 |
214 | if(hour == 0){
215 | hour = 12;
216 | }
217 |
218 | var time_obj = {
219 | h: parseInt(hour, 10),
220 | m: min,
221 | sep: this.options.empty.sep,
222 | postfix: ' ' + ampm
223 | };
224 |
225 | return time_obj;
226 |
227 | },
228 |
229 | /**
230 | * If we have a $(self.options.from_selector), then we type '2' into the To field,
231 | * we should look at the From field to determine whether or not to make it 2pm
232 | * or 2am. Do awesome stuff to figure it out.
233 | */
234 | detectAMPMFromInstanceOverlap: function(){
235 |
236 | var trim_ampm_possibilities = '';
237 | var from_obj = this.getTimeObject($(this.options.from_selector).val());
238 | var to_obj = this.getTimeObject($.trim(this.main_instance.el.val()));
239 |
240 | if(from_obj.postfix && (~from_obj.postfix.toLowerCase().indexOf('a') || ~from_obj.postfix.toLowerCase().indexOf('p'))){
241 |
242 | var from_ampm = (~from_obj.postfix.toLowerCase().indexOf('a')) ? this.options.am_text : this.options.pm_text;
243 | var to_hour = to_obj.h;
244 | var from_hour = from_obj.h;
245 |
246 | // If it's 11:00 PM - 12.. it should say 12 AM and not PM.
247 | if(from_hour == 12 && to_hour != 12){
248 | trim_ampm_possibilities = (from_ampm == this.options.am_text) ? this.options.am_text : this.options.pm_text;
249 | }
250 | else if(to_hour == 12 && from_hour != 12){
251 | trim_ampm_possibilities = (from_ampm == this.options.am_text) ? this.options.pm_text : this.options.am_text;
252 | }
253 | // 10:00 AM > 2:00 PM, 10:00 PM > 2:00 AM
254 | else if(from_hour > to_hour){
255 | trim_ampm_possibilities = (from_ampm == this.options.am_text) ? this.options.pm_text : this.options.am_text;
256 | }
257 | // 10:00 AM < 11:00 AM, 5:00 PM < 7:00 PM
258 | else {
259 | trim_ampm_possibilities = (from_ampm == this.options.am_text) ? this.options.am_text : this.options.pm_text;
260 | }
261 |
262 | }
263 |
264 | return trim_ampm_possibilities;
265 |
266 | },
267 |
268 | /**
269 | * Format what we've got into an english readable format.
270 | * So turn '1030' into '10:30 am' etc.
271 | *
272 | * @param {String} original_val The original value to format
273 | * @param {String} am_pm Whether or not it's 'am' or 'pm'
274 | */
275 | getTimeObject: function(original_val, am_pm){
276 |
277 | var t = this.parseTime(original_val, 'g:i:A').split(':');
278 | var h = t[0];
279 | var m = t[1];
280 | var new_num;
281 |
282 | if(!h && !m){
283 | new_num = this.options.empty;
284 | }
285 | else {
286 | new_num = {
287 | h: h,
288 | m: m,
289 | sep: ':',
290 | postfix: ' ' + (am_pm ? am_pm : t[2])
291 | };
292 | }
293 |
294 | return new_num;
295 |
296 | },
297 |
298 | /*
299 | * Generate an array of times to pass to our autocomplete source.
300 | * ['12:00 AM', '12:15 AM'] etc. Totally depends on the start_hour and increment options set.
301 | */
302 | generateTimes: function(){
303 |
304 | if(!this.options.times.length){
305 |
306 | var start_minute = 60;
307 | var increment = this.options.increment;
308 | var date = new Date(2012, 1, 1, (this.options.start_hour - 1), (start_minute - increment));
309 | var arr = [];
310 | var hour_len = 60;
311 | var hours = this.options.end_hour;
312 | var hour_looper = (hours - this.options.start_hour);
313 | var pop_last = false;
314 |
315 | if(hour_looper == 24){
316 | pop_last = true;
317 | }
318 |
319 | for(var i = 0, loop_int = hour_looper * (hour_len / increment); i <= loop_int; i++){
320 |
321 | date.setMinutes(date.getMinutes() + increment);
322 | var h = date.getHours();
323 | var m = date.getMinutes();
324 | var ampm = h > 11 ? this.options.pm_text : this.options.am_text;
325 |
326 | if(h == 0){
327 | h = 12;
328 | }
329 |
330 | if(h > 12){
331 | h = h - 12;
332 | }
333 |
334 | if(("" + m).length == 1){
335 | m = '0' + m;
336 | }
337 |
338 | var label = h + ':' + m + ' ' + ampm;
339 | arr.push(label);
340 | }
341 |
342 | if(pop_last){
343 | arr.pop();
344 | }
345 |
346 | this.options.times = arr;
347 | }
348 |
349 | },
350 |
351 | parseTime: function(time, format){
352 |
353 | var hour,
354 | minute,
355 | format = format || 'H:i:s',
356 | pm = time.match(/p/i) !== null,
357 | am = time.match(/a/i) !== null,
358 | num = time.replace(/[^0-9]/g, '');
359 |
360 | // Parse for hour and minute
361 | switch(num.length){
362 | case 4:
363 | hour = parseInt(num.charAt(0) + num.charAt(1), 10);
364 | minute = parseInt(num.charAt(2) + num.charAt(3), 10);
365 | break;
366 | case 3:
367 | hour = parseInt(num.charAt(0), 10);
368 | minute = parseInt(num.charAt(1) + num.charAt(2), 10);
369 | break;
370 | case 2:
371 | case 1:
372 | hour = parseInt(num.charAt(0) + (num.charAt(1) || ''), 10);
373 | minute = 0;
374 | break;
375 | default:
376 | return '';
377 | }
378 |
379 | // if 12 and am/pm not specified assume pm
380 | if (hour == 12 && pm === false && am === false) {
381 | hour = 12;
382 | pm = true;
383 | } else if (hour == 12 && pm === false) {
384 | hour = 0;
385 | } else if (pm === true && hour > 0 && hour < 12) {
386 | hour += 12;
387 | }
388 |
389 | // Keep within range
390 | if(hour <= 0 ){
391 | hour = 0;
392 | }
393 |
394 | if(hour >= 24 && ("" + hour + "").length == 2){
395 | var parts = ("" + hour + "").split('');
396 | hour = parseInt(parts[0], 10);
397 | minute = parseInt(parts[1], 10);
398 | if(minute < 6){
399 | minute = minute + '0';
400 | }
401 | }
402 |
403 | if(minute < 0 || minute > 59){
404 | minute = 0;
405 | }
406 |
407 | if(hour >= 13 && hour <= 23){
408 | pm = true;
409 | }
410 |
411 | return format
412 | // 12 hour without leading 0
413 | .replace(/g/g, hour === 0 ? '12' : 'g')
414 | .replace(/g/g, hour > 12 ? hour - 12 : hour)
415 | // 12 hour with leading 0
416 | .replace(/h/g, hour.toString().length > 1 ? (hour > 12 ? hour - 12 : hour) : '0' + (hour > 12 ? hour - 12 : hour))
417 | // 24 hour with leading 0
418 | .replace(/H/g, hour.toString().length > 1 ? hour : '0' + hour)
419 | // minutes with leading zero
420 | .replace(/i/g, minute.toString().length > 1 ? minute : '0' + minute)
421 | // simulate seconds
422 | .replace(/s/g, '00')
423 | // lowercase am/pm
424 | .replace(/A/g, pm ? this.options.pm_text : this.options.am_text);
425 |
426 | }
427 |
428 | };
429 |
430 | })(jQuery);
--------------------------------------------------------------------------------
/src/formatters/french.js:
--------------------------------------------------------------------------------
1 | (function($){
2 |
3 | $.timeAutocomplete.formatters.french = function(){
4 | this.initialize.apply(this, arguments);
5 | };
6 |
7 | $.timeAutocomplete.formatters.french.prototype = $.extend(true, {}, $.timeAutocomplete.formatters['24hr'].prototype, {
8 | default_opts: {
9 | empty: {
10 | sep: 'h'
11 | }
12 | },
13 |
14 | hook_getUsableTimeValue: function(val){
15 | return val.replace(this.options.empty.sep, ':') + ':00'
16 | }
17 | });
18 |
19 | })(jQuery);
--------------------------------------------------------------------------------
/src/jquery.timeAutocomplete.js:
--------------------------------------------------------------------------------
1 | /**
2 | * TimeFromToAutocomplete
3 | *
4 | * The from -> to autocomplete inputs (on absences dialog)
5 | */
6 |
7 | (function($){
8 |
9 | /*
10 | * TimeAutcomplete
11 | *
12 | * @constructor
13 | * @param {Object} opts An object of options to over-ride the defaults
14 | */
15 | var namespace = 'timeAutocomplete';
16 | var time_data_prop = namespace + '.time';
17 |
18 | var TimeAutocomplete = function(){
19 | this.initialize.apply(this, arguments);
20 | };
21 |
22 | TimeAutocomplete.prototype = {
23 |
24 | // Gets set in initialize
25 | el: null,
26 |
27 | // Instance of our formatter
28 | _formatter: null,
29 |
30 | _calling_from_init: false,
31 |
32 | // Default options
33 | default_opts: {
34 | auto_complete: {
35 | delay: 0,
36 | autoFocus: true,
37 | minLength: 0
38 | },
39 | auto_value: true,
40 | value: '',
41 | formatter: 'ampm'
42 | },
43 |
44 | /**
45 | * Init called when we create a new instance
46 | * of this view. First param of 'options' passed in by backbonejs
47 | */
48 | initialize: function($el, opts){
49 | this.options = $.extend(true, {}, this.default_opts, opts);
50 |
51 | // Some global options (if set)
52 | if(typeof($.timeAutocompleteDefaults) !== 'undefined'){
53 | this.options = $.extend(true, {}, this.options, $.timeAutocompleteDefaults);
54 | }
55 |
56 | this.el = $el;
57 | },
58 |
59 | _callAutocomplete: function(){
60 |
61 | this.options.auto_complete.source = this._callFormatterMethod('filterSource', [this.el], function(req, responseFn){
62 | throw new Error("You must set a hook_filterSource method in your formatter.");
63 | });
64 |
65 | // Make sure we have loaded the autocomplete plugin
66 | if(typeof($.fn.autocomplete) === 'undefined'){
67 | throw new Error("You need to include the jQuery UI bundle that has the Autocomplete plugin.");
68 | }
69 |
70 | // Call our autocomplete plugin
71 | this.el.autocomplete(this.options.auto_complete);
72 | },
73 |
74 | /**
75 | * When we click on the element and there are no
76 | * initial values in there, make some to show the user
77 | * they have to start typing a number
78 | */
79 | _bindEvents: function(){
80 |
81 | var self = this;
82 | var allow_focus = true; /* IE fix */
83 |
84 | $('body').on('click.' + namespace, 'ul.ui-autocomplete a', function(){
85 | allow_focus = false;
86 | setTimeout(function(){
87 | allow_focus = true;
88 | }, 100);
89 | });
90 |
91 | this.el
92 | .bind('keydown.' + namespace, function(e){
93 | self._keydownAutocomplete.apply(self, arguments);
94 | })
95 | .bind('keyup.' + namespace, function(e){
96 | self._keyupAutocomplete.apply(self, arguments);
97 | })
98 | .bind('blur.' + namespace, function(e){
99 | self._blurAutocomplete.apply(self, arguments);
100 | })
101 | .bind('focus.' + namespace, function(e){
102 | if(allow_focus){
103 | self._focusAutocomplete.apply(self, arguments);
104 | }
105 | });
106 |
107 | if(this.options.auto_value){
108 | this.el.trigger('blur.' + namespace);
109 | }
110 |
111 | },
112 |
113 | _setupPlaceholder: function(){
114 | if(typeof(this.el.attr('placeholder')) === 'undefined'){
115 | this.el.attr('placeholder', this._callFormatterMethod('placeholderValue', [], ''));
116 | }
117 | },
118 |
119 | _focusAutocomplete: function(){
120 | var val = $.trim(this.el.val()).substr(0, 2);
121 | if(this.el.data('uiAutocomplete')){
122 | this.el.autocomplete('search', val);
123 | }
124 | },
125 |
126 | /*
127 | * Keydown autocomplete event
128 | *
129 | * @param {Object} e Event object
130 | * @param {HTMLElement} input The input we had the event performed on
131 | */
132 | _keydownAutocomplete: function(e){
133 |
134 | var val = $.trim(this.el.val());
135 |
136 | // If they hit any of these keys DO NOT disable the auto complete, these
137 | // are acceptable key strokes.
138 | var ignore_keydowns = [
139 | 8, // backspace
140 | 9, // tab
141 | 13, // enter key
142 | 38, // up arrow key
143 | 40 // down arrow key
144 | ];
145 |
146 | if(!~$.inArray(e.which, ignore_keydowns) && ((e.which == 8) || (val.length > 1 && !~val.indexOf('h') && !~val.indexOf(':') && $.isNumeric(val)))){
147 | try {
148 | this.el.autocomplete('close').autocomplete('disable');
149 | } catch(e){}
150 | }
151 |
152 | },
153 |
154 | /*
155 | * Keyup autocomplete event
156 | *
157 | * @param {Object} e Event object
158 | * @param {HTMLElement} input The input we had the event performed on
159 | */
160 | _keyupAutocomplete: function(e){
161 |
162 | if($.trim(this.el.val()) == '' && this.el.data('uiAutocomplete')){
163 | this.el.autocomplete('enable');
164 | }
165 |
166 | },
167 |
168 | /*
169 | * Blur autocomplete event
170 | *
171 | * @param {Object} e Event object
172 | * @param {HTMLElement} input The input we had the event performed on
173 | */
174 | _blurAutocomplete: function(e){
175 |
176 | var val = $.trim(this.el.val());
177 | val = this._callFormatterMethod('blur', [val], val);
178 | var new_value = '';
179 |
180 | if(val){
181 | new_value = this._createStringFromFormat(this._readMind(val));
182 | }
183 | else {
184 | new_value = this._callFormatterMethod('blurEmpty', [val], val);
185 | }
186 |
187 | this.el.val(new_value);
188 |
189 | this._attacheUsableTimeData();
190 |
191 | },
192 |
193 | /*
194 | * Hit a formatter hook to get at the date value, then store it in a data
195 | * attribute for later if need be
196 | */
197 | _attacheUsableTimeData: function(){
198 | var val = $.trim(this.el.val());
199 | this.el.data(time_data_prop, this._callFormatterMethod('getUsableTimeValue', [val]));
200 | },
201 |
202 | /**
203 | * Our 'ampm' formatter should be used by default. If we're adding a new
204 | * formatter, it will go into $.timeAutocomplete.formatters[formatter]
205 | *
206 | * @param {String} formatter The formater name we're setting to use.
207 | */
208 | setFormatter: function(formatter){
209 |
210 | this.options.formatter = formatter || this.options.formatter;
211 |
212 | if(!$.timeAutocomplete.formatters[this.options.formatter]){
213 | throw new Error("Formatter: '" + formatter + "' was not found. Make sure you're loading it (formatters/" + this.options.formatter + ".js) after you load src/TimeAutocomplete.js");
214 | }
215 | else {
216 | this._formatter = new $.timeAutocomplete.formatters[this.options.formatter](this, this.options);
217 |
218 | if(!this._calling_from_init){
219 | this._callAutocomplete();
220 | }
221 |
222 | this._calling_from_init = false;
223 | }
224 |
225 | },
226 |
227 | /*
228 | * Gets the formatter
229 | */
230 | getFormatter: function(){
231 | return this._formatter;
232 | },
233 |
234 | /*
235 | * Gets the time in H:i:s format
236 | */
237 | getTime: function(){
238 | return this.el.data(time_data_prop) || '';
239 | },
240 |
241 | /**
242 | * Call the formatter method (if it exists). If you look in formatters/ampm.js, all our hooks that
243 | * get called there are prefixed by "hook_".
244 | *
245 | * @param {String} method_name The method to call in the formatter file
246 | * @param {Array} args The arguments to pass to the formatter
247 | * @param {Array|Function|Object|String} default_val The default if the method_name does not exist in the formatter
248 | */
249 | _callFormatterMethod: function(method_name, args, default_val){
250 |
251 | var formatter = this.getFormatter();
252 |
253 | if($.isFunction(formatter['hook_' + method_name])){
254 | return formatter['hook_' + method_name].apply(formatter, args);
255 | }
256 |
257 | return default_val;
258 |
259 | },
260 |
261 | /**
262 | * The person typed something in that wasn't to our satisfaction.
263 | * Like '10' or '13' or '135' or '1350'
264 | *
265 | * @param {String} val The value from our input
266 | */
267 | _readMind: function(val){
268 | return this._callFormatterMethod('readMind', [val], val);
269 | },
270 |
271 | /**
272 | * Combine formatted things
273 | *
274 | * @param {Object} obj The object containing h, m, sep etc.
275 | */
276 | _createStringFromFormat: function(obj){
277 |
278 | var combined = ("" + obj.h + "") + obj.sep + ("" + obj.m + "");
279 |
280 | if(obj.postfix){
281 | combined += obj.postfix;
282 | }
283 |
284 | return combined;
285 |
286 | },
287 |
288 | /*
289 | * Pass an H:i:s time format in as the value: '' attribute on the element or 'current'
290 | */
291 | _setValueAsTime: function(){
292 |
293 | var val = $.trim(this.el.val());
294 | var val_parts = val.split(':');
295 |
296 | if(val == '' && this.options.value){
297 | this.setTime(this.options.value);
298 | }
299 | else if(val_parts.length == 3 && this.isNumber(val_parts[0]) && this.isNumber(val_parts[1]) && this.isNumber(val_parts[2])){
300 | this.setTime(val);
301 | }
302 | else {
303 | var time = this._getCurrentTimeAsValue();
304 | this.el.val(time);
305 | this._attacheUsableTimeData();
306 | }
307 |
308 | },
309 |
310 | /*
311 | * Check if its a number
312 | *
313 | * @param {String|Int} n
314 | */
315 | isNumber: function(n) {
316 | return !isNaN(parseFloat(n)) && isFinite(n);
317 | },
318 |
319 | /*
320 | * Set the time by passing it a H:i:s format (13:30:00)
321 | *
322 | * @param {String} time 13:30:00
323 | */
324 | setTime: function(time){
325 |
326 | var stripped_time = time.replace(/[^0-9.]/g, "");
327 | var matched = stripped_time.match(/^[0-9]+$/);
328 | if(matched && matched.length && (matched[0].length == 5 || matched[0].length == 6)){
329 | var val = this._callFormatterMethod('getTimeObjectFromHis', [time]);
330 | val = this._createStringFromFormat(val);
331 | this.el.val(val);
332 | this._attacheUsableTimeData();
333 | } else {
334 | throw new Error('Setting a time must be in H:i:s format. Example: 03:30:00');
335 | }
336 |
337 | },
338 |
339 | /*
340 | * Populate the input with the current time value
341 | */
342 | _getCurrentTimeAsValue: function(){
343 |
344 | var formatter = this.getFormatter();
345 | var fake_date_data = [1987, 1, 17];
346 | var date = this._getCurrentDate();
347 | var current_h = date.getHours();
348 | var current_m = date.getMinutes();
349 | var current_time = (new Date(fake_date_data[0], fake_date_data[1], fake_date_data[2], current_h, current_m)).getTime();
350 | var bound_times = formatter.options.times.slice().concat(formatter.options.times);
351 | var entered_next_times = [];
352 |
353 | for(var i = 0, t = bound_times.length; i < t; i++){
354 |
355 | var time = this._callFormatterMethod('getTime', [bound_times[i], fake_date_data]);
356 | var next_time = (bound_times[i + 1]) ? this._callFormatterMethod('getTime', [bound_times[i + 1], fake_date_data]) : false;
357 | var already_entered_next_times = !!($.inArray(next_time, entered_next_times) !== -1);
358 | entered_next_times.push(next_time);
359 |
360 | if(current_time > time && ((next_time && current_time <= next_time) || (already_entered_next_times))){
361 | return bound_times[i + 1];
362 | }
363 | }
364 |
365 | },
366 |
367 | /*
368 | * Get the current date
369 | */
370 | _getCurrentDate: function(){
371 | return new Date();
372 | },
373 |
374 | /*
375 | * Destroy the bound event to the element
376 | */
377 | destroy: function(){
378 | this.el.removeData(namespace);
379 | this.el.removeData(time_data_prop);
380 | this.el.unbind('.' + namespace);
381 | if(this.el.data('uiAutocomplete')){
382 | this.el.autocomplete('destroy');
383 | }
384 | },
385 |
386 | /*
387 | * Render it out to the page
388 | */
389 | render: function(){
390 |
391 | // Which formatter we're using.. 'ampm', 'french'?
392 | this._calling_from_init = true;
393 | this.setFormatter();
394 | this._callAutocomplete();
395 |
396 | if(this.options.auto_value){
397 | this._setValueAsTime();
398 | }
399 |
400 | this._bindEvents();
401 | this._setupPlaceholder();
402 |
403 | return this;
404 |
405 | }
406 |
407 | };
408 |
409 | /**
410 | * Just slappin' on a global object to access some convenient formatters
411 | */
412 | $.timeAutocomplete = {
413 | formatters: {},
414 | _raw: TimeAutocomplete // exposed globally for the sake of testing it
415 | };
416 |
417 | /*
418 | * Wrap it all into a nice jQuery function
419 | *
420 | * @param {Object} opts The options passed to it when called (optional)
421 | */
422 | $.fn.timeAutocomplete = function(opts){
423 |
424 | // Do the nasty on each one.
425 | return this.each(function(){
426 |
427 | var $el = $(this);
428 |
429 | // If it already exists, tear it down before setting a new one up
430 | if($el.data(namespace))
431 | {
432 | $el.data(namespace).destroy();
433 | }
434 |
435 | // Set up a new instance of the time autocomplete
436 | var ta_instance = (new TimeAutocomplete($el, opts)).render();
437 | $el.data(namespace, ta_instance);
438 |
439 | });
440 |
441 | };
442 |
443 | })(jQuery);
--------------------------------------------------------------------------------
/tests/index.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 | jQuery timeAutocomplete Tests
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/tests/lib/jasmine-1.3.1/MIT.LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2008-2011 Pivotal Labs
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/tests/lib/jasmine-1.3.1/jasmine-html.js:
--------------------------------------------------------------------------------
1 | jasmine.HtmlReporterHelpers = {};
2 |
3 | jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
4 | var el = document.createElement(type);
5 |
6 | for (var i = 2; i < arguments.length; i++) {
7 | var child = arguments[i];
8 |
9 | if (typeof child === 'string') {
10 | el.appendChild(document.createTextNode(child));
11 | } else {
12 | if (child) {
13 | el.appendChild(child);
14 | }
15 | }
16 | }
17 |
18 | for (var attr in attrs) {
19 | if (attr == "className") {
20 | el[attr] = attrs[attr];
21 | } else {
22 | el.setAttribute(attr, attrs[attr]);
23 | }
24 | }
25 |
26 | return el;
27 | };
28 |
29 | jasmine.HtmlReporterHelpers.getSpecStatus = function(child) {
30 | var results = child.results();
31 | var status = results.passed() ? 'passed' : 'failed';
32 | if (results.skipped) {
33 | status = 'skipped';
34 | }
35 |
36 | return status;
37 | };
38 |
39 | jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
40 | var parentDiv = this.dom.summary;
41 | var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
42 | var parent = child[parentSuite];
43 |
44 | if (parent) {
45 | if (typeof this.views.suites[parent.id] == 'undefined') {
46 | this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
47 | }
48 | parentDiv = this.views.suites[parent.id].element;
49 | }
50 |
51 | parentDiv.appendChild(childElement);
52 | };
53 |
54 |
55 | jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
56 | for(var fn in jasmine.HtmlReporterHelpers) {
57 | ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
58 | }
59 | };
60 |
61 | jasmine.HtmlReporter = function(_doc) {
62 | var self = this;
63 | var doc = _doc || window.document;
64 |
65 | var reporterView;
66 |
67 | var dom = {};
68 |
69 | // Jasmine Reporter Public Interface
70 | self.logRunningSpecs = false;
71 |
72 | self.reportRunnerStarting = function(runner) {
73 | var specs = runner.specs() || [];
74 |
75 | if (specs.length == 0) {
76 | return;
77 | }
78 |
79 | createReporterDom(runner.env.versionString());
80 | doc.body.appendChild(dom.reporter);
81 | setExceptionHandling();
82 |
83 | reporterView = new jasmine.HtmlReporter.ReporterView(dom);
84 | reporterView.addSpecs(specs, self.specFilter);
85 | };
86 |
87 | self.reportRunnerResults = function(runner) {
88 | reporterView && reporterView.complete();
89 | };
90 |
91 | self.reportSuiteResults = function(suite) {
92 | reporterView.suiteComplete(suite);
93 | };
94 |
95 | self.reportSpecStarting = function(spec) {
96 | if (self.logRunningSpecs) {
97 | self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
98 | }
99 | };
100 |
101 | self.reportSpecResults = function(spec) {
102 | reporterView.specComplete(spec);
103 | };
104 |
105 | self.log = function() {
106 | var console = jasmine.getGlobal().console;
107 | if (console && console.log) {
108 | if (console.log.apply) {
109 | console.log.apply(console, arguments);
110 | } else {
111 | console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
112 | }
113 | }
114 | };
115 |
116 | self.specFilter = function(spec) {
117 | if (!focusedSpecName()) {
118 | return true;
119 | }
120 |
121 | return spec.getFullName().indexOf(focusedSpecName()) === 0;
122 | };
123 |
124 | return self;
125 |
126 | function focusedSpecName() {
127 | var specName;
128 |
129 | (function memoizeFocusedSpec() {
130 | if (specName) {
131 | return;
132 | }
133 |
134 | var paramMap = [];
135 | var params = jasmine.HtmlReporter.parameters(doc);
136 |
137 | for (var i = 0; i < params.length; i++) {
138 | var p = params[i].split('=');
139 | paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
140 | }
141 |
142 | specName = paramMap.spec;
143 | })();
144 |
145 | return specName;
146 | }
147 |
148 | function createReporterDom(version) {
149 | dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
150 | dom.banner = self.createDom('div', { className: 'banner' },
151 | self.createDom('span', { className: 'title' }, "Jasmine "),
152 | self.createDom('span', { className: 'version' }, version)),
153 |
154 | dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
155 | dom.alert = self.createDom('div', {className: 'alert'},
156 | self.createDom('span', { className: 'exceptions' },
157 | self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),
158 | self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),
159 | dom.results = self.createDom('div', {className: 'results'},
160 | dom.summary = self.createDom('div', { className: 'summary' }),
161 | dom.details = self.createDom('div', { id: 'details' }))
162 | );
163 | }
164 |
165 | function noTryCatch() {
166 | return window.location.search.match(/catch=false/);
167 | }
168 |
169 | function searchWithCatch() {
170 | var params = jasmine.HtmlReporter.parameters(window.document);
171 | var removed = false;
172 | var i = 0;
173 |
174 | while (!removed && i < params.length) {
175 | if (params[i].match(/catch=/)) {
176 | params.splice(i, 1);
177 | removed = true;
178 | }
179 | i++;
180 | }
181 | if (jasmine.CATCH_EXCEPTIONS) {
182 | params.push("catch=false");
183 | }
184 |
185 | return params.join("&");
186 | }
187 |
188 | function setExceptionHandling() {
189 | var chxCatch = document.getElementById('no_try_catch');
190 |
191 | if (noTryCatch()) {
192 | chxCatch.setAttribute('checked', true);
193 | jasmine.CATCH_EXCEPTIONS = false;
194 | }
195 | chxCatch.onclick = function() {
196 | window.location.search = searchWithCatch();
197 | };
198 | }
199 | };
200 | jasmine.HtmlReporter.parameters = function(doc) {
201 | var paramStr = doc.location.search.substring(1);
202 | var params = [];
203 |
204 | if (paramStr.length > 0) {
205 | params = paramStr.split('&');
206 | }
207 | return params;
208 | }
209 | jasmine.HtmlReporter.sectionLink = function(sectionName) {
210 | var link = '?';
211 | var params = [];
212 |
213 | if (sectionName) {
214 | params.push('spec=' + encodeURIComponent(sectionName));
215 | }
216 | if (!jasmine.CATCH_EXCEPTIONS) {
217 | params.push("catch=false");
218 | }
219 | if (params.length > 0) {
220 | link += params.join("&");
221 | }
222 |
223 | return link;
224 | };
225 | jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);
226 | jasmine.HtmlReporter.ReporterView = function(dom) {
227 | this.startedAt = new Date();
228 | this.runningSpecCount = 0;
229 | this.completeSpecCount = 0;
230 | this.passedCount = 0;
231 | this.failedCount = 0;
232 | this.skippedCount = 0;
233 |
234 | this.createResultsMenu = function() {
235 | this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
236 | this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
237 | ' | ',
238 | this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
239 |
240 | this.summaryMenuItem.onclick = function() {
241 | dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
242 | };
243 |
244 | this.detailsMenuItem.onclick = function() {
245 | showDetails();
246 | };
247 | };
248 |
249 | this.addSpecs = function(specs, specFilter) {
250 | this.totalSpecCount = specs.length;
251 |
252 | this.views = {
253 | specs: {},
254 | suites: {}
255 | };
256 |
257 | for (var i = 0; i < specs.length; i++) {
258 | var spec = specs[i];
259 | this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
260 | if (specFilter(spec)) {
261 | this.runningSpecCount++;
262 | }
263 | }
264 | };
265 |
266 | this.specComplete = function(spec) {
267 | this.completeSpecCount++;
268 |
269 | if (isUndefined(this.views.specs[spec.id])) {
270 | this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
271 | }
272 |
273 | var specView = this.views.specs[spec.id];
274 |
275 | switch (specView.status()) {
276 | case 'passed':
277 | this.passedCount++;
278 | break;
279 |
280 | case 'failed':
281 | this.failedCount++;
282 | break;
283 |
284 | case 'skipped':
285 | this.skippedCount++;
286 | break;
287 | }
288 |
289 | specView.refresh();
290 | this.refresh();
291 | };
292 |
293 | this.suiteComplete = function(suite) {
294 | var suiteView = this.views.suites[suite.id];
295 | if (isUndefined(suiteView)) {
296 | return;
297 | }
298 | suiteView.refresh();
299 | };
300 |
301 | this.refresh = function() {
302 |
303 | if (isUndefined(this.resultsMenu)) {
304 | this.createResultsMenu();
305 | }
306 |
307 | // currently running UI
308 | if (isUndefined(this.runningAlert)) {
309 | this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "runningAlert bar" });
310 | dom.alert.appendChild(this.runningAlert);
311 | }
312 | this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
313 |
314 | // skipped specs UI
315 | if (isUndefined(this.skippedAlert)) {
316 | this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "skippedAlert bar" });
317 | }
318 |
319 | this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
320 |
321 | if (this.skippedCount === 1 && isDefined(dom.alert)) {
322 | dom.alert.appendChild(this.skippedAlert);
323 | }
324 |
325 | // passing specs UI
326 | if (isUndefined(this.passedAlert)) {
327 | this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: "passingAlert bar" });
328 | }
329 | this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
330 |
331 | // failing specs UI
332 | if (isUndefined(this.failedAlert)) {
333 | this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
334 | }
335 | this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
336 |
337 | if (this.failedCount === 1 && isDefined(dom.alert)) {
338 | dom.alert.appendChild(this.failedAlert);
339 | dom.alert.appendChild(this.resultsMenu);
340 | }
341 |
342 | // summary info
343 | this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
344 | this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
345 | };
346 |
347 | this.complete = function() {
348 | dom.alert.removeChild(this.runningAlert);
349 |
350 | this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
351 |
352 | if (this.failedCount === 0) {
353 | dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
354 | } else {
355 | showDetails();
356 | }
357 |
358 | dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
359 | };
360 |
361 | return this;
362 |
363 | function showDetails() {
364 | if (dom.reporter.className.search(/showDetails/) === -1) {
365 | dom.reporter.className += " showDetails";
366 | }
367 | }
368 |
369 | function isUndefined(obj) {
370 | return typeof obj === 'undefined';
371 | }
372 |
373 | function isDefined(obj) {
374 | return !isUndefined(obj);
375 | }
376 |
377 | function specPluralizedFor(count) {
378 | var str = count + " spec";
379 | if (count > 1) {
380 | str += "s"
381 | }
382 | return str;
383 | }
384 |
385 | };
386 |
387 | jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
388 |
389 |
390 | jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
391 | this.spec = spec;
392 | this.dom = dom;
393 | this.views = views;
394 |
395 | this.symbol = this.createDom('li', { className: 'pending' });
396 | this.dom.symbolSummary.appendChild(this.symbol);
397 |
398 | this.summary = this.createDom('div', { className: 'specSummary' },
399 | this.createDom('a', {
400 | className: 'description',
401 | href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()),
402 | title: this.spec.getFullName()
403 | }, this.spec.description)
404 | );
405 |
406 | this.detail = this.createDom('div', { className: 'specDetail' },
407 | this.createDom('a', {
408 | className: 'description',
409 | href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
410 | title: this.spec.getFullName()
411 | }, this.spec.getFullName())
412 | );
413 | };
414 |
415 | jasmine.HtmlReporter.SpecView.prototype.status = function() {
416 | return this.getSpecStatus(this.spec);
417 | };
418 |
419 | jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
420 | this.symbol.className = this.status();
421 |
422 | switch (this.status()) {
423 | case 'skipped':
424 | break;
425 |
426 | case 'passed':
427 | this.appendSummaryToSuiteDiv();
428 | break;
429 |
430 | case 'failed':
431 | this.appendSummaryToSuiteDiv();
432 | this.appendFailureDetail();
433 | break;
434 | }
435 | };
436 |
437 | jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
438 | this.summary.className += ' ' + this.status();
439 | this.appendToSummary(this.spec, this.summary);
440 | };
441 |
442 | jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
443 | this.detail.className += ' ' + this.status();
444 |
445 | var resultItems = this.spec.results().getItems();
446 | var messagesDiv = this.createDom('div', { className: 'messages' });
447 |
448 | for (var i = 0; i < resultItems.length; i++) {
449 | var result = resultItems[i];
450 |
451 | if (result.type == 'log') {
452 | messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
453 | } else if (result.type == 'expect' && result.passed && !result.passed()) {
454 | messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
455 |
456 | if (result.trace.stack) {
457 | messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
458 | }
459 | }
460 | }
461 |
462 | if (messagesDiv.childNodes.length > 0) {
463 | this.detail.appendChild(messagesDiv);
464 | this.dom.details.appendChild(this.detail);
465 | }
466 | };
467 |
468 | jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
469 | this.suite = suite;
470 | this.dom = dom;
471 | this.views = views;
472 |
473 | this.element = this.createDom('div', { className: 'suite' },
474 | this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description)
475 | );
476 |
477 | this.appendToSummary(this.suite, this.element);
478 | };
479 |
480 | jasmine.HtmlReporter.SuiteView.prototype.status = function() {
481 | return this.getSpecStatus(this.suite);
482 | };
483 |
484 | jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
485 | this.element.className += " " + this.status();
486 | };
487 |
488 | jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
489 |
490 | /* @deprecated Use jasmine.HtmlReporter instead
491 | */
492 | jasmine.TrivialReporter = function(doc) {
493 | this.document = doc || document;
494 | this.suiteDivs = {};
495 | this.logRunningSpecs = false;
496 | };
497 |
498 | jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
499 | var el = document.createElement(type);
500 |
501 | for (var i = 2; i < arguments.length; i++) {
502 | var child = arguments[i];
503 |
504 | if (typeof child === 'string') {
505 | el.appendChild(document.createTextNode(child));
506 | } else {
507 | if (child) { el.appendChild(child); }
508 | }
509 | }
510 |
511 | for (var attr in attrs) {
512 | if (attr == "className") {
513 | el[attr] = attrs[attr];
514 | } else {
515 | el.setAttribute(attr, attrs[attr]);
516 | }
517 | }
518 |
519 | return el;
520 | };
521 |
522 | jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
523 | var showPassed, showSkipped;
524 |
525 | this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },
526 | this.createDom('div', { className: 'banner' },
527 | this.createDom('div', { className: 'logo' },
528 | this.createDom('span', { className: 'title' }, "Jasmine"),
529 | this.createDom('span', { className: 'version' }, runner.env.versionString())),
530 | this.createDom('div', { className: 'options' },
531 | "Show ",
532 | showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
533 | this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
534 | showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
535 | this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
536 | )
537 | ),
538 |
539 | this.runnerDiv = this.createDom('div', { className: 'runner running' },
540 | this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
541 | this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
542 | this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
543 | );
544 |
545 | this.document.body.appendChild(this.outerDiv);
546 |
547 | var suites = runner.suites();
548 | for (var i = 0; i < suites.length; i++) {
549 | var suite = suites[i];
550 | var suiteDiv = this.createDom('div', { className: 'suite' },
551 | this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
552 | this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
553 | this.suiteDivs[suite.id] = suiteDiv;
554 | var parentDiv = this.outerDiv;
555 | if (suite.parentSuite) {
556 | parentDiv = this.suiteDivs[suite.parentSuite.id];
557 | }
558 | parentDiv.appendChild(suiteDiv);
559 | }
560 |
561 | this.startedAt = new Date();
562 |
563 | var self = this;
564 | showPassed.onclick = function(evt) {
565 | if (showPassed.checked) {
566 | self.outerDiv.className += ' show-passed';
567 | } else {
568 | self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
569 | }
570 | };
571 |
572 | showSkipped.onclick = function(evt) {
573 | if (showSkipped.checked) {
574 | self.outerDiv.className += ' show-skipped';
575 | } else {
576 | self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
577 | }
578 | };
579 | };
580 |
581 | jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
582 | var results = runner.results();
583 | var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
584 | this.runnerDiv.setAttribute("class", className);
585 | //do it twice for IE
586 | this.runnerDiv.setAttribute("className", className);
587 | var specs = runner.specs();
588 | var specCount = 0;
589 | for (var i = 0; i < specs.length; i++) {
590 | if (this.specFilter(specs[i])) {
591 | specCount++;
592 | }
593 | }
594 | var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
595 | message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
596 | this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
597 |
598 | this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
599 | };
600 |
601 | jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
602 | var results = suite.results();
603 | var status = results.passed() ? 'passed' : 'failed';
604 | if (results.totalCount === 0) { // todo: change this to check results.skipped
605 | status = 'skipped';
606 | }
607 | this.suiteDivs[suite.id].className += " " + status;
608 | };
609 |
610 | jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
611 | if (this.logRunningSpecs) {
612 | this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
613 | }
614 | };
615 |
616 | jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
617 | var results = spec.results();
618 | var status = results.passed() ? 'passed' : 'failed';
619 | if (results.skipped) {
620 | status = 'skipped';
621 | }
622 | var specDiv = this.createDom('div', { className: 'spec ' + status },
623 | this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
624 | this.createDom('a', {
625 | className: 'description',
626 | href: '?spec=' + encodeURIComponent(spec.getFullName()),
627 | title: spec.getFullName()
628 | }, spec.description));
629 |
630 |
631 | var resultItems = results.getItems();
632 | var messagesDiv = this.createDom('div', { className: 'messages' });
633 | for (var i = 0; i < resultItems.length; i++) {
634 | var result = resultItems[i];
635 |
636 | if (result.type == 'log') {
637 | messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
638 | } else if (result.type == 'expect' && result.passed && !result.passed()) {
639 | messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
640 |
641 | if (result.trace.stack) {
642 | messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
643 | }
644 | }
645 | }
646 |
647 | if (messagesDiv.childNodes.length > 0) {
648 | specDiv.appendChild(messagesDiv);
649 | }
650 |
651 | this.suiteDivs[spec.suite.id].appendChild(specDiv);
652 | };
653 |
654 | jasmine.TrivialReporter.prototype.log = function() {
655 | var console = jasmine.getGlobal().console;
656 | if (console && console.log) {
657 | if (console.log.apply) {
658 | console.log.apply(console, arguments);
659 | } else {
660 | console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
661 | }
662 | }
663 | };
664 |
665 | jasmine.TrivialReporter.prototype.getLocation = function() {
666 | return this.document.location;
667 | };
668 |
669 | jasmine.TrivialReporter.prototype.specFilter = function(spec) {
670 | var paramMap = {};
671 | var params = this.getLocation().search.substring(1).split('&');
672 | for (var i = 0; i < params.length; i++) {
673 | var p = params[i].split('=');
674 | paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
675 | }
676 |
677 | if (!paramMap.spec) {
678 | return true;
679 | }
680 | return spec.getFullName().indexOf(paramMap.spec) === 0;
681 | };
682 |
--------------------------------------------------------------------------------
/tests/lib/jasmine-1.3.1/jasmine.css:
--------------------------------------------------------------------------------
1 | body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
2 |
3 | #HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
4 | #HTMLReporter a { text-decoration: none; }
5 | #HTMLReporter a:hover { text-decoration: underline; }
6 | #HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
7 | #HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
8 | #HTMLReporter #jasmine_content { position: fixed; right: 100%; }
9 | #HTMLReporter .version { color: #aaaaaa; }
10 | #HTMLReporter .banner { margin-top: 14px; }
11 | #HTMLReporter .duration { color: #aaaaaa; float: right; }
12 | #HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
13 | #HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
14 | #HTMLReporter .symbolSummary li.passed { font-size: 14px; }
15 | #HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
16 | #HTMLReporter .symbolSummary li.failed { line-height: 9px; }
17 | #HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
18 | #HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
19 | #HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
20 | #HTMLReporter .symbolSummary li.pending { line-height: 11px; }
21 | #HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
22 | #HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
23 | #HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
24 | #HTMLReporter .runningAlert { background-color: #666666; }
25 | #HTMLReporter .skippedAlert { background-color: #aaaaaa; }
26 | #HTMLReporter .skippedAlert:first-child { background-color: #333333; }
27 | #HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
28 | #HTMLReporter .passingAlert { background-color: #a6b779; }
29 | #HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
30 | #HTMLReporter .failingAlert { background-color: #cf867e; }
31 | #HTMLReporter .failingAlert:first-child { background-color: #b03911; }
32 | #HTMLReporter .results { margin-top: 14px; }
33 | #HTMLReporter #details { display: none; }
34 | #HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
35 | #HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
36 | #HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
37 | #HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
38 | #HTMLReporter.showDetails .summary { display: none; }
39 | #HTMLReporter.showDetails #details { display: block; }
40 | #HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
41 | #HTMLReporter .summary { margin-top: 14px; }
42 | #HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
43 | #HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
44 | #HTMLReporter .summary .specSummary.failed a { color: #b03911; }
45 | #HTMLReporter .description + .suite { margin-top: 0; }
46 | #HTMLReporter .suite { margin-top: 14px; }
47 | #HTMLReporter .suite a { color: #333333; }
48 | #HTMLReporter #details .specDetail { margin-bottom: 28px; }
49 | #HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
50 | #HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
51 | #HTMLReporter .resultMessage span.result { display: block; }
52 | #HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
53 |
54 | #TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
55 | #TrivialReporter a:visited, #TrivialReporter a { color: #303; }
56 | #TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
57 | #TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
58 | #TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
59 | #TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
60 | #TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
61 | #TrivialReporter .runner.running { background-color: yellow; }
62 | #TrivialReporter .options { text-align: right; font-size: .8em; }
63 | #TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
64 | #TrivialReporter .suite .suite { margin: 5px; }
65 | #TrivialReporter .suite.passed { background-color: #dfd; }
66 | #TrivialReporter .suite.failed { background-color: #fdd; }
67 | #TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
68 | #TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
69 | #TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
70 | #TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
71 | #TrivialReporter .spec.skipped { background-color: #bbb; }
72 | #TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
73 | #TrivialReporter .passed { background-color: #cfc; display: none; }
74 | #TrivialReporter .failed { background-color: #fbb; }
75 | #TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
76 | #TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
77 | #TrivialReporter .resultMessage .mismatch { color: black; }
78 | #TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
79 | #TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
80 | #TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
81 | #TrivialReporter #jasmine_content { position: fixed; right: 100%; }
82 | #TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
83 |
--------------------------------------------------------------------------------
/tests/lib/jasmine-affix.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | jasmine-fixture 1.0.5
4 | Makes injecting HTML snippets into the DOM easy & clean!
5 | site: https://github.com/searls/jasmine-fixture
6 | */
7 |
8 |
9 | (function() {
10 | var createHTMLBlock;
11 |
12 | (function($) {
13 | var jasmineFixture, originalAffix, originalInject, originalJasmineFixture, root, _;
14 | root = this;
15 | originalJasmineFixture = root.jasmineFixture;
16 | originalInject = root.inject;
17 | originalAffix = root.affix;
18 | _ = function(list) {
19 | return {
20 | inject: function(iterator, memo) {
21 | var item, _i, _len, _results;
22 | _results = [];
23 | for (_i = 0, _len = list.length; _i < _len; _i++) {
24 | item = list[_i];
25 | _results.push(memo = iterator(memo, item));
26 | }
27 | return _results;
28 | }
29 | };
30 | };
31 | root.jasmineFixture = function($) {
32 | var $whatsTheRootOf, applyAttributes, defaultConfiguration, defaults, init, injectContents, isReady, isString, itLooksLikeHtml, rootId, tidyUp;
33 | $.fn.affix = root.affix = function(selectorOptions) {
34 | var $top;
35 | $top = null;
36 | _(selectorOptions.split(/[ ](?=[^\]]*?(?:\[|$))/)).inject(function($parent, elementSelector) {
37 | var $el;
38 | if (elementSelector === ">") {
39 | return $parent;
40 | }
41 | $el = createHTMLBlock($, elementSelector).appendTo($parent);
42 | $top || ($top = $el);
43 | return $el;
44 | }, $whatsTheRootOf(this));
45 | return $top;
46 | };
47 | $whatsTheRootOf = function(that) {
48 | if (that.jquery != null) {
49 | return that;
50 | } else if ($('#jasmine_content').length > 0) {
51 | return $('#jasmine_content');
52 | } else {
53 | return $('
').appendTo('body');
54 | }
55 | };
56 | afterEach(function() {
57 | return $('#jasmine_content').remove();
58 | });
59 | isReady = false;
60 | rootId = "specContainer";
61 | defaultConfiguration = {
62 | el: "div",
63 | cssClass: "",
64 | id: "",
65 | text: "",
66 | html: "",
67 | defaultAttribute: "class",
68 | attrs: {}
69 | };
70 | defaults = $.extend({}, defaultConfiguration);
71 | $.jasmine = {
72 | inject: function(arg, context) {
73 | var $toInject, config, parent;
74 | if (isReady !== true) {
75 | init();
76 | }
77 | parent = (context ? context : $("#" + rootId));
78 | $toInject = void 0;
79 | if (itLooksLikeHtml(arg)) {
80 | $toInject = $(arg);
81 | } else {
82 | config = $.extend({}, defaults, arg, {
83 | userString: arg
84 | });
85 | $toInject = $("<" + config.el + ">" + config.el + ">");
86 | applyAttributes($toInject, config);
87 | injectContents($toInject, config);
88 | }
89 | return $toInject.appendTo(parent);
90 | },
91 | configure: function(config) {
92 | return $.extend(defaults, config);
93 | },
94 | restoreDefaults: function() {
95 | return defaults = $.extend({}, defaultConfiguration);
96 | },
97 | noConflict: function() {
98 | root.jasmineFixture = originalJasmineFixture;
99 | root.inject = originalInject;
100 | root.affix = originalAffix;
101 | return this;
102 | }
103 | };
104 | $.fn.inject = function(html) {
105 | return $.jasmine.inject(html, $(this));
106 | };
107 | applyAttributes = function($html, config) {
108 | var attrs, key, _results;
109 | attrs = $.extend({}, {
110 | id: config.id,
111 | "class": config["class"] || config.cssClass
112 | }, config.attrs);
113 | if (isString(config.userString)) {
114 | attrs[config.defaultAttribute] = config.userString;
115 | }
116 | _results = [];
117 | for (key in attrs) {
118 | if (attrs[key]) {
119 | _results.push($html.attr(key, attrs[key]));
120 | } else {
121 | _results.push(void 0);
122 | }
123 | }
124 | return _results;
125 | };
126 | injectContents = function($el, config) {
127 | if (config.text && config.html) {
128 | throw "Error: because they conflict, you may only configure inject() to set `html` or `text`, not both! \n\nHTML was: " + config.html + " \n\n Text was: " + config.text;
129 | } else if (config.text) {
130 | return $el.text(config.text);
131 | } else {
132 | if (config.html) {
133 | return $el.html(config.html);
134 | }
135 | }
136 | };
137 | itLooksLikeHtml = function(arg) {
138 | return isString(arg) && arg.indexOf("<") !== -1;
139 | };
140 | isString = function(arg) {
141 | return arg && arg.constructor === String;
142 | };
143 | init = function() {
144 | $("body").append("
");
145 | return isReady = true;
146 | };
147 | tidyUp = function() {
148 | $("#" + rootId).remove();
149 | return isReady = false;
150 | };
151 | $(function($) {
152 | return init();
153 | });
154 | afterEach(function() {
155 | return tidyUp();
156 | });
157 | return $.jasmine;
158 | };
159 | if ($) {
160 | jasmineFixture = root.jasmineFixture($);
161 | return root.inject = root.inject || jasmineFixture.inject;
162 | }
163 | })(window.jQuery);
164 |
165 | createHTMLBlock = (function() {
166 | var bindData, bindEvents, parseAttributes, parseClasses, parseContents, parseEnclosure, parseReferences, parseVariableScope, regAttr, regAttrDfn, regAttrs, regCBrace, regClass, regClasses, regData, regDatas, regEvent, regEvents, regExclamation, regId, regReference, regTag, regTagNotContent, regZenTagDfn;
167 | createHTMLBlock = function($, ZenObject, data, functions, indexes) {
168 | var ZenCode, arr, block, blockAttrs, blockClasses, blockHTML, blockId, blockTag, blocks, el, el2, els, forScope, indexName, inner, len, obj, origZenCode, paren, result, ret, zc, zo;
169 | if ($.isPlainObject(ZenObject)) {
170 | ZenCode = ZenObject.main;
171 | } else {
172 | ZenCode = ZenObject;
173 | ZenObject = {
174 | main: ZenCode
175 | };
176 | }
177 | origZenCode = ZenCode;
178 | if (indexes === undefined) {
179 | indexes = {};
180 | }
181 | if (ZenCode.charAt(0) === "!" || $.isArray(data)) {
182 | if ($.isArray(data)) {
183 | forScope = ZenCode;
184 | } else {
185 | obj = parseEnclosure(ZenCode, "!");
186 | obj = obj.substring(obj.indexOf(":") + 1, obj.length - 1);
187 | forScope = parseVariableScope(ZenCode);
188 | }
189 | while (forScope.charAt(0) === "@") {
190 | forScope = parseVariableScope("!for:!" + parseReferences(forScope, ZenObject));
191 | }
192 | zo = ZenObject;
193 | zo.main = forScope;
194 | el = $();
195 | if (ZenCode.substring(0, 5) === "!for:" || $.isArray(data)) {
196 | if (!$.isArray(data) && obj.indexOf(":") > 0) {
197 | indexName = obj.substring(0, obj.indexOf(":"));
198 | obj = obj.substr(obj.indexOf(":") + 1);
199 | }
200 | arr = ($.isArray(data) ? data : data[obj]);
201 | zc = zo.main;
202 | if ($.isArray(arr) || $.isPlainObject(arr)) {
203 | $.map(arr, function(value, index) {
204 | var next;
205 | zo.main = zc;
206 | if (indexName !== undefined) {
207 | indexes[indexName] = index;
208 | }
209 | if (!$.isPlainObject(value)) {
210 | value = {
211 | value: value
212 | };
213 | }
214 | next = createHTMLBlock($, zo, value, functions, indexes);
215 | if (el.length !== 0) {
216 | return $.each(next, function(index, value) {
217 | return el.push(value);
218 | });
219 | }
220 | });
221 | }
222 | if (!$.isArray(data)) {
223 | ZenCode = ZenCode.substr(obj.length + 6 + forScope.length);
224 | } else {
225 | ZenCode = "";
226 | }
227 | } else if (ZenCode.substring(0, 4) === "!if:") {
228 | result = parseContents("!" + obj + "!", data, indexes);
229 | if (result !== "undefined" || result !== "false" || result !== "") {
230 | el = createHTMLBlock($, zo, data, functions, indexes);
231 | }
232 | ZenCode = ZenCode.substr(obj.length + 5 + forScope.length);
233 | }
234 | ZenObject.main = ZenCode;
235 | } else if (ZenCode.charAt(0) === "(") {
236 | paren = parseEnclosure(ZenCode, "(", ")");
237 | inner = paren.substring(1, paren.length - 1);
238 | ZenCode = ZenCode.substr(paren.length);
239 | zo = ZenObject;
240 | zo.main = inner;
241 | el = createHTMLBlock($, zo, data, functions, indexes);
242 | } else {
243 | blocks = ZenCode.match(regZenTagDfn);
244 | block = blocks[0];
245 | if (block.length === 0) {
246 | return "";
247 | }
248 | if (block.indexOf("@") >= 0) {
249 | ZenCode = parseReferences(ZenCode, ZenObject);
250 | zo = ZenObject;
251 | zo.main = ZenCode;
252 | return createHTMLBlock($, zo, data, functions, indexes);
253 | }
254 | block = parseContents(block, data, indexes);
255 | blockClasses = parseClasses($, block);
256 | if (regId.test(block)) {
257 | blockId = regId.exec(block)[1];
258 | }
259 | blockAttrs = parseAttributes(block, data);
260 | blockTag = (block.charAt(0) === "{" ? "span" : "div");
261 | if (ZenCode.charAt(0) !== "#" && ZenCode.charAt(0) !== "." && ZenCode.charAt(0) !== "{") {
262 | blockTag = regTag.exec(block)[1];
263 | }
264 | if (block.search(regCBrace) !== -1) {
265 | blockHTML = block.match(regCBrace)[1];
266 | }
267 | blockAttrs = $.extend(blockAttrs, {
268 | id: blockId,
269 | "class": blockClasses,
270 | html: blockHTML
271 | });
272 | el = $("<" + blockTag + ">", blockAttrs);
273 | el.attr(blockAttrs);
274 | el = bindEvents(block, el, functions);
275 | el = bindData(block, el, data);
276 | ZenCode = ZenCode.substr(blocks[0].length);
277 | ZenObject.main = ZenCode;
278 | }
279 | if (ZenCode.length > 0) {
280 | if (ZenCode.charAt(0) === ">") {
281 | if (ZenCode.charAt(1) === "(") {
282 | zc = parseEnclosure(ZenCode.substr(1), "(", ")");
283 | ZenCode = ZenCode.substr(zc.length + 1);
284 | } else if (ZenCode.charAt(1) === "!") {
285 | obj = parseEnclosure(ZenCode.substr(1), "!");
286 | forScope = parseVariableScope(ZenCode.substr(1));
287 | zc = obj + forScope;
288 | ZenCode = ZenCode.substr(zc.length + 1);
289 | } else {
290 | len = Math.max(ZenCode.indexOf("+"), ZenCode.length);
291 | zc = ZenCode.substring(1, len);
292 | ZenCode = ZenCode.substr(len);
293 | }
294 | zo = ZenObject;
295 | zo.main = zc;
296 | els = $(createHTMLBlock($, zo, data, functions, indexes));
297 | els.appendTo(el);
298 | }
299 | if (ZenCode.charAt(0) === "+") {
300 | zo = ZenObject;
301 | zo.main = ZenCode.substr(1);
302 | el2 = createHTMLBlock($, zo, data, functions, indexes);
303 | $.each(el2, function(index, value) {
304 | return el.push(value);
305 | });
306 | }
307 | }
308 | ret = el;
309 | return ret;
310 | };
311 | bindData = function(ZenCode, el, data) {
312 | var datas, i, split;
313 | if (ZenCode.search(regDatas) === 0) {
314 | return el;
315 | }
316 | datas = ZenCode.match(regDatas);
317 | if (datas === null) {
318 | return el;
319 | }
320 | i = 0;
321 | while (i < datas.length) {
322 | split = regData.exec(datas[i]);
323 | if (split[3] === undefined) {
324 | $(el).data(split[1], data[split[1]]);
325 | } else {
326 | $(el).data(split[1], data[split[3]]);
327 | }
328 | i++;
329 | }
330 | return el;
331 | };
332 | bindEvents = function(ZenCode, el, functions) {
333 | var bindings, fn, i, split;
334 | if (ZenCode.search(regEvents) === 0) {
335 | return el;
336 | }
337 | bindings = ZenCode.match(regEvents);
338 | if (bindings === null) {
339 | return el;
340 | }
341 | i = 0;
342 | while (i < bindings.length) {
343 | split = regEvent.exec(bindings[i]);
344 | if (split[2] === undefined) {
345 | fn = functions[split[1]];
346 | } else {
347 | fn = functions[split[2]];
348 | }
349 | $(el).bind(split[1], fn);
350 | i++;
351 | }
352 | return el;
353 | };
354 | parseAttributes = function(ZenBlock, data) {
355 | var attrStrs, attrs, i, parts;
356 | if (ZenBlock.search(regAttrDfn) === -1) {
357 | return undefined;
358 | }
359 | attrStrs = ZenBlock.match(regAttrDfn);
360 | attrs = {};
361 | i = 0;
362 | while (i < attrStrs.length) {
363 | parts = regAttr.exec(attrStrs[i]);
364 | attrs[parts[1]] = "";
365 | if (parts[3] !== undefined) {
366 | attrs[parts[1]] = parseContents(parts[3], data);
367 | }
368 | i++;
369 | }
370 | return attrs;
371 | };
372 | parseClasses = function($, ZenBlock) {
373 | var classes, clsString, i;
374 | ZenBlock = ZenBlock.match(regTagNotContent)[0];
375 | if (ZenBlock.search(regClasses) === -1) {
376 | return undefined;
377 | }
378 | classes = ZenBlock.match(regClasses);
379 | clsString = "";
380 | i = 0;
381 | while (i < classes.length) {
382 | clsString += " " + regClass.exec(classes[i])[1];
383 | i++;
384 | }
385 | return $.trim(clsString);
386 | };
387 | parseContents = function(ZenBlock, data, indexes) {
388 | var html;
389 | if (indexes === undefined) {
390 | indexes = {};
391 | }
392 | html = ZenBlock;
393 | if (data === undefined) {
394 | return html;
395 | }
396 | while (regExclamation.test(html)) {
397 | html = html.replace(regExclamation, function(str, str2) {
398 | var begChar, fn, val;
399 | begChar = "";
400 | if (str.indexOf("!for:") > 0 || str.indexOf("!if:") > 0) {
401 | return str;
402 | }
403 | if (str.charAt(0) !== "!") {
404 | begChar = str.charAt(0);
405 | str = str.substring(2, str.length - 1);
406 | }
407 | fn = new Function("data", "indexes", "var r=undefined;" + "with(data){try{r=" + str + ";}catch(e){}}" + "with(indexes){try{if(r===undefined)r=" + str + ";}catch(e){}}" + "return r;");
408 | val = unescape(fn(data, indexes));
409 | return begChar + val;
410 | });
411 | }
412 | html = html.replace(/\\./g, function(str) {
413 | return str.charAt(1);
414 | });
415 | return unescape(html);
416 | };
417 | parseEnclosure = function(ZenCode, open, close, count) {
418 | var index, ret;
419 | if (close === undefined) {
420 | close = open;
421 | }
422 | index = 1;
423 | if (count === undefined) {
424 | count = (ZenCode.charAt(0) === open ? 1 : 0);
425 | }
426 | if (count === 0) {
427 | return;
428 | }
429 | while (count > 0 && index < ZenCode.length) {
430 | if (ZenCode.charAt(index) === close && ZenCode.charAt(index - 1) !== "\\") {
431 | count--;
432 | } else {
433 | if (ZenCode.charAt(index) === open && ZenCode.charAt(index - 1) !== "\\") {
434 | count++;
435 | }
436 | }
437 | index++;
438 | }
439 | ret = ZenCode.substring(0, index);
440 | return ret;
441 | };
442 | parseReferences = function(ZenCode, ZenObject) {
443 | ZenCode = ZenCode.replace(regReference, function(str) {
444 | var fn;
445 | str = str.substr(1);
446 | fn = new Function("objs", "var r=\"\";" + "with(objs){try{" + "r=" + str + ";" + "}catch(e){}}" + "return r;");
447 | return fn(ZenObject, parseReferences);
448 | });
449 | return ZenCode;
450 | };
451 | parseVariableScope = function(ZenCode) {
452 | var forCode, rest, tag;
453 | if (ZenCode.substring(0, 5) !== "!for:" && ZenCode.substring(0, 4) !== "!if:") {
454 | return undefined;
455 | }
456 | forCode = parseEnclosure(ZenCode, "!");
457 | ZenCode = ZenCode.substr(forCode.length);
458 | if (ZenCode.charAt(0) === "(") {
459 | return parseEnclosure(ZenCode, "(", ")");
460 | }
461 | tag = ZenCode.match(regZenTagDfn)[0];
462 | ZenCode = ZenCode.substr(tag.length);
463 | if (ZenCode.length === 0 || ZenCode.charAt(0) === "+") {
464 | return tag;
465 | } else if (ZenCode.charAt(0) === ">") {
466 | rest = "";
467 | rest = parseEnclosure(ZenCode.substr(1), "(", ")", 1);
468 | return tag + ">" + rest;
469 | }
470 | return undefined;
471 | };
472 | regZenTagDfn = /([#\.\@]?[\w-]+|\[([\w-!?=:"']+(="([^"]|\\")+")? {0,})+\]|\~[\w$]+=[\w$]+|&[\w$]+(=[\w$]+)?|[#\.\@]?!([^!]|\\!)+!){0,}(\{([^\}]|\\\})+\})?/i;
473 | regTag = /(\w+)/i;
474 | regId = /#([\w-!]+)/i;
475 | regTagNotContent = /((([#\.]?[\w-]+)?(\[([\w!]+(="([^"]|\\")+")? {0,})+\])?)+)/i;
476 | regClasses = /(\.[\w-]+)/g;
477 | regClass = /\.([\w-]+)/i;
478 | regReference = /(@[\w$_][\w$_\d]+)/i;
479 | regAttrDfn = /(\[([\w-!]+(="?([^"]|\\")+"?)? {0,})+\])/ig;
480 | regAttrs = /([\w-!]+(="([^"]|\\")+")?)/g;
481 | regAttr = /([\w-!]+)(="?(([^"\]]|\\")+)"?)?/i;
482 | regCBrace = /\{(([^\}]|\\\})+)\}/i;
483 | regExclamation = /(?:([^\\]|^))!([^!]|\\!)+!/g;
484 | regEvents = /\~[\w$]+(=[\w$]+)?/g;
485 | regEvent = /\~([\w$]+)=([\w$]+)/i;
486 | regDatas = /&[\w$]+(=[\w$]+)?/g;
487 | regData = /&([\w$]+)(=([\w$]+))?/i;
488 | return createHTMLBlock;
489 | })();
490 |
491 | }).call(this);
--------------------------------------------------------------------------------
/tests/spec/formatters/24hr.spec.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/tests/spec/formatters/24hr.spec.js
--------------------------------------------------------------------------------
/tests/spec/formatters/ampm.spec.js:
--------------------------------------------------------------------------------
1 | describe('formatter/ampm', function(){
2 |
3 | var view;
4 |
5 | beforeEach(function(){
6 | view = new $.timeAutocomplete.formatters.ampm(null, {});
7 | });
8 |
9 | describe('times', function(){
10 |
11 | it('should use times passed to it', function(){
12 |
13 | var times = [
14 | '1:00 AM',
15 | '1:30 AM',
16 | '1:50 AM',
17 | '1:00 PM',
18 | '3:00 PM'
19 | ];
20 |
21 | var Formatter = new $.timeAutocomplete.formatters.ampm(null, {
22 | times: times
23 | });
24 |
25 | expect(Formatter.options.times).toEqual(times);
26 |
27 | });
28 |
29 | it('should generate times when no times are passed in', function(){
30 |
31 | expect(view.options.times.length).toEqual(96);
32 | expect(view.options.times[0]).toEqual('12:00 AM');
33 | expect(view.options.times[1]).toEqual('12:15 AM');
34 | expect(view.options.times[2]).toEqual('12:30 AM');
35 | expect(view.options.times[3]).toEqual('12:45 AM');
36 | expect(view.options.times[4]).toEqual('1:00 AM');
37 |
38 | });
39 |
40 | });
41 |
42 |
43 | describe('increment', function(){
44 |
45 | it('should start with a different hour and use a 10 increment', function(){
46 |
47 | var Formatter = new $.timeAutocomplete.formatters.ampm(null, {
48 | increment: 10,
49 | start_hour: 23,
50 | end_hour: 24
51 | });
52 |
53 | expect(Formatter.options.times.length).toEqual(7);
54 | expect(Formatter.options.times[0]).toEqual('11:00 PM');
55 | expect(Formatter.options.times[1]).toEqual('11:10 PM');
56 | expect(Formatter.options.times[2]).toEqual('11:20 PM');
57 | expect(Formatter.options.times[3]).toEqual('11:30 PM');
58 | expect(Formatter.options.times[4]).toEqual('11:40 PM');
59 | expect(Formatter.options.times[5]).toEqual('11:50 PM');
60 | expect(Formatter.options.times[6]).toEqual('12:00 AM');
61 |
62 | });
63 |
64 | it('should start with a different hour and use a 10 increment', function(){
65 |
66 | var Formatter = new $.timeAutocomplete.formatters.ampm(null, {
67 | increment: 30,
68 | start_hour: 1,
69 | end_hour: 3
70 | });
71 |
72 | expect(Formatter.options.times.length).toEqual(5);
73 | expect(Formatter.options.times[0]).toEqual('1:00 AM');
74 | expect(Formatter.options.times[1]).toEqual('1:30 AM');
75 | expect(Formatter.options.times[2]).toEqual('2:00 AM');
76 | expect(Formatter.options.times[3]).toEqual('2:30 AM');
77 | expect(Formatter.options.times[4]).toEqual('3:00 AM');
78 |
79 | });
80 |
81 | });
82 |
83 | describe('am/pm text', function(){
84 |
85 | it('should change the am/pm text', function(){
86 |
87 | var Formatter = new $.timeAutocomplete.formatters.ampm(null, {
88 | pm_text: 'pee-em',
89 | am_text: 'eh-em',
90 | start_hour: 11,
91 | end_hour: 13
92 | });
93 |
94 | var result = ["11:00 eh-em", "11:15 eh-em", "11:30 eh-em", "11:45 eh-em", "12:00 pee-em", "12:15 pee-em", "12:30 pee-em", "12:45 pee-em", "1:00 pee-em"];
95 |
96 | expect(Formatter.options.times).toEqual(result);
97 |
98 | });
99 |
100 | });
101 |
102 | describe('hook_getTimeObjectFromHis', function(){
103 |
104 | it('should return the proper formatted time when over 12pm', function(){
105 |
106 | var Formatter = new $.timeAutocomplete.formatters.ampm(null, {});
107 | expect(Formatter.hook_getTimeObjectFromHis('19:00:00')).toEqual({
108 | h: 7,
109 | m: '00',
110 | sep: ':',
111 | postfix : ' PM'
112 | });
113 |
114 | });
115 |
116 | it('should return the proper formatted time when under 12pm', function(){
117 |
118 | var Formatter = new $.timeAutocomplete.formatters.ampm(null, {});
119 | expect(Formatter.hook_getTimeObjectFromHis('05:43:00')).toEqual({
120 | h: 5,
121 | m: '43',
122 | sep: ':',
123 | postfix : ' AM'
124 | });
125 |
126 | });
127 |
128 | it('should return the proper formatted time when under 12pm', function(){
129 |
130 | var Formatter = new $.timeAutocomplete.formatters.ampm(null, {});
131 | expect(Formatter.hook_getTimeObjectFromHis('00:43:00')).toEqual({
132 | h: 12,
133 | m: '43',
134 | sep: ':',
135 | postfix : ' AM'
136 | });
137 |
138 | });
139 |
140 | });
141 |
142 | describe('parseTime', function(){
143 |
144 | it('should parse any time into H:i:s format', function(){
145 |
146 | var re = {
147 | '01:00pm': '13:00:00',
148 | '12am': '00:00:00',
149 | '12 a': '00:00:00',
150 | '123 am': '01:23:00',
151 | '13': '13:00:00',
152 | '2330': '23:30:00',
153 | '2:3': '23:00:00',
154 | '2:15am': '02:15:00',
155 | '15:30am': '15:30:00',
156 | '6:30 PM': '18:30:00',
157 | '6:60 PM': '18:00:00',
158 | '25:60 PM': '02:50:00',
159 | '83': '08:30:00',
160 | '27': '02:07:00',
161 | '33': '03:30:00'
162 | };
163 |
164 | for(var k in re){
165 | expect(view.parseTime(k)).toEqual(re[k]);
166 | }
167 |
168 | });
169 |
170 | it('should parse any time into g:i A format', function(){
171 |
172 | var re = {
173 | '01:00pm': '1:00 PM',
174 | '12am': '12:00 AM',
175 | '12 a': '12:00 AM',
176 | '123 am': '1:23 AM',
177 | '13': '1:00 PM',
178 | '2330': '11:30 PM',
179 | '2:3': '11:00 PM',
180 | '2:15am': '2:15 AM',
181 | '15:30am': '3:30 PM',
182 | '6:30 PM': '6:30 PM',
183 | '12:60 PM': '12:00 PM',
184 | '25:60 PM': '2:50 PM',
185 | '83 PM': '8:30 PM',
186 | '27 PM': '2:07 PM',
187 | '33 PM': '3:30 PM',
188 | '23': '11:00 PM',
189 | '00': '12:00 AM',
190 | '12': '12:00 PM'
191 | };
192 |
193 | for(var k in re){
194 | expect(view.parseTime(k, 'g:i A')).toEqual(re[k]);
195 | }
196 |
197 | });
198 |
199 | });
200 |
201 | });
--------------------------------------------------------------------------------
/tests/spec/formatters/french.spec.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/7shifts/jQueryTimeAutocomplete/3e761d5b60318b9e4b5a1c33305da3f00e318e8f/tests/spec/formatters/french.spec.js
--------------------------------------------------------------------------------
/tests/spec/timeAutocomplete.spec.js:
--------------------------------------------------------------------------------
1 | describe("timeAutocomplete", function() {
2 |
3 | var sut,
4 | $el;
5 |
6 | beforeEach(function(){
7 | $el = affix('input');
8 | sut = new $.timeAutocomplete._raw($el);
9 | });
10 |
11 | describe('initialize', function(){
12 |
13 | it('should merge in default_opts with opts passed in', function(){
14 | var opts = { passed: 'options', formatter: 'bleh' };
15 | sut.initialize($el, opts);
16 | expect(sut.options).toEqual($.extend(true, {}, sut.default_opts, opts));
17 | });
18 |
19 | });
20 |
21 | describe('render', function(){
22 |
23 | beforeEach(function(){
24 | spyOn(sut, 'setFormatter');
25 | spyOn(sut, '_callFormatterMethod');
26 | spyOn(sut, '_callAutocomplete');
27 | spyOn(sut, '_bindEvents');
28 | spyOn(sut, '_setupPlaceholder');
29 | spyOn(sut, '_setValueAsTime');
30 |
31 | sut.render();
32 | });
33 |
34 | it('should call setFormatter', function(){
35 | expect(sut.setFormatter).toHaveBeenCalled();
36 | });
37 |
38 | it('should call _setValueAsTime', function(){
39 | expect(sut._setValueAsTime).toHaveBeenCalled();
40 | });
41 |
42 | it('should call_bindEvents', function(){
43 | expect(sut._bindEvents).toHaveBeenCalled();
44 | });
45 |
46 | it('should call _callAutocomplete', function(){
47 | expect(sut._callAutocomplete).toHaveBeenCalled();
48 | });
49 |
50 | it('should call _setupPlaceholder', function(){
51 | expect(sut._setupPlaceholder).toHaveBeenCalled();
52 | });
53 |
54 | it('should not call _setValueAsTime if this.options.auto_value is false', function(){
55 | var $ta_el = affix('input');
56 | var TimeAutocompleteInstance = new $.timeAutocomplete._raw($ta_el);
57 | spyOn(TimeAutocompleteInstance, 'setFormatter');
58 | spyOn(TimeAutocompleteInstance, '_callFormatterMethod');
59 | spyOn(TimeAutocompleteInstance, '_callAutocomplete');
60 | spyOn(TimeAutocompleteInstance, '_bindEvents');
61 | spyOn(TimeAutocompleteInstance, '_setupPlaceholder');
62 | spyOn(TimeAutocompleteInstance, '_setValueAsTime');
63 |
64 | TimeAutocompleteInstance.options.auto_value = false;
65 | TimeAutocompleteInstance.render();
66 |
67 | expect(TimeAutocompleteInstance._setValueAsTime).not.toHaveBeenCalled();
68 | });
69 |
70 | });
71 |
72 | describe('_setValueAsTime', function(){
73 |
74 | beforeEach(function(){
75 | spyOn(sut, 'setTime');
76 | spyOn(sut, '_attacheUsableTimeData');
77 | spyOn(sut, '_getCurrentTimeAsValue');
78 |
79 | });
80 |
81 | it('should not set time with options.value', function(){
82 | sut.el = affix('input[value=""]');
83 | sut.options.value = '03:40:00';
84 | sut._setValueAsTime();
85 | expect(sut.setTime).toHaveBeenCalledWith(sut.options.value);
86 | });
87 |
88 | it('should not set time (string)', function(){
89 | sut.el = affix('input[value="some thing"]');
90 | sut._setValueAsTime();
91 | expect(sut.setTime).not.toHaveBeenCalled();
92 | });
93 |
94 | it('should not set the time (badly formed number)', function(){
95 | sut.el = affix('input[value="03:00:"]');
96 | sut._setValueAsTime();
97 | expect(sut.setTime).not.toHaveBeenCalled();
98 | });
99 |
100 | it('should set the time', function(){
101 | sut.el = affix('input[value="03:00:00"]');
102 | sut._setValueAsTime();
103 | expect(sut.setTime).toHaveBeenCalledWith('03:00:00');
104 | });
105 |
106 | });
107 |
108 | describe('_callAutocomplete', function(){
109 |
110 | beforeEach(function(){
111 | spyOn(sut, '_callFormatterMethod');
112 | spyOn(sut.el, 'autocomplete');
113 | sut.options.auto_complete = { wee: 'data' };
114 | sut._callAutocomplete();
115 | });
116 |
117 | it('should call our callFormatterMethod with args', function(){
118 | expect(sut._callFormatterMethod.argsForCall[0][0]).toEqual('filterSource');
119 | expect(sut._callFormatterMethod.argsForCall[0][1]).toEqual([$el]);
120 | expect(function(){ sut._callFormatterMethod.argsForCall[0][2]() }).toThrow('You must set a hook_filterSource method in your formatter.');
121 | });
122 |
123 | it('should call autocomplete', function(){
124 | expect(sut.el.autocomplete).toHaveBeenCalledWith(sut.options.auto_complete);
125 | });
126 |
127 | });
128 |
129 | describe('_bindEvents', function(){
130 |
131 | beforeEach(function(){
132 | sut.el = affix('input');
133 | spyOn($.fn, 'bind').andCallThrough();
134 | spyOn($.fn, 'trigger');
135 | sut._bindEvents();
136 | });
137 |
138 | it('should bind keydown', function(){
139 | spyOn(sut, '_keydownAutocomplete');
140 | expect($.fn.bind.argsForCall[0][0]).toEqual('keydown.timeAutocomplete');
141 | var e = { target: 'a' };
142 | var ctx = {};
143 | $.fn.bind.argsForCall[0][1].call(ctx, e);
144 | expect(sut._keydownAutocomplete).toHaveBeenCalledWith(e);
145 | });
146 |
147 | it('should bind keyup', function(){
148 | spyOn(sut, '_keyupAutocomplete');
149 | expect($.fn.bind.argsForCall[1][0]).toEqual('keyup.timeAutocomplete');
150 | var e = { target: 'a' };
151 | var ctx = {};
152 | $.fn.bind.argsForCall[1][1].call(ctx, e);
153 | expect(sut._keyupAutocomplete).toHaveBeenCalledWith(e);
154 | });
155 |
156 | it('should bind blur', function(){
157 | spyOn(sut, '_blurAutocomplete');
158 | expect($.fn.bind.argsForCall[2][0]).toEqual('blur.timeAutocomplete');
159 | var e = { target: 'a' };
160 | var ctx = {};
161 | $.fn.bind.argsForCall[2][1].call(ctx, e);
162 | expect(sut._blurAutocomplete).toHaveBeenCalledWith(e);
163 | });
164 |
165 | it('should trigger a blur event', function(){
166 | expect($.fn.trigger).toHaveBeenCalledWith('blur.timeAutocomplete');
167 | });
168 |
169 | });
170 |
171 | describe('_callFormatterMethod', function(){
172 |
173 | it('should call formatter if it exists', function(){
174 | var method = 'myMethod';
175 | sut._formatter = {
176 | hook_myMethod: jasmine.createSpy()
177 | };
178 | sut._callFormatterMethod(method, ['some', 'args'], 1);
179 | expect(sut._formatter.hook_myMethod).toHaveBeenCalledWith('some', 'args');
180 | });
181 |
182 | it('should return default val', function(){
183 | var method = 'myMethod';
184 | sut._formatter = {};
185 | expect(sut._callFormatterMethod(method, ['some', 'args'], 1)).toEqual(1);
186 | });
187 |
188 | });
189 |
190 | describe('_readMind', function(){
191 |
192 | it('should call callFormatterMethod with proper params', function(){
193 | spyOn(sut, '_callFormatterMethod');
194 | var v = 'my default val';
195 | sut._readMind(v);
196 | expect(sut._callFormatterMethod).toHaveBeenCalledWith('readMind', [v], v);
197 | });
198 |
199 | });
200 |
201 | describe('_getCurrentTimeAsValue', function(){
202 |
203 | var _24hr,
204 | times;
205 |
206 | beforeEach(function(){
207 | times = [
208 | '12:00 AM',
209 | '12:15 AM',
210 | '11:00 PM',
211 | '11:15 PM',
212 | '11:30 PM',
213 | '11:45 PM',
214 | '12:00 AM'
215 | ];
216 |
217 | _24hr = {
218 | '12:00 AM': '00:00:00',
219 | '12:15 AM': '00:15:00',
220 | '11:00 PM': '23:00:00',
221 | '11:15 PM': '23:15:00',
222 | '11:30 PM': '23:30:00',
223 | '11:45 PM': '23:45:00'
224 | };
225 |
226 | spyOn(sut, 'getFormatter').andReturn({
227 | options: {
228 | times: times
229 | }
230 | });
231 |
232 | spyOn(sut, '_callFormatterMethod').andCallFake(function(method, args){
233 |
234 | var time_parts = _24hr[args[0]].split(':');
235 | var h = time_parts[0];
236 | var m = time_parts[1];
237 |
238 | return (new Date(args[1][0], args[1][1], args[1][2], h, m)).getTime();
239 | });
240 | });
241 |
242 | it('should set the proper start time based on the users current time: 11:23 PM', function(){
243 |
244 | spyOn(sut, '_getCurrentDate').andReturn(new Date(1999, 1, 1, 23, 23));
245 | var val = sut._getCurrentTimeAsValue();
246 | expect(val).toEqual('11:30 PM');
247 |
248 | });
249 |
250 | it('should set the proper start time based on the users current time 11:58 PM', function(){
251 |
252 | spyOn(sut, '_getCurrentDate').andReturn(new Date(1999, 1, 1, 23, 58));
253 | var val = sut._getCurrentTimeAsValue();
254 | expect(val).toEqual('12:00 AM');
255 |
256 | });
257 |
258 | it('should set the proper start time based on the users current time 11:45 PM', function(){
259 |
260 | spyOn(sut, '_getCurrentDate').andReturn(new Date(1999, 1, 1, 23, 45));
261 | var val = sut._getCurrentTimeAsValue();
262 | expect(val).toEqual('11:45 PM');
263 |
264 | });
265 |
266 | });
267 |
268 | });
--------------------------------------------------------------------------------
/timeAutocomplete.jquery.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "timeAutocomplete",
3 | "title": "jQuery Time Autocomplete",
4 | "description": "A time autocomplete plugin similar to how Google Calendar's time autocomplete works.",
5 | "keywords": [
6 | "time",
7 | "autocomplete"
8 | ],
9 | "version": "1.0.2",
10 | "author": {
11 | "name": "Jordan Boesch"
12 | },
13 | "licenses": [
14 | {
15 | "type": "MIT",
16 | "url": "https://github.com/7shifts/jQueryTimeAutocomplete/blob/master/MIT-LICENSE.txt"
17 | }
18 | ],
19 | "bugs": "https://github.com/7shifts/jQueryTimeAutocomplete/issues",
20 | "homepage": "http://7shifts.com/blog/better-time-drop-downs-jquery-timeautocomplete/",
21 | "docs": "http://7shifts.com/blog/better-time-drop-downs-jquery-timeautocomplete/",
22 | "download": "http://7shifts.com/blog/better-time-drop-downs-jquery-timeautocomplete/",
23 | "dependencies": {
24 | "jquery": ">=1.10"
25 | }
26 | }
--------------------------------------------------------------------------------