1/*! 2 * @authors yusen 3 * @date 2017-01-04 21:34:19 4 * @github https://github.com/yscoder/Calendar 5 */ 6(function (root, factory) { 7 if (typeof define === 'function' && define.amd) { 8 define('calendar', ['jquery'], factory); 9 } else if (typeof exports === 'object') { 10 module.exports = factory(require('jquery')); 11 } else { 12 factory(root.jQuery); 13 } 14}(this, function ($) { 15 16 // default config 17 18 var defaults = { 19 20 // 宽度 21 width: 280, 22 // é«åº¦, ä¸å å«å¤´é¨ï¼å¤´é¨åºå®é«åº¦ 23 height: 280, 24 25 zIndex: 1, 26 27 // selector 28 // è®¾ç½®è§¦åæ¾ç¤ºçå ç´ ï¼ä¸ºnullæ¶é»è®¤æ¾ç¤º 29 trigger: null, 30 31 // åç§»ä½ç½®ï¼å¯è®¾æ£è´å¼ 32 // trigger 设置æ¶çæ 33 offset: [0, 1], 34 35 // èªå®ä¹ç±»ï¼ç¨äºéåæ ·å¼ 36 customClass: '', 37 38 // æ¾ç¤ºè§å¾ 39 // å¯éï¼date, month 40 view: 'date', 41 42 // é»è®¤æ¥æä¸ºå½åæ¥æ 43 date: new Date(), 44 format: 'yyyy/mm/dd', 45 46 // ä¸å¨ç第ä¸å¤© 47 // 0è¡¨ç¤ºå¨æ¥ï¼ä¾æ¬¡ç±»æ¨ 48 startWeek: 0, 49 50 // æææ ¼å¼ 51 weekArray: ['æ¥', 'ä¸', 'äº', 'ä¸', 'å', 'äº', 'å '], 52 53 // æä»½æ ¼å¼ 54 monthArray: ['1æ', '2æ', '3æ', '4æ', '5æ', '6æ', '7æ', '8æ', '9æ', '10æ', '11æ', '12æ'], 55 56 // è®¾ç½®éæ©èå´ 57 // æ ¼å¼ï¼[å¼å§æ¥æ, ç»ææ¥æ] 58 // å¼å§æ¥æä¸ºç©ºï¼åæ ä¸éï¼ç»ææ¥æä¸ºç©ºï¼åæ ä¸é 59 // å¦è®¾ç½®2015å¹´11æ23æ¥ä»¥åä¸å¯éï¼[new Date(), null] or ['2015/11/23'] 60 selectedRang: null, 61 62 // æ¥æå ³èæ°æ® [{ date: string, value: object }, ... ] 63 // æ¥ææ ¼å¼ä¸ format ä¸è´ 64 // å¦ [ {date: '2015/11/23', value: 'é¢è¯'} ] 65 data: null, 66 67 // å±ç¤ºå ³èæ°æ® 68 // æ ¼å¼ååæ°ï¼{m}è§å¾ï¼{d}æ¥æï¼{v}value 69 // 设置 false è¡¨ç¤ºä¸æ¾ç¤º 70 label: '{d}\n{v}', 71 72 // 忢å符 73 prev: '<', 74 next: '>', 75 76 // 忢è§å¾ 77 // åæ°ï¼view, y, m 78 viewChange: $.noop, 79 80 // view: è§å¾ 81 // date: ä¸åè§å¾è¿åä¸åçå¼ 82 // value: æ¥æå ³èæ°æ® 83 onSelected: function (view, date, value) { 84 // body... 85 }, 86 87 // åæ°åä¸ 88 onMouseenter: $.noop, 89 90 onClose: $.noop 91 }, 92 93 // static variable 94 95 ACTION_NAMESPACE = 'data-calendar-', 96 97 DISPLAY_VD = '[' + ACTION_NAMESPACE + 'display-date]', 98 DISPLAY_VM = '[' + ACTION_NAMESPACE + 'display-month]', 99 100 ARROW_DATE = '[' + ACTION_NAMESPACE + 'arrow-date]', 101 ARROW_MONTH = '[' + ACTION_NAMESPACE + 'arrow-month]', 102 103 ITEM_DAY = ACTION_NAMESPACE + 'day', 104 ITEM_MONTH = ACTION_NAMESPACE + 'month', 105 106 DISABLED = 'disabled', 107 MARK_DATA = 'markData', 108 109 VIEW_CLASS = { 110 date: 'calendar-d', 111 month: 'calendar-m' 112 }, 113 114 OLD_DAY_CLASS = 'old', 115 NEW_DAY_CLASS = 'new', 116 TODAY_CLASS = 'now', 117 SELECT_CLASS = 'selected', 118 MARK_DAY_HTML = '<i class="dot"></i>', 119 DATE_DIS_TPL = '{year}/<span class="m">{month}</span>', 120 121 ITEM_STYLE = 'style="width:{w}px;height:{h}px;line-height:{h}px"', 122 WEEK_ITEM_TPL = '<li ' + ITEM_STYLE + '>{wk}</li>', 123 DAY_ITEM_TPL = '<li ' + ITEM_STYLE + ' class="{class}" {action}="{date}">{value}</li>', 124 MONTH_ITEM_TPL = '<li ' + ITEM_STYLE + ' ' + ITEM_MONTH + '>{m}</li>', 125 126 TEMPLATE = [ 127 '<div class="calendar-inner">', 128 '<div class="calendar-views">', 129 '<div class="view view-date">', 130 '<div class="calendar-hd">', 131 '<a href="javascript:;" data-calendar-display-date class="calendar-display">', 132 '{yyyy}/<span class="m">{mm}</span>', 133 '</a>', 134 '<div class="calendar-arrow">', 135 '<span class="prev" data-calendar-arrow-date>{prev}</span>', 136 '<span class="next" data-calendar-arrow-date>{next}</span>', 137 '</div>', 138 '</div>', 139 '<div class="calendar-ct">', 140 '<ol class="week">{week}</ol>', 141 '<ul class="date-items"></ul>', 142 '</div>', 143 '</div>', 144 '<div class="view view-month">', 145 '<div class="calendar-hd">', 146 '<a href="javascript:;" data-calendar-display-month class="calendar-display">{yyyy}</a>', 147 '<div class="calendar-arrow">', 148 '<span class="prev" data-calendar-arrow-month>{prev}</span>', 149 '<span class="next" data-calendar-arrow-month>{next}</span>', 150 '</div>', 151 '</div>', 152 '<ol class="calendar-ct month-items">{month}</ol>', 153 '</div>', 154 '</div>', 155 '</div>', 156 '<div class="calendar-label"><p>HelloWorld</p><i></i></div>' 157 ], 158 OS = Object.prototype.toString; 159 160 // utils 161 162 function isDate(obj) { 163 return OS.call(obj) === '[object Date]'; 164 } 165 166 function isString(obj) { 167 return OS.call(obj) === '[object String]'; 168 } 169 170 171 function getClass(el) { 172 return el.getAttribute('class') || el.getAttribute('className'); 173 } 174 175 // extension methods 176 177 String.prototype.repeat = function (data) { 178 return this.replace(/\{\w+\}/g, function (str) { 179 var prop = str.replace(/\{|\}/g, ''); 180 return data[prop] || ''; 181 }); 182 } 183 184 String.prototype.toDate = function () { 185 var dt = new Date(), 186 dot = this.replace(/\d/g, '').charAt(0), 187 arr = this.split(dot); 188 189 return new Date(parseInt(arr[0]), parseInt(arr[1]) - 1, parseInt(arr[2])); 190 } 191 192 Date.prototype.format = function (exp) { 193 var y = this.getFullYear(), 194 m = this.getMonth() + 1, 195 d = this.getDate(); 196 197 return exp.replace('yyyy', y).replace('mm', m).replace('dd', d); 198 } 199 200 Date.prototype.isSame = function (y, m, d) { 201 if (isDate(y)) { 202 var dt = y; 203 y = dt.getFullYear(); 204 m = dt.getMonth() + 1; 205 d = dt.getDate(); 206 } 207 return this.getFullYear() === y && this.getMonth() + 1 === m && this.getDate() === d; 208 } 209 210 Date.prototype.add = function (n) { 211 this.setDate(this.getDate() + n); 212 } 213 214 Date.prototype.minus = function (n) { 215 this.setDate(this.getDate() - n); 216 } 217 218 Date.prototype.clearTime = function (n) { 219 this.setHours(0); 220 this.setSeconds(0); 221 this.setMinutes(0); 222 this.setMilliseconds(0); 223 return this; 224 } 225 226 Date.isLeap = function (y) { 227 return (y % 100 !== 0 && y % 4 === 0) || (y % 400 === 0); 228 } 229 230 Date.getDaysNum = function (y, m) { 231 var num = 31; 232 233 switch (m) { 234 case 2: 235 num = this.isLeap(y) ? 29 : 28; 236 break; 237 case 4: 238 case 6: 239 case 9: 240 case 11: 241 num = 30; 242 break; 243 } 244 return num; 245 } 246 247 Date.getSiblingsMonth = function (y, m, n) { 248 var d = new Date(y, m - 1); 249 d.setMonth(m - 1 + n); 250 return { 251 y: d.getFullYear(), 252 m: d.getMonth() + 1 253 }; 254 } 255 256 Date.getPrevMonth = function (y, m, n) {
257 return this.getSiblingsMonth(y, m, 0 - (n || 1)); 258 } 259 260 Date.getNextMonth = function (y, m, n) { 261 return this.getSiblingsMonth(y, m, n || 1); 262 } 263 264 Date.tryParse = function (obj) { 265 if (!obj) { 266 return obj; 267 } 268 return isDate(obj) ? obj : obj.toDate(); 269 } 270 271 272 // Calendar class 273 274 function Calendar(element, options) { 275 this.$element = $(element); 276 this.options = $.extend({}, $.fn.calendar.defaults, options); 277 this.$element.addClass('calendar ' + this.options.customClass); 278 this.width = this.options.width; 279 this.height = this.options.height; 280 this.date = this.options.date; 281 this.selectedRang = this.options.selectedRang; 282 this.data = this.options.data; 283 this.init(); 284 } 285 286 Calendar.prototype = { 287 constructor: Calendar, 288 getDayAction: function (day) { 289 var action = ITEM_DAY; 290 if (this.selectedRang) { 291 var start = Date.tryParse(this.selectedRang[0]), 292 end = Date.tryParse(this.selectedRang[1]); 293 294 if ((start && day < start.clearTime()) || (end && day > end.clearTime())) { 295 action = DISABLED; 296 } 297 } 298 299 return action; 300 }, 301 getDayData: function (day) { 302 var ret, data = this.data; 303 304 if (data) { 305 306 for (var i = 0, len = data.length; i < len; i++) { 307 var item = data[i]; 308 309 if (day.isSame(Date.tryParse(item.date))) { 310 ret = item.value; 311 } 312 } 313 } 314 315 return ret; 316 }, 317 getDayItem: function (y, m, d, f) { 318 var dt = this.date, 319 idt = new Date(y, m - 1, d), 320 data = { 321 w: this.width / 7, 322 h: this.height / 7, 323 value: d 324 }, 325 markData, 326 $item; 327 328 var selected = dt.isSame(y, m, d) ? SELECT_CLASS : ''; 329 if (f === 1) { 330 data['class'] = OLD_DAY_CLASS; 331 } else if (f === 3) { 332 data['class'] = NEW_DAY_CLASS; 333 } else { 334 data['class'] = ''; 335 } 336 337 if (dt.isSame(y, m, d)) { 338 data['class'] += ' ' + TODAY_CLASS; 339 } 340 341 data.date = idt.format(this.options.format); 342 data.action = this.getDayAction(idt); 343 markData = this.getDayData(idt); 344 345 $item = $(DAY_ITEM_TPL.repeat(data)); 346 347 if (markData) { 348 $item.data(MARK_DATA, markData); 349 $item.html(d + MARK_DAY_HTML); 350 } 351 352 return $item; 353 }, 354 getDaysHtml: function (y, m) { 355 var year, month, firstWeek, daysNum, prevM, prevDiff, 356 dt = this.date, 357 $days = $('<ol class="days"></ol>'); 358 359 if (isDate(y)) { 360 year = y.getFullYear(); 361 month = y.getMonth() + 1; 362 } else { 363 year = Number(y); 364 month = Number(m); 365 } 366 367 firstWeek = new Date(year, month - 1, 1).getDay() || 7; 368 prevDiff = firstWeek - this.options.startWeek; 369 daysNum = Date.getDaysNum(year, month); 370 prevM = Date.getPrevMonth(year, month); 371 prevDaysNum = Date.getDaysNum(year, prevM.m); 372 nextM = Date.getNextMonth(year, month); 373 // month flag 374 var PREV_FLAG = 1, 375 CURR_FLAG = 2, 376 NEXT_FLAG = 3, 377 count = 0; 378 379 for (var p = prevDaysNum - prevDiff + 1; p <= prevDaysNum; p++ , count++) { 380 381 $days.append(this.getDayItem(prevM.y, prevM.m, p, PREV_FLAG)); 382 } 383 384 for (var c = 1; c <= daysNum; c++ , count++) { 385 $days.append(this.getDayItem(year, month, c, CURR_FLAG)); 386 } 387 388 for (var n = 1, nl = 42 - count; n <= nl; n++) { 389 390 $days.append(this.getDayItem(nextM.y, nextM.m, n, NEXT_FLAG)); 391 } 392 393 return $('<li></li>').width(this.options.width).append($days); 394 }, 395 getWeekHtml: function () { 396 var week = [], 397 weekArray = this.options.weekArray, 398 start = this.options.startWeek, 399 len = weekArray.length, 400 w = this.width / 7, 401 h = this.height / 7; 402 403 for (var i = start; i < len; i++) { 404 week.push(WEEK_ITEM_TPL.repeat({ 405 w: w, 406 h: h, 407 wk: weekArray[i] 408 })); 409 } 410 411 for (var j = 0; j < start; j++) { 412 week.push(WEEK_ITEM_TPL.repeat({ 413 w: w, 414 h: h, 415 wk: weekArray[j] 416 })); 417 } 418 419 return week.join(''); 420 }, 421 getMonthHtml: function () { 422 var monthArray = this.options.monthArray,
423 month = [], 424 w = this.width / 4, 425 h = this.height / 4, 426 i = 0; 427 428 for (; i < 12; i++) { 429 month.push(MONTH_ITEM_TPL.repeat({ 430 w: w, 431 h: h, 432 m: monthArray[i] 433 })); 434 } 435 436 return month.join(''); 437 }, 438 setMonthAction: function (y) { 439 var m = this.date.getMonth() + 1; 440 441 this.$monthItems.children().removeClass(TODAY_CLASS); 442 if (y === this.date.getFullYear()) { 443 this.$monthItems.children().eq(m - 1).addClass(TODAY_CLASS); 444 } 445 }, 446 fillStatic: function () { 447 var staticData = { 448 prev: this.options.prev, 449 next: this.options.next, 450 week: this.getWeekHtml(), 451 month: this.getMonthHtml() 452 }; 453 454 this.$element.html(TEMPLATE.join('').repeat(staticData)); 455 }, 456 updateDisDate: function (y, m) { 457 this.$disDate.html(DATE_DIS_TPL.repeat({ 458 year: y, 459 month: m 460 })); 461 }, 462 updateDisMonth: function (y) { 463 this.$disMonth.html(y); 464 }, 465 fillDateItems: function (y, m) { 466 var ma = [ 467 Date.getPrevMonth(y, m), { 468 y: y, 469 m: m 470 }, 471 Date.getNextMonth(y, m) 472 ]; 473 474 this.$dateItems.html(''); 475 for (var i = 0; i < 3; i++) { 476 var $item = this.getDaysHtml(ma[i].y, ma[i].m); 477 this.$dateItems.append($item); 478 } 479 480 }, 481 hide: function (view, date, data) { 482 this.$trigger.val(date.format(this.options.format)); 483 this.options.onClose.call(this, view, date, data); 484 this.$element.hide(); 485 }, 486 setPosition: function () { 487 var post = this.$trigger.offset(); 488 var offs = this.options.offset; 489 490 this.$element.css({ 491 left: (post.left + offs[0]) + 'px', 492 top: (post.top + this.$trigger.outerHeight() + offs[1]) + 'px' 493 }) 494 }, 495 trigger: function () { 496 497 this.$trigger = $(this.options.trigger); 498 499 var _this = this, 500 $this = _this.$element; 501 502 $this.addClass('calendar-modal').css('zIndex', _this.options.zIndex); 503 504 $(document).click(function (e) { 505 if (_this.$trigger[0] != e.target && !$.contains($this[0], e.target)) { 506 $this.hide(); 507 } 508 }).on('click', this.options.trigger, function () { 509 this.$trigger = $(this); 510 _this.setPosition(); 511 $this.show(); 512 }) 513 514 $(window).resize(function () { 515 _this.setPosition(); 516 }); 517 }, 518 render: function () { 519 this.$week = this.$element.find('.week'); 520 this.$dateItems = this.$element.find('.date-items'); 521 this.$monthItems = this.$element.find('.month-items'); 522 this.$label = this.$element.find('.calendar-label'); 523 this.$disDate = this.$element.find(DISPLAY_VD); 524 this.$disMonth = this.$element.find(DISPLAY_VM); 525 526 var y = this.date.getFullYear(), 527 m = this.date.getMonth() + 1; 528 529 this.updateDisDate(y, m); 530 this.updateMonthView(y); 531 532 this.fillDateItems(y, m); 533 534 this.options.trigger && this.trigger(); 535 536 }, 537 setView: function (view) { 538 this.$element.removeClass(VIEW_CLASS.date + ' ' + VIEW_CLASS.month) 539 .addClass(VIEW_CLASS[view]); 540 this.view = view; 541 }, 542 updateDateView: function (y, m, dirc, cb) { 543 m = m || this.date.getMonth() + 1; 544 545 var _this = this, 546 $dis = this.$dateItems, 547 exec = { 548 prev: function () { 549 var pm = Date.getPrevMonth(y, m), 550 ppm = Date.getPrevMonth(y, m, 2), 551 $prevItem = _this.getDaysHtml(ppm.y, ppm.m); 552 553 m = pm.m; 554 y = pm.y; 555 556 $dis.animate({ 557 marginLeft: 0 558 }, 300, 'swing', function () { 559 $dis.children(':last').remove(); 560 $dis.prepend($prevItem).css('margin-left', '-100%'); 561 562 $.isFunction(cb) && cb.call(_this); 563 }); 564 }, 565 next: function () { 566 var nm = Date.getNextMonth(y, m), 567 nnm = Date.getNextMonth(y, m, 2), 568 $nextItem = _this.getDaysHtml(nnm.y, nnm.m); 569 570 m = nm.m; 571 y = nm.y; 572 573 $dis.animate({ 574 marginLeft: '-200%' 575 }, 300, 'swing', function () { 576 $dis.children(':first').remove(); 577 $dis.append($nextItem).css('margin-left', '-100%'); 578 579 $.isFunction(cb) && cb.call(_this); 580 }); 581 582 } 583 }; 584 585 586 if (dirc) { 587 exec[dirc](); 588 } else { 589 this.fillDateItems(y, m); 590 } 591 592 this.updateDisDate(y, m); 593 594 this.setView('date'); 595 596 return { 597 y: y, 598 m: m 599 }; 600 }, 601 updateMonthView: function (y) { 602 this.updateDisMonth(y); 603 this.setMonthAction(y); 604 this.setView('month'); 605 }, 606 getDisDateValue: function () { 607 var arr = this.$disDate.html().split('/'), 608 y = Number(arr[0]), 609 m = Number(arr[1].match(/\d{1,2}/)[0]); 610 611 return [y, m]; 612 }, 613 selectedDay: function (d, type) { 614 var arr = this.getDisDateValue(), 615 y = arr[0], 616 m = arr[1], 617 toggleClass = function () { 618 this.$dateItems.children(':eq(1)') 619 .find('[' + ITEM_DAY + ']:not(.' + NEW_DAY_CLASS + ', .' + OLD_DAY_CLASS + ')') 620 .removeClass(SELECT_CLASS) 621 .filter(function (index) { 622 return parseInt(this.innerHTML) === d; 623 }).addClass(SELECT_CLASS); 624 }; 625 626 if (type) { 627 var ret = this.updateDateView(y, m, { 628 'old': 'prev', 629 'new': 'next' 630 }[type], toggleClass); 631 y = ret.y; 632 m = ret.m; 633 this.options.viewChange('date', y, m); 634 } else { 635 toggleClass.call(this); 636 } 637 638 return new Date(y, m - 1, d); 639 }, 640 showLabel: function (event, view, date, data) { 641 var $lbl = this.$label; 642 643 $lbl.find('p').html(this.options.label.repeat({ 644 m: view, 645 d: date.format(this.options.format), 646 v: data 647 }).replace(/\n/g, '<br>')); 648 649 var w = $lbl.outerWidth(), 650 h = $lbl.outerHeight(); 651 652 $lbl.css({ 653 left: (event.pageX - w / 2) + 'px', 654 top: (event.pageY - h - 20) + 'px', 655 zIndex: this.options.zIndex + 1 656 }).show(); 657 }, 658 hasLabel: function () { 659 if (this.options.label) { 660 $('body').append(this.$label); 661 return true; 662 } 663 return false;
664 }, 665 event: function () { 666 var _this = this, 667 vc = _this.options.viewChange; 668 669 // view change 670 _this.$element.on('click', DISPLAY_VD, function () { 671 var arr = _this.getDisDateValue(); 672 _this.updateMonthView(arr[0], arr[1]); 673 674 vc('month', arr[0], arr[1]); 675 676 }).on('click', DISPLAY_VM, function () { 677 var y = this.innerHTML; 678 679 _this.updateDateView(y); 680 vc('date', y); 681 }); 682 683 // arrow 684 _this.$element.on('click', ARROW_DATE, function () { 685 var arr = _this.getDisDateValue(), 686 type = getClass(this), 687 y = arr[0], 688 m = arr[1]; 689 690 var d = _this.updateDateView(y, m, type, function () { 691 vc('date', d.y, d.m); 692 }); 693 694 }).on('click', ARROW_MONTH, function () { 695 696 var y = Number(_this.$disMonth.html()), 697 type = getClass(this); 698 699 y = type === 'prev' ? y - 1 : y + 1; 700 _this.updateMonthView(y); 701 vc('month', y); 702 }); 703 704 // selected 705 _this.$element.on('click', '[' + ITEM_DAY + ']', function () { 706 var d = parseInt(this.innerHTML), 707 cls = getClass(this), 708 type = /new|old/.test(cls) ? cls.match(/new|old/)[0] : ''; 709 710 var day = _this.selectedDay(d, type); 711 712 _this.options.onSelected.call(this, 'date', day, $(this).data(MARK_DATA)); 713 714 _this.$trigger && _this.hide('date', day, $(this).data(MARK_DATA)); 715 716 }).on('click', '[' + ITEM_MONTH + ']', function () { 717 var y = Number(_this.$disMonth.html()), 718 m = $(this).index() + 1; 719 720 _this.updateDateView(y, m); 721 vc('date', y, m); 722 _this.options.onSelected.call(this, 'month', new Date(y, m - 1)); 723 }); 724 725 // hover 726 _this.$element.on('mouseenter', '[' + ITEM_DAY + ']', function (e) { 727 var $this = $(this), 728 day = $this.attr(ITEM_DAY).toDate(); 729 730 if (_this.hasLabel() && $this.data(MARK_DATA)) { 731 _this.showLabel(e, 'date', day, $this.data(MARK_DATA)); 732 } 733 734 _this.options.onMouseenter.call(this, 'date', day, $this.data(MARK_DATA)); 735 }).on('mouseleave', '[' + ITEM_DAY + ']', function () { 736 _this.$label.hide(); 737 }); 738 }, 739 resize: function () { 740 var w = this.width, 741 h = this.height, 742 hdH = this.$element.find('.calendar-hd').outerHeight(); 743 744 this.$element.width(w).height(h + hdH) 745 .find('.calendar-inner, .view') 746 .css('width', w + 'px'); 747 748 this.$element.find('.calendar-ct').width(w).height(h); 749 750 }, 751 init: function () { 752 753 this.fillStatic(); 754 this.resize(); 755 this.render(); 756 this.view = this.options.view; 757 this.setView(this.view); 758 this.event(); 759 }, 760 setData: function (data) { 761 this.data = data; 762 763 if (this.view === 'date') { 764 var d = this.getDisDateValue(); 765 this.fillDateItems(d[0], d[1]); 766 } else if (this.view === 'month') { 767 this.updateMonthView(this.$disMonth.html()); 768 } 769 }, 770 setDate: function (date) { 771 var dateObj = Date.tryParse(date); 772 this.updateDateView(dateObj.getFullYear(), dateObj.getMonth() + 1); 773 this.selectedDay(dateObj.getDate()); 774 }, 775 methods: function (name, args) { 776 if (OS.call(this[name]) === '[object Function]') { 777 return this[name].apply(this, args); 778 } 779 } 780 }; 781 782 $.fn.calendar = function (options) { 783 var calendar = this.data('calendar'), 784 fn, 785 args = [].slice.call(arguments); 786 787 if (!calendar) { 788 return this.each(function () { 789 return $(this).data('calendar', new Calendar(this, options)); 790 }); 791 } 792 if (isString(options)) { 793 fn = options; 794 args.shift(); 795 return calendar.methods(fn, args); 796 } 797 798 return this; 799 } 800
801 $.fn.calendar.defaults = defaults; 802 803}));
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.