vendor: 5,309 bytes, lines 1-183
1/*! 2 * jquery-timepicker v1.13.10 - A jQuery timepicker plugin inspired by Google Calendar. It supports both mouse and keyboard navigation. 3 * Copyright (c) 2020 Jon Thornton - https://www.jonthornton.com/jquery-timepicker/ 4 * License: MIT 5 */ 6(function () { 7 'use strict'; 8 9 function _typeof(obj) { 10 "@babel/helpers - typeof"; 11 12 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { 13 _typeof = function (obj) { 14 return typeof obj; 15 }; 16 } else { 17 _typeof = function (obj) { 18 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 19 }; 20 } 21 22 return _typeof(obj); 23 } 24 25 function _classCallCheck(instance, Constructor) { 26 if (!(instance instanceof Constructor)) { 27 throw new TypeError("Cannot call a class as a function"); 28 } 29 } 30 31 function _defineProperties(target, props) { 32 for (var i = 0; i < props.length; i++) { 33 var descriptor = props[i]; 34 descriptor.enumerable = descriptor.enumerable || false; 35 descriptor.configurable = true; 36 if ("value" in descriptor) descriptor.writable = true; 37 Object.defineProperty(target, descriptor.key, descriptor); 38 } 39 } 40 41 function _createClass(Constructor, protoProps, staticProps) { 42 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 43 if (staticProps) _defineProperties(Constructor, staticProps); 44 return Constructor; 45 } 46 47 function _defineProperty(obj, key, value) { 48 if (key in obj) { 49 Object.defineProperty(obj, key, { 50 value: value, 51 enumerable: true, 52 configurable: true, 53 writable: true 54 }); 55 } else { 56 obj[key] = value; 57 } 58 59 return obj; 60 } 61 62 function ownKeys(object, enumerableOnly) { 63 var keys = Object.keys(object); 64 65 if (Object.getOwnPropertySymbols) { 66 var symbols = Object.getOwnPropertySymbols(object); 67 if (enumerableOnly) symbols = symbols.filter(function (sym) { 68 return Object.getOwnPropertyDescriptor(object, sym).enumerable; 69 }); 70 keys.push.apply(keys, symbols); 71 } 72 73 return keys; 74 } 75 76 function _objectSpread2(target) { 77 for (var i = 1; i < arguments.length; i++) { 78 var source = arguments[i] != null ? arguments[i] : {}; 79 80 if (i % 2) { 81 ownKeys(Object(source), true).forEach(function (key) { 82 _defineProperty(target, key, source[key]); 83 }); 84 } else if (Object.getOwnPropertyDescriptors) { 85 Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); 86 } else { 87 ownKeys(Object(source)).forEach(function (key) { 88 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); 89 }); 90 } 91 } 92 93 return target; 94 } 95 96 function _unsupportedIterableToArray(o, minLen) { 97 if (!o) return; 98 if (typeof o === "string") return _arrayLikeToArray(o, minLen); 99 var n = Object.prototype.toString.call(o).slice(8, -1); 100 if (n === "Object" && o.constructor) n = o.constructor.name; 101 if (n === "Map" || n === "Set") return Array.from(n); 102 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); 103 } 104 105 function _arrayLikeToArray(arr, len) { 106 if (len == null || len > arr.length) len = arr.length; 107 108 for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; 109 110 return arr2; 111 } 112 113 function _createForOfIteratorHelper(o) { 114 if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { 115 if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { 116 var i = 0; 117 118 var F = function () {}; 119 120 return { 121 s: F, 122 n: function () { 123 if (i >= o.length) return { 124 done: true 125 }; 126 return { 127 done: false, 128 value: o[i++] 129 }; 130 }, 131 e: function (e) { 132 throw e; 133 }, 134 f: F 135 }; 136 } 137 138 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 139 } 140 141 var it, 142 normalCompletion = true, 143 didErr = false, 144 err; 145 return { 146 s: function () { 147 it = o[Symbol.iterator](); 148 }, 149 n: function () { 150 var step = it.next(); 151 normalCompletion = step.done; 152 return step; 153 }, 154 e: function (e) { 155 didErr = true; 156 err = e; 157 }, 158 f: function () { 159 try { 160 if (!normalCompletion && it.return != null) it.return(); 161 } finally { 162 if (didErr) throw err; 163 } 164 } 165 }; 166 } 167 168 var ONE_DAY = 86400; 169 170 var roundingFunction = function roundingFunction(seconds, settings) { 171 if (seconds === null) { 172 return null; 173 } else if (typeof settings.step !== "number") { 174 // TODO: nearest fit irregular steps 175 return seconds; 176 } else { 177 var offset = seconds % (settings.step * 60); // step is in minutes 178 179 var start = settings.minTime || 0; // adjust offset by start mod step so that the offset is aligned not to 00:00 but to the start 180 181 offset -= start % (settings.step * 60); 182 183 if (offset >= settings.step * 30) {
184 // if offset is larger than a half step, round up 185 seconds += settings.step * 60 - offset; 186 } else { 187 // round down 188 seconds -= offset; 189 } 190 191 return _moduloSeconds$1(seconds, settings); 192 } 193 }; 194 195 function _moduloSeconds$1(seconds, settings) { 196 if (seconds == ONE_DAY && settings.show2400) { 197 return seconds; 198 } 199 200 return seconds % ONE_DAY; 201 } 202 203 var DEFAULT_SETTINGS = { 204 appendTo: "body", 205 className: null, 206 closeOnWindowScroll: false, 207 disableTextInput: false, 208 disableTimeRanges: [], 209 disableTouchKeyboard: false, 210 durationTime: null, 211 forceRoundTime: false, 212 lang: {}, 213 maxTime: null, 214 minTime: null, 215 noneOption: false, 216 orientation: "l", 217 roundingFunction: roundingFunction, 218 scrollDefault: null, 219 selectOnBlur: false, 220 show2400: false, 221 showDuration: false, 222 showOn: ["click", "focus"], 223 showOnFocus: true, 224 step: 30, 225 stopScrollPropagation: false, 226 timeFormat: "g:ia", 227 typeaheadHighlight: true, 228 useSelect: false, 229 wrapHours: true 230 }; 231 var DEFAULT_LANG = { 232 am: "am", 233 pm: "pm", 234 AM: "AM", 235 PM: "PM", 236 decimal: ".", 237 mins: "mins", 238 hr: "hr", 239 hrs: "hrs" 240 }; 241 242 var Timepicker = /*#__PURE__*/function () { 243 function Timepicker(targetEl) { 244 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 245 246 _classCallCheck(this, Timepicker); 247 248 var attrOptions = Timepicker.extractAttrOptions(targetEl, Object.keys(DEFAULT_SETTINGS)); 249 this.settings = this.parseSettings(_objectSpread2(_objectSpread2(_objectSpread2({}, DEFAULT_SETTINGS), options), attrOptions)); 250 } 251 252 _createClass(Timepicker, [{ 253 key: "time2int", 254 value: function time2int(timeString) { 255 if (timeString === "" || timeString === null || timeString === undefined) return null; 256 257 if (timeString instanceof Date) { 258 return timeString.getHours() * 3600 + timeString.getMinutes() * 60 + timeString.getSeconds(); 259 } 260 261 if (typeof timeString != "string") { 262 return timeString; 263 } 264 265 timeString = timeString.toLowerCase().replace(/[\s\.]/g, ""); // if the last character is an "a" or "p", add the "m" 266 267 if (timeString.slice(-1) == "a" || timeString.slice(-1) == "p") { 268 timeString += "m"; 269 } 270 271 var pattern = /^(([^0-9]*))?([0-9]?[0-9])(\W?([0-5][0-9]))?(\W+([0-5][0-9]))?(([^0-9]*))$/;
272 var time = timeString.match(pattern); 273 274 if (!time) { 275 return null; 276 } 277 278 var hour = parseInt(time[3] * 1, 10); 279 var ampm = time[2] || time[9]; 280 var hours = hour; 281 var minutes = time[5] * 1 || 0; 282 var seconds = time[7] * 1 || 0; 283 284 if (hour <= 12 && ampm) { 285 ampm = ampm.trim(); 286 var isPm = ampm == this.settings.lang.pm || ampm == this.settings.lang.PM; 287 288 if (hour == 12) { 289 hours = isPm ? 12 : 0; 290 } else { 291 hours = hour + (isPm ? 12 : 0); 292 } 293 } else { 294 var t = hour * 3600 + minutes * 60 + seconds; 295 296 if (t >= ONE_DAY + (this.settings.show2400 ? 1 : 0)) { 297 if (this.settings.wrapHours === false) { 298 return null; 299 } 300 301 hours = hour % 24; 302 } 303 } 304 305 var timeInt = hours * 3600 + minutes * 60 + seconds; // if no am/pm provided, intelligently guess based on the scrollDefault 306 307 if (hour < 12 && !ampm && this.settings._twelveHourTime && this.settings.scrollDefault) { 308 var delta = timeInt - this.settings.scrollDefault(); 309 310 if (delta < 0 && delta >= ONE_DAY / -2) { 311 timeInt = (timeInt + ONE_DAY / 2) % ONE_DAY; 312 } 313 } 314 315 return timeInt; 316 } 317 }, { 318 key: "parseSettings", 319 value: function parseSettings(settings) { 320 var _this = this; 321 322 settings.lang = _objectSpread2(_objectSpread2({}, DEFAULT_LANG), settings.lang); // lang is used by other functions the rest of this depends on 323 // todo: unwind circular dependency on lang 324 325 this.settings = settings; 326 327 if (settings.minTime) { 328 settings.minTime = this.time2int(settings.minTime); 329 } 330 331 if (settings.maxTime) { 332 settings.maxTime = this.time2int(settings.maxTime); 333 } 334 335 if (settings.durationTime && typeof settings.durationTime !== "function") { 336 settings.durationTime = this.time2int(settings.durationTime); 337 } 338 339 if (settings.scrollDefault == "now") { 340 settings.scrollDefault = function () { 341 return settings.roundingFunction(_this.time2int(new Date()), settings); 342 }; 343 } else if (settings.scrollDefault && typeof settings.scrollDefault != "function") { 344 var val = settings.scrollDefault; 345 346 settings.scrollDefault = function () { 347 return settings.roundingFunction(_this.time2int(val), settings); 348 }; 349 } else if (settings.minTime) { 350 settings.scrollDefault = function () { 351 return settings.roundingFunction(settings.minTime, settings); 352 }; 353 } 354 355 if (typeof settings.timeFormat === "string" && settings.timeFormat.match(/[gh]/)) { 356 settings._twelveHourTime = true; 357 } 358 359 if (settings.showOnFocus === false && settings.showOn.indexOf("focus") != -1) { 360 settings.showOn.splice(settings.showOn.indexOf("focus"), 1); 361 } 362 363 if (!settings.disableTimeRanges) { 364 settings.disableTimeRanges = []; 365 } 366 367 if (settings.disableTimeRanges.length > 0) { 368 // convert string times to integers 369 for (var i in settings.disableTimeRanges) { 370 settings.disableTimeRanges[i] = [this.time2int(settings.disableTimeRanges[i][0]), this.time2int(settings.disableTimeRanges[i][1])]; 371 } // sort by starting time 372 373 374 settings.disableTimeRanges = settings.disableTimeRanges.sort(function (a, b) { 375 return a[0] - b[0]; 376 }); // merge any overlapping ranges 377 378 for (var i = settings.disableTimeRanges.length - 1; i > 0; i--) { 379 if (settings.disableTimeRanges[i][0] <= settings.disableTimeRanges[i - 1][1]) { 380 settings.disableTimeRanges[i - 1] = [Math.min(settings.disableTimeRanges[i][0], settings.disableTimeRanges[i - 1][0]), Math.max(settings.disableTimeRanges[i][1], settings.disableTimeRanges[i - 1][1])]; 381 settings.disableTimeRanges.splice(i, 1); 382 } 383 } 384 } 385 386 return settings; 387 } 388 }], [{ 389 key: "extractAttrOptions", 390 value: function extractAttrOptions(element, keys) { 391 var output = {}; 392 393 var _iterator = _createForOfIteratorHelper(keys), 394 _step; 395 396 try { 397 for (_iterator.s();
397 !(_step = _iterator.n()).done;) { 398 var key = _step.value; 399 400 // console.log(key, element) 401 if (key in element.dataset) { 402 output[key] = element.dataset[key]; 403 } 404 } 405 } catch (err) { 406 _iterator.e(err); 407 } finally { 408 _iterator.f(); 409 } 410 411 return output; 412 } 413 }]); 414 415 return Timepicker; 416 }(); 417 418 (function (factory) { 419 if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && exports && (typeof module === "undefined" ? "undefined" : _typeof(module)) === "object" && module && module.exports === exports) { 420 // Browserify. Attach to jQuery module. 421 factory(require("jquery")); 422 } else if (typeof define === "function" && define.amd) { 423 // AMD. Register as an anonymous module. 424 define(["jquery"], factory); 425 } else { 426 // Browser globals 427 factory(jQuery); 428 } 429 })(function ($) { 430 var _lang = {}; 431 var methods = { 432 init: function init(options) { 433 return this.each(function () { 434 var self = $(this); 435 var tp = new Timepicker(this, options); 436 var settings = tp.settings; 437 _lang = settings.lang; 438 self.data("timepicker-settings", settings); 439 self.data("timepicker-obj", tp); 440 self.addClass("ui-timepicker-input"); 441 442 if (settings.useSelect) { 443 _render(self); 444 } else { 445 self.prop("autocomplete", "off"); 446 447 if (settings.showOn) { 448 for (var i in settings.showOn) { 449 self.on(settings.showOn[i] + ".timepicker", methods.show); 450 } 451 } 452 453 self.on("change.timepicker", _formatValue); 454 self.on("keydown.timepicker", _keydownhandler); 455 self.on("keyup.timepicker", _keyuphandler); 456 457 if (settings.disableTextInput) { 458 self.on("keydown.timepicker", _disableTextInputHandler); 459 } 460 461 self.on("cut.timepicker", _keyuphandler); 462 self.on("paste.timepicker", _keyuphandler); 463 464 _formatValue.call(self.get(0), null, "initial"); 465 } 466 }); 467 }, 468 show: function show(e) { 469 var self = $(this); 470 var settings = self.data("timepicker-settings"); 471 var tp = self.data("timepicker-obj"); 472 473 if (e) { 474 e.preventDefault(); 475 } 476 477 if (settings.useSelect) { 478 self.data("timepicker-list").focus(); 479 return; 480 } 481 482 if (_hideKeyboard(self)) { 483 // block the keyboard on mobile devices 484 self.blur(); 485 } 486 487 var list = self.data("timepicker-list"); // check if input is readonly 488 489 if (self.prop("readonly")) { 490 return; 491 } // check if list needs to be rendered 492 493 494 if (!list || list.length === 0 || typeof settings.durationTime === "function") { 495 _render(self); 496 497 list = self.data("timepicker-list"); 498 } 499 500 if (_isVisible(list)) { 501 return; 502 } 503 504 self.data("ui-timepicker-value", self.val()); 505 506 _setSelected(self, list); // make sure other pickers are hidden 507 508 509 methods.hide(); 510 511 if (typeof settings.listWidth == "number") { 512 console.log(settings.listWidth); 513 list.width(self.outerWidth() * settings.listWidth); 514 } // position the dropdown relative to the input 515 516 517 list.show(); 518 var listOffset = {}; 519 520 if (settings.orientation.match(/r/)) { 521 // right-align the dropdown 522 listOffset.left = self.offset().left + self.outerWidth() - list.outerWidth() + parseInt(list.css("marginLeft").replace("px", ""), 10); 523 } else if (settings.orientation.match(/l/)) { 524 // left-align the dropdown 525 listOffset.left = self.offset().left + parseInt(list.css("marginLeft").replace("px", ""), 10); 526 } else if (settings.orientation.match(/c/)) { 527 // center-align the dropdown 528 listOffset.left = self.offset().left + (self.outerWidth() - list.outerWidth()) / 2 + parseInt(list.css("marginLeft").replace("px", ""), 10); 529 } 530 531 var verticalOrientation; 532 533 if (settings.orientation.match(/t/)) { 534 verticalOrientation = "t"; 535 } else if (settings.orientation.match(/b/)) { 536 verticalOrientation = "b"; 537 } else if (self.offset().top + self.outerHeight(true) + list.outerHeight() > $(window).height() + $(window).scrollTop()) { 538 verticalOrientation = "t"; 539 } else { 540 verticalOrientation = "b"; 541 } 542 543 if (verticalOrientation == "t") { 544 // position the dropdown on top 545 list.addClass("ui-timepicker-positioned-top"); 546 listOffset.top = self.offset().top - list.outerHeight() + parseInt(list.css("marginTop").replace("px", ""), 10); 547 } else { 548 // put it under the input 549 list.removeClass("ui-timepicker-positioned-top"); 550 listOffset.top = self.offset().top + self.outerHeight() + parseInt(list.css("marginTop").replace("px", ""), 10); 551 } 552 553 list.offset(listOffset); // position scrolling 554 555 var selected = list.find(".ui-timepicker-selected"); 556 557 if (!selected.length) { 558 var timeInt = tp.time2int(_getTimeValue(self)); 559 560 if (timeInt !== null) { 561 selected = _findRow(self, list, timeInt); 562 } else if (settings.scrollDefault) { 563 selected = _findRow(self, list, settings.scrollDefault()); 564 } 565 } // if not found or disabled, intelligently find first selectable element 566 567 568 if (!selected.length || selected.hasClass("ui-timepicker-disabled")) { 569 selected = list.find("li:not(.ui-timepicker-disabled):first"); 570 } 571 572 if (selected && selected.length) { 573 var topOffset = list.scrollTop() + selected.position().top - selected.outerHeight(); 574 list.scrollTop(topOffset); 575 } else { 576 list.scrollTop(0); 577 } // prevent scroll propagation 578 579 580 if (settings.stopScrollPropagation) { 581 $(document).on("wheel.ui-timepicker", ".ui-timepicker-wrapper", function (e) { 582 e.preventDefault(); 583 var currentScroll = $(this).scrollTop(); 584 $(this).scrollTop(currentScroll + e.originalEvent.deltaY); 585 }); 586 } // attach close handlers 587 588 589 $(document).on("touchstart.ui-timepicker mousedown.ui-timepicker", _closeHandler); 590 $(window).on("resize.ui-timepicker", _closeHandler); 591 592 if (settings.closeOnWindowScroll) { 593 $(document).on("scroll.ui-timepicker", _closeHandler); 594 } 595 596 self.trigger("showTimepicker"); 597 return this; 598 }, 599 hide: function hide(e) { 600 var self = $(this); 601 var settings = self.data("timepicker-settings"); 602 603 if (settings && settings.useSelect) { 604 self.blur(); 605 } 606 607 $(".ui-timepicker-wrapper").each(function () { 608 var list = $(this); 609 610 if (!_isVisible(list)) { 611 return; 612 } 613 614 var self = list.data("timepicker-input"); 615 var settings = self.data("timepicker-settings"); 616 617 if (settings && settings.selectOnBlur) { 618 _selectValue(self); 619 } 620 621 list.hide(); 622 self.trigger("hideTimepicker"); 623 }); 624 return this; 625 }, 626 option: function option(key, value) { 627 if (typeof key == "string" && typeof value == "undefined") { 628 return $(this).data("timepicker-settings")[key]; 629 } 630 631 return this.each(function () { 632 var self = $(this); 633 var settings = self.data("timepicker-settings"); 634 var tp = self.data("timepicker-obj"); 635 var list = self.data("timepicker-list"); 636
637 if (_typeof(key) == "object") { 638 settings = $.extend(settings, key); 639 } else if (typeof key == "string") { 640 settings[key] = value; 641 } 642 643 settings = tp.parseSettings(settings); 644 self.data("timepicker-settings", settings); 645 646 _formatValue.call(self.get(0), { 647 type: "change" 648 }, "initial"); 649 650 if (list) { 651 list.remove(); 652 self.data("timepicker-list", false); 653 } 654 655 if (settings.useSelect) { 656 _render(self); 657 } 658 }); 659 }, 660 getSecondsFromMidnight: function getSecondsFromMidnight() { 661 var self = $(this); 662 var tp = self.data("timepicker-obj"); 663 return tp.time2int(_getTimeValue(this)); 664 }, 665 getTime: function getTime(relative_date) { 666 var self = $(this); 667 var tp = self.data("timepicker-obj"); 668 669 var time_string = _getTimeValue(self); 670 671 if (!time_string) { 672 return null; 673 } 674 675 var offset = tp.time2int(time_string); 676 677 if (offset === null) { 678 return null; 679 } 680 681 if (!relative_date) { 682 relative_date = new Date(); 683 } // construct a Date from relative date, and offset's time 684 685 686 var time = new Date(relative_date); 687 time.setHours(offset / 3600); 688 time.setMinutes(offset % 3600 / 60); 689 time.setSeconds(offset % 60); 690 time.setMilliseconds(0); 691 return time; 692 }, 693 isVisible: function isVisible() { 694 var self = this; 695 var list = self.data("timepicker-list"); 696 return !!(list && _isVisible(list)); 697 }, 698 setTime: function setTime(value) { 699 var self = this; 700 var settings = self.data("timepicker-settings"); 701 var tp = self.data("timepicker-obj"); 702 703 if (settings.forceRoundTime) { 704 var prettyTime = _roundAndFormatTime(tp.time2int(value), settings); 705 } else { 706 var prettyTime = _int2time(tp.time2int(value), settings); 707 } 708 709 if (value && prettyTime === null && settings.noneOption) { 710 prettyTime = value; 711 } 712 713 _setTimeValue(self, prettyTime, "initial"); 714 715 _formatValue.call(self.get(0), { 716 type: "change" 717 }, "initial"); 718 719 if (self.data("timepicker-list")) { 720 _setSelected(self, self.data("timepicker-list")); 721 } 722 723 return this; 724 }, 725 remove: function remove() { 726 var self = this; // check if this element is a timepicker 727 728 if (!self.hasClass("ui-timepicker-input")) { 729 return; 730 } 731 732 var settings = self.data("timepicker-settings"); 733 self.removeAttr("autocomplete", "off"); 734 self.removeClass("ui-timepicker-input"); 735 self.removeData("timepicker-settings"); 736 self.off(".timepicker"); // timepicker-list won't be present unless the user has interacted with this timepicker 737 738 if (self.data("timepicker-list")) { 739 self.data("timepicker-list").remove(); 740 } 741 742 if (settings.useSelect) { 743 self.show(); 744 } 745 746 self.removeData("timepicker-list"); 747 return this; 748 } 749 }; // private methods 750 751 function _isVisible(elem) { 752 var el = elem[0]; 753 return el.offsetWidth > 0 && el.offsetHeight > 0; 754 } 755 756 function _render(self) { 757 var settings = self.data("timepicker-settings"); 758 var list = self.data("timepicker-list"); 759 var tp = self.data("timepicker-obj"); 760 761 if (list && list.length) { 762 list.remove(); 763 self.data("timepicker-list", false); 764 } 765 766 if (settings.useSelect) { 767 list = $("<select />", { 768 "class": "ui-timepicker-select" 769 }); 770 771 if (self.attr("name")) { 772 list.attr("name", "ui-timepicker-" + self.attr("name")); 773 } 774 775 var wrapped_list = list; 776 } else { 777 list = $("<ul />", { 778 "class": "ui-timepicker-list" 779 }); 780 var wrapped_list = $("<div />", { 781 "class": "ui-timepicker-wrapper", 782 tabindex: -1 783 }); 784 wrapped_list.css({ 785 display: "none", 786 position: "absolute" 787 }).append(list); 788 } 789 790 if (settings.noneOption) { 791 if (settings.noneOption === true) { 792 settings.noneOption = settings.useSelect ? "Time..." : "None"; 793 } 794 795 if ($.isArray(settings.noneOption)) { 796 for (var i in settings.noneOption) { 797 if (parseInt(i, 10) == i) { 798 var noneElement = _generateNoneElement(settings.noneOption[i], settings.useSelect); 799 800 list.append(noneElement); 801 } 802 } 803 } else { 804 var noneElement = _generateNoneElement(settings.noneOption, settings.useSelect); 805 806 list.append(noneElement); 807 } 808 } 809 810 if (settings.className) { 811 wrapped_list.addClass(settings.className); 812 } 813 814 if ((settings.minTime !== null || settings.durationTime !== null) && settings.showDuration) { 815 var stepval = typeof settings.step == "function" ? "function" : settings.step; 816 wrapped_list.addClass("ui-timepicker-with-duration"); 817 wrapped_list.addClass("ui-timepicker-step-" + settings.step); 818 } 819 820 var durStart = settings.minTime; 821 822 if (typeof settings.durationTime === "function") {
823 durStart = tp.time2int(settings.durationTime()); 824 } else if (settings.durationTime !== null) { 825 durStart = settings.durationTime; 826 } 827 828 var start = settings.minTime !== null ? settings.minTime : 0; 829 var end = settings.maxTime !== null ? settings.maxTime : start + ONE_DAY - 1; 830 831 if (end < start) { 832 // make sure the end time is greater than start time, otherwise there will be no list to show 833 end += ONE_DAY; 834 } 835 836 if (end === ONE_DAY - 1 && $.type(settings.timeFormat) === "string" && settings.show2400) { 837 // show a 24:00 option when using military time 838 end = ONE_DAY; 839 } 840 841 var dr = settings.disableTimeRanges; 842 var drCur = 0; 843 var drLen = dr.length; 844 var stepFunc = settings.step; 845 846 if (typeof stepFunc != "function") { 847 stepFunc = function stepFunc() { 848 return settings.step; 849 }; 850 } 851 852 for (var i = start, j = 0; i <= end; j++, i += stepFunc(j) * 60) { 853 var timeInt = i; 854 855 var timeString = _int2time(timeInt, settings); 856 857 if (settings.useSelect) { 858 var row = $("<option />", {
859 value: timeString 860 }); 861 row.text(timeString); 862 } else { 863 var row = $("<li />"); 864 row.addClass(timeInt % ONE_DAY < ONE_DAY / 2 ? "ui-timepicker-am" : "ui-timepicker-pm"); 865 row.data("time", roundingFunction(timeInt, settings)); 866 row.text(timeString); 867 } 868 869 if ((settings.minTime !== null || settings.durationTime !== null) && settings.showDuration) { 870 var durationString = _int2duration(i - durStart, settings.step); 871 872 if (settings.useSelect) { 873 row.text(row.text() + " (" + durationString + ")"); 874 } else { 875 var duration = $("<span />", { 876 "class": "ui-timepicker-duration" 877 }); 878 duration.text(" (" + durationString + ")"); 879 row.append(duration); 880 } 881 } 882 883 if (drCur < drLen) { 884 if (timeInt >= dr[drCur][1]) { 885 drCur += 1; 886 } 887 888 if (dr[drCur] && timeInt >= dr[drCur][0] && timeInt < dr[drCur][1]) { 889 if (settings.useSelect) { 890 row.prop("disabled", true); 891 } else { 892 row.addClass("ui-timepicker-disabled"); 893 } 894 } 895 } 896 897 list.append(row); 898 } 899 900 wrapped_list.data("timepicker-input", self); 901 self.data("timepicker-list", wrapped_list); 902 903 if (settings.useSelect) { 904 if (self.val()) { 905 list.val(_roundAndFormatTime(tp.time2int(self.val()), settings)); 906 } 907 908 list.on("focus", function () { 909 $(this).data("timepicker-input").trigger("showTimepicker"); 910 }); 911 list.on("blur", function () { 912 $(this).data("timepicker-input").trigger("hideTimepicker"); 913 }); 914 list.on("change", function () { 915 _setTimeValue(self, $(this).val(), "select"); 916 }); 917 918 _setTimeValue(self, list.val(), "initial"); 919 920 self.hide().after(list); 921 } else { 922 var appendTo = settings.appendTo; 923 924 if (typeof appendTo === "string") { 925 appendTo = $(appendTo); 926 } else if (typeof appendTo === "function") { 927 appendTo = appendTo(self); 928 } 929 930 appendTo.append(wrapped_list); 931 932 _setSelected(self, list); 933 934 list.on("mousedown click", "li", function (e) { 935 // hack: temporarily disable the focus handler 936 // to deal with the fact that IE fires 'focus' 937 // events asynchronously 938 self.off("focus.timepicker"); 939 self.on("focus.timepicker-ie-hack", function () { 940 self.off("focus.timepicker-ie-hack"); 941 self.on("focus.timepicker", methods.show); 942 }); 943 944 if (!_hideKeyboard(self)) { 945 self[0].focus(); 946 } // make sure only the clicked row is selected 947 948 949 list.find("li").removeClass("ui-timepicker-selected"); 950 $(this).addClass("ui-timepicker-selected"); 951 952 if (_selectValue(self)) { 953 self.trigger("hideTimepicker"); 954 list.on("mouseup.timepicker click.timepicker", "li", function (e) { 955 list.off("mouseup.timepicker click.timepicker"); 956 wrapped_list.hide(); 957 }); 958 } 959 }); 960 } 961 } 962 963 function _generateNoneElement(optionValue, useSelect) { 964 var label, className, value; 965 966 if (_typeof(optionValue) == "object") { 967 label = optionValue.label; 968 className = optionValue.className; 969 value = optionValue.value; 970 } else if (typeof optionValue == "string") { 971 label = optionValue; 972 value = ""; 973 } else { 974 $.error("Invalid noneOption value"); 975 } 976 977 if (useSelect) { 978 return $("<option />", { 979 value: value, 980 "class": className, 981 text: label 982 }); 983 } else { 984 return $("<li />", { 985 "class": className, 986 text: label 987 }).data("time", String(value)); 988 } 989 } 990 991 function _roundAndFormatTime(seconds, settings) { 992 seconds = settings.roundingFunction(seconds, settings); 993 994 if (seconds !== null) { 995 return _int2time(seconds, settings); 996 } 997 } // event handler to decide whether to close timepicker 998 999 1000 function _closeHandler(e) { 1001 if (e.target == window) { 1002 // mobile Chrome fires focus events against window for some reason 1003 return; 1004 } 1005 1006 var target = $(e.target); 1007 1008 if (target.closest(".ui-timepicker-input").length || target.closest(".ui-timepicker-wrapper").length) { 1009 // active timepicker was focused. ignore 1010 return; 1011 } 1012 1013 methods.hide(); 1014 $(document).unbind(".ui-timepicker"); 1015 $(window).unbind(".ui-timepicker"); 1016 } 1017 1018 function _hideKeyboard(self) { 1019 var settings = self.data("timepicker-settings"); 1020 return (window.navigator.msMaxTouchPoints || "ontouchstart" in document) && settings.disableTouchKeyboard; 1021 } 1022 1023 function _findRow(self, list, value) { 1024 if (!value && value !== 0) { 1025 return false;
1026 } 1027 1028 var settings = self.data("timepicker-settings"); 1029 var out = false; 1030 var value = settings.roundingFunction(value, settings); // loop through the menu items 1031 1032 list.find("li").each(function (i, obj) { 1033 var jObj = $(obj); 1034 1035 if (typeof jObj.data("time") != "number") { 1036 return; 1037 } 1038 1039 if (jObj.data("time") == value) { 1040 out = jObj; 1041 return false; 1042 } 1043 }); 1044 return out; 1045 } 1046 1047 function _setSelected(self, list) { 1048 list.find("li").removeClass("ui-timepicker-selected"); 1049 var settings = self.data("timepicker-settings"); 1050 var tp = self.data("timepicker-obj"); 1051 var timeValue = tp.time2int(_getTimeValue(self)); 1052 1053 if (timeValue === null) { 1054 return; 1055 } 1056 1057 var selected = _findRow(self, list, timeValue); 1058 1059 if (selected) { 1060 var topDelta = selected.offset().top - list.offset().top; 1061 1062 if (topDelta + selected.outerHeight() > list.outerHeight() || topDelta < 0) { 1063 list.scrollTop(list.scrollTop() + selected.position().top - selected.outerHeight()); 1064 } 1065 1066 if (settings.forceRoundTime || selected.data("time") === timeValue) { 1067 selected.addClass("ui-timepicker-selected"); 1068 } 1069 } 1070 } 1071 1072 function _formatValue(e, origin) { 1073 if (origin == "timepicker") { 1074 return; 1075 } 1076 1077 var self = $(this); 1078 1079 if (this.value === "") { 1080 _setTimeValue(self, null, origin); 1081 1082 return; 1083 } 1084 1085 if (self.is(":focus") && (!e || e.type != "change")) { 1086 return; 1087 } 1088 1089 var settings = self.data("timepicker-settings"); 1090 var tp = self.data("timepicker-obj"); 1091 var seconds = tp.time2int(this.value); 1092 1093 if (seconds === null) { 1094 self.trigger("timeFormatError"); 1095 return; 1096 } 1097 1098 var rangeError = false;
1098 // check that the time in within bounds 1099 1100 if (settings.minTime !== null && settings.maxTime !== null && (seconds < settings.minTime || seconds > settings.maxTime)) { 1101 rangeError = true; 1102 } // check that time isn't within disabled time ranges 1103 1104 1105 $.each(settings.disableTimeRanges, function () { 1106 if (seconds >= this[0] && seconds < this[1]) { 1107 rangeError = true; 1108 return false; 1109 } 1110 }); 1111 1112 if (settings.forceRoundTime) { 1113 var roundSeconds = settings.roundingFunction(seconds, settings); 1114 1115 if (roundSeconds != seconds) { 1116 seconds = roundSeconds; 1117 origin = null; 1118 } 1119 } 1120 1121 var prettyTime = _int2time(seconds, settings); 1122 1123 if (rangeError) { 1124 if (_setTimeValue(self, prettyTime, "error") || e && e.type == "change") { 1125 self.trigger("timeRangeError"); 1126 } 1127 } else { 1128 _setTimeValue(self, prettyTime, origin); 1129 } 1130 } 1131 1132 function _getTimeValue(self) { 1133 if (self.is("input")) { 1134 return self.val(); 1135 } else { 1136 // use the element's data attributes to store values 1137 return self.data("ui-timepicker-value"); 1138 } 1139 } 1140 1141 function _setTimeValue(self, value, source) { 1142 if (self.is("input")) { 1143 if (value !== null || self.val() != "") { 1144 self.val(value); 1145 } 1146 1147 var settings = self.data("timepicker-settings"); 1148 var tp = self.data("timepicker-obj"); 1149 1150 if (settings.useSelect && source != "select" && self.data("timepicker-list")) { 1151 self.data("timepicker-list").val(_roundAndFormatTime(tp.time2int(value), settings)); 1152 } 1153 } 1154 1155 if (self.data("ui-timepicker-value") != value) { 1156 self.data("ui-timepicker-value", value); 1157 1158 if (source == "select") { 1159 self.trigger("selectTime").trigger("changeTime").trigger("change", "timepicker"); 1160 } else if (["error", "initial"].indexOf(source) == -1) { 1161 self.trigger("changeTime"); 1162 } 1163 1164 return true; 1165 } else { 1166 if (["error", "initial"].indexOf(source) == -1) { 1167 self.trigger("selectTime"); 1168 } 1169 1170 return false; 1171 } 1172 } 1173 /* 1174 * Filter freeform input 1175 */ 1176 1177 1178 function _disableTextInputHandler(e) { 1179 switch (e.keyCode) { 1180 case 13: // return 1181 1182 case 9: 1183 //tab 1184 return; 1185 1186 default: 1187 e.preventDefault(); 1188 } 1189 } 1190 /* 1191 * Keyboard navigation via arrow keys 1192 */ 1193 1194 1195 function _keydownhandler(e) { 1196 var self = $(this); 1197 var list = self.data("timepicker-list"); 1198 1199 if (!list || !_isVisible(list)) { 1200 if (e.keyCode == 40) { 1201 // show the list! 1202 methods.show.call(self.get(0)); 1203 list = self.data("timepicker-list"); 1204 1205 if (!_hideKeyboard(self)) { 1206 self.focus(); 1207 } 1208 } else { 1209 return true; 1210 } 1211 } 1212 1213 switch (e.keyCode) { 1214 case 13: 1215 // return 1216 if (_selectValue(self)) { 1217 _formatValue.call(self.get(0), { 1218 type: "change" 1219 }); 1220 1221 methods.hide.apply(this); 1222 } 1223 1224 e.preventDefault(); 1225 return false; 1226 1227 case 38: 1228 // up 1229 var selected = list.find(".ui-timepicker-selected"); 1230 1231 if (!selected.length) { 1232 list.find("li").each(function (i, obj) { 1233 if ($(obj).position().top > 0) { 1234 selected = $(obj); 1235 return false; 1236 } 1237 }); 1238 selected.addClass("ui-timepicker-selected"); 1239 } else if (!selected.is(":first-child")) { 1240 selected.removeClass("ui-timepicker-selected"); 1241 selected.prev().addClass("ui-timepicker-selected"); 1242 1243 if (selected.prev().position().top < selected.outerHeight()) { 1244 list.scrollTop(list.scrollTop() - selected.outerHeight()); 1245 } 1246 } 1247 1248 return false; 1249 1250 case 40: 1251 // down 1252 selected = list.find(".ui-timepicker-selected"); 1253 1254 if (selected.length === 0) { 1255 list.find("li").each(function (i, obj) { 1256 if ($(obj).position().top > 0) { 1257 selected = $(obj); 1258 return false;
1259 } 1260 }); 1261 selected.addClass("ui-timepicker-selected"); 1262 } else if (!selected.is(":last-child")) { 1263 selected.removeClass("ui-timepicker-selected"); 1264 selected.next().addClass("ui-timepicker-selected"); 1265 1266 if (selected.next().position().top + 2 * selected.outerHeight() > list.outerHeight()) { 1267 list.scrollTop(list.scrollTop() + selected.outerHeight()); 1268 } 1269 } 1270 1271 return false; 1272 1273 case 27: 1274 // escape 1275 list.find("li").removeClass("ui-timepicker-selected"); 1276 methods.hide(); 1277 break; 1278 1279 case 9: 1280 //tab 1281 methods.hide(); 1282 break; 1283 1284 default: 1285 return true; 1286 } 1287 } 1288 /* 1289 * Time typeahead 1290 */ 1291 1292 1293 function _keyuphandler(e) { 1294 var self = $(this); 1295 var list = self.data("timepicker-list"); 1296 var settings = self.data("timepicker-settings"); 1297 1298 if (!list || !_isVisible(list) || settings.disableTextInput) { 1299 return true; 1300 } 1301 1302 if (e.type === "paste" || e.type === "cut") { 1303 setTimeout(function () { 1304 if (settings.typeaheadHighlight) { 1305 _setSelected(self, list); 1306 } else { 1307 list.hide(); 1308 } 1309 }, 0); 1310 return; 1311 } 1312 1313 switch (e.keyCode) { 1314 case 96: // numpad numerals 1315 1316 case 97: 1317 case 98: 1318 case 99: 1319 case 100: 1320 case 101: 1321 case 102: 1322 case 103: 1323 case 104: 1324 case 105: 1325 case 48: // numerals 1326 1327 case 49: 1328 case 50: 1329 case 51: 1330 case 52: 1331 case 53: 1332 case 54: 1333 case 55: 1334 case 56: 1335 case 57: 1336 case 65: // a 1337 1338 case 77: // m 1339 1340 case 80: // p 1341 1342 case 186: // colon 1343 1344 case 8: // backspace 1345 1346 case 46: 1347 // delete 1348 if (settings.typeaheadHighlight) { 1349 _setSelected(self, list); 1350 } else { 1351 list.hide(); 1352 } 1353 1354 break; 1355 } 1356 } 1357 1358 function _selectValue(self) { 1359 var settings = self.data("timepicker-settings"); 1360 var list = self.data("timepicker-list"); 1361 var timeValue = null; 1362 var cursor = list.find(".ui-timepicker-selected"); 1363 1364 if (cursor.hasClass("ui-timepicker-disabled")) { 1365 return false; 1366 } 1367 1368 if (cursor.length) { 1369 // selected value found 1370 timeValue = cursor.data("time"); 1371 } 1372 1373 if (timeValue !== null) { 1374 if (typeof timeValue != "string") { 1375 timeValue = _int2time(timeValue, settings); 1376 } 1377 1378 _setTimeValue(self, timeValue, "select"); 1379 } 1380 1381 return true; 1382 } 1383 1384 function _int2duration(seconds, step) { 1385 seconds = Math.abs(seconds); 1386 var minutes = Math.round(seconds / 60), 1387 duration = [], 1388 hours, 1389 mins; 1390 1391 if (minutes < 60) { 1392 // Only show (x mins) under 1 hour 1393 duration = [minutes, _lang.mins]; 1394 } else { 1395 hours = Math.floor(minutes / 60); 1396 mins = minutes % 60; // Show decimal notation (eg: 1.5 hrs) for 30 minute steps 1397 1398 if (step == 30 && mins == 30) { 1399 hours += _lang.decimal + 5; 1400 } 1401 1402 duration.push(hours); 1403 duration.push(hours == 1 ? _lang.hr : _lang.hrs); // Show remainder minutes notation (eg: 1 hr 15 mins) for non-30 minute steps 1404 // and only if there are remainder minutes to show 1405 1406 if (step != 30 && mins) { 1407 duration.push(mins); 1408 duration.push(_lang.mins); 1409 } 1410 } 1411 1412 return duration.join(" "); 1413 } 1414 1415 function _int2time(timeInt, settings) { 1416 if (typeof timeInt != "number") { 1417 return null; 1418 } 1419 1420 var seconds = parseInt(timeInt % 60), 1421 minutes = parseInt(timeInt / 60 % 60), 1422 hours = parseInt(timeInt / (60 * 60) % 24); 1423 var time = new Date(1970, 0, 2, hours, minutes, seconds, 0); 1424 1425 if (isNaN(time.getTime())) { 1426 return null; 1427 } 1428 1429 if ($.type(settings.timeFormat) === "function") { 1430 return settings.timeFormat(time); 1431 } 1432 1433 var output = "";
1434 var hour, code; 1435 1436 for (var i = 0; i < settings.timeFormat.length; i++) { 1437 code = settings.timeFormat.charAt(i); 1438 1439 switch (code) { 1440 case "a": 1441 output += time.getHours() > 11 ? _lang.pm : _lang.am; 1442 break; 1443 1444 case "A": 1445 output += time.getHours() > 11 ? _lang.PM : _lang.AM; 1446 break; 1447 1448 case "g": 1449 hour = time.getHours() % 12; 1450 output += hour === 0 ? "12" : hour; 1451 break; 1452 1453 case "G": 1454 hour = time.getHours(); 1455 if (timeInt === ONE_DAY) hour = settings.show2400 ? 24 : 0; 1456 output += hour; 1457 break; 1458 1459 case "h": 1460 hour = time.getHours() % 12; 1461 1462 if (hour !== 0 && hour < 10) { 1463 hour = "0" + hour; 1464 } 1465 1466 output += hour === 0 ? "12" : hour; 1467 break; 1468 1469 case "H": 1470 hour = time.getHours(); 1471 if (timeInt === ONE_DAY) hour = settings.show2400 ? 24 : 0; 1472 output += hour > 9 ? hour : "0" + hour; 1473 break; 1474 1475 case "i": 1476 var minutes = time.getMinutes(); 1477 output += minutes > 9 ? minutes : "0" + minutes; 1478 break; 1479 1480 case "s": 1481 seconds = time.getSeconds(); 1482 output += seconds > 9 ? seconds : "0" + seconds; 1483 break; 1484 1485 case "\\": 1486 // escape character; add the next character and skip ahead 1487 i++; 1488 output += settings.timeFormat.charAt(i); 1489 break; 1490 1491 default: 1492 output += code; 1493 } 1494 } 1495 1496 return output; 1497 } 1498 1499 1500 $.fn.timepicker = function (method) { 1501 if (!this.length) return this; 1502 1503 if (methods[method]) { 1504 // check if this element is a timepicker 1505 if (!this.hasClass("ui-timepicker-input")) { 1506 return this; 1507 } 1508 1509 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 1510 } else if (_typeof(method) === "object" || !method) { 1511 return methods.init.apply(this, arguments); 1512 } else { 1513 $.error("Method " + method + " does not exist on jQuery.timepicker"); 1514 } 1515 }; // Default plugin options. 1516 1517 1518 $.fn.timepicker.defaults = { 1519 appendTo: "body", 1520 className: null, 1521 closeOnWindowScroll: false, 1522 disableTextInput: false, 1523 disableTimeRanges: [], 1524 disableTouchKeyboard: false, 1525 durationTime: null, 1526 forceRoundTime: false, 1527 listWidth: null, 1528 // Set to 1 to match input width, 2 to double input width, .5 to halve input width, etc 1529 maxTime: null, 1530 minTime: null, 1531 noneOption: false, 1532 orientation: "l", 1533 roundingFunction: function roundingFunction(seconds, settings) { 1534 if (seconds === null) { 1535 return null; 1536 } else if (typeof settings.step !== "number") { 1537 // TODO: nearest fit irregular steps 1538 return seconds; 1539 } else { 1540 var offset = seconds % (settings.step * 60); // step is in minutes 1541 1542 var start = settings.minTime || 0; // adjust offset by start mod step so that the offset is aligned not to 00:00 but to the start 1543 1544 offset -= start % (settings.step * 60); 1545 1546 if (offset >= settings.step * 30) { 1547 // if offset is larger than a half step, round up 1548 seconds += settings.step * 60 - offset; 1549 } else { 1550 // round down 1551 seconds -= offset; 1552 } 1553 1554 return _moduloSeconds(seconds, settings); 1555 } 1556 }, 1557 scrollDefault: null, 1558 selectOnBlur: false, 1559 show2400: false, 1560 showDuration: false, 1561 showOn: ["click", "focus"], 1562 showOnFocus: true, 1563 step: 30, 1564 stopScrollPropagation: false, 1565 timeFormat: "g:ia", 1566 typeaheadHighlight: true, 1567 useSelect: false, 1568 wrapHours: true 1569 }; 1570 }); 1571 1572}());
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.