1/*! 2 * FullCalendar v3.10.5 3 * Docs & License: https://fullcalendar.io/ 4 * (c) 2019 Adam Shaw 5 */ 6(function webpackUniversalModuleDefinition(root, factory) { 7 if(typeof exports === 'object' && typeof module === 'object') 8 module.exports = factory(require("moment"), require("jquery")); 9 else if(typeof define === 'function' && define.amd) 10 define(["moment", "jquery"], factory); 11 else if(typeof exports === 'object') 12 exports["FullCalendar"] = factory(require("moment"), require("jquery")); 13 else 14 root["FullCalendar"] = factory(root["moment"], root["jQuery"]); 15})(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE_0__, __WEBPACK_EXTERNAL_MODULE_3__) { 16return /******/ (function(modules) { // webpackBootstrap 17/******/ // The module cache 18/******/ var installedModules = {}; 19/******/ 20/******/ // The require function 21/******/ function __webpack_require__(moduleId) { 22/******/ 23/******/ // Check if module is in cache 24/******/ if(installedModules[moduleId]) { 25/******/ return installedModules[moduleId].exports; 26/******/ } 27/******/ // Create a new module (and put it into the cache) 28/******/ var module = installedModules[moduleId] = { 29/******/ i: moduleId, 30/******/ l: false, 31/******/ exports: {} 32/******/ }; 33/******/ 34/******/ // Execute the module function 35/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 36/******/ 37/******/ // Flag the module as loaded 38/******/ module.l = true; 39/******/ 40/******/ // Return the exports of the module 41/******/ return module.exports; 42/******/ } 43/******/ 44/******/ 45/******/ // expose the modules object (__webpack_modules__) 46/******/ __webpack_require__.m = modules; 47/******/ 48/******/ // expose the module cache 49/******/ __webpack_require__.c = installedModules; 50/******/ 51/******/ // define getter function for harmony exports 52/******/ __webpack_require__.d = function(exports, name, getter) { 53/******/ if(!__webpack_require__.o(exports, name)) { 54/******/ Object.defineProperty(exports, name, { 55/******/ configurable: false, 56/******/ enumerable: true, 57/******/ get: getter 58/******/ }); 59/******/ } 60/******/ }; 61/******/ 62/******/ // getDefaultExport function for compatibility with non-harmony modules 63/******/ __webpack_require__.n = function(module) { 64/******/ var getter = module && module.__esModule ? 65/******/ function getDefault() { return module['default']; } : 66/******/ function getModuleExports() { return module; }; 67/******/ __webpack_require__.d(getter, 'a', getter); 68/******/ return getter; 69/******/ }; 70/******/ 71/******/ // Object.prototype.hasOwnProperty.call 72/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 73/******/ 74/******/ // __webpack_public_path__ 75/******/ __webpack_require__.p = ""; 76/******/ 77/******/ // Load entry module and return exports 78/******/ return __webpack_require__(__webpack_require__.s = 256); 79/******/ }) 80/************************************************************************/ 81/******/ ([ 82/* 0 */ 83/***/ (function(module, exports) { 84 85module.exports = __WEBPACK_EXTERNAL_MODULE_0__; 86 87/***/ }), 88/* 1 */, 89/* 2 */ 90/***/ (function(module, exports) { 91 92/* 93derived from: 94https://github.com/Microsoft/tslib/blob/v1.6.0/tslib.js 95 96only include the helpers we need, to keep down filesize 97*/ 98var extendStatics = Object.setPrototypeOf || 99 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 100 function (d, b) { for (var p in b) 101 if (b.hasOwnProperty(p)) 102 d[p] = b[p]; }; 103exports.__extends = function (d, b) { 104 extendStatics(d, b); 105 function __() { this.constructor = d; } 106 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 107}; 108 109 110/***/ }), 111/* 3 */ 112/***/ (function(module, exports) { 113 114module.exports = __WEBPACK_EXTERNAL_MODULE_3__; 115 116/***/ }), 117/* 4 */ 118/***/ (function(module, exports, __webpack_require__) { 119 120Object.defineProperty(exports, "__esModule", { value: true }); 121var moment = __webpack_require__(0); 122var $ = __webpack_require__(3); 123/* FullCalendar-specific DOM Utilities 124----------------------------------------------------------------------------------------------------------------------*/ 125// Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left 126// and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that. 127function compensateScroll(rowEls, scrollbarWidths) { 128 if (scrollbarWidths.left) { 129 rowEls.css({ 130 'border-left-width': 1, 131 'margin-left': scrollbarWidths.left - 1 132 }); 133 } 134 if (scrollbarWidths.right) { 135 rowEls.css({ 136 'border-right-width': 1, 137 'margin-right': scrollbarWidths.right - 1 138 }); 139 } 140} 141exports.compensateScroll = compensateScroll; 142// Undoes compensateScroll and restores all borders/margins 143function uncompensateScroll(rowEls) { 144 rowEls.css({ 145 'margin-left': '', 146 'margin-right': '', 147 'border-left-width': '', 148 'border-right-width': '' 149 }); 150} 151exports.uncompensateScroll = uncompensateScroll; 152// Make the mouse cursor express that an event is not allowed in the current area 153function disableCursor() { 154 $('body').addClass('fc-not-allowed'); 155} 156exports.disableCursor = disableCursor; 157// Returns the mouse cursor to its original look 158function enableCursor() { 159 $('body').removeClass('fc-not-allowed'); 160} 161exports.enableCursor = enableCursor; 162// Given a total available height to fill, have `els` (essentially child rows) expand to accomodate. 163// By default, all elements that are shorter than the recommended height are expanded uniformly, not considering 164// any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and 165// reduces the available height. 166function distributeHeight(els, availableHeight, shouldRedistribute) { 167 // *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions, 168 // and it is better to be shorter than taller, to avoid creating unnecessary scrollbars. 169 var minOffset1 = Math.floor(availableHeight / els.length); // for non-last element 170 var minOffset2 = Math.floor(availableHeight - minOffset1 * (els.length - 1)); // for last element *FLOORING NOTE* 171 var flexEls = []; // elements that are allowed to expand. array of DOM nodes 172 var flexOffsets = []; // amount of vertical space it takes up 173 var flexHeights = []; // actual css height 174 var usedHeight = 0; 175 undistributeHeight(els); // give all elements their natural height 176 // find elements that are below the recommended height (expandable). 177 // important to query for heights in a single first pass (to avoid reflow oscillation). 178 els.each(function (i, el) { 179 var minOffset = i === els.length - 1 ? minOffset2 : minOffset1; 180 var naturalOffset = $(el).outerHeight(true); 181 if (naturalOffset < minOffset) { 182 flexEls.push(el); 183 flexOffsets.push(naturalOffset); 184 flexHeights.push($(el).height()); 185 } 186 else { 187 // this element stretches past recommended height (non-expandable). mark the space as occupied. 188 usedHeight += naturalOffset; 189 } 190 }); 191 // readjust the recommended height to only consider the height available to non-maxed-out rows. 192 if (shouldRedistribute) { 193 availableHeight -= usedHeight; 194 minOffset1 = Math.floor(availableHeight / flexEls.length); 195 minOffset2 = Math.floor(availableHeight - minOffset1 * (flexEls.length - 1)); // *FLOORING NOTE* 196 } 197 // assign heights to all expandable elements 198 $(flexEls).each(function (i, el) { 199 var minOffset = i === flexEls.length - 1 ? minOffset2 : minOffset1; 200 var naturalOffset = flexOffsets[i]; 201 var naturalHeight = flexHeights[i]; 202 var newHeight = minOffset - (naturalOffset - naturalHeight); // subtract the margin/padding 203 if (naturalOffset < minOffset) { // we check this again because redistribution might have changed things 204 $(el).height(newHeight); 205 } 206 }); 207} 208exports.distributeHeight = distributeHeight; 209// Undoes distrubuteHeight, restoring all els to their natural height 210function undistributeHeight(els) { 211 els.height(''); 212} 213exports.undistributeHeight = undistributeHeight; 214// Given `els`, a jQuery set of <td> cells, find the cell with the largest natural width and set the widths of all the 215// cells to be that width. 216// PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline 217function matchCellWidths(els) { 218 var maxInnerWidth = 0; 219 els.find('> *').each(function (i, innerEl) { 220 var innerWidth = $(innerEl).outerWidth(); 221 if (innerWidth > maxInnerWidth) { 222 maxInnerWidth = innerWidth; 223 } 224 }); 225 maxInnerWidth++; // sometimes not accurate of width the text needs to stay on one line. insurance 226 els.width(maxInnerWidth); 227 return maxInnerWidth; 228} 229exports.matchCellWidths = matchCellWidths; 230// Given one element that resides inside another, 231// Subtracts the height of the inner element from the outer element. 232function subtractInnerElHeight(outerEl, innerEl) { 233 var both = outerEl.add(innerEl); 234 var diff; 235 // effin' IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked 236 both.css({ 237 position: 'relative', 238 left: -1 // ensure reflow in case the el was already relative. negative is less likely to cause new scroll 239 }); 240 diff = outerEl.outerHeight() - innerEl.outerHeight(); // grab the dimensions 241 both.css({ position: '', left: '' }); // undo hack 242 return diff; 243} 244exports.subtractInnerElHeight = subtractInnerElHeight; 245/* Element Geom Utilities 246----------------------------------------------------------------------------------------------------------------------*/ 247// borrowed from https://github.com/jquery/jquery-ui/blob/1.11.0/ui/core.js#L51 248function getScrollParent(el) { 249 var position = el.css('position'); 250 var scrollParent = el.parents().filter(function () { 251 var parent = $(this); 252 return (/(auto|scroll)/).test(parent.css('overflow') + parent.css('overflow-y') + parent.css('overflow-x')); 253 }).eq(0); 254 return position === 'fixed' || !scrollParent.length ? $(el[0].ownerDocument || document) : scrollParent; 255} 256exports.getScrollParent = getScrollParent; 257// Queries the outer bounding area of a jQuery element. 258// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive). 259// Origin is optional. 260function getOuterRect(el, origin) { 261 var offset = el.offset(); 262 var left = offset.left - (origin ? origin.left : 0); 263 var top = offset.top - (origin ? origin.top : 0); 264 return { 265 left: left, 266 right: left + el.outerWidth(), 267 top: top, 268 bottom: top + el.outerHeight() 269 }; 270} 271exports.getOuterRect = getOuterRect; 272// Queries the area within the margin/border/scrollbars of a jQuery element. Does not go within the padding. 273// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive). 274// Origin is optional. 275// WARNING: given element can't have borders 276// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser. 277function getClientRect(el, origin) { 278 var offset = el.offset(); 279 var scrollbarWidths = getScrollbarWidths(el); 280 var left = offset.left + getCssFloat(el, 'border-left-width') + scrollbarWidths.left - (origin ? origin.left : 0); 281 var top = offset.top + getCssFloat(el, 'border-top-width') + scrollbarWidths.top - (origin ? origin.top : 0); 282 return { 283 left: left, 284 right: left + el[0].clientWidth, 285 top: top, 286 bottom: top + el[0].clientHeight // clientHeight includes padding but NOT scrollbars 287 }; 288} 289exports.getClientRect = getClientRect; 290// Queries the area within the margin/border/padding of a jQuery element. Assumed not to have scrollbars. 291// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive). 292// Origin is optional. 293function getContentRect(el, origin) { 294 var offset = el.offset(); // just outside of border, margin not included 295 var left = offset.left + getCssFloat(el, 'border-left-width') + getCssFloat(el, 'padding-left') - 296 (origin ? origin.left : 0); 297 var top = offset.top + getCssFloat(el, 'border-top-width') + getCssFloat(el, 'padding-top') - 298 (origin ? origin.top : 0); 299 return { 300 left: left, 301 right: left + el.width(), 302 top: top, 303 bottom: top + el.height() 304 }; 305} 306exports.getContentRect = getContentRect; 307// Returns the computed left/right/top/bottom scrollbar widths for the given jQuery element. 308// WARNING: given element can't have borders (which will cause offsetWidth/offsetHeight to be larger). 309// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser. 310function getScrollbarWidths(el) { 311 var leftRightWidth = el[0].offsetWidth - el[0].clientWidth; 312 var bottomWidth = el[0].offsetHeight - el[0].clientHeight; 313 var widths; 314 leftRightWidth = sanitizeScrollbarWidth(leftRightWidth); 315 bottomWidth = sanitizeScrollbarWidth(bottomWidth); 316 widths = { left: 0, right: 0, top: 0, bottom: bottomWidth }; 317 if (getIsLeftRtlScrollbars() && el.css('direction') === 'rtl') { // is the scrollbar on the left side? 318 widths.left = leftRightWidth; 319 } 320 else { 321 widths.right = leftRightWidth; 322 } 323 return widths; 324} 325exports.getScrollbarWidths = getScrollbarWidths; 326// The scrollbar width computations in getScrollbarWidths are sometimes flawed when it comes to 327// retina displays, rounding, and IE11. Massage them into a usable value. 328function sanitizeScrollbarWidth(width) { 329 width = Math.max(0, width); // no negatives 330 width = Math.round(width); 331 return width; 332} 333// Logic for determining if, when the element is right-to-left, the scrollbar appears on the left side 334var _isLeftRtlScrollbars = null; 335function getIsLeftRtlScrollbars() { 336 if (_isLeftRtlScrollbars === null) { 337 _isLeftRtlScrollbars = computeIsLeftRtlScrollbars(); 338 } 339 return _isLeftRtlScrollbars; 340} 341function computeIsLeftRtlScrollbars() { 342 var el = $('<div><div></div></div>') 343 .css({ 344 position: 'absolute', 345 top: -1000, 346 left: 0, 347 border: 0, 348 padding: 0, 349 overflow: 'scroll', 350 direction: 'rtl' 351 }) 352 .appendTo('body'); 353 var innerEl = el.children(); 354 var res = innerEl.offset().left > el.offset().left; // is the inner div shifted to accommodate a left scrollbar? 355 el.remove(); 356 return res; 357} 358// Retrieves a jQuery element's computed CSS value as a floating-point number. 359// If the queried value is non-numeric (ex: IE can return "medium" for border width), will just return zero. 360function getCssFloat(el, prop) { 361 return parseFloat(el.css(prop)) || 0; 362} 363/* Mouse / Touch Utilities 364----------------------------------------------------------------------------------------------------------------------*/ 365// Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac) 366function isPrimaryMouseButton(ev) { 367 return ev.which === 1 && !ev.ctrlKey; 368} 369exports.isPrimaryMouseButton = isPrimaryMouseButton; 370function getEvX(ev) { 371 var touches = ev.originalEvent.touches; 372 // on mobile FF, pageX for touch events is present, but incorrect, 373 // so, look at touch coordinates first. 374 if (touches && touches.length) { 375 return touches[0].pageX; 376 } 377 return ev.pageX; 378} 379exports.getEvX = getEvX; 380function getEvY(ev) { 381 var touches = ev.originalEvent.touches; 382 // on mobile FF, pageX for touch events is present, but incorrect, 383 // so, look at touch coordinates first. 384 if (touches && touches.length) { 385 return touches[0].pageY; 386 } 387 return ev.pageY; 388} 389exports.getEvY = getEvY; 390function getEvIsTouch(ev) { 391 return /^touch/.test(ev.type); 392} 393exports.getEvIsTouch = getEvIsTouch; 394function preventSelection(el) { 395 el.addClass('fc-unselectable') 396 .on('selectstart', preventDefault); 397} 398exports.preventSelection = preventSelection; 399function allowSelection(el) { 400 el.removeClass('fc-unselectable') 401 .off('selectstart', preventDefault); 402} 403exports.allowSelection = allowSelection; 404// Stops a mouse/touch event from doing it's native browser action 405function preventDefault(ev) { 406 ev.preventDefault(); 407} 408exports.preventDefault = preventDefault; 409/* General Geometry Utils 410----------------------------------------------------------------------------------------------------------------------*/ 411// Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false 412function intersectRects(rect1, rect2) { 413 var res = { 414 left: Math.max(rect1.left, rect2.left), 415 right: Math.min(rect1.right, rect2.right), 416 top: Math.max(rect1.top, rect2.top), 417 bottom: Math.min(rect1.bottom, rect2.bottom) 418 }; 419 if (res.left < res.right && res.top < res.bottom) { 420 return res; 421 } 422 return false; 423} 424exports.intersectRects = intersectRects; 425// Returns a new point that will have been moved to reside within the given rectangle 426function constrainPoint(point, rect) { 427 return { 428 left: Math.min(Math.max(point.left, rect.left), rect.right), 429 top: Math.min(Math.max(point.top, rect.top), rect.bottom) 430 }; 431} 432exports.constrainPoint = constrainPoint; 433// Returns a point that is the center of the given rectangle 434function getRectCenter(rect) { 435 return { 436 left: (rect.left + rect.right) / 2, 437 top: (rect.top + rect.bottom) / 2 438 }; 439} 440exports.getRectCenter = getRectCenter; 441// Subtracts point2's coordinates from point1's coordinates, returning a delta 442function diffPoints(point1, point2) { 443 return { 444 left: point1.left - point2.left, 445 top: point1.top - point2.top 446 }; 447} 448exports.diffPoints = diffPoints; 449/* Object Ordering by Field 450----------------------------------------------------------------------------------------------------------------------*/ 451function parseFieldSpecs(input) { 452 var specs = []; 453 var tokens = []; 454 var i; 455 var token; 456 if (typeof input === 'string') { 457 tokens = input.split(/\s*,\s*/); 458 } 459 else if (typeof input === 'function') { 460 tokens = [input]; 461 } 462 else if ($.isArray(input)) { 463 tokens = input; 464 } 465 for (i = 0; i < tokens.length; i++) { 466 token = tokens[i]; 467 if (typeof token === 'string') { 468 specs.push(token.charAt(0) === '-' ? 469 { field: token.substring(1), order: -1 } : 470 { field: token, order: 1 }); 471 } 472 else if (typeof token === 'function') { 473 specs.push({ func: token }); 474 } 475 } 476 return specs; 477} 478exports.parseFieldSpecs = parseFieldSpecs; 479function compareByFieldSpecs(obj1, obj2, fieldSpecs, obj1fallback, obj2fallback) { 480 var i; 481 var cmp; 482 for (i = 0; i < fieldSpecs.length; i++) { 483 cmp = compareByFieldSpec(obj1, obj2, fieldSpecs[i], obj1fallback, obj2fallback); 484 if (cmp) { 485 return cmp; 486 } 487 } 488 return 0; 489} 490exports.compareByFieldSpecs = compareByFieldSpecs; 491function compareByFieldSpec(obj1, obj2, fieldSpec, obj1fallback, obj2fallback) { 492 if (fieldSpec.func) { 493 return fieldSpec.func(obj1, obj2); 494 } 495 var val1 = obj1[fieldSpec.field]; 496 var val2 = obj2[fieldSpec.field]; 497 if (val1 == null && obj1fallback) { 498 val1 = obj1fallback[fieldSpec.field]; 499 } 500 if (val2 == null && obj2fallback) { 501 val2 = obj2fallback[fieldSpec.field]; 502 } 503 return flexibleCompare(val1, val2) * (fieldSpec.order || 1); 504} 505exports.compareByFieldSpec = compareByFieldSpec; 506function flexibleCompare(a, b) { 507 if (!a && !b) { 508 return 0; 509 } 510 if (b == null) { 511 return -1; 512 } 513 if (a == null) { 514 return 1; 515 } 516 if ($.type(a) === 'string' || $.type(b) === 'string') { 517 return String(a).localeCompare(String(b)); 518 } 519 return a - b; 520} 521exports.flexibleCompare = flexibleCompare; 522/* Date Utilities 523----------------------------------------------------------------------------------------------------------------------*/ 524exports.dayIDs = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; 525exports.unitsDesc = ['year', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; // descending 526// Diffs the two moments into a Duration where full-days are recorded first, then the remaining time. 527// Moments will have their timezones normalized. 528function diffDayTime(a, b) { 529 return moment.duration({ 530 days: a.clone().stripTime().diff(b.clone().stripTime(), 'days'), 531 ms: a.time() - b.time() // time-of-day from day start. disregards timezone 532 }); 533} 534exports.diffDayTime = diffDayTime; 535// Diffs the two moments via their start-of-day (regardless of timezone). Produces whole-day durations. 536function diffDay(a, b) { 537 return moment.duration({ 538 days: a.clone().stripTime().diff(b.clone().stripTime(), 'days') 539 }); 540} 541exports.diffDay = diffDay; 542// Diffs two moments, producing a duration, made of a whole-unit-increment of the given unit. Uses rounding. 543function diffByUnit(a, b, unit) { 544 return moment.duration(Math.round(a.diff(b, unit, true)), // returnFloat=true 545 unit); 546} 547exports.diffByUnit = diffByUnit; 548// Computes the unit name of the largest whole-unit period of time. 549// For example, 48 hours will be "days" whereas 49 hours will be "hours". 550// Accepts start/end, a range object, or an original duration object. 551function computeGreatestUnit(start, end) { 552 var i; 553 var unit; 554 var val; 555 for (i = 0; i < exports.unitsDesc.length; i++) { 556 unit = exports.unitsDesc[i]; 557 val = computeRangeAs(unit, start, end); 558 if (val >= 1 && isInt(val)) { 559 break; 560 } 561 } 562 return unit; // will be "milliseconds" if nothing else matches 563} 564exports.computeGreatestUnit = computeGreatestUnit; 565// like computeGreatestUnit, but has special abilities to interpret the source input for clues 566function computeDurationGreatestUnit(duration, durationInput) { 567 var unit = computeGreatestUnit(duration); 568 // prevent days:7 from being interpreted as a week 569 if (unit === 'week' && typeof durationInput === 'object' && durationInput.days) { 570 unit = 'day'; 571 } 572 return unit; 573} 574exports.computeDurationGreatestUnit = computeDurationGreatestUnit; 575// Computes the number of units (like "hours") in the given range. 576// Range can be a {start,end} object, separate start/end args, or a Duration. 577// Results are based on Moment's .as() and .diff() methods, so results can depend on internal handling 578// of month-diffing logic (which tends to vary from version to version). 579function computeRangeAs(unit, start, end) { 580 if (end != null) { // given start, end 581 return end.diff(start, unit, true); 582 } 583 else if (moment.isDuration(start)) { // given duration 584 return start.as(unit); 585 } 586 else { // given { start, end } range object 587 return start.end.diff(start.start, unit, true); 588 } 589} 590// Intelligently divides a range (specified by a start/end params) by a duration 591function divideRangeByDuration(start, end, dur) { 592 var months; 593 if (durationHasTime(dur)) { 594 return (end - start) / dur; 595 } 596 months = dur.asMonths(); 597 if (Math.abs(months) >= 1 && isInt(months)) { 598 return end.diff(start, 'months', true) / months; 599 } 600 return end.diff(start, 'days', true) / dur.asDays(); 601} 602exports.divideRangeByDuration = divideRangeByDuration; 603// Intelligently divides one duration by another 604function divideDurationByDuration(dur1, dur2) { 605 var months1; 606 var months2; 607 if (durationHasTime(dur1) || durationHasTime(dur2)) { 608 return dur1 / dur2; 609 } 610 months1 = dur1.asMonths(); 611 months2 = dur2.asMonths(); 612 if (Math.abs(months1) >= 1 && isInt(months1) && 613 Math.abs(months2) >= 1 && isInt(months2)) { 614 return months1 / months2; 615 } 616 return dur1.asDays() / dur2.asDays(); 617} 618exports.divideDurationByDuration = divideDurationByDuration; 619// Intelligently multiplies a duration by a number 620function multiplyDuration(dur, n) { 621 var months; 622 if (durationHasTime(dur)) { 623 return moment.duration(dur * n); 624 } 625 months = dur.asMonths(); 626 if (Math.abs(months) >= 1 && isInt(months)) { 627 return moment.duration({ months: months * n }); 628 } 629 return moment.duration({ days: dur.asDays() * n }); 630} 631exports.multiplyDuration = multiplyDuration; 632// Returns a boolean about whether the given duration has any time parts (hours/minutes/seconds/ms) 633function durationHasTime(dur) { 634 return Boolean(dur.hours() || dur.minutes() || dur.seconds() || dur.milliseconds()); 635} 636exports.durationHasTime = durationHasTime; 637function isNativeDate(input) { 638 return Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date; 639} 640exports.isNativeDate = isNativeDate; 641// Returns a boolean about whether the given input is a time string, like "06:40:00" or "06:00" 642function isTimeString(str) { 643 return typeof str === 'string' && 644 /^\d+\:\d+(?:\:\d+\.?(?:\d{3})?)?$/.test(str); 645} 646exports.isTimeString = isTimeString; 647/* Logging and Debug 648----------------------------------------------------------------------------------------------------------------------*/ 649function log() { 650 var args = []; 651 for (var _i = 0; _i < arguments.length; _i++) { 652 args[_i] = arguments[_i]; 653 } 654 var console = window.console; 655 if (console && console.log) { 656 return console.log.apply(console, args); 657 } 658} 659exports.log = log; 660function warn() { 661 var args = []; 662 for (var _i = 0; _i < arguments.length; _i++) { 663 args[_i] = arguments[_i]; 664 } 665 var console = window.console; 666 if (console && console.warn) { 667 return console.warn.apply(console, args); 668 } 669 else { 670 return log.apply(null, args); 671 } 672} 673exports.warn = warn; 674/* General Utilities 675----------------------------------------------------------------------------------------------------------------------*/ 676var hasOwnPropMethod = {}.hasOwnProperty; 677// Merges an array of objects into a single object. 678// The second argument allows for an array of property names who's object values will be merged together. 679function mergeProps(propObjs, complexProps) { 680 var dest = {}; 681 var i; 682 var name; 683 var complexObjs; 684 var j; 685 var val; 686 var props; 687 if (complexProps) { 688 for (i = 0; i < complexProps.length; i++) { 689 name = complexProps[i]; 690 complexObjs = []; 691 // collect the trailing object values, stopping when a non-object is discovered 692 for (j = propObjs.length - 1; j >= 0; j--) { 693 val = propObjs[j][name]; 694 if (typeof val === 'object') { 695 complexObjs.unshift(val); 696 } 697 else if (val !== undefined) { 698 dest[name] = val; // if there were no objects, this value will be used 699 break; 700 } 701 } 702 // if the trailing values were objects, use the merged value 703 if (complexObjs.length) { 704 dest[name] = mergeProps(complexObjs); 705 } 706 } 707 } 708 // copy values into the destination, going from last to first 709 for (i = propObjs.length - 1; i >= 0; i--) { 710 props = propObjs[i]; 711 for (name in props) { 712 if (!(name in dest)) { // if already assigned by previous props or complex props, don't reassign 713 dest[name] = props[name]; 714 } 715 } 716 } 717 return dest; 718} 719exports.mergeProps = mergeProps; 720function copyOwnProps(src, dest) { 721 for (var name_1 in src) { 722 if (hasOwnProp(src, name_1)) { 723 dest[name_1] = src[name_1]; 724 } 725 } 726} 727exports.copyOwnProps = copyOwnProps; 728function hasOwnProp(obj, name) { 729 return hasOwnPropMethod.call(obj, name); 730} 731exports.hasOwnProp = hasOwnProp; 732function applyAll(functions, thisObj, args) { 733 if ($.isFunction(functions)) { 734 functions = [functions]; 735 } 736 if (functions) { 737 var i = void 0; 738 var ret = void 0; 739 for (i = 0; i < functions.length; i++) { 740 ret = functions[i].apply(thisObj, args) || ret; 741 } 742 return ret; 743 } 744} 745exports.applyAll = applyAll; 746function removeMatching(array, testFunc) { 747 var removeCnt = 0; 748 var i = 0; 749 while (i < array.length) { 750 if (testFunc(array[i])) { // truthy value means *remove* 751 array.splice(i, 1); 752 removeCnt++; 753 } 754 else { 755 i++; 756 } 757 } 758 return removeCnt; 759} 760exports.removeMatching = removeMatching; 761function removeExact(array, exactVal) { 762 var removeCnt = 0; 763 var i = 0; 764 while (i < array.length) { 765 if (array[i] === exactVal) { 766 array.splice(i, 1); 767 removeCnt++; 768 } 769 else { 770 i++; 771 } 772 } 773 return removeCnt; 774} 775exports.removeExact = removeExact; 776function isArraysEqual(a0, a1) { 777 var len = a0.length; 778 var i; 779 if (len == null || len !== a1.length) { // not array? or not same length? 780 return false; 781 } 782 for (i = 0; i < len; i++) { 783 if (a0[i] !== a1[i]) { 784 return false; 785 } 786 } 787 return true; 788} 789exports.isArraysEqual = isArraysEqual; 790function firstDefined() { 791 var args = []; 792 for (var _i = 0; _i < arguments.length; _i++) { 793 args[_i] = arguments[_i]; 794 } 795 for (var i = 0; i < args.length; i++) { 796 if (args[i] !== undefined) { 797 return args[i]; 798 } 799 } 800} 801exports.firstDefined = firstDefined; 802function htmlEscape(s) { 803 return (s + '').replace(/&/g, '&') 804 .replace(/</g, '<') 805 .replace(/>/g, '>') 806 .replace(/'/g, ''') 807 .replace(/"/g, '"') 808 .replace(/\n/g, '<br>'); 809} 810exports.htmlEscape = htmlEscape; 811function stripHtmlEntities(text) { 812 return text.replace(/&.*?;/g, ''); 813} 814exports.stripHtmlEntities = stripHtmlEntities; 815// Given a hash of CSS properties, returns a string of CSS. 816// Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values. 817function cssToStr(cssProps) { 818 var statements = []; 819 $.each(cssProps, function (name, val) { 820 if (val != null) { 821 statements.push(name + ':' + val); 822 } 823 }); 824 return statements.join(';'); 825} 826exports.cssToStr = cssToStr; 827// Given an object hash of HTML attribute names to values, 828// generates a string that can be injected between < > in HTML 829function attrsToStr(attrs) { 830 var parts = []; 831 $.each(attrs, function (name, val) { 832 if (val != null) { 833 parts.push(name + '="' + htmlEscape(val) + '"'); 834 } 835 }); 836 return parts.join(' '); 837} 838exports.attrsToStr = attrsToStr; 839function capitaliseFirstLetter(str) { 840 return str.charAt(0).toUpperCase() + str.slice(1); 841} 842exports.capitaliseFirstLetter = capitaliseFirstLetter; 843function compareNumbers(a, b) { 844 return a - b; 845} 846exports.compareNumbers = compareNumbers; 847function isInt(n) { 848 return n % 1 === 0; 849} 850exports.isInt = isInt; 851// Returns a method bound to the given object context. 852// Just like one of the jQuery.proxy signatures, but without the undesired behavior of treating the same method with 853// different contexts as identical when binding/unbinding events. 854function proxy(obj, methodName) { 855 var method = obj[methodName]; 856 return function () { 857 return method.apply(obj, arguments); 858 }; 859} 860exports.proxy = proxy; 861// Returns a function, that, as long as it continues to be invoked, will not 862// be triggered. The function will be called after it stops being called for 863// N milliseconds. If `immediate` is passed, trigger the function on the 864// leading edge, instead of the trailing. 865// https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714 866function debounce(func, wait, immediate) { 867 if (immediate === void 0) { immediate = false; } 868 var timeout; 869 var args; 870 var context; 871 var timestamp; 872 var result; 873 var later = function () { 874 var last = +new Date() - timestamp; 875 if (last < wait) { 876 timeout = setTimeout(later, wait - last); 877 } 878 else { 879 timeout = null; 880 if (!immediate) { 881 result = func.apply(context, args); 882 context = args = null; 883 } 884 } 885 }; 886 return function () { 887 context = this; 888 args = arguments; 889 timestamp = +new Date(); 890 var callNow = immediate && !timeout; 891 if (!timeout) { 892 timeout = setTimeout(later, wait); 893 } 894 if (callNow) { 895 result = func.apply(context, args); 896 context = args = null; 897 } 898 return result; 899 }; 900} 901exports.debounce = debounce; 902 903 904/***/ }), 905/* 5 */ 906/***/ (function(module, exports, __webpack_require__) { 907 908Object.defineProperty(exports, "__esModule", { value: true }); 909var moment = __webpack_require__(0); 910var moment_ext_1 = __webpack_require__(11); 911var UnzonedRange = /** @class */ (function () { 912 function UnzonedRange(startInput, endInput) { 913 // TODO: move these into footprint. 914 // Especially, doesn't make sense for null startMs/endMs. 915 this.isStart = true; 916 this.isEnd = true; 917 if (moment.isMoment(startInput)) { 918 startInput = startInput.clone().stripZone(); 919 } 920 if (moment.isMoment(endInput)) { 921 endInput = endInput.clone().stripZone(); 922 } 923 if (startInput) { 924 this.startMs = startInput.valueOf(); 925 } 926 if (endInput) { 927 this.endMs = endInput.valueOf(); 928 } 929 } 930 /* 931 SIDEEFFECT: will mutate eventRanges. 932 Will return a new array result. 933 Only works for non-open-ended ranges. 934 */ 935 UnzonedRange.invertRanges = function (ranges, constraintRange) { 936 var invertedRanges = []; 937 var startMs = constraintRange.startMs; // the end of the previous range. the start of the new range 938 var i; 939 var dateRange; 940 // ranges need to be in order. required for our date-walking algorithm 941 ranges.sort(compareUnzonedRanges); 942 for (i = 0; i < ranges.length; i++) { 943 dateRange = ranges[i]; 944 // add the span of time before the event (if there is any) 945 if (dateRange.startMs > startMs) { // compare millisecond time (skip any ambig logic) 946 invertedRanges.push(new UnzonedRange(startMs, dateRange.startMs)); 947 } 948 if (dateRange.endMs > startMs) { 949 startMs = dateRange.endMs; 950 } 951 } 952 // add the span of time after the last event (if there is any) 953 if (startMs < constraintRange.endMs) { // compare millisecond time (skip any ambig logic) 954 invertedRanges.push(new UnzonedRange(startMs, constraintRange.endMs)); 955 } 956 return invertedRanges; 957 }; 958 UnzonedRange.prototype.intersect = function (otherRange) { 959 var startMs = this.startMs; 960 var endMs = this.endMs; 961 var newRange = null; 962 if (otherRange.startMs != null) { 963 if (startMs == null) { 964 startMs = otherRange.startMs; 965 } 966 else { 967 startMs = Math.max(startMs, otherRange.startMs); 968 } 969 } 970 if (otherRange.endMs != null) { 971 if (endMs == null) { 972 endMs = otherRange.endMs; 973 } 974 else { 975 endMs = Math.min(endMs, otherRange.endMs); 976 } 977 } 978 if (startMs == null || endMs == null || startMs < endMs) { 979 newRange = new UnzonedRange(startMs, endMs); 980 newRange.isStart = this.isStart && startMs === this.startMs; 981 newRange.isEnd = this.isEnd && endMs === this.endMs; 982 } 983 return newRange; 984 }; 985 UnzonedRange.prototype.intersectsWith = function (otherRange) { 986 return (this.endMs == null || otherRange.startMs == null || this.endMs > otherRange.startMs) && 987 (this.startMs == null || otherRange.endMs == null || this.startMs < otherRange.endMs); 988 }; 989 UnzonedRange.prototype.containsRange = function (innerRange) { 990 return (this.startMs == null || (innerRange.startMs != null && innerRange.startMs >= this.startMs)) && 991 (this.endMs == null || (innerRange.endMs != null && innerRange.endMs <= this.endMs)); 992 }; 993 // `date` can be a moment, a Date, or a millisecond time. 994 UnzonedRange.prototype.containsDate = function (date) { 995 var ms = date.valueOf(); 996 return (this.startMs == null || ms >= this.startMs) && 997 (this.endMs == null || ms < this.endMs); 998 }; 999 // If the given date is not within the given range, move it inside. 1000 // (If it's past the end, make it one millisecond before the end). 1001 // `date` can be a moment, a Date, or a millisecond time. 1002 // Returns a MS-time. 1003 UnzonedRange.prototype.constrainDate = function (date) { 1004 var ms = date.valueOf(); 1005 if (this.startMs != null && ms < this.startMs) { 1006 ms = this.startMs; 1007 } 1008 if (this.endMs != null && ms >= this.endMs) { 1009 ms = this.endMs - 1; 1010 } 1011 return ms; 1012 }; 1013 UnzonedRange.prototype.equals = function (otherRange) { 1014 return this.startMs === otherRange.startMs && this.endMs === otherRange.endMs; 1015 }; 1016 UnzonedRange.prototype.clone = function () { 1017 var range = new UnzonedRange(this.startMs, this.endMs); 1018 range.isStart = this.isStart; 1019 range.isEnd = this.isEnd; 1020 return range; 1021 }; 1022 // Returns an ambig-zoned moment from startMs. 1023 // BEWARE: returned moment is not localized. 1024 // Formatting and start-of-week will be default. 1025 UnzonedRange.prototype.getStart = function () { 1026 if (this.startMs != null) { 1027 return moment_ext_1.default.utc(this.startMs).stripZone(); 1028 } 1029 return null; 1030 }; 1031 // Returns an ambig-zoned moment from startMs. 1032 // BEWARE: returned moment is not localized. 1033 // Formatting and start-of-week will be default. 1034 UnzonedRange.prototype.getEnd = function () { 1035 if (this.endMs != null) { 1036 return moment_ext_1.default.utc(this.endMs).stripZone(); 1037 } 1038 return null; 1039 }; 1040 UnzonedRange.prototype.as = function (unit) { 1041 return moment.utc(this.endMs).diff(moment.utc(this.startMs), unit, true); 1042 }; 1043 return UnzonedRange; 1044}()); 1045exports.default = UnzonedRange; 1046/* 1047Only works for non-open-ended ranges. 1048*/ 1049function compareUnzonedRanges(range1, range2) { 1050 return range1.startMs - range2.startMs; // earlier ranges go first 1051} 1052 1053 1054/***/ }), 1055/* 6 */ 1056/***/ (function(module, exports, __webpack_require__) { 1057 1058Object.defineProperty(exports, "__esModule", { value: true }); 1059var tslib_1 = __webpack_require__(2); 1060var $ = __webpack_require__(3); 1061var ParsableModelMixin_1 = __webpack_require__(52); 1062var Class_1 = __webpack_require__(35); 1063var EventDefParser_1 = __webpack_require__(36); 1064var EventSource = /** @class */ (function (_super) { 1065 tslib_1.__extends(EventSource, _super); 1066 // can we do away with calendar? at least for the abstract? 1067 // useful for buildEventDef 1068 function EventSource(calendar) { 1069 var _this = _super.call(this) || this; 1070 _this.calendar = calendar; 1071 _this.className = []; 1072 _this.uid = String(EventSource.uuid++); 1073 return _this; 1074 } 1075 /* 1076 rawInput can be any data type! 1077 */ 1078 EventSource.parse = function (rawInput, calendar) { 1079 var source = new this(calendar); 1080 if (typeof rawInput === 'object') { 1081 if (source.applyProps(rawInput)) { 1082 return source; 1083 } 1084 } 1085 return false; 1086 }; 1087 EventSource.normalizeId = function (id) { 1088 if (id) { 1089 return String(id); 1090 } 1091 return null; 1092 }; 1093 EventSource.prototype.fetch = function (start, end, timezone) { 1094 // subclasses must implement. must return a promise. 1095 }; 1096 EventSource.prototype.removeEventDefsById = function (eventDefId) { 1097 // optional for subclasses to implement 1098 }; 1099 EventSource.prototype.removeAllEventDefs = function () { 1100 // optional for subclasses to implement 1101 }; 1102 /* 1103 For compairing/matching 1104 */ 1105 EventSource.prototype.getPrimitive = function (otherSource) { 1106 // subclasses must implement 1107 }; 1108 EventSource.prototype.parseEventDefs = function (rawEventDefs) { 1109 var i; 1110 var eventDef; 1111 var eventDefs = []; 1112 for (i = 0; i < rawEventDefs.length; i++) { 1113 eventDef = this.parseEventDef(rawEventDefs[i]); 1114 if (eventDef) { 1115 eventDefs.push(eventDef); 1116 } 1117 } 1118 return eventDefs; 1119 }; 1120 EventSource.prototype.parseEventDef = function (rawInput) { 1121 var calendarTransform = this.calendar.opt('eventDataTransform'); 1122 var sourceTransform = this.eventDataTransform; 1123 if (calendarTransform) { 1124 rawInput = calendarTransform(rawInput, this.calendar); 1125 } 1126 if (sourceTransform) { 1127 rawInput = sourceTransform(rawInput, this.calendar); 1128 } 1129 return EventDefParser_1.default.parse(rawInput, this); 1130 }; 1131 EventSource.prototype.applyManualStandardProps = function (rawProps) { 1132 if (rawProps.id != null) { 1133 this.id = EventSource.normalizeId(rawProps.id); 1134 } 1135 // TODO: converge with EventDef 1136 if ($.isArray(rawProps.className)) { 1137 this.className = rawProps.className; 1138 } 1139 else if (typeof rawProps.className === 'string') { 1140 this.className = rawProps.className.split(/\s+/); 1141 } 1142 return true; 1143 }; 1144 EventSource.uuid = 0; 1145 EventSource.defineStandardProps = ParsableModelMixin_1.default.defineStandardProps; 1146 EventSource.copyVerbatimStandardProps = ParsableModelMixin_1.default.copyVerbatimStandardProps; 1147 return EventSource; 1148}(Class_1.default)); 1149exports.default = EventSource; 1150ParsableModelMixin_1.default.mixInto(EventSource); 1151// Parsing 1152// --------------------------------------------------------------------------------------------------------------------- 1153EventSource.defineStandardProps({ 1154 // manually process... 1155 id: false, 1156 className: false, 1157 // automatically transfer... 1158 color: true, 1159 backgroundColor: true, 1160 borderColor: true, 1161 textColor: true, 1162 editable: true, 1163 startEditable: true, 1164 durationEditable: true, 1165 rendering: true, 1166 overlap: true, 1167 constraint: true, 1168 allDayDefault: true, 1169 eventDataTransform: true 1170}); 1171 1172 1173/***/ }), 1174/* 7 */ 1175/***/ (function(module, exports, __webpack_require__) { 1176 1177/* 1178Utility methods for easily listening to events on another object, 1179and more importantly, easily unlistening from them. 1180 1181USAGE: 1182 import { default as ListenerMixin, ListenerInterface } from './ListenerMixin' 1183in class: 1184 listenTo: ListenerInterface['listenTo'] 1185 stopListeningTo: ListenerInterface['stopListeningTo'] 1186after class: 1187 ListenerMixin.mixInto(TheClass) 1188*/ 1189Object.defineProperty(exports, "__esModule", { value: true }); 1190var tslib_1 = __webpack_require__(2); 1191var $ = __webpack_require__(3); 1192var Mixin_1 = __webpack_require__(15); 1193var guid = 0; 1194var ListenerMixin = /** @class */ (function (_super) { 1195 tslib_1.__extends(ListenerMixin, _super); 1196 function ListenerMixin() { 1197 return _super !== null && _super.apply(this, arguments) || this; 1198 } 1199 /* 1200 Given an `other` object that has on/off methods, bind the given `callback` to an event by the given name. 1201 The `callback` will be called with the `this` context of the object that .listenTo is being called on. 1202 Can be called: 1203 .listenTo(other, eventName, callback) 1204 OR 1205 .listenTo(other, { 1206 eventName1: callback1, 1207 eventName2: callback2 1208 }) 1209 */ 1210 ListenerMixin.prototype.listenTo = function (other, arg, callback) { 1211 if (typeof arg === 'object') { // given dictionary of callbacks 1212 for (var eventName in arg) { 1213 if (arg.hasOwnProperty(eventName)) { 1214 this.listenTo(other, eventName, arg[eventName]); 1215 } 1216 } 1217 } 1218 else if (typeof arg === 'string') { 1219 other.on(arg + '.' + this.getListenerNamespace(), // use event namespacing to identify this object 1220 $.proxy(callback, this) // always use `this` context 1221 // the usually-undesired jQuery guid behavior doesn't matter, 1222 // because we always unbind via namespace 1223 ); 1224 } 1225 }; 1226 /* 1227 Causes the current object to stop listening to events on the `other` object. 1228 `eventName` is optional. If omitted, will stop listening to ALL events on `other`. 1229 */ 1230 ListenerMixin.prototype.stopListeningTo = function (other, eventName) { 1231 other.off((eventName || '') + '.' + this.getListenerNamespace()); 1232 }; 1233 /* 1234 Returns a string, unique to this object, to be used for event namespacing 1235 */ 1236 ListenerMixin.prototype.getListenerNamespace = function () { 1237 if (this.listenerId == null) { 1238 this.listenerId = guid++; 1239 } 1240 return '_listener' + this.listenerId; 1241 }; 1242 return ListenerMixin; 1243}(Mixin_1.default)); 1244exports.default = ListenerMixin; 1245 1246 1247/***/ }), 1248/* 8 */, 1249/* 9 */ 1250/***/ (function(module, exports, __webpack_require__) { 1251 1252Object.defineProperty(exports, "__esModule", { value: true }); 1253var tslib_1 = __webpack_require__(2); 1254var EventDef_1 = __webpack_require__(37); 1255var EventInstance_1 = __webpack_require__(53); 1256var EventDateProfile_1 = __webpack_require__(16); 1257var SingleEventDef = /** @class */ (function (_super) { 1258 tslib_1.__extends(SingleEventDef, _super); 1259 function SingleEventDef() { 1260 return _super !== null && _super.apply(this, arguments) || this; 1261 } 1262 /* 1263 Will receive start/end params, but will be ignored. 1264 */ 1265 SingleEventDef.prototype.buildInstances = function () { 1266 return [this.buildInstance()]; 1267 }; 1268 SingleEventDef.prototype.buildInstance = function () { 1269 return new EventInstance_1.default(this, // definition 1270 this.dateProfile); 1271 }; 1272 SingleEventDef.prototype.isAllDay = function () { 1273 return this.dateProfile.isAllDay(); 1274 }; 1275 SingleEventDef.prototype.clone = function () { 1276 var def = _super.prototype.clone.call(this); 1277 def.dateProfile = this.dateProfile; 1278 return def; 1279 }; 1280 SingleEventDef.prototype.rezone = function () { 1281 var calendar = this.source.calendar; 1282 var dateProfile = this.dateProfile; 1283 this.dateProfile = new EventDateProfile_1.default(calendar.moment(dateProfile.start), dateProfile.end ? calendar.moment(dateProfile.end) : null, calendar); 1284 }; 1285 /* 1286 NOTE: if super-method fails, should still attempt to apply 1287 */ 1288 SingleEventDef.prototype.applyManualStandardProps = function (rawProps) { 1289 var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps); 1290 var dateProfile = EventDateProfile_1.default.parse(rawProps, this.source); // returns null on failure 1291 if (dateProfile) { 1292 this.dateProfile = dateProfile; 1293 // make sure `date` shows up in the legacy event objects as-is 1294 if (rawProps.date != null) { 1295 this.miscProps.date = rawProps.date; 1296 } 1297 return superSuccess; 1298 } 1299 else { 1300 return false; 1301 } 1302 }; 1303 return SingleEventDef; 1304}(EventDef_1.default)); 1305exports.default = SingleEventDef; 1306// Parsing 1307// --------------------------------------------------------------------------------------------------------------------- 1308SingleEventDef.defineStandardProps({ 1309 start: false, 1310 date: false, 1311 end: false, 1312 allDay: false 1313}); 1314 1315 1316/***/ }), 1317/* 10 */, 1318/* 11 */ 1319/***/ (function(module, exports, __webpack_require__) { 1320 1321Object.defineProperty(exports, "__esModule", { value: true }); 1322var moment = __webpack_require__(0); 1323var $ = __webpack_require__(3); 1324var util_1 = __webpack_require__(4); 1325var ambigDateOfMonthRegex = /^\s*\d{4}-\d\d$/; 1326var ambigTimeOrZoneRegex = /^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?)?$/; 1327var newMomentProto = moment.fn; // where we will attach our new methods 1328exports.newMomentProto = newMomentProto; 1329var oldMomentProto = $.extend({}, newMomentProto); // copy of original moment methods 1330exports.oldMomentProto = oldMomentProto; 1331// tell momentjs to transfer these properties upon clone 1332var momentProperties = moment.momentProperties; 1333momentProperties.push('_fullCalendar'); 1334momentProperties.push('_ambigTime'); 1335momentProperties.push('_ambigZone'); 1336/* 1337Call this if you want Moment's original format method to be used 1338*/ 1339function oldMomentFormat(mom, formatStr) { 1340 return oldMomentProto.format.call(mom, formatStr); // oldMomentProto defined in moment-ext.js 1341} 1342exports.oldMomentFormat = oldMomentFormat; 1343// Creating 1344// ------------------------------------------------------------------------------------------------- 1345// Creates a new moment, similar to the vanilla moment(...) constructor, but with 1346// extra features (ambiguous time, enhanced formatting). When given an existing moment, 1347// it will function as a clone (and retain the zone of the moment). Anything else will 1348// result in a moment in the local zone. 1349var momentExt = function () { 1350 return makeMoment(arguments); 1351}; 1352exports.default = momentExt; 1353// Sames as momentExt, but forces the resulting moment to be in the UTC timezone. 1354momentExt.utc = function () { 1355 var mom = makeMoment(arguments, true); 1356 // Force it into UTC because makeMoment doesn't guarantee it 1357 // (if given a pre-existing moment for example) 1358 if (mom.hasTime()) { // don't give ambiguously-timed moments a UTC zone 1359 mom.utc(); 1360 } 1361 return mom; 1362}; 1363// Same as momentExt, but when given an ISO8601 string, the timezone offset is preserved. 1364// ISO8601 strings with no timezone offset will become ambiguously zoned. 1365momentExt.parseZone = function () { 1366 return makeMoment(arguments, true, true); 1367}; 1368// Builds an enhanced moment from args. When given an existing moment, it clones. When given a 1369// native Date, or called with no arguments (the current time), the resulting moment will be local. 1370// Anything else needs to be "parsed" (a string or an array), and will be affected by: 1371// parseAsUTC - if there is no zone information, should we parse the input in UTC? 1372// parseZone - if there is zone information, should we force the zone of the moment? 1373function makeMoment(args, parseAsUTC, parseZone) { 1374 if (parseAsUTC === void 0) { parseAsUTC = false; } 1375 if (parseZone === void 0) { parseZone = false; } 1376 var input = args[0]; 1377 var isSingleString = args.length === 1 && typeof input === 'string'; 1378 var isAmbigTime; 1379 var isAmbigZone; 1380 var ambigMatch; 1381 var mom; 1382 if (moment.isMoment(input) || util_1.isNativeDate(input) || input === undefined) { 1383 mom = moment.apply(null, args); 1384 } 1385 else { // "parsing" is required 1386 isAmbigTime = false; 1387 isAmbigZone = false; 1388 if (isSingleString) { 1389 if (ambigDateOfMonthRegex.test(input)) { 1390 // accept strings like '2014-05', but convert to the first of the month 1391 input += '-01'; 1392 args = [input]; // for when we pass it on to moment's constructor 1393 isAmbigTime = true; 1394 isAmbigZone = true; 1395 } 1396 else if ((ambigMatch = ambigTimeOrZoneRegex.exec(input))) { 1397 isAmbigTime = !ambigMatch[5]; // no time part? 1398 isAmbigZone = true; 1399 } 1400 } 1401 else if ($.isArray(input)) { 1402 // arrays have no timezone information, so assume ambiguous zone 1403 isAmbigZone = true; 1404 } 1405 // otherwise, probably a string with a format 1406 if (parseAsUTC || isAmbigTime) { 1407 mom = moment.utc.apply(moment, args); 1408 } 1409 else { 1410 mom = moment.apply(null, args); 1411 } 1412 if (isAmbigTime) { 1413 mom._ambigTime = true; 1414 mom._ambigZone = true; // ambiguous time always means ambiguous zone 1415 } 1416 else if (parseZone) { // let's record the inputted zone somehow 1417 if (isAmbigZone) { 1418 mom._ambigZone = true; 1419 } 1420 else if (isSingleString) { 1421 mom.utcOffset(input); // if not a valid zone, will assign UTC 1422 } 1423 } 1424 } 1425 mom._fullCalendar = true; // flag for extended functionality 1426 return mom; 1427} 1428// Week Number 1429// ------------------------------------------------------------------------------------------------- 1430// Returns the week number, considering the locale's custom week number calcuation 1431// `weeks` is an alias for `week` 1432newMomentProto.week = newMomentProto.weeks = function (input) { 1433 var weekCalc = this._locale._fullCalendar_weekCalc; 1434 if (input == null && typeof weekCalc === 'function') { // custom function only works for getter 1435 return weekCalc(this); 1436 } 1437 else if (weekCalc === 'ISO') { 1438 return oldMomentProto.isoWeek.apply(this, arguments); // ISO getter/setter 1439 } 1440 return oldMomentProto.week.apply(this, arguments); // local getter/setter 1441}; 1442// Time-of-day 1443// ------------------------------------------------------------------------------------------------- 1444// GETTER 1445// Returns a Duration with the hours/minutes/seconds/ms values of the moment. 1446// If the moment has an ambiguous time, a duration of 00:00 will be returned. 1447// 1448// SETTER 1449// You can supply a Duration, a Moment, or a Duration-like argument. 1450// When setting the time, and the moment has an ambiguous time, it then becomes unambiguous. 1451newMomentProto.time = function (time) { 1452 // Fallback to the original method (if there is one) if this moment wasn't created via FullCalendar. 1453 // `time` is a generic enough method name where this precaution is necessary to avoid collisions w/ other plugins. 1454 if (!this._fullCalendar) { 1455 return oldMomentProto.time.apply(this, arguments); 1456 } 1457 if (time == null) { // getter 1458 return moment.duration({ 1459 hours: this.hours(), 1460 minutes: this.minutes(), 1461 seconds: this.seconds(), 1462 milliseconds: this.milliseconds() 1463 }); 1464 } 1465 else { // setter 1466 this._ambigTime = false; // mark that the moment now has a time 1467 if (!moment.isDuration(time) && !moment.isMoment(time)) { 1468 time = moment.duration(time); 1469 } 1470 // The day value should cause overflow (so 24 hours becomes 00:00:00 of next day). 1471 // Only for Duration times, not Moment times. 1472 var dayHours = 0; 1473 if (moment.isDuration(time)) { 1474 dayHours = Math.floor(time.asDays()) * 24; 1475 } 1476 // We need to set the individual fields. 1477 // Can't use startOf('day') then add duration. In case of DST at start of day. 1478 return this.hours(dayHours + time.hours()) 1479 .minutes(time.minutes()) 1480 .seconds(time.seconds()) 1481 .milliseconds(time.milliseconds()); 1482 } 1483}; 1484// Converts the moment to UTC, stripping out its time-of-day and timezone offset, 1485// but preserving its YMD. A moment with a stripped time will display no time 1486// nor timezone offset when .format() is called. 1487newMomentProto.stripTime = function () { 1488 if (!this._ambigTime) { 1489 this.utc(true); // keepLocalTime=true (for keeping *date* value) 1490 // set time to zero 1491 this.set({ 1492 hours: 0, 1493 minutes: 0, 1494 seconds: 0, 1495 ms: 0 1496 }); 1497 // Mark the time as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(), 1498 // which clears all ambig flags. 1499 this._ambigTime = true; 1500 this._ambigZone = true; // if ambiguous time, also ambiguous timezone offset 1501 } 1502 return this; // for chaining 1503}; 1504// Returns if the moment has a non-ambiguous time (boolean) 1505newMomentProto.hasTime = function () { 1506 return !this._ambigTime; 1507}; 1508// Timezone 1509// ------------------------------------------------------------------------------------------------- 1510// Converts the moment to UTC, stripping out its timezone offset, but preserving its 1511// YMD and time-of-day. A moment with a stripped timezone offset will display no 1512// timezone offset when .format() is called. 1513newMomentProto.stripZone = function () { 1514 var wasAmbigTime; 1515 if (!this._ambigZone) { 1516 wasAmbigTime = this._ambigTime; 1517 this.utc(true); // keepLocalTime=true (for keeping date and time values) 1518 // the above call to .utc()/.utcOffset() unfortunately might clear the ambig flags, so restore 1519 this._ambigTime = wasAmbigTime || false; 1520 // Mark the zone as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(), 1521 // which clears the ambig flags. 1522 this._ambigZone = true; 1523 } 1524 return this; // for chaining 1525}; 1526// Returns of the moment has a non-ambiguous timezone offset (boolean) 1527newMomentProto.hasZone = function () { 1528 return !this._ambigZone; 1529}; 1530// implicitly marks a zone 1531newMomentProto.local = function (keepLocalTime) { 1532 // for when converting from ambiguously-zoned to local, 1533 // keep the time values when converting from UTC -> local 1534 oldMomentProto.local.call(this, this._ambigZone || keepLocalTime); 1535 // ensure non-ambiguous 1536 // this probably already happened via local() -> utcOffset(), but don't rely on Moment's internals 1537 this._ambigTime = false; 1538 this._ambigZone = false; 1539 return this; // for chaining 1540}; 1541// implicitly marks a zone 1542newMomentProto.utc = function (keepLocalTime) { 1543 oldMomentProto.utc.call(this, keepLocalTime); 1544 // ensure non-ambiguous 1545 // this probably already happened via utc() -> utcOffset(), but don't rely on Moment's internals 1546 this._ambigTime = false; 1547 this._ambigZone = false; 1548 return this; 1549}; 1550// implicitly marks a zone (will probably get called upon .utc() and .local()) 1551newMomentProto.utcOffset = function (tzo) { 1552 if (tzo != null) { // setter 1553 // these assignments needs to happen before the original zone method is called. 1554 // I forget why, something to do with a browser crash. 1555 this._ambigTime = false; 1556 this._ambigZone = false; 1557 } 1558 return oldMomentProto.utcOffset.apply(this, arguments); 1559}; 1560 1561 1562/***/ }), 1563/* 12 */ 1564/***/ (function(module, exports) { 1565 1566Object.defineProperty(exports, "__esModule", { value: true }); 1567/* 1568Meant to be immutable 1569*/ 1570var ComponentFootprint = /** @class */ (function () { 1571 function ComponentFootprint(unzonedRange, isAllDay) { 1572 this.isAllDay = false; // component can choose to ignore this 1573 this.unzonedRange = unzonedRange; 1574 this.isAllDay = isAllDay; 1575 } 1576 /* 1577 Only works for non-open-ended ranges. 1578 */ 1579 ComponentFootprint.prototype.toLegacy = function (calendar) { 1580 return { 1581 start: calendar.msToMoment(this.unzonedRange.startMs, this.isAllDay), 1582 end: calendar.msToMoment(this.unzonedRange.endMs, this.isAllDay) 1583 }; 1584 }; 1585 return ComponentFootprint; 1586}()); 1587exports.default = ComponentFootprint; 1588 1589 1590/***/ }), 1591/* 13 */ 1592/***/ (function(module, exports, __webpack_require__) { 1593 1594/* 1595USAGE: 1596 import { default as EmitterMixin, EmitterInterface } from './EmitterMixin' 1597in class: 1598 on: EmitterInterface['on'] 1599 one: EmitterInterface['one'] 1600 off: EmitterInterface['off'] 1601 trigger: EmitterInterface['trigger'] 1602 triggerWith: EmitterInterface['triggerWith'] 1603 hasHandlers: EmitterInterface['hasHandlers'] 1604after class: 1605 EmitterMixin.mixInto(TheClass) 1606*/ 1607Object.defineProperty(exports, "__esModule", { value: true }); 1608var tslib_1 = __webpack_require__(2); 1609var $ = __webpack_require__(3); 1610var Mixin_1 = __webpack_require__(15); 1611var EmitterMixin = /** @class */ (function (_super) { 1612 tslib_1.__extends(EmitterMixin, _super); 1613 function EmitterMixin() { 1614 return _super !== null && _super.apply(this, arguments) || this; 1615 } 1616 // jQuery-ification via $(this) allows a non-DOM object to have 1617 // the same event handling capabilities (including namespaces). 1618 EmitterMixin.prototype.on = function (types, handler) { 1619 $(this).on(types, this._prepareIntercept(handler)); 1620 return this; // for chaining 1621 }; 1622 EmitterMixin.prototype.one = function (types, handler) { 1623 $(this).one(types, this._prepareIntercept(handler)); 1624 return this; // for chaining 1625 }; 1626 EmitterMixin.prototype._prepareIntercept = function (handler) { 1627 // handlers are always called with an "event" object as their first param. 1628 // sneak the `this` context and arguments into the extra parameter object 1629 // and forward them on to the original handler. 1630 var intercept = function (ev, extra) { 1631 return handler.apply(extra.context || this, extra.args || []); 1632 }; 1633 // mimick jQuery's internal "proxy" system (risky, I know) 1634 // causing all functions with the same .guid to appear to be the same. 1635 // https://github.com/jquery/jquery/blob/2.2.4/src/core.js#L448 1636 // this is needed for calling .off with the original non-intercept handler. 1637 if (!handler.guid) { 1638 handler.guid = $.guid++; 1639 } 1640 intercept.guid = handler.guid; 1641 return intercept; 1642 }; 1643 EmitterMixin.prototype.off = function (types, handler) { 1644 $(this).off(types, handler); 1645 return this; // for chaining 1646 }; 1647 EmitterMixin.prototype.trigger = function (types) { 1648 var args = []; 1649 for (var _i = 1; _i < arguments.length; _i++) { 1650 args[_i - 1] = arguments[_i]; 1651 } 1652 // pass in "extra" info to the intercept 1653 $(this).triggerHandler(types, { args: args }); 1654 return this; // for chaining 1655 }; 1656 EmitterMixin.prototype.triggerWith = function (types, context, args) { 1657 // `triggerHandler` is less reliant on the DOM compared to `trigger`. 1658 // pass in "extra" info to the intercept. 1659 $(this).triggerHandler(types, { context: context, args: args }); 1660 return this; // for chaining 1661 }; 1662 EmitterMixin.prototype.hasHandlers = function (type) { 1663 var hash = $._data(this, 'events'); // http://blog.jquery.com/2012/08/09/jquery-1-8-released/ 1664 return hash && hash[type] && hash[type].length > 0; 1665 }; 1666 return EmitterMixin; 1667}(Mixin_1.default)); 1668exports.default = EmitterMixin; 1669 1670 1671/***/ }), 1672/* 14 */ 1673/***/ (function(module, exports) { 1674 1675Object.defineProperty(exports, "__esModule", { value: true }); 1676var Interaction = /** @class */ (function () { 1677 function Interaction(component) { 1678 this.view = component._getView(); 1679 this.component = component; 1680 } 1681 Interaction.prototype.opt = function (name) { 1682 return this.view.opt(name); 1683 }; 1684 Interaction.prototype.end = function () { 1685 // subclasses can implement 1686 }; 1687 return Interaction; 1688}()); 1689exports.default = Interaction; 1690 1691 1692/***/ }), 1693/* 15 */ 1694/***/ (function(module, exports) { 1695 1696Object.defineProperty(exports, "__esModule", { value: true }); 1697var Mixin = /** @class */ (function () { 1698 function Mixin() { 1699 } 1700 Mixin.mixInto = function (destClass) { 1701 var _this = this; 1702 Object.getOwnPropertyNames(this.prototype).forEach(function (name) { 1703 if (!destClass.prototype[name]) { // if destination class doesn't already define it 1704 destClass.prototype[name] = _this.prototype[name]; 1705 } 1706 }); 1707 }; 1708 /* 1709 will override existing methods 1710 TODO: remove! not used anymore 1711 */ 1712 Mixin.mixOver = function (destClass) { 1713 var _this = this; 1714 Object.getOwnPropertyNames(this.prototype).forEach(function (name) { 1715 destClass.prototype[name] = _this.prototype[name]; 1716 }); 1717 }; 1718 return Mixin; 1719}()); 1720exports.default = Mixin; 1721 1722 1723/***/ }), 1724/* 16 */ 1725/***/ (function(module, exports, __webpack_require__) { 1726 1727Object.defineProperty(exports, "__esModule", { value: true }); 1728var UnzonedRange_1 = __webpack_require__(5); 1729/* 1730Meant to be immutable 1731*/ 1732var EventDateProfile = /** @class */ (function () { 1733 function EventDateProfile(start, end, calendar) { 1734 this.start = start; 1735 this.end = end || null; 1736 this.unzonedRange = this.buildUnzonedRange(calendar); 1737 } 1738 /* 1739 Needs an EventSource object 1740 */ 1741 EventDateProfile.parse = function (rawProps, source) { 1742 var startInput = rawProps.start || rawProps.date; 1743 var endInput = rawProps.end; 1744 if (!startInput) { 1745 return false; 1746 } 1747 var calendar = source.calendar; 1748 var start = calendar.moment(startInput); 1749 var end = endInput ? calendar.moment(endInput) : null; 1750 var forcedAllDay = rawProps.allDay; 1751 var forceEventDuration = calendar.opt('forceEventDuration'); 1752 if (!start.isValid()) { 1753 return false; 1754 } 1755 if (forcedAllDay == null) { 1756 forcedAllDay = source.allDayDefault; 1757 if (forcedAllDay == null) { 1758 forcedAllDay = calendar.opt('allDayDefault'); 1759 } 1760 } 1761 if (forcedAllDay === true) { 1762 start.stripTime(); 1763 if (end) { 1764 end.stripTime(); 1765 } 1766 } 1767 else if (forcedAllDay === false) { 1768 if (!start.hasTime()) { 1769 start.time(0); 1770 } 1771 if (end && !end.hasTime()) { 1772 end.time(0); 1773 } 1774 } 1775 if (end && (!end.isValid() || !end.isAfter(start))) { 1776 end = null; 1777 } 1778 if (!end && forceEventDuration) { 1779 end = calendar.getDefaultEventEnd(!start.hasTime(), start); 1780 } 1781 return new EventDateProfile(start, end, calendar); 1782 }; 1783 EventDateProfile.isStandardProp = function (propName) { 1784 return propName === 'start' || propName === 'date' || propName === 'end' || propName === 'allDay'; 1785 }; 1786 EventDateProfile.prototype.isAllDay = function () { 1787 return !(this.start.hasTime() || (this.end && this.end.hasTime())); 1788 }; 1789 /* 1790 Needs a Calendar object 1791 */ 1792 EventDateProfile.prototype.buildUnzonedRange = function (calendar) { 1793 var startMs = this.start.clone().stripZone().valueOf(); 1794 var endMs = this.getEnd(calendar).stripZone().valueOf(); 1795 return new UnzonedRange_1.default(startMs, endMs); 1796 }; 1797 /* 1798 Needs a Calendar object 1799 */ 1800 EventDateProfile.prototype.getEnd = function (calendar) { 1801 return this.end ? 1802 this.end.clone() : 1803 // derive the end from the start and allDay. compute allDay if necessary 1804 calendar.getDefaultEventEnd(this.isAllDay(), this.start); 1805 }; 1806 return EventDateProfile; 1807}()); 1808exports.default = EventDateProfile; 1809 1810 1811/***/ }), 1812/* 17 */ 1813/***/ (function(module, exports, __webpack_require__) { 1814 1815Object.defineProperty(exports, "__esModule", { value: true }); 1816var tslib_1 = __webpack_require__(2); 1817var util_1 = __webpack_require__(4); 1818var DragListener_1 = __webpack_require__(59); 1819/* Tracks mouse movements over a component and raises events about which hit the mouse is over. 1820------------------------------------------------------------------------------------------------------------------------ 1821options: 1822- subjectEl 1823- subjectCenter 1824*/ 1825var HitDragListener = /** @class */ (function (_super) { 1826 tslib_1.__extends(HitDragListener, _super); 1827 function HitDragListener(component, options) { 1828 var _this = _super.call(this, options) || this; 1829 _this.component = component; 1830 return _this; 1831 } 1832 // Called when drag listening starts (but a real drag has not necessarily began). 1833 // ev might be undefined if dragging was started manually. 1834 HitDragListener.prototype.handleInteractionStart = function (ev) { 1835 var subjectEl = this.subjectEl; 1836 var subjectRect; 1837 var origPoint; 1838 var point; 1839 this.component.hitsNeeded(); 1840 this.computeScrollBounds(); // for autoscroll 1841 if (ev) { 1842 origPoint = { left: util_1.getEvX(ev), top: util_1.getEvY(ev) }; 1843 point = origPoint; 1844 // constrain the point to bounds of the element being dragged 1845 if (subjectEl) { 1846 subjectRect = util_1.getOuterRect(subjectEl); // used for centering as well 1847 point = util_1.constrainPoint(point, subjectRect); 1848 } 1849 this.origHit = this.queryHit(point.left, point.top); 1850 // treat the center of the subject as the collision point? 1851 if (subjectEl && this.options.subjectCenter) { 1852 // only consider the area the subject overlaps the hit. best for large subjects. 1853 // TODO: skip this if hit didn't supply left/right/top/bottom 1854 if (this.origHit) { 1855 subjectRect = util_1.intersectRects(this.origHit, subjectRect) || 1856 subjectRect; // in case there is no intersection 1857 } 1858 point = util_1.getRectCenter(subjectRect); 1859 } 1860 this.coordAdjust = util_1.diffPoints(point, origPoint); // point - origPoint 1861 } 1862 else { 1863 this.origHit = null; 1864 this.coordAdjust = null; 1865 } 1866 // call the super-method. do it after origHit has been computed 1867 _super.prototype.handleInteractionStart.call(this, ev); 1868 }; 1869 // Called when the actual drag has started 1870 HitDragListener.prototype.handleDragStart = function (ev) { 1871 var hit; 1872 _super.prototype.handleDragStart.call(this, ev); 1873 // might be different from this.origHit if the min-distance is large 1874 hit = this.queryHit(util_1.getEvX(ev), util_1.getEvY(ev)); 1875 // report the initial hit the mouse is over 1876 // especially important if no min-distance and drag starts immediately 1877 if (hit) { 1878 this.handleHitOver(hit); 1879 } 1880 }; 1881 // Called when the drag moves 1882 HitDragListener.prototype.handleDrag = function (dx, dy, ev) { 1883 var hit; 1884 _super.prototype.handleDrag.call(this, dx, dy, ev); 1885 hit = this.queryHit(util_1.getEvX(ev), util_1.getEvY(ev)); 1886 if (!isHitsEqual(hit, this.hit)) { // a different hit than before? 1887 if (this.hit) { 1888 this.handleHitOut(); 1889 } 1890 if (hit) { 1891 this.handleHitOver(hit); 1892 } 1893 } 1894 }; 1895 // Called when dragging has been stopped 1896 HitDragListener.prototype.handleDragEnd = function (ev) { 1897 this.handleHitDone(); 1898 _super.prototype.handleDragEnd.call(this, ev); 1899 }; 1900 // Called when a the mouse has just moved over a new hit 1901 HitDragListener.prototype.handleHitOver = function (hit) { 1902 var isOrig = isHitsEqual(hit, this.origHit); 1903 this.hit = hit; 1904 this.trigger('hitOver', this.hit, isOrig, this.origHit); 1905 }; 1906 // Called when the mouse has just moved out of a hit 1907 HitDragListener.prototype.handleHitOut = function () { 1908 if (this.hit) { 1909 this.trigger('hitOut', this.hit); 1910 this.handleHitDone(); 1911 this.hit = null; 1912 } 1913 }; 1914 // Called after a hitOut. Also called before a dragStop 1915 HitDragListener.prototype.handleHitDone = function () { 1916 if (this.hit) { 1917 this.trigger('hitDone', this.hit); 1918 } 1919 }; 1920 // Called when the interaction ends, whether there was a real drag or not 1921 HitDragListener.prototype.handleInteractionEnd = function (ev, isCancelled) { 1922 _super.prototype.handleInteractionEnd.call(this, ev, isCancelled); 1923 this.origHit = null; 1924 this.hit = null; 1925 this.component.hitsNotNeeded(); 1926 }; 1927 // Called when scrolling has stopped, whether through auto scroll, or the user scrolling 1928 HitDragListener.prototype.handleScrollEnd = function () { 1929 _super.prototype.handleScrollEnd.call(this); 1930 // hits' absolute positions will be in new places after a user's scroll. 1931 // HACK for recomputing. 1932 if (this.isDragging) { 1933 this.component.releaseHits(); 1934 this.component.prepareHits(); 1935 } 1936 }; 1937 // Gets the hit underneath the coordinates for the given mouse event 1938 HitDragListener.prototype.queryHit = function (left, top) { 1939 if (this.coordAdjust) { 1940 left += this.coordAdjust.left; 1941 top += this.coordAdjust.top; 1942 } 1943 return this.component.queryHit(left, top); 1944 }; 1945 return HitDragListener; 1946}(DragListener_1.default)); 1947exports.default = HitDragListener; 1948// Returns `true` if the hits are identically equal. `false` otherwise. Must be from the same component. 1949// Two null values will be considered equal, as two "out of the component" states are the same. 1950function isHitsEqual(hit0, hit1) { 1951 if (!hit0 && !hit1) { 1952 return true; 1953 } 1954 if (hit0 && hit1) { 1955 return hit0.component === hit1.component && 1956 isHitPropsWithin(hit0, hit1) && 1957 isHitPropsWithin(hit1, hit0); // ensures all props are identical 1958 } 1959 return false; 1960} 1961// Returns true if all of subHit's non-standard properties are within superHit 1962function isHitPropsWithin(subHit, superHit) { 1963 for (var propName in subHit) { 1964 if (!/^(component|left|right|top|bottom)$/.test(propName)) { 1965 if (subHit[propName] !== superHit[propName]) { 1966 return false; 1967 } 1968 } 1969 } 1970 return true; 1971} 1972 1973 1974/***/ }), 1975/* 18 */ 1976/***/ (function(module, exports, __webpack_require__) { 1977 1978Object.defineProperty(exports, "__esModule", { value: true }); 1979exports.version = '3.10.5'; 1980// When introducing internal API incompatibilities (where fullcalendar plugins would break), 1981// the minor version of the calendar should be upped (ex: 2.7.2 -> 2.8.0) 1982// and the below integer should be incremented. 1983exports.internalApiVersion = 12; 1984var util_1 = __webpack_require__(4); 1985exports.applyAll = util_1.applyAll; 1986exports.debounce = util_1.debounce; 1987exports.isInt = util_1.isInt; 1988exports.htmlEscape = util_1.htmlEscape; 1989exports.cssToStr = util_1.cssToStr; 1990exports.proxy = util_1.proxy; 1991exports.capitaliseFirstLetter = util_1.capitaliseFirstLetter; 1992exports.getOuterRect = util_1.getOuterRect; 1993exports.getClientRect = util_1.getClientRect; 1994exports.getContentRect = util_1.getContentRect; 1995exports.getScrollbarWidths = util_1.getScrollbarWidths; 1996exports.preventDefault = util_1.preventDefault; 1997exports.parseFieldSpecs = util_1.parseFieldSpecs; 1998exports.compareByFieldSpecs = util_1.compareByFieldSpecs; 1999exports.compareByFieldSpec = util_1.compareByFieldSpec; 2000exports.flexibleCompare = util_1.flexibleCompare; 2001exports.computeGreatestUnit = util_1.computeGreatestUnit; 2002exports.divideRangeByDuration = util_1.divideRangeByDuration; 2003exports.divideDurationByDuration = util_1.divideDurationByDuration; 2004exports.multiplyDuration = util_1.multiplyDuration; 2005exports.durationHasTime = util_1.durationHasTime; 2006exports.log = util_1.log; 2007exports.warn = util_1.warn; 2008exports.removeExact = util_1.removeExact; 2009exports.intersectRects = util_1.intersectRects; 2010exports.allowSelection = util_1.allowSelection; 2011exports.attrsToStr = util_1.attrsToStr; 2012exports.compareNumbers = util_1.compareNumbers; 2013exports.compensateScroll = util_1.compensateScroll; 2014exports.computeDurationGreatestUnit = util_1.computeDurationGreatestUnit; 2015exports.constrainPoint = util_1.constrainPoint; 2016exports.copyOwnProps = util_1.copyOwnProps; 2017exports.diffByUnit = util_1.diffByUnit; 2018exports.diffDay = util_1.diffDay; 2019exports.diffDayTime = util_1.diffDayTime; 2020exports.diffPoints = util_1.diffPoints; 2021exports.disableCursor = util_1.disableCursor; 2022exports.distributeHeight = util_1.distributeHeight; 2023exports.enableCursor = util_1.enableCursor; 2024exports.firstDefined = util_1.firstDefined; 2025exports.getEvIsTouch = util_1.getEvIsTouch; 2026exports.getEvX = util_1.getEvX; 2027exports.getEvY = util_1.getEvY; 2028exports.getRectCenter = util_1.getRectCenter; 2029exports.getScrollParent = util_1.getScrollParent; 2030exports.hasOwnProp = util_1.hasOwnProp; 2031exports.isArraysEqual = util_1.isArraysEqual; 2032exports.isNativeDate = util_1.isNativeDate; 2033exports.isPrimaryMouseButton = util_1.isPrimaryMouseButton; 2034exports.isTimeString = util_1.isTimeString; 2035exports.matchCellWidths = util_1.matchCellWidths; 2036exports.mergeProps = util_1.mergeProps; 2037exports.preventSelection = util_1.preventSelection; 2038exports.removeMatching = util_1.removeMatching; 2039exports.stripHtmlEntities = util_1.stripHtmlEntities; 2040exports.subtractInnerElHeight = util_1.subtractInnerElHeight; 2041exports.uncompensateScroll = util_1.uncompensateScroll; 2042exports.undistributeHeight = util_1.undistributeHeight; 2043exports.dayIDs = util_1.dayIDs; 2044exports.unitsDesc = util_1.unitsDesc; 2045var date_formatting_1 = __webpack_require__(49); 2046exports.formatDate = date_formatting_1.formatDate; 2047exports.formatRange = date_formatting_1.formatRange; 2048exports.queryMostGranularFormatUnit = date_formatting_1.queryMostGranularFormatUnit; 2049var locale_1 = __webpack_require__(32); 2050exports.datepickerLocale = locale_1.datepickerLocale; 2051exports.locale = locale_1.locale; 2052exports.getMomentLocaleData = locale_1.getMomentLocaleData; 2053exports.populateInstanceComputableOptions = locale_1.populateInstanceComputableOptions; 2054var util_2 = __webpack_require__(19); 2055exports.eventDefsToEventInstances = util_2.eventDefsToEventInstances; 2056exports.eventFootprintToComponentFootprint = util_2.eventFootprintToComponentFootprint; 2057exports.eventInstanceToEventRange = util_2.eventInstanceToEventRange; 2058exports.eventInstanceToUnzonedRange = util_2.eventInstanceToUnzonedRange; 2059exports.eventRangeToEventFootprint = util_2.eventRangeToEventFootprint; 2060var moment_ext_1 = __webpack_require__(11); 2061exports.moment = moment_ext_1.default; 2062var EmitterMixin_1 = __webpack_require__(13); 2063exports.EmitterMixin = EmitterMixin_1.default; 2064var ListenerMixin_1 = __webpack_require__(7); 2065exports.ListenerMixin = ListenerMixin_1.default; 2066var Model_1 = __webpack_require__(51); 2067exports.Model = Model_1.default; 2068var Constraints_1 = __webpack_require__(217); 2069exports.Constraints = Constraints_1.default; 2070var DateProfileGenerator_1 = __webpack_require__(55); 2071exports.DateProfileGenerator = DateProfileGenerator_1.default; 2072var UnzonedRange_1 = __webpack_require__(5); 2073exports.UnzonedRange = UnzonedRange_1.default; 2074var ComponentFootprint_1 = __webpack_require__(12); 2075exports.ComponentFootprint = ComponentFootprint_1.default; 2076var BusinessHourGenerator_1 = __webpack_require__(218); 2077exports.BusinessHourGenerator = BusinessHourGenerator_1.default; 2078var EventPeriod_1 = __webpack_require__(219); 2079exports.EventPeriod = EventPeriod_1.default; 2080var EventManager_1 = __webpack_require__(220); 2081exports.EventManager = EventManager_1.default; 2082var EventDef_1 = __webpack_require__(37); 2083exports.EventDef = EventDef_1.default; 2084var EventDefMutation_1 = __webpack_require__(39); 2085exports.EventDefMutation = EventDefMutation_1.default; 2086var EventDefParser_1 = __webpack_require__(36); 2087exports.EventDefParser = EventDefParser_1.default; 2088var EventInstance_1 = __webpack_require__(53); 2089exports.EventInstance = EventInstance_1.default; 2090var EventRange_1 = __webpack_require__(50); 2091exports.EventRange = EventRange_1.default; 2092var RecurringEventDef_1 = __webpack_require__(54); 2093exports.RecurringEventDef = RecurringEventDef_1.default; 2094var SingleEventDef_1 = __webpack_require__(9); 2095exports.SingleEventDef = SingleEventDef_1.default; 2096var EventDefDateMutation_1 = __webpack_require__(40); 2097exports.EventDefDateMutation = EventDefDateMutation_1.default; 2098var EventDateProfile_1 = __webpack_require__(16); 2099exports.EventDateProfile = EventDateProfile_1.default; 2100var EventSourceParser_1 = __webpack_require__(38); 2101exports.EventSourceParser = EventSourceParser_1.default; 2102var EventSource_1 = __webpack_require__(6); 2103exports.EventSource = EventSource_1.default; 2104var ThemeRegistry_1 = __webpack_require__(57); 2105exports.defineThemeSystem = ThemeRegistry_1.defineThemeSystem; 2106exports.getThemeSystemClass = ThemeRegistry_1.getThemeSystemClass; 2107var EventInstanceGroup_1 = __webpack_require__(20); 2108exports.EventInstanceGroup = EventInstanceGroup_1.default; 2109var ArrayEventSource_1 = __webpack_require__(56); 2110exports.ArrayEventSource = ArrayEventSource_1.default; 2111var FuncEventSource_1 = __webpack_require__(223); 2112exports.FuncEventSource = FuncEventSource_1.default; 2113var JsonFeedEventSource_1 = __webpack_require__(224); 2114exports.JsonFeedEventSource = JsonFeedEventSource_1.default; 2115var EventFootprint_1 = __webpack_require__(34); 2116exports.EventFootprint = EventFootprint_1.default; 2117var Class_1 = __webpack_require__(35); 2118exports.Class = Class_1.default; 2119var Mixin_1 = __webpack_require__(15); 2120exports.Mixin = Mixin_1.default; 2121var CoordCache_1 = __webpack_require__(58); 2122exports.CoordCache = CoordCache_1.default; 2123var Iterator_1 = __webpack_require__(225); 2124exports.Iterator = Iterator_1.default; 2125var DragListener_1 = __webpack_require__(59); 2126exports.DragListener = DragListener_1.default; 2127var HitDragListener_1 = __webpack_require__(17); 2128exports.HitDragListener = HitDragListener_1.default; 2129var MouseFollower_1 = __webpack_require__(226); 2130exports.MouseFollower = MouseFollower_1.default; 2131var ParsableModelMixin_1 = __webpack_require__(52); 2132exports.ParsableModelMixin = ParsableModelMixin_1.default; 2133var Popover_1 = __webpack_require__(227); 2134exports.Popover = Popover_1.default; 2135var Promise_1 = __webpack_require__(21); 2136exports.Promise = Promise_1.default; 2137var TaskQueue_1 = __webpack_require__(228); 2138exports.TaskQueue = TaskQueue_1.default; 2139var RenderQueue_1 = __webpack_require__(229); 2140exports.RenderQueue = RenderQueue_1.default; 2141var Scroller_1 = __webpack_require__(41); 2142exports.Scroller = Scroller_1.default; 2143var Theme_1 = __webpack_require__(22); 2144exports.Theme = Theme_1.default; 2145var Component_1 = __webpack_require__(230); 2146exports.Component = Component_1.default; 2147var DateComponent_1 = __webpack_require__(231); 2148exports.DateComponent = DateComponent_1.default; 2149var InteractiveDateComponent_1 = __webpack_require__(42); 2150exports.InteractiveDateComponent = InteractiveDateComponent_1.default; 2151var Calendar_1 = __webpack_require__(232); 2152exports.Calendar = Calendar_1.default; 2153var View_1 = __webpack_require__(43); 2154exports.View = View_1.default; 2155var ViewRegistry_1 = __webpack_require__(24); 2156exports.defineView = ViewRegistry_1.defineView; 2157exports.getViewConfig = ViewRegistry_1.getViewConfig; 2158var DayTableMixin_1 = __webpack_require__(60); 2159exports.DayTableMixin = DayTableMixin_1.default; 2160var BusinessHourRenderer_1 = __webpack_require__(61); 2161exports.BusinessHourRenderer = BusinessHourRenderer_1.default; 2162var EventRenderer_1 = __webpack_require__(44); 2163exports.EventRenderer = EventRenderer_1.default; 2164var FillRenderer_1 = __webpack_require__(62); 2165exports.FillRenderer = FillRenderer_1.default; 2166var HelperRenderer_1 = __webpack_require__(63); 2167exports.HelperRenderer = HelperRenderer_1.default; 2168var ExternalDropping_1 = __webpack_require__(233); 2169exports.ExternalDropping = ExternalDropping_1.default; 2170var EventResizing_1 = __webpack_require__(234); 2171exports.EventResizing = EventResizing_1.default; 2172var EventPointing_1 = __webpack_require__(64); 2173exports.EventPointing = EventPointing_1.default; 2174var EventDragging_1 = __webpack_require__(235); 2175exports.EventDragging = EventDragging_1.default; 2176var DateSelecting_1 = __webpack_require__(236); 2177exports.DateSelecting = DateSelecting_1.default; 2178var DateClicking_1 = __webpack_require__(237); 2179exports.DateClicking = DateClicking_1.default; 2180var Interaction_1 = __webpack_require__(14); 2181exports.Interaction = Interaction_1.default; 2182var StandardInteractionsMixin_1 = __webpack_require__(65); 2183exports.StandardInteractionsMixin = StandardInteractionsMixin_1.default; 2184var AgendaView_1 = __webpack_require__(238); 2185exports.AgendaView = AgendaView_1.default; 2186var TimeGrid_1 = __webpack_require__(239); 2187exports.TimeGrid = TimeGrid_1.default; 2188var TimeGridEventRenderer_1 = __webpack_require__(240); 2189exports.TimeGridEventRenderer = TimeGridEventRenderer_1.default; 2190var TimeGridFillRenderer_1 = __webpack_require__(242); 2191exports.TimeGridFillRenderer = TimeGridFillRenderer_1.default; 2192var TimeGridHelperRenderer_1 = __webpack_require__(241); 2193exports.TimeGridHelperRenderer = TimeGridHelperRenderer_1.default; 2194var DayGrid_1 = __webpack_require__(66); 2195exports.DayGrid = DayGrid_1.default; 2196var DayGridEventRenderer_1 = __webpack_require__(243); 2197exports.DayGridEventRenderer = DayGridEventRenderer_1.default; 2198var DayGridFillRenderer_1 = __webpack_require__(245); 2199exports.DayGridFillRenderer = DayGridFillRenderer_1.default; 2200var DayGridHelperRenderer_1 = __webpack_require__(244); 2201exports.DayGridHelperRenderer = DayGridHelperRenderer_1.default; 2202var BasicView_1 = __webpack_require__(67); 2203exports.BasicView = BasicView_1.default; 2204var BasicViewDateProfileGenerator_1 = __webpack_require__(68); 2205exports.BasicViewDateProfileGenerator = BasicViewDateProfileGenerator_1.default; 2206var MonthView_1 = __webpack_require__(246); 2207exports.MonthView = MonthView_1.default; 2208var MonthViewDateProfileGenerator_1 = __webpack_require__(247); 2209exports.MonthViewDateProfileGenerator = MonthViewDateProfileGenerator_1.default; 2210var ListView_1 = __webpack_require__(248); 2211exports.ListView = ListView_1.default; 2212var ListEventPointing_1 = __webpack_require__(250); 2213exports.ListEventPointing = ListEventPointing_1.default; 2214var ListEventRenderer_1 = __webpack_require__(249); 2215exports.ListEventRenderer = ListEventRenderer_1.default; 2216 2217 2218/***/ }), 2219/* 19 */ 2220/***/ (function(module, exports, __webpack_require__) { 2221 2222Object.defineProperty(exports, "__esModule", { value: true }); 2223var EventRange_1 = __webpack_require__(50); 2224var EventFootprint_1 = __webpack_require__(34); 2225var ComponentFootprint_1 = __webpack_require__(12); 2226function eventDefsToEventInstances(eventDefs, unzonedRange) { 2227 var eventInstances = []; 2228 var i; 2229 for (i = 0; i < eventDefs.length; i++) { 2230 eventInstances.push.apply(eventInstances, // append 2231 eventDefs[i].buildInstances(unzonedRange)); 2232 } 2233 return eventInstances; 2234} 2235exports.eventDefsToEventInstances = eventDefsToEventInstances; 2236function eventInstanceToEventRange(eventInstance) { 2237 return new EventRange_1.default(eventInstance.dateProfile.unzonedRange, eventInstance.def, eventInstance); 2238} 2239exports.eventInstanceToEventRange = eventInstanceToEventRange; 2240function eventRangeToEventFootprint(eventRange) { 2241 return new EventFootprint_1.default(new ComponentFootprint_1.default(eventRange.unzonedRange, eventRange.eventDef.isAllDay()), eventRange.eventDef, eventRange.eventInstance // might not exist 2242 ); 2243} 2244exports.eventRangeToEventFootprint = eventRangeToEventFootprint; 2245function eventInstanceToUnzonedRange(eventInstance) { 2246 return eventInstance.dateProfile.unzonedRange; 2247} 2248exports.eventInstanceToUnzonedRange = eventInstanceToUnzonedRange; 2249function eventFootprintToComponentFootprint(eventFootprint) { 2250 return eventFootprint.componentFootprint; 2251} 2252exports.eventFootprintToComponentFootprint = eventFootprintToComponentFootprint; 2253 2254 2255/***/ }), 2256/* 20 */ 2257/***/ (function(module, exports, __webpack_require__) { 2258 2259Object.defineProperty(exports, "__esModule", { value: true }); 2260var UnzonedRange_1 = __webpack_require__(5); 2261var util_1 = __webpack_require__(19); 2262var EventRange_1 = __webpack_require__(50); 2263/* 2264It's expected that there will be at least one EventInstance, 2265OR that an explicitEventDef is assigned. 2266*/ 2267var EventInstanceGroup = /** @class */ (function () { 2268 function EventInstanceGroup(eventInstances) { 2269 this.eventInstances = eventInstances || []; 2270 } 2271 EventInstanceGroup.prototype.getAllEventRanges = function (constraintRange) { 2272 if (constraintRange) { 2273 return this.sliceNormalRenderRanges(constraintRange); 2274 } 2275 else { 2276 return this.eventInstances.map(util_1.eventInstanceToEventRange); 2277 } 2278 }; 2279 EventInstanceGroup.prototype.sliceRenderRanges = function (constraintRange) { 2280 if (this.isInverse()) { 2281 return this.sliceInverseRenderRanges(constraintRange); 2282 } 2283 else { 2284 return this.sliceNormalRenderRanges(constraintRange); 2285 } 2286 }; 2287 EventInstanceGroup.prototype.sliceNormalRenderRanges = function (constraintRange) { 2288 var eventInstances = this.eventInstances; 2289 var i; 2290 var eventInstance; 2291 var slicedRange; 2292 var slicedEventRanges = []; 2293 for (i = 0; i < eventInstances.length; i++) { 2294 eventInstance = eventInstances[i]; 2295 slicedRange = eventInstance.dateProfile.unzonedRange.intersect(constraintRange); 2296 if (slicedRange) { 2297 slicedEventRanges.push(new EventRange_1.default(slicedRange, eventInstance.def, eventInstance)); 2298 } 2299 } 2300 return slicedEventRanges; 2301 }; 2302 EventInstanceGroup.prototype.sliceInverseRenderRanges = function (constraintRange) { 2303 var unzonedRanges = this.eventInstances.map(util_1.eventInstanceToUnzonedRange); 2304 var ownerDef = this.getEventDef(); 2305 unzonedRanges = UnzonedRange_1.default.invertRanges(unzonedRanges, constraintRange); 2306 return unzonedRanges.map(function (unzonedRange) { 2307 return new EventRange_1.default(unzonedRange, ownerDef); // don't give an EventInstance 2308 }); 2309 }; 2310 EventInstanceGroup.prototype.isInverse = function () { 2311 return this.getEventDef().hasInverseRendering(); 2312 }; 2313 EventInstanceGroup.prototype.getEventDef = function () { 2314 return this.explicitEventDef || this.eventInstances[0].def; 2315 }; 2316 return EventInstanceGroup; 2317}()); 2318exports.default = EventInstanceGroup; 2319 2320 2321/***/ }), 2322/* 21 */ 2323/***/ (function(module, exports, __webpack_require__) { 2324 2325Object.defineProperty(exports, "__esModule", { value: true }); 2326var $ = __webpack_require__(3); 2327var PromiseStub = { 2328 construct: function (executor) { 2329 var deferred = $.Deferred(); 2330 var promise = deferred.promise(); 2331 if (typeof executor === 'function') { 2332 executor(function (val) { 2333 deferred.resolve(val); 2334 attachImmediatelyResolvingThen(promise, val); 2335 }, function () { 2336 deferred.reject(); 2337 attachImmediatelyRejectingThen(promise); 2338 }); 2339 } 2340 return promise; 2341 }, 2342 resolve: function (val) { 2343 var deferred = $.Deferred().resolve(val); 2344 var promise = deferred.promise(); 2345 attachImmediatelyResolvingThen(promise, val); 2346 return promise; 2347 }, 2348 reject: function () { 2349 var deferred = $.Deferred().reject(); 2350 var promise = deferred.promise(); 2351 attachImmediatelyRejectingThen(promise); 2352 return promise; 2353 } 2354}; 2355exports.default = PromiseStub; 2356function attachImmediatelyResolvingThen(promise, val) { 2357 promise.then = function (onResolve) { 2358 if (typeof onResolve === 'function') { 2359 return PromiseStub.resolve(onResolve(val)); 2360 } 2361 return promise; 2362 }; 2363} 2364function attachImmediatelyRejectingThen(promise) { 2365 promise.then = function (onResolve, onReject) { 2366 if (typeof onReject === 'function') { 2367 onReject(); 2368 } 2369 return promise; 2370 }; 2371} 2372 2373 2374/***/ }), 2375/* 22 */ 2376/***/ (function(module, exports, __webpack_require__) { 2377 2378Object.defineProperty(exports, "__esModule", { value: true }); 2379var $ = __webpack_require__(3); 2380var Theme = /** @class */ (function () { 2381 function Theme(optionsManager) { 2382 this.optionsManager = optionsManager; 2383 this.processIconOverride(); 2384 } 2385 Theme.prototype.processIconOverride = function () { 2386 if (this.iconOverrideOption) { 2387 this.setIconOverride(this.optionsManager.get(this.iconOverrideOption)); 2388 } 2389 }; 2390 Theme.prototype.setIconOverride = function (iconOverrideHash) { 2391 var iconClassesCopy; 2392 var buttonName; 2393 if ($.isPlainObject(iconOverrideHash)) { 2394 iconClassesCopy = $.extend({}, this.iconClasses); 2395 for (buttonName in iconOverrideHash) { 2396 iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]); 2397 } 2398 this.iconClasses = iconClassesCopy; 2399 } 2400 else if (iconOverrideHash === false) { 2401 this.iconClasses = {}; 2402 } 2403 }; 2404 Theme.prototype.applyIconOverridePrefix = function (className) { 2405 var prefix = this.iconOverridePrefix; 2406 if (prefix && className.indexOf(prefix) !== 0) { // if not already present 2407 className = prefix + className; 2408 } 2409 return className; 2410 }; 2411 Theme.prototype.getClass = function (key) { 2412 return this.classes[key] || ''; 2413 }; 2414 Theme.prototype.getIconClass = function (buttonName) { 2415 var className = this.iconClasses[buttonName]; 2416 if (className) { 2417 return this.baseIconClass + ' ' + className; 2418 } 2419 return ''; 2420 }; 2421 Theme.prototype.getCustomButtonIconClass = function (customButtonProps) { 2422 var className; 2423 if (this.iconOverrideCustomButtonOption) { 2424 className = customButtonProps[this.iconOverrideCustomButtonOption]; 2425 if (className) { 2426 return this.baseIconClass + ' ' + this.applyIconOverridePrefix(className); 2427 } 2428 } 2429 return ''; 2430 }; 2431 return Theme; 2432}()); 2433exports.default = Theme; 2434Theme.prototype.classes = {}; 2435Theme.prototype.iconClasses = {}; 2436Theme.prototype.baseIconClass = ''; 2437Theme.prototype.iconOverridePrefix = ''; 2438 2439 2440/***/ }), 2441/* 23 */ 2442/***/ (function(module, exports, __webpack_require__) { 2443 2444Object.defineProperty(exports, "__esModule", { value: true }); 2445var $ = __webpack_require__(3); 2446var exportHooks = __webpack_require__(18); 2447var EmitterMixin_1 = __webpack_require__(13); 2448var ListenerMixin_1 = __webpack_require__(7); 2449exportHooks.touchMouseIgnoreWait = 500; 2450var globalEmitter = null; 2451var neededCount = 0; 2452/* 2453Listens to document and window-level user-interaction events, like touch events and mouse events, 2454and fires these events as-is to whoever is observing a GlobalEmitter. 2455Best when used as a singleton via GlobalEmitter.get() 2456 2457Normalizes mouse/touch events. For examples: 2458- ignores the the simulated mouse events that happen after a quick tap: mousemove+mousedown+mouseup+click 2459- compensates for various buggy scenarios where a touchend does not fire 2460*/ 2461var GlobalEmitter = /** @class */ (function () { 2462 function GlobalEmitter() { 2463 this.isTouching = false; 2464 this.mouseIgnoreDepth = 0; 2465 } 2466 // gets the singleton 2467 GlobalEmitter.get = function () { 2468 if (!globalEmitter) { 2469 globalEmitter = new GlobalEmitter(); 2470 globalEmitter.bind(); 2471 } 2472 return globalEmitter; 2473 }; 2474 // called when an object knows it will need a GlobalEmitter in the near future. 2475 GlobalEmitter.needed = function () { 2476 GlobalEmitter.get(); // ensures globalEmitter 2477 neededCount++; 2478 }; 2479 // called when the object that originally called needed() doesn't need a GlobalEmitter anymore. 2480 GlobalEmitter.unneeded = function () { 2481 neededCount--; 2482 if (!neededCount) { // nobody else needs it 2483 globalEmitter.unbind(); 2484 globalEmitter = null; 2485 } 2486 }; 2487 GlobalEmitter.prototype.bind = function () { 2488 var _this = this; 2489 this.listenTo($(document), { 2490 touchstart: this.handleTouchStart, 2491 touchcancel: this.handleTouchCancel, 2492 touchend: this.handleTouchEnd, 2493 mousedown: this.handleMouseDown, 2494 mousemove: this.handleMouseMove, 2495 mouseup: this.handleMouseUp, 2496 click: this.handleClick, 2497 selectstart: this.handleSelectStart, 2498 contextmenu: this.handleContextMenu 2499 }); 2500 // because we need to call preventDefault 2501 // because https://www.chromestatus.com/features/5093566007214080 2502 // TODO: investigate performance because this is a global handler 2503 window.addEventListener('touchmove', this.handleTouchMoveProxy = function (ev) { 2504 _this.handleTouchMove($.Event(ev)); 2505 }, { passive: false } // allows preventDefault() 2506 ); 2507 // attach a handler to get called when ANY scroll action happens on the page. 2508 // this was impossible to do with normal on/off because 'scroll' doesn't bubble. 2509 // http://stackoverflow.com/a/32954565/96342 2510 window.addEventListener('scroll', this.handleScrollProxy = function (ev) { 2511 _this.handleScroll($.Event(ev)); 2512 }, true // useCapture 2513 ); 2514 }; 2515 GlobalEmitter.prototype.unbind = function () { 2516 this.stopListeningTo($(document)); 2517 window.removeEventListener('touchmove', this.handleTouchMoveProxy, { passive: false } // use same options as addEventListener 2518 ); 2519 window.removeEventListener('scroll', this.handleScrollProxy, true // useCapture 2520 ); 2521 }; 2522 // Touch Handlers 2523 // ----------------------------------------------------------------------------------------------------------------- 2524 GlobalEmitter.prototype.handleTouchStart = function (ev) { 2525 // if a previous touch interaction never ended with a touchend, then implicitly end it, 2526 // but since a new touch interaction is about to begin, don't start the mouse ignore period. 2527 this.stopTouch(ev, true); // skipMouseIgnore=true 2528 this.isTouching = true; 2529 this.trigger('touchstart', ev); 2530 }; 2531 GlobalEmitter.prototype.handleTouchMove = function (ev) { 2532 if (this.isTouching) { 2533 this.trigger('touchmove', ev); 2534 } 2535 }; 2536 GlobalEmitter.prototype.handleTouchCancel = function (ev) { 2537 if (this.isTouching) { 2538 this.trigger('touchcancel', ev); 2539 // Have touchcancel fire an artificial touchend. That way, handlers won't need to listen to both. 2540 // If touchend fires later, it won't have any effect b/c isTouching will be false. 2541 this.stopTouch(ev); 2542 } 2543 }; 2544 GlobalEmitter.prototype.handleTouchEnd = function (ev) { 2545 this.stopTouch(ev); 2546 }; 2547 // Mouse Handlers 2548 // ----------------------------------------------------------------------------------------------------------------- 2549 GlobalEmitter.prototype.handleMouseDown = function (ev) { 2550 if (!this.shouldIgnoreMouse()) { 2551 this.trigger('mousedown', ev); 2552 } 2553 }; 2554 GlobalEmitter.prototype.handleMouseMove = function (ev) { 2555 if (!this.shouldIgnoreMouse()) { 2556 this.trigger('mousemove', ev); 2557 } 2558 }; 2559 GlobalEmitter.prototype.handleMouseUp = function (ev) { 2560 if (!this.shouldIgnoreMouse()) { 2561 this.trigger('mouseup', ev); 2562 } 2563 }; 2564 GlobalEmitter.prototype.handleClick = function (ev) { 2565 if (!this.shouldIgnoreMouse()) { 2566 this.trigger('click', ev); 2567 } 2568 }; 2569 // Misc Handlers 2570 // ----------------------------------------------------------------------------------------------------------------- 2571 GlobalEmitter.prototype.handleSelectStart = function (ev) { 2572 this.trigger('selectstart', ev); 2573 }; 2574 GlobalEmitter.prototype.handleContextMenu = function (ev) { 2575 this.trigger('contextmenu', ev); 2576 }; 2577 GlobalEmitter.prototype.handleScroll = function (ev) { 2578 this.trigger('scroll', ev); 2579 }; 2580 // Utils 2581 // ----------------------------------------------------------------------------------------------------------------- 2582 GlobalEmitter.prototype.stopTouch = function (ev, skipMouseIgnore) { 2583 if (skipMouseIgnore === void 0) { skipMouseIgnore = false; } 2584 if (this.isTouching) { 2585 this.isTouching = false; 2586 this.trigger('touchend', ev); 2587 if (!skipMouseIgnore) { 2588 this.startTouchMouseIgnore(); 2589 } 2590 } 2591 }; 2592 GlobalEmitter.prototype.startTouchMouseIgnore = function () { 2593 var _this = this; 2594 var wait = exportHooks.touchMouseIgnoreWait; 2595 if (wait) { 2596 this.mouseIgnoreDepth++; 2597 setTimeout(function () { 2598 _this.mouseIgnoreDepth--; 2599 }, wait); 2600 } 2601 }; 2602 GlobalEmitter.prototype.shouldIgnoreMouse = function () { 2603 return this.isTouching || Boolean(this.mouseIgnoreDepth); 2604 }; 2605 return GlobalEmitter; 2606}()); 2607exports.default = GlobalEmitter; 2608ListenerMixin_1.default.mixInto(GlobalEmitter); 2609EmitterMixin_1.default.mixInto(GlobalEmitter); 2610 2611 2612/***/ }), 2613/* 24 */ 2614/***/ (function(module, exports, __webpack_require__) { 2615 2616Object.defineProperty(exports, "__esModule", { value: true }); 2617var exportHooks = __webpack_require__(18); 2618exports.viewHash = {}; 2619exportHooks.views = exports.viewHash; 2620function defineView(viewName, viewConfig) { 2621 exports.viewHash[viewName] = viewConfig; 2622} 2623exports.defineView = defineView; 2624function getViewConfig(viewName) { 2625 return exports.viewHash[viewName]; 2626} 2627exports.getViewConfig = getViewConfig; 2628 2629 2630/***/ }), 2631/* 25 */, 2632/* 26 */, 2633/* 27 */, 2634/* 28 */, 2635/* 29 */, 2636/* 30 */, 2637/* 31 */, 2638/* 32 */ 2639/***/ (function(module, exports, __webpack_require__) { 2640 2641Object.defineProperty(exports, "__esModule", { value: true }); 2642var $ = __webpack_require__(3); 2643var moment = __webpack_require__(0); 2644var exportHooks = __webpack_require__(18); 2645var options_1 = __webpack_require__(33); 2646var util_1 = __webpack_require__(4); 2647exports.localeOptionHash = {}; 2648exportHooks.locales = exports.localeOptionHash; 2649// NOTE: can't guarantee any of these computations will run because not every locale has datepicker 2650// configs, so make sure there are English fallbacks for these in the defaults file. 2651var dpComputableOptions = { 2652 buttonText: function (dpOptions) { 2653 return { 2654 // the translations sometimes wrongly contain HTML entities 2655 prev: util_1.stripHtmlEntities(dpOptions.prevText), 2656 next: util_1.stripHtmlEntities(dpOptions.nextText), 2657 today: util_1.stripHtmlEntities(dpOptions.currentText) 2658 }; 2659 }, 2660 // Produces format strings like "MMMM YYYY" -> "September 2014" 2661 monthYearFormat: function (dpOptions) { 2662 return dpOptions.showMonthAfterYear ? 2663 'YYYY[' + dpOptions.yearSuffix + '] MMMM' : 2664 'MMMM YYYY[' + dpOptions.yearSuffix + ']'; 2665 } 2666}; 2667var momComputableOptions = { 2668 // Produces format strings like "ddd M/D" -> "Fri 9/15" 2669 dayOfMonthFormat: function (momOptions, fcOptions) { 2670 var format = momOptions.longDateFormat('l'); // for the format like "M/D/YYYY" 2671 // strip the year off the edge, as well as other misc non-whitespace chars 2672 format = format.replace(/^Y+[^\w\s]*|[^\w\s]*Y+$/g, ''); 2673 if (fcOptions.isRTL) { 2674 format += ' ddd'; // for RTL, add day-of-week to end 2675 } 2676 else { 2677 format = 'ddd ' + format; // for LTR, add day-of-week to beginning 2678 } 2679 return format; 2680 }, 2681 // Produces format strings like "h:mma" -> "6:00pm" 2682 mediumTimeFormat: function (momOptions) { 2683 return momOptions.longDateFormat('LT') 2684 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand 2685 }, 2686 // Produces format strings like "h(:mm)a" -> "6pm" / "6:30pm" 2687 smallTimeFormat: function (momOptions) { 2688 return momOptions.longDateFormat('LT') 2689 .replace(':mm', '(:mm)') 2690 .replace(/(\Wmm)$/, '($1)') // like above, but for foreign locales 2691 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand 2692 }, 2693 // Produces format strings like "h(:mm)t" -> "6p" / "6:30p" 2694 extraSmallTimeFormat: function (momOptions) { 2695 return momOptions.longDateFormat('LT') 2696 .replace(':mm', '(:mm)') 2697 .replace(/(\Wmm)$/, '($1)') // like above, but for foreign locales 2698 .replace(/\s*a$/i, 't'); // convert to AM/PM/am/pm to lowercase one-letter. remove any spaces beforehand 2699 }, 2700 // Produces format strings like "ha" / "H" -> "6pm" / "18" 2701 hourFormat: function (momOptions) { 2702 return momOptions.longDateFormat('LT') 2703 .replace(':mm', '') 2704 .replace(/(\Wmm)$/, '') // like above, but for foreign locales 2705 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand 2706 }, 2707 // Produces format strings like "h:mm" -> "6:30" (with no AM/PM) 2708 noMeridiemTimeFormat: function (momOptions) { 2709 return momOptions.longDateFormat('LT') 2710 .replace(/\s*a$/i, ''); // remove trailing AM/PM 2711 } 2712}; 2713// options that should be computed off live calendar options (considers override options) 2714// TODO: best place for this? related to locale? 2715// TODO: flipping text based on isRTL is a bad idea because the CSS `direction` might want to handle it 2716var instanceComputableOptions = { 2717 // Produces format strings for results like "Mo 16" 2718 smallDayDateFormat: function (options) { 2719 return options.isRTL ? 2720 'D dd' : 2721 'dd D'; 2722 }, 2723 // Produces format strings for results like "Wk 5" 2724 weekFormat: function (options) { 2725 return options.isRTL ? 2726 'w[ ' + options.weekNumberTitle + ']' : 2727 '[' + options.weekNumberTitle + ' ]w'; 2728 }, 2729 // Produces format strings for results like "Wk5" 2730 smallWeekFormat: function (options) { 2731 return options.isRTL ? 2732 'w[' + options.weekNumberTitle + ']' : 2733 '[' + options.weekNumberTitle + ']w'; 2734 } 2735}; 2736// TODO: make these computable properties in optionsManager 2737function populateInstanceComputableOptions(options) { 2738 $.each(instanceComputableOptions, function (name, func) { 2739 if (options[name] == null) { 2740 options[name] = func(options); 2741 } 2742 }); 2743} 2744exports.populateInstanceComputableOptions = populateInstanceComputableOptions; 2745// Initialize jQuery UI datepicker translations while using some of the translations 2746// Will set this as the default locales for datepicker. 2747function datepickerLocale(localeCode, dpLocaleCode, dpOptions) { 2748 // get the FullCalendar internal option hash for this locale. create if necessary 2749 var fcOptions = exports.localeOptionHash[localeCode] || (exports.localeOptionHash[localeCode] = {}); 2750 // transfer some simple options from datepicker to fc 2751 fcOptions.isRTL = dpOptions.isRTL; 2752 fcOptions.weekNumberTitle = dpOptions.weekHeader; 2753 // compute some more complex options from datepicker 2754 $.each(dpComputableOptions, function (name, func) { 2755 fcOptions[name] = func(dpOptions); 2756 }); 2757 var jqDatePicker = $.datepicker; 2758 // is jQuery UI Datepicker is on the page? 2759 if (jqDatePicker) { 2760 // Register the locale data. 2761 // FullCalendar and MomentJS use locale codes like "pt-br" but Datepicker 2762 // does it like "pt-BR" or if it doesn't have the locale, maybe just "pt". 2763 // Make an alias so the locale can be referenced either way. 2764 jqDatePicker.regional[dpLocaleCode] = 2765 jqDatePicker.regional[localeCode] = // alias 2766 dpOptions; 2767 // Alias 'en' to the default locale data. Do this every time. 2768 jqDatePicker.regional.en = jqDatePicker.regional['']; 2769 // Set as Datepicker's global defaults. 2770 jqDatePicker.setDefaults(dpOptions); 2771 } 2772} 2773exports.datepickerLocale = datepickerLocale; 2774// Sets FullCalendar-specific translations. Will set the locales as the global default. 2775function locale(localeCode, newFcOptions) { 2776 var fcOptions; 2777 var momOptions; 2778 // get the FullCalendar internal option hash for this locale. create if necessary 2779 fcOptions = exports.localeOptionHash[localeCode] || (exports.localeOptionHash[localeCode] = {}); 2780 // provided new options for this locales? merge them in 2781 if (newFcOptions) { 2782 fcOptions = exports.localeOptionHash[localeCode] = options_1.mergeOptions([fcOptions, newFcOptions]); 2783 } 2784 // compute locale options that weren't defined. 2785 // always do this. newFcOptions can be undefined when initializing from i18n file, 2786 // so no way to tell if this is an initialization or a default-setting. 2787 momOptions = getMomentLocaleData(localeCode); // will fall back to en 2788 $.each(momComputableOptions, function (name, func) { 2789 if (fcOptions[name] == null) { 2790 fcOptions[name] = (func)(momOptions, fcOptions); 2791 } 2792 }); 2793 // set it as the default locale for FullCalendar 2794 options_1.globalDefaults.locale = localeCode; 2795} 2796exports.locale = locale; 2797// Returns moment's internal locale data. If doesn't exist, returns English. 2798function getMomentLocaleData(localeCode) { 2799 return moment.localeData(localeCode) || moment.localeData('en'); 2800} 2801exports.getMomentLocaleData = getMomentLocaleData; 2802// Initialize English by forcing computation of moment-derived options. 2803// Also, sets it as the default. 2804locale('en', options_1.englishDefaults); 2805 2806 2807/***/ }), 2808/* 33 */ 2809/***/ (function(module, exports, __webpack_require__) { 2810 2811Object.defineProperty(exports, "__esModule", { value: true }); 2812var util_1 = __webpack_require__(4); 2813exports.globalDefaults = { 2814 titleRangeSeparator: ' \u2013 ', 2815 monthYearFormat: 'MMMM YYYY', 2816 defaultTimedEventDuration: '02:00:00', 2817 defaultAllDayEventDuration: { days: 1 }, 2818 forceEventDuration: false, 2819 nextDayThreshold: '09:00:00', 2820 // display 2821 columnHeader: true, 2822 defaultView: 'month', 2823 aspectRatio: 1.35, 2824 header: { 2825 left: 'title', 2826 center: '', 2827 right: 'today prev,next' 2828 }, 2829 weekends: true, 2830 weekNumbers: false, 2831 weekNumberTitle: 'W', 2832 weekNumberCalculation: 'local', 2833 // editable: false, 2834 // nowIndicator: false, 2835 scrollTime: '06:00:00', 2836 minTime: '00:00:00', 2837 maxTime: '24:00:00', 2838 showNonCurrentDates: true, 2839 // event ajax 2840 lazyFetching: true, 2841 startParam: 'start', 2842 endParam: 'end', 2843 timezoneParam: 'timezone', 2844 timezone: false, 2845 // allDayDefault: undefined, 2846 // locale 2847 locale: null, 2848 isRTL: false, 2849 buttonText: { 2850 prev: 'prev', 2851 next: 'next', 2852 prevYear: 'prev year', 2853 nextYear: 'next year', 2854 year: 'year', 2855 today: 'today', 2856 month: 'month', 2857 week: 'week', 2858 day: 'day' 2859 }, 2860 // buttonIcons: null, 2861 allDayText: 'all-day', 2862 // allows setting a min-height to the event segment to prevent short events overlapping each other 2863 agendaEventMinHeight: 0, 2864 // jquery-ui theming 2865 theme: false, 2866 // themeButtonIcons: null, 2867 // eventResizableFromStart: false, 2868 dragOpacity: .75, 2869 dragRevertDuration: 500, 2870 dragScroll: true, 2871 // selectable: false, 2872 unselectAuto: true, 2873 // selectMinDistance: 0, 2874 dropAccept: '*', 2875 eventOrder: 'title', 2876 // eventRenderWait: null, 2877 eventLimit: false, 2878 eventLimitText: 'more', 2879 eventLimitClick: 'popover', 2880 dayPopoverFormat: 'LL', 2881 handleWindowResize: true, 2882 windowResizeDelay: 100, 2883 longPressDelay: 1000 2884}; 2885exports.englishDefaults = { 2886 dayPopoverFormat: 'dddd, MMMM D' 2887}; 2888exports.rtlDefaults = { 2889 header: { 2890 left: 'next,prev today', 2891 center: '', 2892 right: 'title' 2893 }, 2894 buttonIcons: { 2895 prev: 'right-single-arrow', 2896 next: 'left-single-arrow', 2897 prevYear: 'right-double-arrow', 2898 nextYear: 'left-double-arrow' 2899 }, 2900 themeButtonIcons: { 2901 prev: 'circle-triangle-e', 2902 next: 'circle-triangle-w', 2903 nextYear: 'seek-prev', 2904 prevYear: 'seek-next' 2905 } 2906}; 2907var complexOptions = [ 2908 'header', 2909 'footer', 2910 'buttonText', 2911 'buttonIcons', 2912 'themeButtonIcons' 2913]; 2914// Merges an array of option objects into a single object 2915function mergeOptions(optionObjs) { 2916 return util_1.mergeProps(optionObjs, complexOptions); 2917} 2918exports.mergeOptions = mergeOptions; 2919 2920 2921/***/ }), 2922/* 34 */ 2923/***/ (function(module, exports) { 2924 2925Object.defineProperty(exports, "__esModule", { value: true }); 2926var EventFootprint = /** @class */ (function () { 2927 function EventFootprint(componentFootprint, eventDef, eventInstance) { 2928 this.componentFootprint = componentFootprint; 2929 this.eventDef = eventDef; 2930 if (eventInstance) { 2931 this.eventInstance = eventInstance; 2932 } 2933 } 2934 EventFootprint.prototype.getEventLegacy = function () { 2935 return (this.eventInstance || this.eventDef).toLegacy(); 2936 }; 2937 return EventFootprint; 2938}()); 2939exports.default = EventFootprint; 2940 2941 2942/***/ }), 2943/* 35 */ 2944/***/ (function(module, exports, __webpack_require__) { 2945 2946Object.defineProperty(exports, "__esModule", { value: true }); 2947var tslib_1 = __webpack_require__(2); 2948var util_1 = __webpack_require__(4); 2949// Class that all other classes will inherit from 2950var Class = /** @class */ (function () { 2951 function Class() { 2952 } 2953 // Called on a class to create a subclass. 2954 // LIMITATION: cannot provide a constructor! 2955 Class.extend = function (members) { 2956 var SubClass = /** @class */ (function (_super) { 2957 tslib_1.__extends(SubClass, _super); 2958 function SubClass() { 2959 return _super !== null && _super.apply(this, arguments) || this; 2960 } 2961 return SubClass; 2962 }(this)); 2963 util_1.copyOwnProps(members, SubClass.prototype); 2964 return SubClass; 2965 }; 2966 // Adds new member variables/methods to the class's prototype. 2967 // Can be called with another class, or a plain object hash containing new members. 2968 Class.mixin = function (members) { 2969 util_1.copyOwnProps(members, this.prototype); 2970 }; 2971 return Class; 2972}()); 2973exports.default = Class; 2974 2975 2976/***/ }), 2977/* 36 */ 2978/***/ (function(module, exports, __webpack_require__) { 2979 2980Object.defineProperty(exports, "__esModule", { value: true }); 2981var moment = __webpack_require__(0); 2982var util_1 = __webpack_require__(4); 2983var SingleEventDef_1 = __webpack_require__(9); 2984var RecurringEventDef_1 = __webpack_require__(54); 2985exports.default = { 2986 parse: function (eventInput, source) { 2987 if (util_1.isTimeString(eventInput.start) || moment.isDuration(eventInput.start) || 2988 util_1.isTimeString(eventInput.end) || moment.isDuration(eventInput.end)) { 2989 return RecurringEventDef_1.default.parse(eventInput, source); 2990 } 2991 else { 2992 return SingleEventDef_1.default.parse(eventInput, source); 2993 } 2994 } 2995}; 2996 2997 2998/***/ }), 2999/* 37 */ 3000/***/ (function(module, exports, __webpack_require__) { 3001 3002Object.defineProperty(exports, "__esModule", { value: true }); 3003var $ = __webpack_require__(3); 3004var ParsableModelMixin_1 = __webpack_require__(52); 3005var EventDef = /** @class */ (function () { 3006 function EventDef(source) { 3007 this.source = source; 3008 this.className = []; 3009 this.miscProps = {}; 3010 } 3011 EventDef.parse = function (rawInput, source) { 3012 var def = new this(source); 3013 if (def.applyProps(rawInput)) { 3014 return def; 3015 } 3016 return false; 3017 }; 3018 EventDef.normalizeId = function (id) { 3019 return String(id); 3020 }; 3021 EventDef.generateId = function () { 3022 return '_fc' + (EventDef.uuid++); 3023 }; 3024 EventDef.prototype.clone = function () { 3025 var copy = new this.constructor(this.source); 3026 copy.id = this.id; 3027 copy.rawId = this.rawId; 3028 copy.uid = this.uid; // not really unique anymore :( 3029 EventDef.copyVerbatimStandardProps(this, copy); 3030 copy.className = this.className.slice(); // copy 3031 copy.miscProps = $.extend({}, this.miscProps); 3032 return copy; 3033 }; 3034 EventDef.prototype.hasInverseRendering = function () { 3035 return this.getRendering() === 'inverse-background'; 3036 }; 3037 EventDef.prototype.hasBgRendering = function () { 3038 var rendering = this.getRendering(); 3039 return rendering === 'inverse-background' || rendering === 'background'; 3040 }; 3041 EventDef.prototype.getRendering = function () { 3042 if (this.rendering != null) { 3043 return this.rendering; 3044 } 3045 return this.source.rendering; 3046 }; 3047 EventDef.prototype.getConstraint = function () { 3048 if (this.constraint != null) { 3049 return this.constraint; 3050 } 3051 if (this.source.constraint != null) { 3052 return this.source.constraint; 3053 } 3054 return this.source.calendar.opt('eventConstraint'); // what about View option? 3055 }; 3056 EventDef.prototype.getOverlap = function () { 3057 if (this.overlap != null) { 3058 return this.overlap; 3059 } 3060 if (this.source.overlap != null) { 3061 return this.source.overlap; 3062 } 3063 return this.source.calendar.opt('eventOverlap'); // what about View option? 3064 }; 3065 EventDef.prototype.isStartExplicitlyEditable = function () { 3066 if (this.startEditable != null) { 3067 return this.startEditable; 3068 } 3069 return this.source.startEditable; 3070 }; 3071 EventDef.prototype.isDurationExplicitlyEditable = function () { 3072 if (this.durationEditable != null) { 3073 return this.durationEditable; 3074 } 3075 return this.source.durationEditable; 3076 }; 3077 EventDef.prototype.isExplicitlyEditable = function () { 3078 if (this.editable != null) { 3079 return this.editable; 3080 } 3081 return this.source.editable; 3082 }; 3083 EventDef.prototype.toLegacy = function () { 3084 var obj = $.extend({}, this.miscProps); 3085 obj._id = this.uid; 3086 obj.source = this.source; 3087 obj.className = this.className.slice(); // copy 3088 obj.allDay = this.isAllDay(); 3089 if (this.rawId != null) { 3090 obj.id = this.rawId; 3091 } 3092 EventDef.copyVerbatimStandardProps(this, obj); 3093 return obj; 3094 }; 3095 EventDef.prototype.applyManualStandardProps = function (rawProps) { 3096 if (rawProps.id != null) { 3097 this.id = EventDef.normalizeId((this.rawId = rawProps.id)); 3098 } 3099 else { 3100 this.id = EventDef.generateId(); 3101 } 3102 if (rawProps._id != null) { // accept this prop, even tho somewhat internal 3103 this.uid = String(rawProps._id); 3104 } 3105 else { 3106 this.uid = EventDef.generateId(); 3107 } 3108 // TODO: converge with EventSource 3109 if ($.isArray(rawProps.className)) { 3110 this.className = rawProps.className; 3111 } 3112 if (typeof rawProps.className === 'string') { 3113 this.className = rawProps.className.split(/\s+/); 3114 } 3115 return true; 3116 }; 3117 EventDef.prototype.applyMiscProps = function (rawProps) { 3118 $.extend(this.miscProps, rawProps); 3119 }; 3120 EventDef.uuid = 0; 3121 EventDef.defineStandardProps = ParsableModelMixin_1.default.defineStandardProps; 3122 EventDef.copyVerbatimStandardProps = ParsableModelMixin_1.default.copyVerbatimStandardProps; 3123 return EventDef; 3124}()); 3125exports.default = EventDef; 3126ParsableModelMixin_1.default.mixInto(EventDef); 3127EventDef.defineStandardProps({ 3128 // not automatically assigned (`false`) 3129 _id: false, 3130 id: false, 3131 className: false, 3132 source: false, 3133 // automatically assigned (`true`) 3134 title: true, 3135 url: true, 3136 rendering: true, 3137 constraint: true, 3138 overlap: true, 3139 editable: true, 3140 startEditable: true, 3141 durationEditable: true, 3142 color: true, 3143 backgroundColor: true, 3144 borderColor: true, 3145 textColor: true 3146}); 3147 3148 3149/***/ }), 3150/* 38 */ 3151/***/ (function(module, exports) { 3152 3153Object.defineProperty(exports, "__esModule", { value: true }); 3154exports.default = { 3155 sourceClasses: [], 3156 registerClass: function (EventSourceClass) { 3157 this.sourceClasses.unshift(EventSourceClass); // give highest priority 3158 }, 3159 parse: function (rawInput, calendar) { 3160 var sourceClasses = this.sourceClasses; 3161 var i; 3162 var eventSource; 3163 for (i = 0; i < sourceClasses.length; i++) { 3164 eventSource = sourceClasses[i].parse(rawInput, calendar); 3165 if (eventSource) { 3166 return eventSource; 3167 } 3168 } 3169 } 3170}; 3171 3172 3173/***/ }), 3174/* 39 */ 3175/***/ (function(module, exports, __webpack_require__) { 3176 3177Object.defineProperty(exports, "__esModule", { value: true }); 3178var util_1 = __webpack_require__(4); 3179var EventDateProfile_1 = __webpack_require__(16); 3180var EventDef_1 = __webpack_require__(37); 3181var EventDefDateMutation_1 = __webpack_require__(40); 3182var SingleEventDef_1 = __webpack_require__(9); 3183var EventDefMutation = /** @class */ (function () { 3184 function EventDefMutation() { 3185 } 3186 EventDefMutation.createFromRawProps = function (eventInstance, rawProps, largeUnit) { 3187 var eventDef = eventInstance.def; 3188 var dateProps = {}; 3189 var standardProps = {}; 3190 var miscProps = {}; 3191 var verbatimStandardProps = {}; 3192 var eventDefId = null; 3193 var className = null; 3194 var propName; 3195 var dateProfile; 3196 var dateMutation; 3197 var defMutation; 3198 for (propName in rawProps) { 3199 if (EventDateProfile_1.default.isStandardProp(propName)) { 3200 dateProps[propName] = rawProps[propName]; 3201 } 3202 else if (eventDef.isStandardProp(propName)) { 3203 standardProps[propName] = rawProps[propName]; 3204 } 3205 else if (eventDef.miscProps[propName] !== rawProps[propName]) { // only if changed 3206 miscProps[propName] = rawProps[propName]; 3207 } 3208 } 3209 dateProfile = EventDateProfile_1.default.parse(dateProps, eventDef.source); 3210 if (dateProfile) { // no failure? 3211 dateMutation = EventDefDateMutation_1.default.createFromDiff(eventInstance.dateProfile, dateProfile, largeUnit); 3212 } 3213 if (standardProps.id !== eventDef.id) { 3214 eventDefId = standardProps.id; // only apply if there's a change 3215 } 3216 if (!util_1.isArraysEqual(standardProps.className, eventDef.className)) { 3217 className = standardProps.className; // only apply if there's a change 3218 } 3219 EventDef_1.default.copyVerbatimStandardProps(standardProps, // src 3220 verbatimStandardProps // dest 3221 ); 3222 defMutation = new EventDefMutation(); 3223 defMutation.eventDefId = eventDefId; 3224 defMutation.className = className; 3225 defMutation.verbatimStandardProps = verbatimStandardProps; 3226 defMutation.miscProps = miscProps; 3227 if (dateMutation) { 3228 defMutation.dateMutation = dateMutation; 3229 } 3230 return defMutation; 3231 }; 3232 /* 3233 eventDef assumed to be a SingleEventDef. 3234 returns an undo function. 3235 */ 3236 EventDefMutation.prototype.mutateSingle = function (eventDef) { 3237 var origDateProfile; 3238 if (this.dateMutation) { 3239 origDateProfile = eventDef.dateProfile; 3240 eventDef.dateProfile = this.dateMutation.buildNewDateProfile(origDateProfile, eventDef.source.calendar); 3241 } 3242 // can't undo 3243 // TODO: more DRY with EventDef::applyManualStandardProps 3244 if (this.eventDefId != null) { 3245 eventDef.id = EventDef_1.default.normalizeId((eventDef.rawId = this.eventDefId)); 3246 } 3247 // can't undo 3248 // TODO: more DRY with EventDef::applyManualStandardProps 3249 if (this.className) { 3250 eventDef.className = this.className; 3251 } 3252 // can't undo 3253 if (this.verbatimStandardProps) { 3254 SingleEventDef_1.default.copyVerbatimStandardProps(this.verbatimStandardProps, // src 3255 eventDef // dest 3256 ); 3257 } 3258 // can't undo 3259 if (this.miscProps) { 3260 eventDef.applyMiscProps(this.miscProps); 3261 } 3262 if (origDateProfile) { 3263 return function () { 3264 eventDef.dateProfile = origDateProfile; 3265 }; 3266 } 3267 else { 3268 return function () { }; 3269 } 3270 }; 3271 EventDefMutation.prototype.setDateMutation = function (dateMutation) { 3272 if (dateMutation && !dateMutation.isEmpty()) { 3273 this.dateMutation = dateMutation; 3274 } 3275 else { 3276 this.dateMutation = null; 3277 } 3278 }; 3279 EventDefMutation.prototype.isEmpty = function () { 3280 return !this.dateMutation; 3281 }; 3282 return EventDefMutation; 3283}()); 3284exports.default = EventDefMutation; 3285 3286 3287/***/ }), 3288/* 40 */ 3289/***/ (function(module, exports, __webpack_require__) { 3290 3291Object.defineProperty(exports, "__esModule", { value: true }); 3292var util_1 = __webpack_require__(4); 3293var EventDateProfile_1 = __webpack_require__(16); 3294var EventDefDateMutation = /** @class */ (function () { 3295 function EventDefDateMutation() { 3296 this.clearEnd = false; 3297 this.forceTimed = false; 3298 this.forceAllDay = false; 3299 } 3300 EventDefDateMutation.createFromDiff = function (dateProfile0, dateProfile1, largeUnit) { 3301 var clearEnd = dateProfile0.end && !dateProfile1.end; 3302 var forceTimed = dateProfile0.isAllDay() && !dateProfile1.isAllDay(); 3303 var forceAllDay = !dateProfile0.isAllDay() && dateProfile1.isAllDay(); 3304 var dateDelta; 3305 var endDiff; 3306 var endDelta; 3307 var mutation; 3308 // subtracts the dates in the appropriate way, returning a duration 3309 function subtractDates(date1, date0) { 3310 if (largeUnit) { 3311 return util_1.diffByUnit(date1, date0, largeUnit); // poorly named 3312 } 3313 else if (dateProfile1.isAllDay()) { 3314 return util_1.diffDay(date1, date0); // poorly named 3315 } 3316 else { 3317 return util_1.diffDayTime(date1, date0); // poorly named 3318 } 3319 } 3320 dateDelta = subtractDates(dateProfile1.start, dateProfile0.start); 3321 if (dateProfile1.end) { 3322 // use unzonedRanges because dateProfile0.end might be null 3323 endDiff = subtractDates(dateProfile1.unzonedRange.getEnd(), dateProfile0.unzonedRange.getEnd()); 3324 endDelta = endDiff.subtract(dateDelta); 3325 } 3326 mutation = new EventDefDateMutation(); 3327 mutation.clearEnd = clearEnd; 3328 mutation.forceTimed = forceTimed; 3329 mutation.forceAllDay = forceAllDay; 3330 mutation.setDateDelta(dateDelta); 3331 mutation.setEndDelta(endDelta); 3332 return mutation; 3333 }; 3334 /* 3335 returns an undo function. 3336 */ 3337 EventDefDateMutation.prototype.buildNewDateProfile = function (eventDateProfile, calendar) { 3338 var start = eventDateProfile.start.clone(); 3339 var end = null; 3340 var shouldRezone = false; 3341 if (eventDateProfile.end && !this.clearEnd) { 3342 end = eventDateProfile.end.clone(); 3343 } 3344 else if (this.endDelta && !end) { 3345 end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start); 3346 } 3347 if (this.forceTimed) { 3348 shouldRezone = true; 3349 if (!start.hasTime()) { 3350 start.time(0); 3351 } 3352 if (end && !end.hasTime()) { 3353 end.time(0); 3354 } 3355 } 3356 else if (this.forceAllDay) { 3357 if (start.hasTime()) { 3358 start.stripTime(); 3359 } 3360 if (end && end.hasTime()) { 3361 end.stripTime(); 3362 } 3363 } 3364 if (this.dateDelta) { 3365 shouldRezone = true; 3366 start.add(this.dateDelta); 3367 if (end) { 3368 end.add(this.dateDelta); 3369 } 3370 } 3371 // do this before adding startDelta to start, so we can work off of start 3372 if (this.endDelta) { 3373 shouldRezone = true; 3374 end.add(this.endDelta); 3375 } 3376 if (this.startDelta) { 3377 shouldRezone = true; 3378 start.add(this.startDelta); 3379 } 3380 if (shouldRezone) { 3381 start = calendar.applyTimezone(start); 3382 if (end) { 3383 end = calendar.applyTimezone(end); 3384 } 3385 } 3386 // TODO: okay to access calendar option? 3387 if (!end && calendar.opt('forceEventDuration')) { 3388 end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start); 3389 } 3390 return new EventDateProfile_1.default(start, end, calendar); 3391 }; 3392 EventDefDateMutation.prototype.setDateDelta = function (dateDelta) { 3393 if (dateDelta && dateDelta.valueOf()) { 3394 this.dateDelta = dateDelta; 3395 } 3396 else { 3397 this.dateDelta = null; 3398 } 3399 }; 3400 EventDefDateMutation.prototype.setStartDelta = function (startDelta) { 3401 if (startDelta && startDelta.valueOf()) { 3402 this.startDelta = startDelta; 3403 } 3404 else { 3405 this.startDelta = null; 3406 } 3407 }; 3408 EventDefDateMutation.prototype.setEndDelta = function (endDelta) { 3409 if (endDelta && endDelta.valueOf()) { 3410 this.endDelta = endDelta; 3411 } 3412 else { 3413 this.endDelta = null; 3414 } 3415 }; 3416 EventDefDateMutation.prototype.isEmpty = function () { 3417 return !this.clearEnd && !this.forceTimed && !this.forceAllDay && 3418 !this.dateDelta && !this.startDelta && !this.endDelta; 3419 }; 3420 return EventDefDateMutation; 3421}()); 3422exports.default = EventDefDateMutation; 3423 3424 3425/***/ }), 3426/* 41 */ 3427/***/ (function(module, exports, __webpack_require__) { 3428 3429Object.defineProperty(exports, "__esModule", { value: true }); 3430var tslib_1 = __webpack_require__(2); 3431var $ = __webpack_require__(3); 3432var util_1 = __webpack_require__(4); 3433var Class_1 = __webpack_require__(35); 3434/* 3435Embodies a div that has potential scrollbars 3436*/ 3437var Scroller = /** @class */ (function (_super) { 3438 tslib_1.__extends(Scroller, _super); 3439 function Scroller(options) { 3440 var _this = _super.call(this) || this; 3441 options = options || {}; 3442 _this.overflowX = options.overflowX || options.overflow || 'auto'; 3443 _this.overflowY = options.overflowY || options.overflow || 'auto'; 3444 return _this; 3445 } 3446 Scroller.prototype.render = function () { 3447 this.el = this.renderEl(); 3448 this.applyOverflow(); 3449 }; 3450 Scroller.prototype.renderEl = function () { 3451 return (this.scrollEl = $('<div class="fc-scroller"></div>')); 3452 }; 3453 // sets to natural height, unlocks overflow 3454 Scroller.prototype.clear = function () { 3455 this.setHeight('auto'); 3456 this.applyOverflow(); 3457 }; 3458 Scroller.prototype.destroy = function () { 3459 this.el.remove(); 3460 }; 3461 // Overflow 3462 // ----------------------------------------------------------------------------------------------------------------- 3463 Scroller.prototype.applyOverflow = function () { 3464 this.scrollEl.css({ 3465 'overflow-x': this.overflowX, 3466 'overflow-y': this.overflowY 3467 }); 3468 }; 3469 // Causes any 'auto' overflow values to resolves to 'scroll' or 'hidden'. 3470 // Useful for preserving scrollbar widths regardless of future resizes. 3471 // Can pass in scrollbarWidths for optimization. 3472 Scroller.prototype.lockOverflow = function (scrollbarWidths) { 3473 var overflowX = this.overflowX; 3474 var overflowY = this.overflowY; 3475 scrollbarWidths = scrollbarWidths || this.getScrollbarWidths(); 3476 if (overflowX === 'auto') { 3477 overflowX = (scrollbarWidths.top || scrollbarWidths.bottom || // horizontal scrollbars? 3478 // OR scrolling pane with massless scrollbars? 3479 this.scrollEl[0].scrollWidth - 1 > this.scrollEl[0].clientWidth 3480 // subtract 1 because of IE off-by-one issue 3481 ) ? 'scroll' : 'hidden'; 3482 } 3483 if (overflowY === 'auto') { 3484 overflowY = (scrollbarWidths.left || scrollbarWidths.right || // vertical scrollbars? 3485 // OR scrolling pane with massless scrollbars? 3486 this.scrollEl[0].scrollHeight - 1 > this.scrollEl[0].clientHeight 3487 // subtract 1 because of IE off-by-one issue 3488 ) ? 'scroll' : 'hidden'; 3489 } 3490 this.scrollEl.css({ 'overflow-x': overflowX, 'overflow-y': overflowY }); 3491 }; 3492 // Getters / Setters 3493 // ----------------------------------------------------------------------------------------------------------------- 3494 Scroller.prototype.setHeight = function (height) { 3495 this.scrollEl.height(height); 3496 }; 3497 Scroller.prototype.getScrollTop = function () { 3498 return this.scrollEl.scrollTop(); 3499 }; 3500 Scroller.prototype.setScrollTop = function (top) { 3501 this.scrollEl.scrollTop(top); 3502 }; 3503 Scroller.prototype.getClientWidth = function () { 3504 return this.scrollEl[0].clientWidth; 3505 }; 3506 Scroller.prototype.getClientHeight = function () { 3507 return this.scrollEl[0].clientHeight; 3508 }; 3509 Scroller.prototype.getScrollbarWidths = function () { 3510 return util_1.getScrollbarWidths(this.scrollEl); 3511 }; 3512 return Scroller; 3513}(Class_1.default)); 3514exports.default = Scroller; 3515 3516 3517/***/ }), 3518/* 42 */ 3519/***/ (function(module, exports, __webpack_require__) { 3520 3521Object.defineProperty(exports, "__esModule", { value: true }); 3522var tslib_1 = __webpack_require__(2); 3523var $ = __webpack_require__(3); 3524var util_1 = __webpack_require__(4); 3525var DateComponent_1 = __webpack_require__(231); 3526var GlobalEmitter_1 = __webpack_require__(23); 3527var InteractiveDateComponent = /** @class */ (function (_super) { 3528 tslib_1.__extends(InteractiveDateComponent, _super); 3529 function InteractiveDateComponent(_view, _options) { 3530 var _this = _super.call(this, _view, _options) || this; 3531 // self-config, overridable by subclasses 3532 _this.segSelector = '.fc-event-container > *'; // what constitutes an event element? 3533 if (_this.dateSelectingClass) { 3534 _this.dateClicking = new _this.dateClickingClass(_this); 3535 } 3536 if (_this.dateSelectingClass) { 3537 _this.dateSelecting = new _this.dateSelectingClass(_this); 3538 } 3539 if (_this.eventPointingClass) { 3540 _this.eventPointing = new _this.eventPointingClass(_this); 3541 } 3542 if (_this.eventDraggingClass && _this.eventPointing) { 3543 _this.eventDragging = new _this.eventDraggingClass(_this, _this.eventPointing); 3544 } 3545 if (_this.eventResizingClass && _this.eventPointing) { 3546 _this.eventResizing = new _this.eventResizingClass(_this, _this.eventPointing); 3547 } 3548 if (_this.externalDroppingClass) { 3549 _this.externalDropping = new _this.externalDroppingClass(_this); 3550 } 3551 return _this; 3552 } 3553 // Sets the container element that the view should render inside of, does global DOM-related initializations, 3554 // and renders all the non-date-related content inside. 3555 InteractiveDateComponent.prototype.setElement = function (el) { 3556 _super.prototype.setElement.call(this, el); 3557 if (this.dateClicking) { 3558 this.dateClicking.bindToEl(el); 3559 } 3560 if (this.dateSelecting) { 3561 this.dateSelecting.bindToEl(el); 3562 } 3563 this.bindAllSegHandlersToEl(el); 3564 }; 3565 InteractiveDateComponent.prototype.removeElement = function () { 3566 this.endInteractions(); 3567 _super.prototype.removeElement.call(this); 3568 }; 3569 InteractiveDateComponent.prototype.executeEventUnrender = function () { 3570 this.endInteractions(); 3571 _super.prototype.executeEventUnrender.call(this); 3572 }; 3573 InteractiveDateComponent.prototype.bindGlobalHandlers = function () { 3574 _super.prototype.bindGlobalHandlers.call(this); 3575 if (this.externalDropping) { 3576 this.externalDropping.bindToDocument(); 3577 } 3578 }; 3579 InteractiveDateComponent.prototype.unbindGlobalHandlers = function () { 3580 _super.prototype.unbindGlobalHandlers.call(this); 3581 if (this.externalDropping) { 3582 this.externalDropping.unbindFromDocument(); 3583 } 3584 }; 3585 InteractiveDateComponent.prototype.bindDateHandlerToEl = function (el, name, handler) { 3586 var _this = this; 3587 // attach a handler to the grid's root element. 3588 // jQuery will take care of unregistering them when removeElement gets called. 3589 this.el.on(name, function (ev) { 3590 if (!$(ev.target).is(_this.segSelector + ':not(.fc-helper),' + // directly on an event element 3591 _this.segSelector + ':not(.fc-helper) *,' + // within an event element 3592 '.fc-more,' + // a "more.." link 3593 'a[data-goto]' // a clickable nav link 3594 )) { 3595 return handler.call(_this, ev); 3596 } 3597 }); 3598 }; 3599 InteractiveDateComponent.prototype.bindAllSegHandlersToEl = function (el) { 3600 [ 3601 this.eventPointing, 3602 this.eventDragging, 3603 this.eventResizing 3604 ].forEach(function (eventInteraction) { 3605 if (eventInteraction) { 3606 eventInteraction.bindToEl(el); 3607 } 3608 }); 3609 }; 3610 InteractiveDateComponent.prototype.bindSegHandlerToEl = function (el, name, handler) { 3611 var _this = this; 3612 el.on(name, this.segSelector, function (ev) { 3613 var segEl = $(ev.currentTarget); 3614 if (!segEl.is('.fc-helper')) { 3615 var seg = segEl.data('fc-seg'); // grab segment data. put there by View::renderEventsPayload 3616 if (seg && !_this.shouldIgnoreEventPointing()) { 3617 return handler.call(_this, seg, ev); // context will be the Grid 3618 } 3619 } 3620 }); 3621 }; 3622 InteractiveDateComponent.prototype.shouldIgnoreMouse = function () { 3623 // HACK 3624 // This will still work even though bindDateHandlerToEl doesn't use GlobalEmitter. 3625 return GlobalEmitter_1.default.get().shouldIgnoreMouse(); 3626 }; 3627 InteractiveDateComponent.prototype.shouldIgnoreTouch = function () { 3628 var view = this._getView(); 3629 // On iOS (and Android?) when a new selection is initiated overtop another selection, 3630 // the touchend never fires because the elements gets removed mid-touch-interaction (my theory). 3631 // HACK: simply don't allow this to happen. 3632 // ALSO: prevent selection when an *event* is already raised. 3633 return view.isSelected || view.selectedEvent; 3634 }; 3635 InteractiveDateComponent.prototype.shouldIgnoreEventPointing = function () { 3636 // only call the handlers if there is not a drag/resize in progress 3637 return (this.eventDragging && this.eventDragging.isDragging) || 3638 (this.eventResizing && this.eventResizing.isResizing); 3639 }; 3640 InteractiveDateComponent.prototype.canStartSelection = function (seg, ev) { 3641 return util_1.getEvIsTouch(ev) && 3642 !this.canStartResize(seg, ev) && 3643 (this.isEventDefDraggable(seg.footprint.eventDef) || 3644 this.isEventDefResizable(seg.footprint.eventDef)); 3645 }; 3646 InteractiveDateComponent.prototype.canStartDrag = function (seg, ev) { 3647 return !this.canStartResize(seg, ev) && 3648 this.isEventDefDraggable(seg.footprint.eventDef); 3649 }; 3650 InteractiveDateComponent.prototype.canStartResize = function (seg, ev) { 3651 var view = this._getView(); 3652 var eventDef = seg.footprint.eventDef; 3653 return (!util_1.getEvIsTouch(ev) || view.isEventDefSelected(eventDef)) && 3654 this.isEventDefResizable(eventDef) && 3655 $(ev.target).is('.fc-resizer'); 3656 }; 3657 // Kills all in-progress dragging. 3658 // Useful for when public API methods that result in re-rendering are invoked during a drag. 3659 // Also useful for when touch devices misbehave and don't fire their touchend. 3660 InteractiveDateComponent.prototype.endInteractions = function () { 3661 [ 3662 this.dateClicking, 3663 this.dateSelecting, 3664 this.eventPointing, 3665 this.eventDragging, 3666 this.eventResizing 3667 ].forEach(function (interaction) { 3668 if (interaction) { 3669 interaction.end(); 3670 } 3671 }); 3672 }; 3673 // Event Drag-n-Drop 3674 // --------------------------------------------------------------------------------------------------------------- 3675 // Computes if the given event is allowed to be dragged by the user 3676 InteractiveDateComponent.prototype.isEventDefDraggable = function (eventDef) { 3677 return this.isEventDefStartEditable(eventDef); 3678 }; 3679 InteractiveDateComponent.prototype.isEventDefStartEditable = function (eventDef) { 3680 var isEditable = eventDef.isStartExplicitlyEditable(); 3681 if (isEditable == null) { 3682 isEditable = this.opt('eventStartEditable'); 3683 if (isEditable == null) { 3684 isEditable = this.isEventDefGenerallyEditable(eventDef); 3685 } 3686 } 3687 return isEditable; 3688 }; 3689 InteractiveDateComponent.prototype.isEventDefGenerallyEditable = function (eventDef) { 3690 var isEditable = eventDef.isExplicitlyEditable(); 3691 if (isEditable == null) { 3692 isEditable = this.opt('editable'); 3693 } 3694 return isEditable; 3695 }; 3696 // Event Resizing 3697 // --------------------------------------------------------------------------------------------------------------- 3698 // Computes if the given event is allowed to be resized from its starting edge 3699 InteractiveDateComponent.prototype.isEventDefResizableFromStart = function (eventDef) { 3700 return this.opt('eventResizableFromStart') && this.isEventDefResizable(eventDef); 3701 }; 3702 // Computes if the given event is allowed to be resized from its ending edge 3703 InteractiveDateComponent.prototype.isEventDefResizableFromEnd = function (eventDef) { 3704 return this.isEventDefResizable(eventDef); 3705 }; 3706 // Computes if the given event is allowed to be resized by the user at all 3707 InteractiveDateComponent.prototype.isEventDefResizable = function (eventDef) { 3708 var isResizable = eventDef.isDurationExplicitlyEditable(); 3709 if (isResizable == null) { 3710 isResizable = this.opt('eventDurationEditable'); 3711 if (isResizable == null) { 3712 isResizable = this.isEventDefGenerallyEditable(eventDef); 3713 } 3714 } 3715 return isResizable; 3716 }; 3717 // Event Mutation / Constraints 3718 // --------------------------------------------------------------------------------------------------------------- 3719 // Diffs the two dates, returning a duration, based on granularity of the grid 3720 // TODO: port isTimeScale into this system? 3721 InteractiveDateComponent.prototype.diffDates = function (a, b) { 3722 if (this.largeUnit) { 3723 return util_1.diffByUnit(a, b, this.largeUnit); 3724 } 3725 else { 3726 return util_1.diffDayTime(a, b); 3727 } 3728 }; 3729 // is it allowed, in relation to the view's validRange? 3730 // NOTE: very similar to isExternalInstanceGroupAllowed 3731 InteractiveDateComponent.prototype.isEventInstanceGroupAllowed = function (eventInstanceGroup) { 3732 var view = this._getView(); 3733 var dateProfile = this.dateProfile; 3734 var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges()); 3735 var i; 3736 for (i = 0; i < eventFootprints.length; i++) { 3737 // TODO: just use getAllEventRanges directly 3738 if (!dateProfile.validUnzonedRange.containsRange(eventFootprints[i].componentFootprint.unzonedRange)) { 3739 return false; 3740 } 3741 } 3742 return view.calendar.constraints.isEventInstanceGroupAllowed(eventInstanceGroup); 3743 }; 3744 // NOTE: very similar to isEventInstanceGroupAllowed 3745 // when it's a completely anonymous external drag, no event. 3746 InteractiveDateComponent.prototype.isExternalInstanceGroupAllowed = function (eventInstanceGroup) { 3747 var view = this._getView(); 3748 var dateProfile = this.dateProfile; 3749 var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges()); 3750 var i; 3751 for (i = 0; i < eventFootprints.length; i++) { 3752 if (!dateProfile.validUnzonedRange.containsRange(eventFootprints[i].componentFootprint.unzonedRange)) { 3753 return false; 3754 } 3755 } 3756 for (i = 0; i < eventFootprints.length; i++) { 3757 // treat it as a selection 3758 // TODO: pass in eventInstanceGroup instead 3759 // because we don't want calendar's constraint system to depend on a component's 3760 // determination of footprints. 3761 if (!view.calendar.constraints.isSelectionFootprintAllowed(eventFootprints[i].componentFootprint)) { 3762 return false; 3763 } 3764 } 3765 return true; 3766 }; 3767 return InteractiveDateComponent; 3768}(DateComponent_1.default)); 3769exports.default = InteractiveDateComponent; 3770 3771 3772/***/ }), 3773/* 43 */ 3774/***/ (function(module, exports, __webpack_require__) { 3775 3776Object.defineProperty(exports, "__esModule", { value: true }); 3777var tslib_1 = __webpack_require__(2); 3778var $ = __webpack_require__(3); 3779var moment = __webpack_require__(0); 3780var util_1 = __webpack_require__(4); 3781var RenderQueue_1 = __webpack_require__(229); 3782var DateProfileGenerator_1 = __webpack_require__(55); 3783var InteractiveDateComponent_1 = __webpack_require__(42); 3784var GlobalEmitter_1 = __webpack_require__(23); 3785var UnzonedRange_1 = __webpack_require__(5); 3786/* An abstract class from which other views inherit from 3787----------------------------------------------------------------------------------------------------------------------*/ 3788var View = /** @class */ (function (_super) { 3789 tslib_1.__extends(View, _super); 3790 function View(calendar, viewSpec) { 3791 var _this = _super.call(this, null, viewSpec.options) || this; 3792 _this.batchRenderDepth = 0; 3793 _this.isSelected = false; // boolean whether a range of time is user-selected or not 3794 _this.calendar = calendar; 3795 _this.viewSpec = viewSpec; 3796 // shortcuts 3797 _this.type = viewSpec.type; 3798 // .name is deprecated 3799 _this.name = _this.type; 3800 _this.initRenderQueue(); 3801 _this.initHiddenDays(); 3802 _this.dateProfileGenerator = new _this.dateProfileGeneratorClass(_this); 3803 _this.bindBaseRenderHandlers(); 3804 _this.eventOrderSpecs = util_1.parseFieldSpecs(_this.opt('eventOrder')); 3805 // legacy 3806 if (_this['initialize']) { 3807 _this['initialize'](); 3808 } 3809 return _this; 3810 } 3811 View.prototype._getView = function () { 3812 return this; 3813 }; 3814 // Retrieves an option with the given name 3815 View.prototype.opt = function (name) { 3816 return this.options[name]; 3817 }; 3818 /* Render Queue 3819 ------------------------------------------------------------------------------------------------------------------*/ 3820 View.prototype.initRenderQueue = function () { 3821 this.renderQueue = new RenderQueue_1.default({ 3822 event: this.opt('eventRenderWait') 3823 }); 3824 this.renderQueue.on('start', this.onRenderQueueStart.bind(this)); 3825 this.renderQueue.on('stop', this.onRenderQueueStop.bind(this)); 3826 this.on('before:change', this.startBatchRender); 3827 this.on('change', this.stopBatchRender); 3828 }; 3829 View.prototype.onRenderQueueStart = function () { 3830 this.calendar.freezeContentHeight(); 3831 this.addScroll(this.queryScroll()); 3832 }; 3833 View.prototype.onRenderQueueStop = function () { 3834 if (this.calendar.updateViewSize()) { // success? 3835 this.popScroll(); 3836 } 3837 this.calendar.thawContentHeight(); 3838 }; 3839 View.prototype.startBatchRender = function () { 3840 if (!(this.batchRenderDepth++)) { 3841 this.renderQueue.pause(); 3842 } 3843 }; 3844 View.prototype.stopBatchRender = function () { 3845 if (!(--this.batchRenderDepth)) { 3846 this.renderQueue.resume(); 3847 } 3848 }; 3849 View.prototype.requestRender = function (func, namespace, actionType) { 3850 this.renderQueue.queue(func, namespace, actionType); 3851 }; 3852 // given func will auto-bind to `this` 3853 View.prototype.whenSizeUpdated = function (func) { 3854 if (this.renderQueue.isRunning) { 3855 this.renderQueue.one('stop', func.bind(this)); 3856 } 3857 else { 3858 func.call(this); 3859 } 3860 }; 3861 /* Title and Date Formatting 3862 ------------------------------------------------------------------------------------------------------------------*/ 3863 // Computes what the title at the top of the calendar should be for this view 3864 View.prototype.computeTitle = function (dateProfile) { 3865 var unzonedRange; 3866 // for views that span a large unit of time, show the proper interval, ignoring stray days before and after 3867 if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) { 3868 unzonedRange = dateProfile.currentUnzonedRange; 3869 } 3870 else { // for day units or smaller, use the actual day range 3871 unzonedRange = dateProfile.activeUnzonedRange; 3872 } 3873 return this.formatRange({ 3874 start: this.calendar.msToMoment(unzonedRange.startMs, dateProfile.isRangeAllDay), 3875 end: this.calendar.msToMoment(unzonedRange.endMs, dateProfile.isRangeAllDay) 3876 }, dateProfile.isRangeAllDay, this.opt('titleFormat') || this.computeTitleFormat(dateProfile), this.opt('titleRangeSeparator')); 3877 }; 3878 // Generates the format string that should be used to generate the title for the current date range. 3879 // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`. 3880 View.prototype.computeTitleFormat = function (dateProfile) { 3881 var currentRangeUnit = dateProfile.currentRangeUnit; 3882 if (currentRangeUnit === 'year') { 3883 return 'YYYY'; 3884 } 3885 else if (currentRangeUnit === 'month') { 3886 return this.opt('monthYearFormat'); // like "September 2014" 3887 } 3888 else if (dateProfile.currentUnzonedRange.as('days') > 1) { 3889 return 'll'; // multi-day range. shorter, like "Sep 9 - 10 2014" 3890 } 3891 else { 3892 return 'LL'; // one day. longer, like "September 9 2014" 3893 } 3894 }; 3895 // Date Setting/Unsetting 3896 // ----------------------------------------------------------------------------------------------------------------- 3897 View.prototype.setDate = function (date) { 3898 var currentDateProfile = this.get('dateProfile'); 3899 var newDateProfile = this.dateProfileGenerator.build(date, undefined, true); // forceToValid=true 3900 if (!currentDateProfile || 3901 !currentDateProfile.activeUnzonedRange.equals(newDateProfile.activeUnzonedRange)) { 3902 this.set('dateProfile', newDateProfile); 3903 } 3904 }; 3905 View.prototype.unsetDate = function () { 3906 this.unset('dateProfile'); 3907 }; 3908 // Event Data 3909 // ----------------------------------------------------------------------------------------------------------------- 3910 View.prototype.fetchInitialEvents = function (dateProfile) { 3911 var calendar = this.calendar; 3912 var forceAllDay = dateProfile.isRangeAllDay && !this.usesMinMaxTime; 3913 return calendar.requestEvents(calendar.msToMoment(dateProfile.activeUnzonedRange.startMs, forceAllDay), calendar.msToMoment(dateProfile.activeUnzonedRange.endMs, forceAllDay)); 3914 }; 3915 View.prototype.bindEventChanges = function () { 3916 this.listenTo(this.calendar, 'eventsReset', this.resetEvents); // TODO: make this a real event 3917 }; 3918 View.prototype.unbindEventChanges = function () { 3919 this.stopListeningTo(this.calendar, 'eventsReset'); 3920 }; 3921 View.prototype.setEvents = function (eventsPayload) { 3922 this.set('currentEvents', eventsPayload); 3923 this.set('hasEvents', true); 3924 }; 3925 View.prototype.unsetEvents = function () { 3926 this.unset('currentEvents'); 3927 this.unset('hasEvents'); 3928 }; 3929 View.prototype.resetEvents = function (eventsPayload) { 3930 this.startBatchRender(); 3931 this.unsetEvents(); 3932 this.setEvents(eventsPayload); 3933 this.stopBatchRender(); 3934 }; 3935 // Date High-level Rendering 3936 // ----------------------------------------------------------------------------------------------------------------- 3937 View.prototype.requestDateRender = function (dateProfile) { 3938 var _this = this; 3939 this.requestRender(function () { 3940 _this.executeDateRender(dateProfile); 3941 }, 'date', 'init'); 3942 }; 3943 View.prototype.requestDateUnrender = function () { 3944 var _this = this; 3945 this.requestRender(function () { 3946 _this.executeDateUnrender(); 3947 }, 'date', 'destroy'); 3948 }; 3949 // if dateProfile not specified, uses current 3950 View.prototype.executeDateRender = function (dateProfile) { 3951 _super.prototype.executeDateRender.call(this, dateProfile); 3952 if (this['render']) { 3953 this['render'](); // TODO: deprecate 3954 } 3955 this.trigger('datesRendered'); 3956 this.addScroll({ isDateInit: true }); 3957 this.startNowIndicator(); // shouldn't render yet because updateSize will be called soon 3958 }; 3959 View.prototype.executeDateUnrender = function () { 3960 this.unselect(); 3961 this.stopNowIndicator(); 3962 this.trigger('before:datesUnrendered'); 3963 if (this['destroy']) { 3964 this['destroy'](); // TODO: deprecate 3965 } 3966 _super.prototype.executeDateUnrender.call(this); 3967 }; 3968 // "Base" rendering 3969 // ----------------------------------------------------------------------------------------------------------------- 3970 View.prototype.bindBaseRenderHandlers = function () { 3971 var _this = this; 3972 this.on('datesRendered', function () { 3973 _this.whenSizeUpdated(_this.triggerViewRender); 3974 }); 3975 this.on('before:datesUnrendered', function () { 3976 _this.triggerViewDestroy(); 3977 }); 3978 }; 3979 View.prototype.triggerViewRender = function () { 3980 this.publiclyTrigger('viewRender', { 3981 context: this, 3982 args: [this, this.el] 3983 }); 3984 }; 3985 View.prototype.triggerViewDestroy = function () { 3986 this.publiclyTrigger('viewDestroy', { 3987 context: this, 3988 args: [this, this.el] 3989 }); 3990 }; 3991 // Event High-level Rendering 3992 // ----------------------------------------------------------------------------------------------------------------- 3993 View.prototype.requestEventsRender = function (eventsPayload) { 3994 var _this = this; 3995 this.requestRender(function () { 3996 _this.executeEventRender(eventsPayload); 3997 _this.whenSizeUpdated(_this.triggerAfterEventsRendered); 3998 }, 'event', 'init'); 3999 }; 4000 View.prototype.requestEventsUnrender = function () { 4001 var _this = this; 4002 this.requestRender(function () { 4003 _this.triggerBeforeEventsDestroyed(); 4004 _this.executeEventUnrender(); 4005 }, 'event', 'destroy'); 4006 }; 4007 // Business Hour High-level Rendering 4008 // ----------------------------------------------------------------------------------------------------------------- 4009 View.prototype.requestBusinessHoursRender = function (businessHourGenerator) { 4010 var _this = this; 4011 this.requestRender(function () { 4012 _this.renderBusinessHours(businessHourGenerator); 4013 }, 'businessHours', 'init'); 4014 }; 4015 View.prototype.requestBusinessHoursUnrender = function () { 4016 var _this = this; 4017 this.requestRender(function () { 4018 _this.unrenderBusinessHours(); 4019 }, 'businessHours', 'destroy'); 4020 }; 4021 // Misc view rendering utils 4022 // ----------------------------------------------------------------------------------------------------------------- 4023 // Binds DOM handlers to elements that reside outside the view container, such as the document 4024 View.prototype.bindGlobalHandlers = function () { 4025 _super.prototype.bindGlobalHandlers.call(this); 4026 this.listenTo(GlobalEmitter_1.default.get(), { 4027 touchstart: this.processUnselect, 4028 mousedown: this.handleDocumentMousedown 4029 }); 4030 }; 4031 // Unbinds DOM handlers from elements that reside outside the view container 4032 View.prototype.unbindGlobalHandlers = function () { 4033 _super.prototype.unbindGlobalHandlers.call(this); 4034 this.stopListeningTo(GlobalEmitter_1.default.get()); 4035 }; 4036 /* Now Indicator 4037 ------------------------------------------------------------------------------------------------------------------*/ 4038 // Immediately render the current time indicator and begins re-rendering it at an interval, 4039 // which is defined by this.getNowIndicatorUnit(). 4040 // TODO: somehow do this for the current whole day's background too 4041 View.prototype.startNowIndicator = function () { 4042 var _this = this; 4043 var unit; 4044 var update; 4045 var delay; // ms wait value 4046 if (this.opt('nowIndicator')) { 4047 unit = this.getNowIndicatorUnit(); 4048 if (unit) { 4049 update = util_1.proxy(this, 'updateNowIndicator'); // bind to `this` 4050 this.initialNowDate = this.calendar.getNow(); 4051 this.initialNowQueriedMs = new Date().valueOf(); 4052 // wait until the beginning of the next interval 4053 delay = this.initialNowDate.clone().startOf(unit).add(1, unit).valueOf() - this.initialNowDate.valueOf(); 4054 this.nowIndicatorTimeoutID = setTimeout(function () { 4055 _this.nowIndicatorTimeoutID = null; 4056 update(); 4057 delay = +moment.duration(1, unit); 4058 delay = Math.max(100, delay); // prevent too frequent 4059 _this.nowIndicatorIntervalID = setInterval(update, delay); // update every interval 4060 }, delay); 4061 } 4062 // rendering will be initiated in updateSize 4063 } 4064 }; 4065 // rerenders the now indicator, computing the new current time from the amount of time that has passed 4066 // since the initial getNow call. 4067 View.prototype.updateNowIndicator = function () { 4068 if (this.isDatesRendered && 4069 this.initialNowDate // activated before? 4070 ) { 4071 this.unrenderNowIndicator(); // won't unrender if unnecessary 4072 this.renderNowIndicator(this.initialNowDate.clone().add(new Date().valueOf() - this.initialNowQueriedMs) // add ms 4073 ); 4074 this.isNowIndicatorRendered = true; 4075 } 4076 }; 4077 // Immediately unrenders the view's current time indicator and stops any re-rendering timers. 4078 // Won't cause side effects if indicator isn't rendered. 4079 View.prototype.stopNowIndicator = function () { 4080 if (this.isNowIndicatorRendered) { 4081 if (this.nowIndicatorTimeoutID) { 4082 clearTimeout(this.nowIndicatorTimeoutID); 4083 this.nowIndicatorTimeoutID = null; 4084 } 4085 if (this.nowIndicatorIntervalID) { 4086 clearInterval(this.nowIndicatorIntervalID); 4087 this.nowIndicatorIntervalID = null; 4088 } 4089 this.unrenderNowIndicator(); 4090 this.isNowIndicatorRendered = false; 4091 } 4092 }; 4093 /* Dimensions 4094 ------------------------------------------------------------------------------------------------------------------*/ 4095 View.prototype.updateSize = function (totalHeight, isAuto, isResize) { 4096 if (this['setHeight']) { // for legacy API 4097 this['setHeight'](totalHeight, isAuto); 4098 } 4099 else { 4100 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize); 4101 } 4102 this.updateNowIndicator(); 4103 }; 4104 /* Scroller 4105 ------------------------------------------------------------------------------------------------------------------*/ 4106 View.prototype.addScroll = function (scroll) { 4107 var queuedScroll = this.queuedScroll || (this.queuedScroll = {}); 4108 $.extend(queuedScroll, scroll); 4109 }; 4110 View.prototype.popScroll = function () { 4111 this.applyQueuedScroll(); 4112 this.queuedScroll = null; 4113 }; 4114 View.prototype.applyQueuedScroll = function () { 4115 if (this.queuedScroll) { 4116 this.applyScroll(this.queuedScroll); 4117 } 4118 }; 4119 View.prototype.queryScroll = function () { 4120 var scroll = {}; 4121 if (this.isDatesRendered) { 4122 $.extend(scroll, this.queryDateScroll()); 4123 } 4124 return scroll; 4125 }; 4126 View.prototype.applyScroll = function (scroll) { 4127 if (scroll.isDateInit && this.isDatesRendered) { 4128 $.extend(scroll, this.computeInitialDateScroll()); 4129 } 4130 if (this.isDatesRendered) { 4131 this.applyDateScroll(scroll); 4132 } 4133 }; 4134 View.prototype.computeInitialDateScroll = function () { 4135 return {}; // subclasses must implement 4136 }; 4137 View.prototype.queryDateScroll = function () { 4138 return {}; // subclasses must implement 4139 }; 4140 View.prototype.applyDateScroll = function (scroll) { 4141 // subclasses must implement 4142 }; 4143 /* Event Drag-n-Drop 4144 ------------------------------------------------------------------------------------------------------------------*/ 4145 View.prototype.reportEventDrop = function (eventInstance, eventMutation, el, ev) { 4146 var eventManager = this.calendar.eventManager; 4147 var undoFunc = eventManager.mutateEventsWithId(eventInstance.def.id, eventMutation); 4148 var dateMutation = eventMutation.dateMutation; 4149 // update the EventInstance, for handlers 4150 if (dateMutation) { 4151 eventInstance.dateProfile = dateMutation.buildNewDateProfile(eventInstance.dateProfile, this.calendar); 4152 } 4153 this.triggerEventDrop(eventInstance, 4154 // a drop doesn't necessarily mean a date mutation (ex: resource change) 4155 (dateMutation && dateMutation.dateDelta) || moment.duration(), undoFunc, el, ev); 4156 }; 4157 // Triggers event-drop handlers that have subscribed via the API 4158 View.prototype.triggerEventDrop = function (eventInstance, dateDelta, undoFunc, el, ev) { 4159 this.publiclyTrigger('eventDrop', { 4160 context: el[0], 4161 args: [ 4162 eventInstance.toLegacy(), 4163 dateDelta, 4164 undoFunc, 4165 ev, 4166 {}, 4167 this 4168 ] 4169 }); 4170 }; 4171 /* External Element Drag-n-Drop 4172 ------------------------------------------------------------------------------------------------------------------*/ 4173 // Must be called when an external element, via jQuery UI, has been dropped onto the calendar. 4174 // `meta` is the parsed data that has been embedded into the dragging event. 4175 // `dropLocation` is an object that contains the new zoned start/end/allDay values for the event. 4176 View.prototype.reportExternalDrop = function (singleEventDef, isEvent, isSticky, el, ev, ui) { 4177 if (isEvent) { 4178 this.calendar.eventManager.addEventDef(singleEventDef, isSticky); 4179 } 4180 this.triggerExternalDrop(singleEventDef, isEvent, el, ev, ui); 4181 }; 4182 // Triggers external-drop handlers that have subscribed via the API 4183 View.prototype.triggerExternalDrop = function (singleEventDef, isEvent, el, ev, ui) { 4184 // trigger 'drop' regardless of whether element represents an event 4185 this.publiclyTrigger('drop', { 4186 context: el[0], 4187 args: [ 4188 singleEventDef.dateProfile.start.clone(), 4189 ev, 4190 ui, 4191 this 4192 ] 4193 }); 4194 if (isEvent) { 4195 // signal an external event landed 4196 this.publiclyTrigger('eventReceive', { 4197 context: this, 4198 args: [ 4199 singleEventDef.buildInstance().toLegacy(), 4200 this 4201 ] 4202 }); 4203 } 4204 }; 4205 /* Event Resizing 4206 ------------------------------------------------------------------------------------------------------------------*/ 4207 // Must be called when an event in the view has been resized to a new length 4208 View.prototype.reportEventResize = function (eventInstance, eventMutation, el, ev) { 4209 var eventManager = this.calendar.eventManager; 4210 var undoFunc = eventManager.mutateEventsWithId(eventInstance.def.id, eventMutation); 4211 // update the EventInstance, for handlers 4212 eventInstance.dateProfile = eventMutation.dateMutation.buildNewDateProfile(eventInstance.dateProfile, this.calendar); 4213 var resizeDelta = eventMutation.dateMutation.endDelta || eventMutation.dateMutation.startDelta; 4214 this.triggerEventResize(eventInstance, resizeDelta, undoFunc, el, ev); 4215 }; 4216 // Triggers event-resize handlers that have subscribed via the API 4217 View.prototype.triggerEventResize = function (eventInstance, resizeDelta, undoFunc, el, ev) { 4218 this.publiclyTrigger('eventResize', { 4219 context: el[0], 4220 args: [ 4221 eventInstance.toLegacy(), 4222 resizeDelta, 4223 undoFunc, 4224 ev, 4225 {}, 4226 this 4227 ] 4228 }); 4229 }; 4230 /* Selection (time range) 4231 ------------------------------------------------------------------------------------------------------------------*/ 4232 // Selects a date span on the view. `start` and `end` are both Moments. 4233 // `ev` is the native mouse event that begin the interaction. 4234 View.prototype.select = function (footprint, ev) { 4235 this.unselect(ev); 4236 this.renderSelectionFootprint(footprint); 4237 this.reportSelection(footprint, ev); 4238 }; 4239 View.prototype.renderSelectionFootprint = function (footprint) { 4240 if (this['renderSelection']) { // legacy method in custom view classes 4241 this['renderSelection'](footprint.toLegacy(this.calendar)); 4242 } 4243 else { 4244 _super.prototype.renderSelectionFootprint.call(this, footprint); 4245 } 4246 }; 4247 // Called when a new selection is made. Updates internal state and triggers handlers. 4248 View.prototype.reportSelection = function (footprint, ev) { 4249 this.isSelected = true; 4250 this.triggerSelect(footprint, ev); 4251 }; 4252 // Triggers handlers to 'select' 4253 View.prototype.triggerSelect = function (footprint, ev) { 4254 var dateProfile = this.calendar.footprintToDateProfile(footprint); // abuse of "Event"DateProfile? 4255 this.publiclyTrigger('select', { 4256 context: this, 4257 args: [ 4258 dateProfile.start, 4259 dateProfile.end, 4260 ev, 4261 this 4262 ] 4263 }); 4264 }; 4265 // Undoes a selection. updates in the internal state and triggers handlers. 4266 // `ev` is the native mouse event that began the interaction. 4267 View.prototype.unselect = function (ev) { 4268 if (this.isSelected) { 4269 this.isSelected = false; 4270 if (this['destroySelection']) { 4271 this['destroySelection'](); // TODO: deprecate 4272 } 4273 this.unrenderSelection(); 4274 this.publiclyTrigger('unselect', { 4275 context: this, 4276 args: [ev, this] 4277 }); 4278 } 4279 }; 4280 /* Event Selection 4281 ------------------------------------------------------------------------------------------------------------------*/ 4282 View.prototype.selectEventInstance = function (eventInstance) { 4283 if (!this.selectedEventInstance || 4284 this.selectedEventInstance !== eventInstance) { 4285 this.unselectEventInstance(); 4286 this.getEventSegs().forEach(function (seg) { 4287 if (seg.footprint.eventInstance === eventInstance && 4288 seg.el // necessary? 4289 ) { 4290 seg.el.addClass('fc-selected'); 4291 } 4292 }); 4293 this.selectedEventInstance = eventInstance; 4294 } 4295 }; 4296 View.prototype.unselectEventInstance = function () { 4297 if (this.selectedEventInstance) { 4298 this.getEventSegs().forEach(function (seg) { 4299 if (seg.el) { // necessary? 4300 seg.el.removeClass('fc-selected'); 4301 } 4302 }); 4303 this.selectedEventInstance = null; 4304 } 4305 }; 4306 View.prototype.isEventDefSelected = function (eventDef) { 4307 // event references might change on refetchEvents(), while selectedEventInstance doesn't, 4308 // so compare IDs 4309 return this.selectedEventInstance && this.selectedEventInstance.def.id === eventDef.id; 4310 }; 4311 /* Mouse / Touch Unselecting (time range & event unselection) 4312 ------------------------------------------------------------------------------------------------------------------*/ 4313 // TODO: move consistently to down/start or up/end? 4314 // TODO: don't kill previous selection if touch scrolling 4315 View.prototype.handleDocumentMousedown = function (ev) { 4316 if (util_1.isPrimaryMouseButton(ev)) { 4317 this.processUnselect(ev); 4318 } 4319 }; 4320 View.prototype.processUnselect = function (ev) { 4321 this.processRangeUnselect(ev); 4322 this.processEventUnselect(ev); 4323 }; 4324 View.prototype.processRangeUnselect = function (ev) { 4325 var ignore; 4326 // is there a time-range selection? 4327 if (this.isSelected && this.opt('unselectAuto')) { 4328 // only unselect if the clicked element is not identical to or inside of an 'unselectCancel' element 4329 ignore = this.opt('unselectCancel'); 4330 if (!ignore || !$(ev.target).closest(ignore).length) { 4331 this.unselect(ev); 4332 } 4333 } 4334 }; 4335 View.prototype.processEventUnselect = function (ev) { 4336 if (this.selectedEventInstance) { 4337 if (!$(ev.target).closest('.fc-selected').length) { 4338 this.unselectEventInstance(); 4339 } 4340 } 4341 }; 4342 /* Triggers 4343 ------------------------------------------------------------------------------------------------------------------*/ 4344 View.prototype.triggerBaseRendered = function () { 4345 this.publiclyTrigger('viewRender', { 4346 context: this, 4347 args: [this, this.el] 4348 }); 4349 }; 4350 View.prototype.triggerBaseUnrendered = function () { 4351 this.publiclyTrigger('viewDestroy', { 4352 context: this, 4353 args: [this, this.el] 4354 }); 4355 }; 4356 // Triggers handlers to 'dayClick' 4357 // Span has start/end of the clicked area. Only the start is useful. 4358 View.prototype.triggerDayClick = function (footprint, dayEl, ev) { 4359 var dateProfile = this.calendar.footprintToDateProfile(footprint); // abuse of "Event"DateProfile? 4360 this.publiclyTrigger('dayClick', { 4361 context: dayEl, 4362 args: [dateProfile.start, ev, this] 4363 }); 4364 }; 4365 /* Date Utils 4366 ------------------------------------------------------------------------------------------------------------------*/ 4367 // For DateComponent::getDayClasses 4368 View.prototype.isDateInOtherMonth = function (date, dateProfile) { 4369 return false; 4370 }; 4371 // Arguments after name will be forwarded to a hypothetical function value 4372 // WARNING: passed-in arguments will be given to generator functions as-is and can cause side-effects. 4373 // Always clone your objects if you fear mutation. 4374 View.prototype.getUnzonedRangeOption = function (name) { 4375 var val = this.opt(name); 4376 if (typeof val === 'function') { 4377 val = val.apply(null, Array.prototype.slice.call(arguments, 1)); 4378 } 4379 if (val) { 4380 return this.calendar.parseUnzonedRange(val); 4381 } 4382 }; 4383 /* Hidden Days 4384 ------------------------------------------------------------------------------------------------------------------*/ 4385 // Initializes internal variables related to calculating hidden days-of-week 4386 View.prototype.initHiddenDays = function () { 4387 var hiddenDays = this.opt('hiddenDays') || []; // array of day-of-week indices that are hidden 4388 var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool) 4389 var dayCnt = 0; 4390 var i; 4391 if (this.opt('weekends') === false) { 4392 hiddenDays.push(0, 6); // 0=sunday, 6=saturday 4393 } 4394 for (i = 0; i < 7; i++) { 4395 if (!(isHiddenDayHash[i] = $.inArray(i, hiddenDays) !== -1)) { 4396 dayCnt++; 4397 } 4398 } 4399 if (!dayCnt) { 4400 throw new Error('invalid hiddenDays'); // all days were hidden? bad. 4401 } 4402 this.isHiddenDayHash = isHiddenDayHash; 4403 }; 4404 // Remove days from the beginning and end of the range that are computed as hidden. 4405 // If the whole range is trimmed off, returns null 4406 View.prototype.trimHiddenDays = function (inputUnzonedRange) { 4407 var start = inputUnzonedRange.getStart(); 4408 var end = inputUnzonedRange.getEnd(); 4409 if (start) { 4410 start = this.skipHiddenDays(start); 4411 } 4412 if (end) { 4413 end = this.skipHiddenDays(end, -1, true); 4414 } 4415 if (start === null || end === null || start < end) { 4416 return new UnzonedRange_1.default(start, end); 4417 } 4418 return null; 4419 }; 4420 // Is the current day hidden? 4421 // `day` is a day-of-week index (0-6), or a Moment 4422 View.prototype.isHiddenDay = function (day) { 4423 if (moment.isMoment(day)) { 4424 day = day.day(); 4425 } 4426 return this.isHiddenDayHash[day]; 4427 }; 4428 // Incrementing the current day until it is no longer a hidden day, returning a copy. 4429 // DOES NOT CONSIDER validUnzonedRange! 4430 // If the initial value of `date` is not a hidden day, don't do anything. 4431 // Pass `isExclusive` as `true` if you are dealing with an end date. 4432 // `inc` defaults to `1` (increment one day forward each time) 4433 View.prototype.skipHiddenDays = function (date, inc, isExclusive) { 4434 if (inc === void 0) { inc = 1; } 4435 if (isExclusive === void 0) { isExclusive = false; } 4436 var out = date.clone(); 4437 while (this.isHiddenDayHash[(out.day() + (isExclusive ? inc : 0) + 7) % 7]) { 4438 out.add(inc, 'days'); 4439 } 4440 return out; 4441 }; 4442 return View; 4443}(InteractiveDateComponent_1.default)); 4444exports.default = View; 4445View.prototype.usesMinMaxTime = false; 4446View.prototype.dateProfileGeneratorClass = DateProfileGenerator_1.default; 4447View.watch('displayingDates', ['isInDom', 'dateProfile'], function (deps) { 4448 this.requestDateRender(deps.dateProfile); 4449}, function () { 4450 this.requestDateUnrender(); 4451}); 4452View.watch('displayingBusinessHours', ['displayingDates', 'businessHourGenerator'], function (deps) { 4453 this.requestBusinessHoursRender(deps.businessHourGenerator); 4454}, function () { 4455 this.requestBusinessHoursUnrender(); 4456}); 4457View.watch('initialEvents', ['dateProfile'], function (deps) { 4458 return this.fetchInitialEvents(deps.dateProfile); 4459}); 4460View.watch('bindingEvents', ['initialEvents'], function (deps) { 4461 this.setEvents(deps.initialEvents); 4462 this.bindEventChanges(); 4463}, function () { 4464 this.unbindEventChanges(); 4465 this.unsetEvents(); 4466}); 4467View.watch('displayingEvents', ['displayingDates', 'hasEvents'], function () { 4468 this.requestEventsRender(this.get('currentEvents')); 4469}, function () { 4470 this.requestEventsUnrender(); 4471}); 4472View.watch('title', ['dateProfile'], function (deps) { 4473 return (this.title = this.computeTitle(deps.dateProfile)); // assign to View for legacy reasons 4474}); 4475View.watch('legacyDateProps', ['dateProfile'], function (deps) { 4476 var calendar = this.calendar; 4477 var dateProfile = deps.dateProfile; 4478 // DEPRECATED, but we need to keep it updated... 4479 this.start = calendar.msToMoment(dateProfile.activeUnzonedRange.startMs, dateProfile.isRangeAllDay); 4480 this.end = calendar.msToMoment(dateProfile.activeUnzonedRange.endMs, dateProfile.isRangeAllDay); 4481 this.intervalStart = calendar.msToMoment(dateProfile.currentUnzonedRange.startMs, dateProfile.isRangeAllDay); 4482 this.intervalEnd = calendar.msToMoment(dateProfile.currentUnzonedRange.endMs, dateProfile.isRangeAllDay); 4483}); 4484 4485 4486/***/ }), 4487/* 44 */ 4488/***/ (function(module, exports, __webpack_require__) { 4489 4490Object.defineProperty(exports, "__esModule", { value: true }); 4491var $ = __webpack_require__(3); 4492var util_1 = __webpack_require__(4); 4493var EventRenderer = /** @class */ (function () { 4494 function EventRenderer(component, fillRenderer) { 4495 this.view = component._getView(); 4496 this.component = component; 4497 this.fillRenderer = fillRenderer; 4498 } 4499 EventRenderer.prototype.opt = function (name) { 4500 return this.view.opt(name); 4501 }; 4502 // Updates values that rely on options and also relate to range 4503 EventRenderer.prototype.rangeUpdated = function () { 4504 var displayEventTime; 4505 var displayEventEnd; 4506 this.eventTimeFormat = 4507 this.opt('eventTimeFormat') || 4508 this.opt('timeFormat') || // deprecated 4509 this.computeEventTimeFormat(); 4510 displayEventTime = this.opt('displayEventTime'); 4511 if (displayEventTime == null) { 4512 displayEventTime = this.computeDisplayEventTime(); // might be based off of range 4513 } 4514 displayEventEnd = this.opt('displayEventEnd'); 4515 if (displayEventEnd == null) { 4516 displayEventEnd = this.computeDisplayEventEnd(); // might be based off of range 4517 } 4518 this.displayEventTime = displayEventTime; 4519 this.displayEventEnd = displayEventEnd; 4520 }; 4521 EventRenderer.prototype.render = function (eventsPayload) { 4522 var dateProfile = this.component._getDateProfile(); 4523 var eventDefId; 4524 var instanceGroup; 4525 var eventRanges; 4526 var bgRanges = []; 4527 var fgRanges = []; 4528 for (eventDefId in eventsPayload) { 4529 instanceGroup = eventsPayload[eventDefId]; 4530 eventRanges = instanceGroup.sliceRenderRanges(dateProfile.activeUnzonedRange); 4531 if (instanceGroup.getEventDef().hasBgRendering()) { 4532 bgRanges.push.apply(bgRanges, eventRanges); 4533 } 4534 else { 4535 fgRanges.push.apply(fgRanges, eventRanges); 4536 } 4537 } 4538 this.renderBgRanges(bgRanges); 4539 this.renderFgRanges(fgRanges); 4540 }; 4541 EventRenderer.prototype.unrender = function () { 4542 this.unrenderBgRanges(); 4543 this.unrenderFgRanges(); 4544 }; 4545 EventRenderer.prototype.renderFgRanges = function (eventRanges) { 4546 var eventFootprints = this.component.eventRangesToEventFootprints(eventRanges); 4547 var segs = this.component.eventFootprintsToSegs(eventFootprints); 4548 // render an `.el` on each seg 4549 // returns a subset of the segs. segs that were actually rendered 4550 segs = this.renderFgSegEls(segs); 4551 if (this.renderFgSegs(segs) !== false) { // no failure? 4552 this.fgSegs = segs; 4553 } 4554 }; 4555 EventRenderer.prototype.unrenderFgRanges = function () { 4556 this.unrenderFgSegs(this.fgSegs || []); 4557 this.fgSegs = null; 4558 }; 4559 EventRenderer.prototype.renderBgRanges = function (eventRanges) { 4560 var eventFootprints = this.component.eventRangesToEventFootprints(eventRanges); 4561 var segs = this.component.eventFootprintsToSegs(eventFootprints); 4562 if (this.renderBgSegs(segs) !== false) { // no failure? 4563 this.bgSegs = segs; 4564 } 4565 }; 4566 EventRenderer.prototype.unrenderBgRanges = function () { 4567 this.unrenderBgSegs(); 4568 this.bgSegs = null; 4569 }; 4570 EventRenderer.prototype.getSegs = function () { 4571 return (this.bgSegs || []).concat(this.fgSegs || []); 4572 }; 4573 // Renders foreground event segments onto the grid 4574 EventRenderer.prototype.renderFgSegs = function (segs) { 4575 // subclasses must implement 4576 // segs already has rendered els, and has been filtered. 4577 return false; // signal failure if not implemented 4578 }; 4579 // Unrenders all currently rendered foreground segments 4580 EventRenderer.prototype.unrenderFgSegs = function (segs) { 4581 // subclasses must implement 4582 }; 4583 EventRenderer.prototype.renderBgSegs = function (segs) { 4584 var _this = this; 4585 if (this.fillRenderer) { 4586 this.fillRenderer.renderSegs('bgEvent', segs, { 4587 getClasses: function (seg) { 4588 return _this.getBgClasses(seg.footprint.eventDef); 4589 }, 4590 getCss: function (seg) { 4591 return { 4592 'background-color': _this.getBgColor(seg.footprint.eventDef) 4593 }; 4594 }, 4595 filterEl: function (seg, el) { 4596 return _this.filterEventRenderEl(seg.footprint, el); 4597 } 4598 }); 4599 } 4600 else { 4601 return false; // signal failure if no fillRenderer 4602 } 4603 }; 4604 EventRenderer.prototype.unrenderBgSegs = function () { 4605 if (this.fillRenderer) { 4606 this.fillRenderer.unrender('bgEvent'); 4607 } 4608 }; 4609 // Renders and assigns an `el` property for each foreground event segment. 4610 // Only returns segments that successfully rendered. 4611 EventRenderer.prototype.renderFgSegEls = function (segs, disableResizing) { 4612 var _this = this; 4613 if (disableResizing === void 0) { disableResizing = false; } 4614 var hasEventRenderHandlers = this.view.hasPublicHandlers('eventRender'); 4615 var html = ''; 4616 var renderedSegs = []; 4617 var i; 4618 if (segs.length) { // don't build an empty html string 4619 // build a large concatenation of event segment HTML 4620 for (i = 0; i < segs.length; i++) { 4621 this.beforeFgSegHtml(segs[i]); 4622 html += this.fgSegHtml(segs[i], disableResizing); 4623 } 4624 // Grab individual elements from the combined HTML string. Use each as the default rendering. 4625 // Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false. 4626 $(html).each(function (i, node) { 4627 var seg = segs[i]; 4628 var el = $(node); 4629 if (hasEventRenderHandlers) { // optimization 4630 el = _this.filterEventRenderEl(seg.footprint, el); 4631 } 4632 if (el) { 4633 el.data('fc-seg', seg); // used by handlers 4634 seg.el = el; 4635 renderedSegs.push(seg); 4636 } 4637 }); 4638 } 4639 return renderedSegs; 4640 }; 4641 EventRenderer.prototype.beforeFgSegHtml = function (seg) { 4642 }; 4643 // Generates the HTML for the default rendering of a foreground event segment. Used by renderFgSegEls() 4644 EventRenderer.prototype.fgSegHtml = function (seg, disableResizing) { 4645 // subclasses should implement 4646 }; 4647 // Generic utility for generating the HTML classNames for an event segment's element 4648 EventRenderer.prototype.getSegClasses = function (seg, isDraggable, isResizable) { 4649 var classes = [ 4650 'fc-event', 4651 seg.isStart ? 'fc-start' : 'fc-not-start', 4652 seg.isEnd ? 'fc-end' : 'fc-not-end' 4653 ].concat(this.getClasses(seg.footprint.eventDef)); 4654 if (isDraggable) { 4655 classes.push('fc-draggable'); 4656 } 4657 if (isResizable) { 4658 classes.push('fc-resizable'); 4659 } 4660 // event is currently selected? attach a className. 4661 if (this.view.isEventDefSelected(seg.footprint.eventDef)) { 4662 classes.push('fc-selected'); 4663 } 4664 return classes; 4665 }; 4666 // Given an event and the default element used for rendering, returns the element that should actually be used. 4667 // Basically runs events and elements through the eventRender hook. 4668 EventRenderer.prototype.filterEventRenderEl = function (eventFootprint, el) { 4669 var legacy = eventFootprint.getEventLegacy(); 4670 var custom = this.view.publiclyTrigger('eventRender', { 4671 context: legacy, 4672 args: [legacy, el, this.view] 4673 }); 4674 if (custom === false) { // means don't render at all 4675 el = null; 4676 } 4677 else if (custom && custom !== true) { 4678 el = $(custom); 4679 } 4680 return el; 4681 }; 4682 // Compute the text that should be displayed on an event's element. 4683 // `range` can be the Event object itself, or something range-like, with at least a `start`. 4684 // If event times are disabled, or the event has no time, will return a blank string. 4685 // If not specified, formatStr will default to the eventTimeFormat setting, 4686 // and displayEnd will default to the displayEventEnd setting. 4687 EventRenderer.prototype.getTimeText = function (eventFootprint, formatStr, displayEnd) { 4688 return this._getTimeText(eventFootprint.eventInstance.dateProfile.start, eventFootprint.eventInstance.dateProfile.end, eventFootprint.componentFootprint.isAllDay, formatStr, displayEnd); 4689 }; 4690 EventRenderer.prototype._getTimeText = function (start, end, isAllDay, formatStr, displayEnd) { 4691 if (formatStr == null) { 4692 formatStr = this.eventTimeFormat; 4693 } 4694 if (displayEnd == null) { 4695 displayEnd = this.displayEventEnd; 4696 } 4697 if (this.displayEventTime && !isAllDay) { 4698 if (displayEnd && end) { 4699 return this.view.formatRange({ start: start, end: end }, false, // allDay 4700 formatStr); 4701 } 4702 else { 4703 return start.format(formatStr); 4704 } 4705 } 4706 return ''; 4707 }; 4708 EventRenderer.prototype.computeEventTimeFormat = function () { 4709 return this.opt('smallTimeFormat'); 4710 }; 4711 EventRenderer.prototype.computeDisplayEventTime = function () { 4712 return true; 4713 }; 4714 EventRenderer.prototype.computeDisplayEventEnd = function () { 4715 return true; 4716 }; 4717 EventRenderer.prototype.getBgClasses = function (eventDef) { 4718 var classNames = this.getClasses(eventDef); 4719 classNames.push('fc-bgevent'); 4720 return classNames; 4721 }; 4722 EventRenderer.prototype.getClasses = function (eventDef) { 4723 var objs = this.getStylingObjs(eventDef); 4724 var i; 4725 var classNames = []; 4726 for (i = 0; i < objs.length; i++) { 4727 classNames.push.apply(// append 4728 classNames, objs[i].eventClassName || objs[i].className || []); 4729 } 4730 return classNames; 4731 }; 4732 // Utility for generating event skin-related CSS properties 4733 EventRenderer.prototype.getSkinCss = function (eventDef) { 4734 return { 4735 'background-color': this.getBgColor(eventDef), 4736 'border-color': this.getBorderColor(eventDef), 4737 color: this.getTextColor(eventDef) 4738 }; 4739 }; 4740 // Queries for caller-specified color, then falls back to default 4741 EventRenderer.prototype.getBgColor = function (eventDef) { 4742 var objs = this.getStylingObjs(eventDef); 4743 var i; 4744 var val; 4745 for (i = 0; i < objs.length && !val; i++) { 4746 val = objs[i].eventBackgroundColor || objs[i].eventColor || 4747 objs[i].backgroundColor || objs[i].color; 4748 } 4749 if (!val) { 4750 val = this.opt('eventBackgroundColor') || this.opt('eventColor'); 4751 } 4752 return val; 4753 }; 4754 // Queries for caller-specified color, then falls back to default 4755 EventRenderer.prototype.getBorderColor = function (eventDef) { 4756 var objs = this.getStylingObjs(eventDef); 4757 var i; 4758 var val; 4759 for (i = 0; i < objs.length && !val; i++) { 4760 val = objs[i].eventBorderColor || objs[i].eventColor || 4761 objs[i].borderColor || objs[i].color; 4762 } 4763 if (!val) { 4764 val = this.opt('eventBorderColor') || this.opt('eventColor'); 4765 } 4766 return val; 4767 }; 4768 // Queries for caller-specified color, then falls back to default 4769 EventRenderer.prototype.getTextColor = function (eventDef) { 4770 var objs = this.getStylingObjs(eventDef); 4771 var i; 4772 var val; 4773 for (i = 0; i < objs.length && !val; i++) { 4774 val = objs[i].eventTextColor || 4775 objs[i].textColor; 4776 } 4777 if (!val) { 4778 val = this.opt('eventTextColor'); 4779 } 4780 return val; 4781 }; 4782 EventRenderer.prototype.getStylingObjs = function (eventDef) { 4783 var objs = this.getFallbackStylingObjs(eventDef); 4784 objs.unshift(eventDef); 4785 return objs; 4786 }; 4787 EventRenderer.prototype.getFallbackStylingObjs = function (eventDef) { 4788 return [eventDef.source]; 4789 }; 4790 EventRenderer.prototype.sortEventSegs = function (segs) { 4791 segs.sort(util_1.proxy(this, 'compareEventSegs')); 4792 }; 4793 // A cmp function for determining which segments should take visual priority 4794 EventRenderer.prototype.compareEventSegs = function (seg1, seg2) { 4795 var f1 = seg1.footprint; 4796 var f2 = seg2.footprint; 4797 var cf1 = f1.componentFootprint; 4798 var cf2 = f2.componentFootprint; 4799 var r1 = cf1.unzonedRange; 4800 var r2 = cf2.unzonedRange; 4801 return r1.startMs - r2.startMs || // earlier events go first 4802 (r2.endMs - r2.startMs) - (r1.endMs - r1.startMs) || // tie? longer events go first 4803 cf2.isAllDay - cf1.isAllDay || // tie? put all-day events first (booleans cast to 0/1) 4804 util_1.compareByFieldSpecs(f1.eventDef, f2.eventDef, this.view.eventOrderSpecs, f1.eventDef.miscProps, f2.eventDef.miscProps); 4805 }; 4806 return EventRenderer; 4807}()); 4808exports.default = EventRenderer; 4809 4810 4811/***/ }), 4812/* 45 */, 4813/* 46 */, 4814/* 47 */, 4815/* 48 */, 4816/* 49 */ 4817/***/ (function(module, exports, __webpack_require__) { 4818 4819Object.defineProperty(exports, "__esModule", { value: true }); 4820var moment_ext_1 = __webpack_require__(11); 4821// Plugin 4822// ------------------------------------------------------------------------------------------------- 4823moment_ext_1.newMomentProto.format = function () { 4824 if (this._fullCalendar && arguments[0]) { // an enhanced moment? and a format string provided? 4825 return formatDate(this, arguments[0]); // our extended formatting 4826 } 4827 if (this._ambigTime) { 4828 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD'); 4829 } 4830 if (this._ambigZone) { 4831 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss'); 4832 } 4833 if (this._fullCalendar) { // enhanced non-ambig moment? 4834 // moment.format() doesn't ensure english, but we want to. 4835 return moment_ext_1.oldMomentFormat(englishMoment(this)); 4836 } 4837 return moment_ext_1.oldMomentProto.format.apply(this, arguments); 4838}; 4839moment_ext_1.newMomentProto.toISOString = function () { 4840 if (this._ambigTime) { 4841 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD'); 4842 } 4843 if (this._ambigZone) { 4844 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss'); 4845 } 4846 if (this._fullCalendar) { // enhanced non-ambig moment? 4847 // depending on browser, moment might not output english. ensure english. 4848 // https://github.com/moment/moment/blob/2.18.1/src/lib/moment/format.js#L22 4849 return moment_ext_1.oldMomentProto.toISOString.apply(englishMoment(this), arguments); 4850 } 4851 return moment_ext_1.oldMomentProto.toISOString.apply(this, arguments); 4852}; 4853function englishMoment(mom) { 4854 if (mom.locale() !== 'en') { 4855 return mom.clone().locale('en'); 4856 } 4857 return mom; 4858} 4859// Config 4860// --------------------------------------------------------------------------------------------------------------------- 4861/* 4862Inserted between chunks in the fake ("intermediate") formatting string. 4863Important that it passes as whitespace (\s) because moment often identifies non-standalone months 4864via a regexp with an \s. 4865*/ 4866var PART_SEPARATOR = '\u000b'; // vertical tab 4867/* 4868Inserted as the first character of a literal-text chunk to indicate that the literal text is not actually literal text, 4869but rather, a "special" token that has custom rendering (see specialTokens map). 4870*/ 4871var SPECIAL_TOKEN_MARKER = '\u001f'; // information separator 1 4872/* 4873Inserted at the beginning and end of a span of text that must have non-zero numeric characters. 4874Handling of these markers is done in a post-processing step at the very end of text rendering. 4875*/ 4876var MAYBE_MARKER = '\u001e'; // information separator 2 4877var MAYBE_REGEXP = new RegExp(MAYBE_MARKER + '([^' + MAYBE_MARKER + ']*)' + MAYBE_MARKER, 'g'); // must be global 4878/* 4879Addition formatting tokens we want recognized 4880*/ 4881var specialTokens = { 4882 t: function (date) { 4883 return moment_ext_1.oldMomentFormat(date, 'a').charAt(0); 4884 }, 4885 T: function (date) { 4886 return moment_ext_1.oldMomentFormat(date, 'A').charAt(0); 4887 } 4888}; 4889/* 4890The first characters of formatting tokens for units that are 1 day or larger. 4891`value` is for ranking relative size (lower means bigger). 4892`unit` is a normalized unit, used for comparing moments. 4893*/ 4894var largeTokenMap = { 4895 Y: { value: 1, unit: 'year' }, 4896 M: { value: 2, unit: 'month' }, 4897 W: { value: 3, unit: 'week' }, 4898 w: { value: 3, unit: 'week' }, 4899 D: { value: 4, unit: 'day' }, 4900 d: { value: 4, unit: 'day' } // day of week 4901}; 4902// Single Date Formatting 4903// --------------------------------------------------------------------------------------------------------------------- 4904/* 4905Formats `date` with a Moment formatting string, but allow our non-zero areas and special token 4906*/ 4907function formatDate(date, formatStr) { 4908 return renderFakeFormatString(getParsedFormatString(formatStr).fakeFormatString, date); 4909} 4910exports.formatDate = formatDate; 4911// Date Range Formatting 4912// ------------------------------------------------------------------------------------------------- 4913// TODO: make it work with timezone offset 4914/* 4915Using a formatting string meant for a single date, generate a range string, like 4916"Sep 2 - 9 2013", that intelligently inserts a separator where the dates differ. 4917If the dates are the same as far as the format string is concerned, just return a single 4918rendering of one date, without any separator. 4919*/ 4920function formatRange(date1, date2, formatStr, separator, isRTL) { 4921 var localeData; 4922 date1 = moment_ext_1.default.parseZone(date1); 4923 date2 = moment_ext_1.default.parseZone(date2); 4924 localeData = date1.localeData(); 4925 // Expand localized format strings, like "LL" -> "MMMM D YYYY". 4926 // BTW, this is not important for `formatDate` because it is impossible to put custom tokens 4927 // or non-zero areas in Moment's localized format strings. 4928 formatStr = localeData.longDateFormat(formatStr) || formatStr; 4929 return renderParsedFormat(getParsedFormatString(formatStr), date1, date2, separator || ' - ', isRTL); 4930} 4931exports.formatRange = formatRange; 4932/* 4933Renders a range with an already-parsed format string. 4934*/ 4935function renderParsedFormat(parsedFormat, date1, date2, separator, isRTL) { 4936 var sameUnits = parsedFormat.sameUnits; 4937 var unzonedDate1 = date1.clone().stripZone(); // for same-unit comparisons 4938 var unzonedDate2 = date2.clone().stripZone(); // " 4939 var renderedParts1 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date1); 4940 var renderedParts2 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date2); 4941 var leftI; 4942 var leftStr = ''; 4943 var rightI; 4944 var rightStr = ''; 4945 var middleI; 4946 var middleStr1 = ''; 4947 var middleStr2 = ''; 4948 var middleStr = ''; 4949 // Start at the leftmost side of the formatting string and continue until you hit a token 4950 // that is not the same between dates. 4951 for (leftI = 0; leftI < sameUnits.length && (!sameUnits[leftI] || unzonedDate1.isSame(unzonedDate2, sameUnits[leftI])); leftI++) { 4952 leftStr += renderedParts1[leftI]; 4953 } 4954 // Similarly, start at the rightmost side of the formatting string and move left 4955 for (rightI = sameUnits.length - 1; rightI > leftI && (!sameUnits[rightI] || unzonedDate1.isSame(unzonedDate2, sameUnits[rightI])); rightI--) { 4956 // If current chunk is on the boundary of unique date-content, and is a special-case 4957 // date-formatting postfix character, then don't consume it. Consider it unique date-content. 4958 // TODO: make configurable 4959 if (rightI - 1 === leftI && renderedParts1[rightI] === '.') { 4960 break; 4961 } 4962 rightStr = renderedParts1[rightI] + rightStr; 4963 } 4964 // The area in the middle is different for both of the dates. 4965 // Collect them distinctly so we can jam them together later. 4966 for (middleI = leftI; middleI <= rightI; middleI++) { 4967 middleStr1 += renderedParts1[middleI]; 4968 middleStr2 += renderedParts2[middleI]; 4969 } 4970 if (middleStr1 || middleStr2) { 4971 if (isRTL) { 4972 middleStr = middleStr2 + separator + middleStr1; 4973 } 4974 else { 4975 middleStr = middleStr1 + separator + middleStr2; 4976 } 4977 } 4978 return processMaybeMarkers(leftStr + middleStr + rightStr); 4979} 4980// Format String Parsing 4981// --------------------------------------------------------------------------------------------------------------------- 4982var parsedFormatStrCache = {}; 4983/* 4984Returns a parsed format string, leveraging a cache. 4985*/ 4986function getParsedFormatString(formatStr) { 4987 return parsedFormatStrCache[formatStr] || 4988 (parsedFormatStrCache[formatStr] = parseFormatString(formatStr)); 4989} 4990/* 4991Parses a format string into the following: 4992- fakeFormatString: a momentJS formatting string, littered with special control characters that get post-processed. 4993- sameUnits: for every part in fakeFormatString, if the part is a token, the value will be a unit string (like "day"), 4994 that indicates how similar a range's start & end must be in order to share the same formatted text. 4995 If not a token, then the value is null. 4996 Always a flat array (not nested liked "chunks"). 4997*/ 4998function parseFormatString(formatStr) { 4999 var chunks = chunkFormatString(formatStr); 5000 return { 5001 fakeFormatString: buildFakeFormatString(chunks), 5002 sameUnits: buildSameUnits(chunks) 5003 }; 5004} 5005/* 5006Break the formatting string into an array of chunks. 5007A 'maybe' chunk will have nested chunks. 5008*/ 5009function chunkFormatString(formatStr) { 5010 var chunks = []; 5011 var match; 5012 // TODO: more descrimination 5013 // \4 is a backreference to the first character of a multi-character set. 5014 var chunker = /\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g; 5015 while ((match = chunker.exec(formatStr))) { 5016 if (match[1]) { // a literal string inside [ ... ] 5017 chunks.push.apply(chunks, // append 5018 splitStringLiteral(match[1])); 5019 } 5020 else if (match[2]) { // non-zero formatting inside ( ... ) 5021 chunks.push({ maybe: chunkFormatString(match[2]) }); 5022 } 5023 else if (match[3]) { // a formatting token 5024 chunks.push({ token: match[3] }); 5025 } 5026 else if (match[5]) { // an unenclosed literal string 5027 chunks.push.apply(chunks, // append 5028 splitStringLiteral(match[5])); 5029 } 5030 } 5031 return chunks; 5032} 5033/* 5034Potentially splits a literal-text string into multiple parts. For special cases. 5035*/ 5036function splitStringLiteral(s) { 5037 if (s === '. ') { 5038 return ['.', ' ']; // for locales with periods bound to the end of each year/month/date 5039 } 5040 else { 5041 return [s]; 5042 } 5043} 5044/* 5045Given chunks parsed from a real format string, generate a fake (aka "intermediate") format string with special control 5046characters that will eventually be given to moment for formatting, and then post-processed. 5047*/ 5048function buildFakeFormatString(chunks) { 5049 var parts = []; 5050 var i; 5051 var chunk; 5052 for (i = 0; i < chunks.length; i++) { 5053 chunk = chunks[i]; 5054 if (typeof chunk === 'string') { 5055 parts.push('[' + chunk + ']'); 5056 } 5057 else if (chunk.token) { 5058 if (chunk.token in specialTokens) { 5059 parts.push(SPECIAL_TOKEN_MARKER + // useful during post-processing 5060 '[' + chunk.token + ']' // preserve as literal text 5061 ); 5062 } 5063 else { 5064 parts.push(chunk.token); // unprotected text implies a format string 5065 } 5066 } 5067 else if (chunk.maybe) { 5068 parts.push(MAYBE_MARKER + // useful during post-processing 5069 buildFakeFormatString(chunk.maybe) + 5070 MAYBE_MARKER); 5071 } 5072 } 5073 return parts.join(PART_SEPARATOR); 5074} 5075/* 5076Given parsed chunks from a real formatting string, generates an array of unit strings (like "day") that indicate 5077in which regard two dates must be similar in order to share range formatting text. 5078The `chunks` can be nested (because of "maybe" chunks), however, the returned array will be flat. 5079*/ 5080function buildSameUnits(chunks) { 5081 var units = []; 5082 var i; 5083 var chunk; 5084 var tokenInfo; 5085 for (i = 0; i < chunks.length; i++) { 5086 chunk = chunks[i]; 5087 if (chunk.token) { 5088 tokenInfo = largeTokenMap[chunk.token.charAt(0)]; 5089 units.push(tokenInfo ? tokenInfo.unit : 'second'); // default to a very strict same-second 5090 } 5091 else if (chunk.maybe) { 5092 units.push.apply(units, // append 5093 buildSameUnits(chunk.maybe)); 5094 } 5095 else { 5096 units.push(null); 5097 } 5098 } 5099 return units; 5100} 5101// Rendering to text 5102// --------------------------------------------------------------------------------------------------------------------- 5103/* 5104Formats a date with a fake format string, post-processes the control characters, then returns. 5105*/ 5106function renderFakeFormatString(fakeFormatString, date) { 5107 return processMaybeMarkers(renderFakeFormatStringParts(fakeFormatString, date).join('')); 5108} 5109/* 5110Formats a date into parts that will have been post-processed, EXCEPT for the "maybe" markers. 5111*/ 5112function renderFakeFormatStringParts(fakeFormatString, date) { 5113 var parts = []; 5114 var fakeRender = moment_ext_1.oldMomentFormat(date, fakeFormatString); 5115 var fakeParts = fakeRender.split(PART_SEPARATOR); 5116 var i; 5117 var fakePart; 5118 for (i = 0; i < fakeParts.length; i++) { 5119 fakePart = fakeParts[i]; 5120 if (fakePart.charAt(0) === SPECIAL_TOKEN_MARKER) { 5121 parts.push( 5122 // the literal string IS the token's name. 5123 // call special token's registered function. 5124 specialTokens[fakePart.substring(1)](date)); 5125 } 5126 else { 5127 parts.push(fakePart); 5128 } 5129 } 5130 return parts; 5131} 5132/* 5133Accepts an almost-finally-formatted string and processes the "maybe" control characters, returning a new string. 5134*/ 5135function processMaybeMarkers(s) { 5136 return s.replace(MAYBE_REGEXP, function (m0, m1) { 5137 if (m1.match(/[1-9]/)) { // any non-zero numeric characters? 5138 return m1; 5139 } 5140 else { 5141 return ''; 5142 } 5143 }); 5144} 5145// Misc Utils 5146// ------------------------------------------------------------------------------------------------- 5147/* 5148Returns a unit string, either 'year', 'month', 'day', or null for the most granular formatting token in the string. 5149*/ 5150function queryMostGranularFormatUnit(formatStr) { 5151 var chunks = chunkFormatString(formatStr); 5152 var i; 5153 var chunk; 5154 var candidate; 5155 var best; 5156 for (i = 0; i < chunks.length; i++) { 5157 chunk = chunks[i]; 5158 if (chunk.token) { 5159 candidate = largeTokenMap[chunk.token.charAt(0)]; 5160 if (candidate) { 5161 if (!best || candidate.value > best.value) { 5162 best = candidate; 5163 } 5164 } 5165 } 5166 } 5167 if (best) { 5168 return best.unit; 5169 } 5170 return null; 5171} 5172exports.queryMostGranularFormatUnit = queryMostGranularFormatUnit; 5173 5174 5175/***/ }), 5176/* 50 */ 5177/***/ (function(module, exports) { 5178 5179Object.defineProperty(exports, "__esModule", { value: true }); 5180var EventRange = /** @class */ (function () { 5181 function EventRange(unzonedRange, eventDef, eventInstance) { 5182 this.unzonedRange = unzonedRange; 5183 this.eventDef = eventDef; 5184 if (eventInstance) { 5185 this.eventInstance = eventInstance; 5186 } 5187 } 5188 return EventRange; 5189}()); 5190exports.default = EventRange; 5191 5192 5193/***/ }), 5194/* 51 */ 5195/***/ (function(module, exports, __webpack_require__) { 5196 5197Object.defineProperty(exports, "__esModule", { value: true }); 5198var tslib_1 = __webpack_require__(2); 5199var Class_1 = __webpack_require__(35); 5200var EmitterMixin_1 = __webpack_require__(13); 5201var ListenerMixin_1 = __webpack_require__(7); 5202var Model = /** @class */ (function (_super) { 5203 tslib_1.__extends(Model, _super); 5204 function Model() { 5205 var _this = _super.call(this) || this; 5206 _this._watchers = {}; 5207 _this._props = {}; 5208 _this.applyGlobalWatchers(); 5209 _this.constructed(); 5210 return _this; 5211 } 5212 Model.watch = function (name) { 5213 var args = []; 5214 for (var _i = 1; _i < arguments.length; _i++) { 5215 args[_i - 1] = arguments[_i]; 5216 } 5217 // subclasses should make a masked-copy of the superclass's map 5218 // TODO: write test 5219 if (!this.prototype.hasOwnProperty('_globalWatchArgs')) { 5220 this.prototype._globalWatchArgs = Object.create(this.prototype._globalWatchArgs); 5221 } 5222 this.prototype._globalWatchArgs[name] = args; 5223 }; 5224 Model.prototype.constructed = function () { 5225 // useful for monkeypatching. TODO: BaseClass? 5226 }; 5227 Model.prototype.applyGlobalWatchers = function () { 5228 var map = this._globalWatchArgs; 5229 var name; 5230 for (name in map) { 5231 this.watch.apply(this, [name].concat(map[name])); 5232 } 5233 }; 5234 Model.prototype.has = function (name) { 5235 return name in this._props; 5236 }; 5237 Model.prototype.get = function (name) { 5238 if (name === undefined) { 5239 return this._props; 5240 } 5241 return this._props[name]; 5242 }; 5243 Model.prototype.set = function (name, val) { 5244 var newProps; 5245 if (typeof name === 'string') { 5246 newProps = {}; 5247 newProps[name] = val === undefined ? null : val; 5248 } 5249 else { 5250 newProps = name; 5251 } 5252 this.setProps(newProps); 5253 }; 5254 Model.prototype.reset = function (newProps) { 5255 var oldProps = this._props; 5256 var changeset = {}; // will have undefined's to signal unsets 5257 var name; 5258 for (name in oldProps) { 5259 changeset[name] = undefined; 5260 } 5261 for (name in newProps) { 5262 changeset[name] = newProps[name]; 5263 } 5264 this.setProps(changeset); 5265 }; 5266 Model.prototype.unset = function (name) { 5267 var newProps = {}; 5268 var names; 5269 var i; 5270 if (typeof name === 'string') { 5271 names = [name]; 5272 } 5273 else { 5274 names = name; 5275 } 5276 for (i = 0; i < names.length; i++) { 5277 newProps[names[i]] = undefined; 5278 } 5279 this.setProps(newProps); 5280 }; 5281 Model.prototype.setProps = function (newProps) { 5282 var changedProps = {}; 5283 var changedCnt = 0; 5284 var name; 5285 var val; 5286 for (name in newProps) { 5287 val = newProps[name]; 5288 // a change in value? 5289 // if an object, don't check equality, because might have been mutated internally. 5290 // TODO: eventually enforce immutability. 5291 if (typeof val === 'object' || 5292 val !== this._props[name]) { 5293 changedProps[name] = val; 5294 changedCnt++; 5295 } 5296 } 5297 if (changedCnt) { 5298 this.trigger('before:batchChange', changedProps); 5299 for (name in changedProps) { 5300 val = changedProps[name]; 5301 this.trigger('before:change', name, val); 5302 this.trigger('before:change:' + name, val); 5303 } 5304 for (name in changedProps) { 5305 val = changedProps[name]; 5306 if (val === undefined) { 5307 delete this._props[name]; 5308 } 5309 else { 5310 this._props[name] = val; 5311 } 5312 this.trigger('change:' + name, val); 5313 this.trigger('change', name, val); 5314 } 5315 this.trigger('batchChange', changedProps); 5316 } 5317 }; 5318 Model.prototype.watch = function (name, depList, startFunc, stopFunc) { 5319 var _this = this; 5320 this.unwatch(name); 5321 this._watchers[name] = this._watchDeps(depList, function (deps) { 5322 var res = startFunc.call(_this, deps); 5323 if (res && res.then) { 5324 _this.unset(name); // put in an unset state while resolving 5325 res.then(function (val) { 5326 _this.set(name, val); 5327 }); 5328 } 5329 else { 5330 _this.set(name, res); 5331 } 5332 }, function (deps) { 5333 _this.unset(name); 5334 if (stopFunc) { 5335 stopFunc.call(_this, deps); 5336 } 5337 }); 5338 }; 5339 Model.prototype.unwatch = function (name) { 5340 var watcher = this._watchers[name]; 5341 if (watcher) { 5342 delete this._watchers[name]; 5343 watcher.teardown(); 5344 } 5345 }; 5346 Model.prototype._watchDeps = function (depList, startFunc, stopFunc) { 5347 var _this = this; 5348 var queuedChangeCnt = 0; 5349 var depCnt = depList.length; 5350 var satisfyCnt = 0; 5351 var values = {}; // what's passed as the `deps` arguments 5352 var bindTuples = []; // array of [ eventName, handlerFunc ] arrays 5353 var isCallingStop = false; 5354 var onBeforeDepChange = function (depName, val, isOptional) { 5355 queuedChangeCnt++; 5356 if (queuedChangeCnt === 1) { // first change to cause a "stop" ? 5357 if (satisfyCnt === depCnt) { // all deps previously satisfied? 5358 isCallingStop = true; 5359 stopFunc(values); 5360 isCallingStop = false; 5361 } 5362 } 5363 }; 5364 var onDepChange = function (depName, val, isOptional) { 5365 if (val === undefined) { // unsetting a value? 5366 // required dependency that was previously set? 5367 if (!isOptional && values[depName] !== undefined) { 5368 satisfyCnt--; 5369 } 5370 delete values[depName]; 5371 } 5372 else { // setting a value? 5373 // required dependency that was previously unset? 5374 if (!isOptional && values[depName] === undefined) { 5375 satisfyCnt++; 5376 } 5377 values[depName] = val; 5378 } 5379 queuedChangeCnt--; 5380 if (!queuedChangeCnt) { // last change to cause a "start"? 5381 // now finally satisfied or satisfied all along? 5382 if (satisfyCnt === depCnt) { 5383 // if the stopFunc initiated another value change, ignore it. 5384 // it will be processed by another change event anyway. 5385 if (!isCallingStop) { 5386 startFunc(values); 5387 } 5388 } 5389 } 5390 }; 5391 // intercept for .on() that remembers handlers 5392 var bind = function (eventName, handler) { 5393 _this.on(eventName, handler); 5394 bindTuples.push([eventName, handler]); 5395 }; 5396 // listen to dependency changes 5397 depList.forEach(function (depName) { 5398 var isOptional = false; 5399 if (depName.charAt(0) === '?') { // TODO: more DRY 5400 depName = depName.substring(1); 5401 isOptional = true; 5402 } 5403 bind('before:change:' + depName, function (val) { 5404 onBeforeDepChange(depName, val, isOptional); 5405 }); 5406 bind('change:' + depName, function (val) { 5407 onDepChange(depName, val, isOptional); 5408 }); 5409 }); 5410 // process current dependency values 5411 depList.forEach(function (depName) { 5412 var isOptional = false; 5413 if (depName.charAt(0) === '?') { // TODO: more DRY 5414 depName = depName.substring(1); 5415 isOptional = true; 5416 } 5417 if (_this.has(depName)) { 5418 values[depName] = _this.get(depName); 5419 satisfyCnt++; 5420 } 5421 else if (isOptional) { 5422 satisfyCnt++; 5423 } 5424 }); 5425 // initially satisfied 5426 if (satisfyCnt === depCnt) { 5427 startFunc(values); 5428 } 5429 return { 5430 teardown: function () { 5431 // remove all handlers 5432 for (var i = 0; i < bindTuples.length; i++) { 5433 _this.off(bindTuples[i][0], bindTuples[i][1]); 5434 } 5435 bindTuples = null; 5436 // was satisfied, so call stopFunc 5437 if (satisfyCnt === depCnt) { 5438 stopFunc(); 5439 } 5440 }, 5441 flash: function () { 5442 if (satisfyCnt === depCnt) { 5443 stopFunc(); 5444 startFunc(values); 5445 } 5446 } 5447 }; 5448 }; 5449 Model.prototype.flash = function (name) { 5450 var watcher = this._watchers[name]; 5451 if (watcher) { 5452 watcher.flash(); 5453 } 5454 }; 5455 return Model; 5456}(Class_1.default)); 5457exports.default = Model; 5458Model.prototype._globalWatchArgs = {}; // mutation protection in Model.watch 5459EmitterMixin_1.default.mixInto(Model); 5460ListenerMixin_1.default.mixInto(Model); 5461 5462 5463/***/ }), 5464/* 52 */ 5465/***/ (function(module, exports, __webpack_require__) { 5466 5467/* 5468USAGE: 5469 import { default as ParsableModelMixin, ParsableModelInterface } from './ParsableModelMixin' 5470in class: 5471 applyProps: ParsableModelInterface['applyProps'] 5472 applyManualStandardProps: ParsableModelInterface['applyManualStandardProps'] 5473 applyMiscProps: ParsableModelInterface['applyMiscProps'] 5474 isStandardProp: ParsableModelInterface['isStandardProp'] 5475 static defineStandardProps = ParsableModelMixin.defineStandardProps 5476 static copyVerbatimStandardProps = ParsableModelMixin.copyVerbatimStandardProps 5477after class: 5478 ParsableModelMixin.mixInto(TheClass) 5479*/ 5480Object.defineProperty(exports, "__esModule", { value: true }); 5481var tslib_1 = __webpack_require__(2); 5482var util_1 = __webpack_require__(4); 5483var Mixin_1 = __webpack_require__(15); 5484var ParsableModelMixin = /** @class */ (function (_super) { 5485 tslib_1.__extends(ParsableModelMixin, _super); 5486 function ParsableModelMixin() { 5487 return _super !== null && _super.apply(this, arguments) || this; 5488 } 5489 ParsableModelMixin.defineStandardProps = function (propDefs) { 5490 var proto = this.prototype; 5491 if (!proto.hasOwnProperty('standardPropMap')) { 5492 proto.standardPropMap = Object.create(proto.standardPropMap); 5493 } 5494 util_1.copyOwnProps(propDefs, proto.standardPropMap); 5495 }; 5496 ParsableModelMixin.copyVerbatimStandardProps = function (src, dest) { 5497 var map = this.prototype.standardPropMap; 5498 var propName; 5499 for (propName in map) { 5500 if (src[propName] != null && // in the src object? 5501 map[propName] === true // false means "copy verbatim" 5502 ) { 5503 dest[propName] = src[propName]; 5504 } 5505 } 5506 }; 5507 /* 5508 Returns true/false for success. 5509 Meant to be only called ONCE, at object creation. 5510 */ 5511 ParsableModelMixin.prototype.applyProps = function (rawProps) { 5512 var standardPropMap = this.standardPropMap; 5513 var manualProps = {}; 5514 var miscProps = {}; 5515 var propName; 5516 for (propName in rawProps) { 5517 if (standardPropMap[propName] === true) { // copy verbatim 5518 this[propName] = rawProps[propName]; 5519 } 5520 else if (standardPropMap[propName] === false) { 5521 manualProps[propName] = rawProps[propName]; 5522 } 5523 else { 5524 miscProps[propName] = rawProps[propName]; 5525 } 5526 } 5527 this.applyMiscProps(miscProps); 5528 return this.applyManualStandardProps(manualProps); 5529 }; 5530 /* 5531 If subclasses override, they must call this supermethod and return the boolean response. 5532 Meant to be only called ONCE, at object creation. 5533 */ 5534 ParsableModelMixin.prototype.applyManualStandardProps = function (rawProps) { 5535 return true; 5536 }; 5537 /* 5538 Can be called even after initial object creation. 5539 */ 5540 ParsableModelMixin.prototype.applyMiscProps = function (rawProps) { 5541 // subclasses can implement 5542 }; 5543 /* 5544 TODO: why is this a method when defineStandardProps is static 5545 */ 5546 ParsableModelMixin.prototype.isStandardProp = function (propName) { 5547 return propName in this.standardPropMap; 5548 }; 5549 return ParsableModelMixin; 5550}(Mixin_1.default)); 5551exports.default = ParsableModelMixin; 5552ParsableModelMixin.prototype.standardPropMap = {}; // will be cloned by defineStandardProps 5553 5554 5555/***/ }), 5556/* 53 */ 5557/***/ (function(module, exports) { 5558 5559Object.defineProperty(exports, "__esModule", { value: true }); 5560var EventInstance = /** @class */ (function () { 5561 function EventInstance(def, dateProfile) { 5562 this.def = def; 5563 this.dateProfile = dateProfile; 5564 } 5565 EventInstance.prototype.toLegacy = function () { 5566 var dateProfile = this.dateProfile; 5567 var obj = this.def.toLegacy(); 5568 obj.start = dateProfile.start.clone(); 5569 obj.end = dateProfile.end ? dateProfile.end.clone() : null; 5570 return obj; 5571 }; 5572 return EventInstance; 5573}()); 5574exports.default = EventInstance; 5575 5576 5577/***/ }), 5578/* 54 */ 5579/***/ (function(module, exports, __webpack_require__) { 5580 5581Object.defineProperty(exports, "__esModule", { value: true }); 5582var tslib_1 = __webpack_require__(2); 5583var $ = __webpack_require__(3); 5584var moment = __webpack_require__(0); 5585var EventDef_1 = __webpack_require__(37); 5586var EventInstance_1 = __webpack_require__(53); 5587var EventDateProfile_1 = __webpack_require__(16); 5588var RecurringEventDef = /** @class */ (function (_super) { 5589 tslib_1.__extends(RecurringEventDef, _super); 5590 function RecurringEventDef() { 5591 return _super !== null && _super.apply(this, arguments) || this; 5592 } 5593 RecurringEventDef.prototype.isAllDay = function () { 5594 return !this.startTime && !this.endTime; 5595 }; 5596 RecurringEventDef.prototype.buildInstances = function (unzonedRange) { 5597 var calendar = this.source.calendar; 5598 var unzonedDate = unzonedRange.getStart(); 5599 var unzonedEnd = unzonedRange.getEnd(); 5600 var zonedDayStart; 5601 var instanceStart; 5602 var instanceEnd; 5603 var instances = []; 5604 while (unzonedDate.isBefore(unzonedEnd)) { 5605 // if everyday, or this particular day-of-week 5606 if (!this.dowHash || this.dowHash[unzonedDate.day()]) { 5607 zonedDayStart = calendar.applyTimezone(unzonedDate); 5608 instanceStart = zonedDayStart.clone(); 5609 instanceEnd = null; 5610 if (this.startTime) { 5611 instanceStart.time(this.startTime); 5612 } 5613 else { 5614 instanceStart.stripTime(); 5615 } 5616 if (this.endTime) { 5617 instanceEnd = zonedDayStart.clone().time(this.endTime); 5618 } 5619 instances.push(new EventInstance_1.default(this, // definition 5620 new EventDateProfile_1.default(instanceStart, instanceEnd, calendar))); 5621 } 5622 unzonedDate.add(1, 'days'); 5623 } 5624 return instances; 5625 }; 5626 RecurringEventDef.prototype.setDow = function (dowNumbers) { 5627 if (!this.dowHash) { 5628 this.dowHash = {}; 5629 } 5630 for (var i = 0; i < dowNumbers.length; i++) { 5631 this.dowHash[dowNumbers[i]] = true; 5632 } 5633 }; 5634 RecurringEventDef.prototype.clone = function () { 5635 var def = _super.prototype.clone.call(this); 5636 if (def.startTime) { 5637 def.startTime = moment.duration(this.startTime); 5638 } 5639 if (def.endTime) { 5640 def.endTime = moment.duration(this.endTime); 5641 } 5642 if (this.dowHash) { 5643 def.dowHash = $.extend({}, this.dowHash); 5644 } 5645 return def; 5646 }; 5647 return RecurringEventDef; 5648}(EventDef_1.default)); 5649exports.default = RecurringEventDef; 5650/* 5651HACK to work with TypeScript mixins 5652NOTE: if super-method fails, should still attempt to apply 5653*/ 5654RecurringEventDef.prototype.applyProps = function (rawProps) { 5655 var superSuccess = EventDef_1.default.prototype.applyProps.call(this, rawProps); 5656 if (rawProps.start) { 5657 this.startTime = moment.duration(rawProps.start); 5658 } 5659 if (rawProps.end) { 5660 this.endTime = moment.duration(rawProps.end); 5661 } 5662 if (rawProps.dow) { 5663 this.setDow(rawProps.dow); 5664 } 5665 return superSuccess; 5666}; 5667// Parsing 5668// --------------------------------------------------------------------------------------------------------------------- 5669RecurringEventDef.defineStandardProps({ 5670 start: false, 5671 end: false, 5672 dow: false 5673}); 5674 5675 5676/***/ }), 5677/* 55 */ 5678/***/ (function(module, exports, __webpack_require__) { 5679 5680Object.defineProperty(exports, "__esModule", { value: true }); 5681var moment = __webpack_require__(0); 5682var util_1 = __webpack_require__(4); 5683var UnzonedRange_1 = __webpack_require__(5); 5684var DateProfileGenerator = /** @class */ (function () { 5685 function DateProfileGenerator(_view) { 5686 this._view = _view; 5687 } 5688 DateProfileGenerator.prototype.opt = function (name) { 5689 return this._view.opt(name); 5690 }; 5691 DateProfileGenerator.prototype.trimHiddenDays = function (unzonedRange) { 5692 return this._view.trimHiddenDays(unzonedRange); 5693 }; 5694 DateProfileGenerator.prototype.msToUtcMoment = function (ms, forceAllDay) { 5695 return this._view.calendar.msToUtcMoment(ms, forceAllDay); 5696 }; 5697 /* Date Range Computation 5698 ------------------------------------------------------------------------------------------------------------------*/ 5699 // Builds a structure with info about what the dates/ranges will be for the "prev" view. 5700 DateProfileGenerator.prototype.buildPrev = function (currentDateProfile) { 5701 var prevDate = currentDateProfile.date.clone() 5702 .startOf(currentDateProfile.currentRangeUnit) 5703 .subtract(currentDateProfile.dateIncrement); 5704 return this.build(prevDate, -1); 5705 }; 5706 // Builds a structure with info about what the dates/ranges will be for the "next" view. 5707 DateProfileGenerator.prototype.buildNext = function (currentDateProfile) { 5708 var nextDate = currentDateProfile.date.clone() 5709 .startOf(currentDateProfile.currentRangeUnit) 5710 .add(currentDateProfile.dateIncrement); 5711 return this.build(nextDate, 1); 5712 }; 5713 // Builds a structure holding dates/ranges for rendering around the given date. 5714 // Optional direction param indicates whether the date is being incremented/decremented 5715 // from its previous value. decremented = -1, incremented = 1 (default). 5716 DateProfileGenerator.prototype.build = function (date, direction, forceToValid) { 5717 if (forceToValid === void 0) { forceToValid = false; } 5718 var isDateAllDay = !date.hasTime(); 5719 var validUnzonedRange; 5720 var minTime = null; 5721 var maxTime = null; 5722 var currentInfo; 5723 var isRangeAllDay; 5724 var renderUnzonedRange; 5725 var activeUnzonedRange; 5726 var isValid; 5727 validUnzonedRange = this.buildValidRange(); 5728 validUnzonedRange = this.trimHiddenDays(validUnzonedRange); 5729 if (forceToValid) { 5730 date = this.msToUtcMoment(validUnzonedRange.constrainDate(date), // returns MS 5731 isDateAllDay); 5732 } 5733 currentInfo = this.buildCurrentRangeInfo(date, direction); 5734 isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit); 5735 renderUnzonedRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.unzonedRange), currentInfo.unit, isRangeAllDay); 5736 renderUnzonedRange = this.trimHiddenDays(renderUnzonedRange); 5737 activeUnzonedRange = renderUnzonedRange.clone(); 5738 if (!this.opt('showNonCurrentDates')) { 5739 activeUnzonedRange = activeUnzonedRange.intersect(currentInfo.unzonedRange); 5740 } 5741 minTime = moment.duration(this.opt('minTime')); 5742 maxTime = moment.duration(this.opt('maxTime')); 5743 activeUnzonedRange = this.adjustActiveRange(activeUnzonedRange, minTime, maxTime); 5744 activeUnzonedRange = activeUnzonedRange.intersect(validUnzonedRange); // might return null 5745 if (activeUnzonedRange) { 5746 date = this.msToUtcMoment(activeUnzonedRange.constrainDate(date), // returns MS 5747 isDateAllDay); 5748 } 5749 // it's invalid if the originally requested date is not contained, 5750 // or if the range is completely outside of the valid range. 5751 isValid = currentInfo.unzonedRange.intersectsWith(validUnzonedRange); 5752 return { 5753 // constraint for where prev/next operations can go and where events can be dragged/resized to. 5754 // an object with optional start and end properties. 5755 validUnzonedRange: validUnzonedRange, 5756 // range the view is formally responsible for. 5757 // for example, a month view might have 1st-31st, excluding padded dates 5758 currentUnzonedRange: currentInfo.unzonedRange, 5759 // name of largest unit being displayed, like "month" or "week" 5760 currentRangeUnit: currentInfo.unit, 5761 isRangeAllDay: isRangeAllDay, 5762 // dates that display events and accept drag-n-drop 5763 // will be `null` if no dates accept events 5764 activeUnzonedRange: activeUnzonedRange, 5765 // date range with a rendered skeleton 5766 // includes not-active days that need some sort of DOM 5767 renderUnzonedRange: renderUnzonedRange, 5768 // Duration object that denotes the first visible time of any given day 5769 minTime: minTime, 5770 // Duration object that denotes the exclusive visible end time of any given day 5771 maxTime: maxTime, 5772 isValid: isValid, 5773 date: date, 5774 // how far the current date will move for a prev/next operation 5775 dateIncrement: this.buildDateIncrement(currentInfo.duration) 5776 // pass a fallback (might be null) ^ 5777 }; 5778 }; 5779 // Builds an object with optional start/end properties. 5780 // Indicates the minimum/maximum dates to display. 5781 // not responsible for trimming hidden days. 5782 DateProfileGenerator.prototype.buildValidRange = function () { 5783 return this._view.getUnzonedRangeOption('validRange', this._view.calendar.getNow()) || 5784 new UnzonedRange_1.default(); // completely open-ended 5785 }; 5786 // Builds a structure with info about the "current" range, the range that is 5787 // highlighted as being the current month for example. 5788 // See build() for a description of `direction`. 5789 // Guaranteed to have `range` and `unit` properties. `duration` is optional. 5790 // TODO: accept a MS-time instead of a moment `date`? 5791 DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) { 5792 var viewSpec = this._view.viewSpec; 5793 var duration = null; 5794 var unit = null; 5795 var unzonedRange = null; 5796 var dayCount; 5797 if (viewSpec.duration) { 5798 duration = viewSpec.duration; 5799 unit = viewSpec.durationUnit; 5800 unzonedRange = this.buildRangeFromDuration(date, direction, duration, unit); 5801 } 5802 else if ((dayCount = this.opt('dayCount'))) { 5803 unit = 'day'; 5804 unzonedRange = this.buildRangeFromDayCount(date, direction, dayCount); 5805 } 5806 else if ((unzonedRange = this.buildCustomVisibleRange(date))) { 5807 unit = util_1.computeGreatestUnit(unzonedRange.getStart(), unzonedRange.getEnd()); 5808 } 5809 else { 5810 duration = this.getFallbackDuration(); 5811 unit = util_1.computeGreatestUnit(duration); 5812 unzonedRange = this.buildRangeFromDuration(date, direction, duration, unit); 5813 } 5814 return { duration: duration, unit: unit, unzonedRange: unzonedRange }; 5815 }; 5816 DateProfileGenerator.prototype.getFallbackDuration = function () { 5817 return moment.duration({ days: 1 }); 5818 }; 5819 // Returns a new activeUnzonedRange to have time values (un-ambiguate) 5820 // minTime or maxTime causes the range to expand. 5821 DateProfileGenerator.prototype.adjustActiveRange = function (unzonedRange, minTime, maxTime) { 5822 var start = unzonedRange.getStart(); 5823 var end = unzonedRange.getEnd(); 5824 if (this._view.usesMinMaxTime) { 5825 if (minTime < 0) { 5826 start.time(0).add(minTime); 5827 } 5828 if (maxTime > 24 * 60 * 60 * 1000) { // beyond 24 hours? 5829 end.time(maxTime - (24 * 60 * 60 * 1000)); 5830 } 5831 } 5832 return new UnzonedRange_1.default(start, end); 5833 }; 5834 // Builds the "current" range when it is specified as an explicit duration. 5835 // `unit` is the already-computed computeGreatestUnit value of duration. 5836 // TODO: accept a MS-time instead of a moment `date`? 5837 DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) { 5838 var alignment = this.opt('dateAlignment'); 5839 var dateIncrementInput; 5840 var dateIncrementDuration; 5841 var start; 5842 var end; 5843 var res; 5844 // compute what the alignment should be 5845 if (!alignment) { 5846 dateIncrementInput = this.opt('dateIncrement'); 5847 if (dateIncrementInput) { 5848 dateIncrementDuration = moment.duration(dateIncrementInput); 5849 // use the smaller of the two units 5850 if (dateIncrementDuration < duration) { 5851 alignment = util_1.computeDurationGreatestUnit(dateIncrementDuration, dateIncrementInput); 5852 } 5853 else { 5854 alignment = unit; 5855 } 5856 } 5857 else { 5858 alignment = unit; 5859 } 5860 } 5861 // if the view displays a single day or smaller 5862 if (duration.as('days') <= 1) { 5863 if (this._view.isHiddenDay(start)) { 5864 start = this._view.skipHiddenDays(start, direction); 5865 start.startOf('day'); 5866 } 5867 } 5868 function computeRes() { 5869 start = date.clone().startOf(alignment); 5870 end = start.clone().add(duration); 5871 res = new UnzonedRange_1.default(start, end); 5872 } 5873 computeRes(); 5874 // if range is completely enveloped by hidden days, go past the hidden days 5875 if (!this.trimHiddenDays(res)) { 5876 date = this._view.skipHiddenDays(date, direction); 5877 computeRes(); 5878 } 5879 return res; 5880 }; 5881 // Builds the "current" range when a dayCount is specified. 5882 // TODO: accept a MS-time instead of a moment `date`? 5883 DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) { 5884 var customAlignment = this.opt('dateAlignment'); 5885 var runningCount = 0; 5886 var start; 5887 var end; 5888 if (customAlignment || direction !== -1) { 5889 start = date.clone(); 5890 if (customAlignment) { 5891 start.startOf(customAlignment); 5892 } 5893 start.startOf('day'); 5894 start = this._view.skipHiddenDays(start); 5895 end = start.clone(); 5896 do { 5897 end.add(1, 'day'); 5898 if (!this._view.isHiddenDay(end)) { 5899 runningCount++; 5900 } 5901 } while (runningCount < dayCount); 5902 } 5903 else { 5904 end = date.clone().startOf('day').add(1, 'day'); 5905 end = this._view.skipHiddenDays(end, -1, true); 5906 start = end.clone(); 5907 do { 5908 start.add(-1, 'day'); 5909 if (!this._view.isHiddenDay(start)) { 5910 runningCount++; 5911 } 5912 } while (runningCount < dayCount); 5913 } 5914 return new UnzonedRange_1.default(start, end); 5915 }; 5916 // Builds a normalized range object for the "visible" range, 5917 // which is a way to define the currentUnzonedRange and activeUnzonedRange at the same time. 5918 // TODO: accept a MS-time instead of a moment `date`? 5919 DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) { 5920 var visibleUnzonedRange = this._view.getUnzonedRangeOption('visibleRange', this._view.calendar.applyTimezone(date) // correct zone. also generates new obj that avoids mutations 5921 ); 5922 if (visibleUnzonedRange && (visibleUnzonedRange.startMs == null || visibleUnzonedRange.endMs == null)) { 5923 return null; 5924 } 5925 return visibleUnzonedRange; 5926 }; 5927 // Computes the range that will represent the element/cells for *rendering*, 5928 // but which may have voided days/times. 5929 // not responsible for trimming hidden days. 5930 DateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) { 5931 return currentUnzonedRange.clone(); 5932 }; 5933 // Compute the duration value that should be added/substracted to the current date 5934 // when a prev/next operation happens. 5935 DateProfileGenerator.prototype.buildDateIncrement = function (fallback) { 5936 var dateIncrementInput = this.opt('dateIncrement'); 5937 var customAlignment; 5938 if (dateIncrementInput) { 5939 return moment.duration(dateIncrementInput); 5940 } 5941 else if ((customAlignment = this.opt('dateAlignment'))) { 5942 return moment.duration(1, customAlignment); 5943 } 5944 else if (fallback) { 5945 return fallback; 5946 } 5947 else { 5948 return moment.duration({ days: 1 }); 5949 } 5950 }; 5951 return DateProfileGenerator; 5952}()); 5953exports.default = DateProfileGenerator; 5954 5955 5956/***/ }), 5957/* 56 */ 5958/***/ (function(module, exports, __webpack_require__) { 5959 5960Object.defineProperty(exports, "__esModule", { value: true }); 5961var tslib_1 = __webpack_require__(2); 5962var $ = __webpack_require__(3); 5963var util_1 = __webpack_require__(4); 5964var Promise_1 = __webpack_require__(21); 5965var EventSource_1 = __webpack_require__(6); 5966var SingleEventDef_1 = __webpack_require__(9); 5967var ArrayEventSource = /** @class */ (function (_super) { 5968 tslib_1.__extends(ArrayEventSource, _super); 5969 function ArrayEventSource(calendar) { 5970 var _this = _super.call(this, calendar) || this; 5971 _this.eventDefs = []; // for if setRawEventDefs is never called 5972 return _this; 5973 } 5974 ArrayEventSource.parse = function (rawInput, calendar) { 5975 var rawProps; 5976 // normalize raw input 5977 if ($.isArray(rawInput.events)) { // extended form 5978 rawProps = rawInput; 5979 } 5980 else if ($.isArray(rawInput)) { // short form 5981 rawProps = { events: rawInput }; 5982 } 5983 if (rawProps) { 5984 return EventSource_1.default.parse.call(this, rawProps, calendar); 5985 } 5986 return false; 5987 }; 5988 ArrayEventSource.prototype.setRawEventDefs = function (rawEventDefs) { 5989 this.rawEventDefs = rawEventDefs; 5990 this.eventDefs = this.parseEventDefs(rawEventDefs); 5991 }; 5992 ArrayEventSource.prototype.fetch = function (start, end, timezone) { 5993 var eventDefs = this.eventDefs; 5994 var i; 5995 if (this.currentTimezone != null && 5996 this.currentTimezone !== timezone) { 5997 for (i = 0; i < eventDefs.length; i++) { 5998 if (eventDefs[i] instanceof SingleEventDef_1.default) { 5999 eventDefs[i].rezone(); 6000 } 6001 } 6002 } 6003 this.currentTimezone = timezone; 6004 return Promise_1.default.resolve(eventDefs); 6005 }; 6006 ArrayEventSource.prototype.addEventDef = function (eventDef) { 6007 this.eventDefs.push(eventDef); 6008 }; 6009 /* 6010 eventDefId already normalized to a string 6011 */ 6012 ArrayEventSource.prototype.removeEventDefsById = function (eventDefId) { 6013 return util_1.removeMatching(this.eventDefs, function (eventDef) { 6014 return eventDef.id === eventDefId; 6015 }); 6016 }; 6017 ArrayEventSource.prototype.removeAllEventDefs = function () { 6018 this.eventDefs = []; 6019 }; 6020 ArrayEventSource.prototype.getPrimitive = function () { 6021 return this.rawEventDefs; 6022 }; 6023 ArrayEventSource.prototype.applyManualStandardProps = function (rawProps) { 6024 var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps); 6025 this.setRawEventDefs(rawProps.events); 6026 return superSuccess; 6027 }; 6028 return ArrayEventSource; 6029}(EventSource_1.default)); 6030exports.default = ArrayEventSource; 6031ArrayEventSource.defineStandardProps({ 6032 events: false // don't automatically transfer 6033}); 6034 6035 6036/***/ }), 6037/* 57 */ 6038/***/ (function(module, exports, __webpack_require__) { 6039 6040Object.defineProperty(exports, "__esModule", { value: true }); 6041var StandardTheme_1 = __webpack_require__(221); 6042var JqueryUiTheme_1 = __webpack_require__(222); 6043var themeClassHash = {}; 6044function defineThemeSystem(themeName, themeClass) { 6045 themeClassHash[themeName] = themeClass; 6046} 6047exports.defineThemeSystem = defineThemeSystem; 6048function getThemeSystemClass(themeSetting) { 6049 if (!themeSetting) { 6050 return StandardTheme_1.default; 6051 } 6052 else if (themeSetting === true) { 6053 return JqueryUiTheme_1.default; 6054 } 6055 else { 6056 return themeClassHash[themeSetting]; 6057 } 6058} 6059exports.getThemeSystemClass = getThemeSystemClass; 6060 6061 6062/***/ }), 6063/* 58 */ 6064/***/ (function(module, exports, __webpack_require__) { 6065 6066Object.defineProperty(exports, "__esModule", { value: true }); 6067var $ = __webpack_require__(3); 6068var util_1 = __webpack_require__(4); 6069/* 6070A cache for the left/right/top/bottom/width/height values for one or more elements. 6071Works with both offset (from topleft document) and position (from offsetParent). 6072 6073options: 6074- els 6075- isHorizontal 6076- isVertical 6077*/ 6078var CoordCache = /** @class */ (function () { 6079 function CoordCache(options) { 6080 this.isHorizontal = false; // whether to query for left/right/width 6081 this.isVertical = false; // whether to query for top/bottom/height 6082 this.els = $(options.els); 6083 this.isHorizontal = options.isHorizontal; 6084 this.isVertical = options.isVertical; 6085 this.forcedOffsetParentEl = options.offsetParent ? $(options.offsetParent) : null; 6086 } 6087 // Queries the els for coordinates and stores them. 6088 // Call this method before using and of the get* methods below. 6089 CoordCache.prototype.build = function () { 6090 var offsetParentEl = this.forcedOffsetParentEl; 6091 if (!offsetParentEl && this.els.length > 0) { 6092 offsetParentEl = this.els.eq(0).offsetParent(); 6093 } 6094 this.origin = offsetParentEl ? 6095 offsetParentEl.offset() : 6096 null; 6097 this.boundingRect = this.queryBoundingRect(); 6098 if (this.isHorizontal) { 6099 this.buildElHorizontals(); 6100 } 6101 if (this.isVertical) { 6102 this.buildElVerticals(); 6103 } 6104 }; 6105 // Destroys all internal data about coordinates, freeing memory 6106 CoordCache.prototype.clear = function () { 6107 this.origin = null; 6108 this.boundingRect = null; 6109 this.lefts = null; 6110 this.rights = null; 6111 this.tops = null; 6112 this.bottoms = null; 6113 }; 6114 // When called, if coord caches aren't built, builds them 6115 CoordCache.prototype.ensureBuilt = function () { 6116 if (!this.origin) { 6117 this.build(); 6118 } 6119 }; 6120 // Populates the left/right internal coordinate arrays 6121 CoordCache.prototype.buildElHorizontals = function () { 6122 var lefts = []; 6123 var rights = []; 6124 this.els.each(function (i, node) { 6125 var el = $(node); 6126 var left = el.offset().left; 6127 var width = el.outerWidth(); 6128 lefts.push(left); 6129 rights.push(left + width); 6130 }); 6131 this.lefts = lefts; 6132 this.rights = rights; 6133 }; 6134 // Populates the top/bottom internal coordinate arrays 6135 CoordCache.prototype.buildElVerticals = function () { 6136 var tops = []; 6137 var bottoms = []; 6138 this.els.each(function (i, node) { 6139 var el = $(node); 6140 var top = el.offset().top; 6141 var height = el.outerHeight(); 6142 tops.push(top); 6143 bottoms.push(top + height); 6144 }); 6145 this.tops = tops; 6146 this.bottoms = bottoms; 6147 }; 6148 // Given a left offset (from document left), returns the index of the el that it horizontally intersects. 6149 // If no intersection is made, returns undefined. 6150 CoordCache.prototype.getHorizontalIndex = function (leftOffset) { 6151 this.ensureBuilt(); 6152 var lefts = this.lefts; 6153 var rights = this.rights; 6154 var len = lefts.length; 6155 var i; 6156 for (i = 0; i < len; i++) { 6157 if (leftOffset >= lefts[i] && leftOffset < rights[i]) { 6158 return i; 6159 } 6160 } 6161 }; 6162 // Given a top offset (from document top), returns the index of the el that it vertically intersects. 6163 // If no intersection is made, returns undefined. 6164 CoordCache.prototype.getVerticalIndex = function (topOffset) { 6165 this.ensureBuilt(); 6166 var tops = this.tops; 6167 var bottoms = this.bottoms; 6168 var len = tops.length; 6169 var i; 6170 for (i = 0; i < len; i++) { 6171 if (topOffset >= tops[i] && topOffset < bottoms[i]) { 6172 return i; 6173 } 6174 } 6175 }; 6176 // Gets the left offset (from document left) of the element at the given index 6177 CoordCache.prototype.getLeftOffset = function (leftIndex) { 6178 this.ensureBuilt(); 6179 return this.lefts[leftIndex]; 6180 }; 6181 // Gets the left position (from offsetParent left) of the element at the given index 6182 CoordCache.prototype.getLeftPosition = function (leftIndex) { 6183 this.ensureBuilt(); 6184 return this.lefts[leftIndex] - this.origin.left; 6185 }; 6186 // Gets the right offset (from document left) of the element at the given index. 6187 // This value is NOT relative to the document's right edge, like the CSS concept of "right" would be. 6188 CoordCache.prototype.getRightOffset = function (leftIndex) { 6189 this.ensureBuilt(); 6190 return this.rights[leftIndex]; 6191 }; 6192 // Gets the right position (from offsetParent left) of the element at the given index. 6193 // This value is NOT relative to the offsetParent's right edge, like the CSS concept of "right" would be. 6194 CoordCache.prototype.getRightPosition = function (leftIndex) { 6195 this.ensureBuilt(); 6196 return this.rights[leftIndex] - this.origin.left; 6197 }; 6198 // Gets the width of the element at the given index 6199 CoordCache.prototype.getWidth = function (leftIndex) { 6200 this.ensureBuilt(); 6201 return this.rights[leftIndex] - this.lefts[leftIndex]; 6202 }; 6203 // Gets the top offset (from document top) of the element at the given index 6204 CoordCache.prototype.getTopOffset = function (topIndex) { 6205 this.ensureBuilt(); 6206 return this.tops[topIndex]; 6207 }; 6208 // Gets the top position (from offsetParent top) of the element at the given position 6209 CoordCache.prototype.getTopPosition = function (topIndex) { 6210 this.ensureBuilt(); 6211 return this.tops[topIndex] - this.origin.top; 6212 }; 6213 // Gets the bottom offset (from the document top) of the element at the given index. 6214 // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be. 6215 CoordCache.prototype.getBottomOffset = function (topIndex) { 6216 this.ensureBuilt(); 6217 return this.bottoms[topIndex]; 6218 }; 6219 // Gets the bottom position (from the offsetParent top) of the element at the given index. 6220 // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be. 6221 CoordCache.prototype.getBottomPosition = function (topIndex) { 6222 this.ensureBuilt(); 6223 return this.bottoms[topIndex] - this.origin.top; 6224 }; 6225 // Gets the height of the element at the given index 6226 CoordCache.prototype.getHeight = function (topIndex) { 6227 this.ensureBuilt(); 6228 return this.bottoms[topIndex] - this.tops[topIndex]; 6229 }; 6230 // Bounding Rect 6231 // TODO: decouple this from CoordCache 6232 // Compute and return what the elements' bounding rectangle is, from the user's perspective. 6233 // Right now, only returns a rectangle if constrained by an overflow:scroll element. 6234 // Returns null if there are no elements 6235 CoordCache.prototype.queryBoundingRect = function () { 6236 var scrollParentEl; 6237 if (this.els.length > 0) { 6238 scrollParentEl = util_1.getScrollParent(this.els.eq(0)); 6239 if (!scrollParentEl.is(document) && 6240 !scrollParentEl.is('html,body') // don't consider these bounding rects. solves issue 3615 6241 ) { 6242 return util_1.getClientRect(scrollParentEl); 6243 } 6244 } 6245 return null; 6246 }; 6247 CoordCache.prototype.isPointInBounds = function (leftOffset, topOffset) { 6248 return this.isLeftInBounds(leftOffset) && this.isTopInBounds(topOffset); 6249 }; 6250 CoordCache.prototype.isLeftInBounds = function (leftOffset) { 6251 return !this.boundingRect || (leftOffset >= this.boundingRect.left && leftOffset < this.boundingRect.right); 6252 }; 6253 CoordCache.prototype.isTopInBounds = function (topOffset) { 6254 return !this.boundingRect || (topOffset >= this.boundingRect.top && topOffset < this.boundingRect.bottom); 6255 }; 6256 return CoordCache; 6257}()); 6258exports.default = CoordCache; 6259 6260 6261/***/ }), 6262/* 59 */ 6263/***/ (function(module, exports, __webpack_require__) { 6264 6265Object.defineProperty(exports, "__esModule", { value: true }); 6266var $ = __webpack_require__(3); 6267var util_1 = __webpack_require__(4); 6268var ListenerMixin_1 = __webpack_require__(7); 6269var GlobalEmitter_1 = __webpack_require__(23); 6270/* Tracks a drag's mouse movement, firing various handlers 6271----------------------------------------------------------------------------------------------------------------------*/ 6272// TODO: use Emitter 6273var DragListener = /** @class */ (function () { 6274 function DragListener(options) { 6275 this.isInteracting = false; 6276 this.isDistanceSurpassed = false; 6277 this.isDelayEnded = false; 6278 this.isDragging = false; 6279 this.isTouch = false; 6280 this.isGeneric = false; // initiated by 'dragstart' (jqui) 6281 this.shouldCancelTouchScroll = true; 6282 this.scrollAlwaysKills = false; 6283 this.isAutoScroll = false; 6284 // defaults 6285 this.scrollSensitivity = 30; // pixels from edge for scrolling to start 6286 this.scrollSpeed = 200; // pixels per second, at maximum speed 6287 this.scrollIntervalMs = 50; // millisecond wait between scroll increment 6288 this.options = options || {}; 6289 } 6290 // Interaction (high-level) 6291 // ----------------------------------------------------------------------------------------------------------------- 6292 DragListener.prototype.startInteraction = function (ev, extraOptions) { 6293 if (extraOptions === void 0) { extraOptions = {}; } 6294 if (ev.type === 'mousedown') { 6295 if (GlobalEmitter_1.default.get().shouldIgnoreMouse()) { 6296 return; 6297 } 6298 else if (!util_1.isPrimaryMouseButton(ev)) { 6299 return; 6300 } 6301 else { 6302 ev.preventDefault(); // prevents native selection in most browsers 6303 } 6304 } 6305 if (!this.isInteracting) { 6306 // process options 6307 this.delay = util_1.firstDefined(extraOptions.delay, this.options.delay, 0); 6308 this.minDistance = util_1.firstDefined(extraOptions.distance, this.options.distance, 0); 6309 this.subjectEl = this.options.subjectEl; 6310 util_1.preventSelection($('body')); 6311 this.isInteracting = true; 6312 this.isTouch = util_1.getEvIsTouch(ev); 6313 this.isGeneric = ev.type === 'dragstart'; 6314 this.isDelayEnded = false; 6315 this.isDistanceSurpassed = false; 6316 this.originX = util_1.getEvX(ev); 6317 this.originY = util_1.getEvY(ev); 6318 this.scrollEl = util_1.getScrollParent($(ev.target)); 6319 this.bindHandlers(); 6320 this.initAutoScroll(); 6321 this.handleInteractionStart(ev); 6322 this.startDelay(ev); 6323 if (!this.minDistance) { 6324 this.handleDistanceSurpassed(ev); 6325 } 6326 } 6327 }; 6328 DragListener.prototype.handleInteractionStart = function (ev) { 6329 this.trigger('interactionStart', ev); 6330 }; 6331 DragListener.prototype.endInteraction = function (ev, isCancelled) { 6332 if (this.isInteracting) { 6333 this.endDrag(ev); 6334 if (this.delayTimeoutId) { 6335 clearTimeout(this.delayTimeoutId); 6336 this.delayTimeoutId = null; 6337 } 6338 this.destroyAutoScroll(); 6339 this.unbindHandlers(); 6340 this.isInteracting = false; 6341 this.handleInteractionEnd(ev, isCancelled); 6342 util_1.allowSelection($('body')); 6343 } 6344 }; 6345 DragListener.prototype.handleInteractionEnd = function (ev, isCancelled) { 6346 this.trigger('interactionEnd', ev, isCancelled || false); 6347 }; 6348 // Binding To DOM 6349 // ----------------------------------------------------------------------------------------------------------------- 6350 DragListener.prototype.bindHandlers = function () { 6351 // some browsers (Safari in iOS 10) don't allow preventDefault on touch events that are bound after touchstart, 6352 // so listen to the GlobalEmitter singleton, which is always bound, instead of the document directly. 6353 var globalEmitter = GlobalEmitter_1.default.get(); 6354 if (this.isGeneric) { 6355 this.listenTo($(document), { 6356 drag: this.handleMove, 6357 dragstop: this.endInteraction 6358 }); 6359 } 6360 else if (this.isTouch) { 6361 this.listenTo(globalEmitter, { 6362 touchmove: this.handleTouchMove, 6363 touchend: this.endInteraction, 6364 scroll: this.handleTouchScroll 6365 }); 6366 } 6367 else { 6368 this.listenTo(globalEmitter, { 6369 mousemove: this.handleMouseMove, 6370 mouseup: this.endInteraction 6371 }); 6372 } 6373 this.listenTo(globalEmitter, { 6374 selectstart: util_1.preventDefault, 6375 contextmenu: util_1.preventDefault // long taps would open menu on Chrome dev tools 6376 }); 6377 }; 6378 DragListener.prototype.unbindHandlers = function () { 6379 this.stopListeningTo(GlobalEmitter_1.default.get()); 6380 this.stopListeningTo($(document)); // for isGeneric 6381 }; 6382 // Drag (high-level) 6383 // ----------------------------------------------------------------------------------------------------------------- 6384 // extraOptions ignored if drag already started 6385 DragListener.prototype.startDrag = function (ev, extraOptions) { 6386 this.startInteraction(ev, extraOptions); // ensure interaction began 6387 if (!this.isDragging) { 6388 this.isDragging = true; 6389 this.handleDragStart(ev); 6390 } 6391 }; 6392 DragListener.prototype.handleDragStart = function (ev) { 6393 this.trigger('dragStart', ev); 6394 }; 6395 DragListener.prototype.handleMove = function (ev) { 6396 var dx = util_1.getEvX(ev) - this.originX; 6397 var dy = util_1.getEvY(ev) - this.originY; 6398 var minDistance = this.minDistance; 6399 var distanceSq; // current distance from the origin, squared 6400 if (!this.isDistanceSurpassed) { 6401 distanceSq = dx * dx + dy * dy; 6402 if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem 6403 this.handleDistanceSurpassed(ev); 6404 } 6405 } 6406 if (this.isDragging) { 6407 this.handleDrag(dx, dy, ev); 6408 } 6409 }; 6410 // Called while the mouse is being moved and when we know a legitimate drag is taking place 6411 DragListener.prototype.handleDrag = function (dx, dy, ev) { 6412 this.trigger('drag', dx, dy, ev); 6413 this.updateAutoScroll(ev); // will possibly cause scrolling 6414 }; 6415 DragListener.prototype.endDrag = function (ev) { 6416 if (this.isDragging) { 6417 this.isDragging = false; 6418 this.handleDragEnd(ev); 6419 } 6420 }; 6421 DragListener.prototype.handleDragEnd = function (ev) { 6422 this.trigger('dragEnd', ev); 6423 }; 6424 // Delay 6425 // ----------------------------------------------------------------------------------------------------------------- 6426 DragListener.prototype.startDelay = function (initialEv) { 6427 var _this = this; 6428 if (this.delay) { 6429 this.delayTimeoutId = setTimeout(function () { 6430 _this.handleDelayEnd(initialEv); 6431 }, this.delay); 6432 } 6433 else { 6434 this.handleDelayEnd(initialEv); 6435 } 6436 }; 6437 DragListener.prototype.handleDelayEnd = function (initialEv) { 6438 this.isDelayEnded = true; 6439 if (this.isDistanceSurpassed) { 6440 this.startDrag(initialEv); 6441 } 6442 }; 6443 // Distance 6444 // ----------------------------------------------------------------------------------------------------------------- 6445 DragListener.prototype.handleDistanceSurpassed = function (ev) { 6446 this.isDistanceSurpassed = true; 6447 if (this.isDelayEnded) { 6448 this.startDrag(ev); 6449 } 6450 }; 6451 // Mouse / Touch 6452 // ----------------------------------------------------------------------------------------------------------------- 6453 DragListener.prototype.handleTouchMove = function (ev) { 6454 // prevent inertia and touchmove-scrolling while dragging 6455 if (this.isDragging && this.shouldCancelTouchScroll) { 6456 ev.preventDefault(); 6457 } 6458 this.handleMove(ev); 6459 }; 6460 DragListener.prototype.handleMouseMove = function (ev) { 6461 this.handleMove(ev); 6462 }; 6463 // Scrolling (unrelated to auto-scroll) 6464 // ----------------------------------------------------------------------------------------------------------------- 6465 DragListener.prototype.handleTouchScroll = function (ev) { 6466 // if the drag is being initiated by touch, but a scroll happens before 6467 // the drag-initiating delay is over, cancel the drag 6468 if (!this.isDragging || this.scrollAlwaysKills) { 6469 this.endInteraction(ev, true); // isCancelled=true 6470 } 6471 }; 6472 // Utils 6473 // ----------------------------------------------------------------------------------------------------------------- 6474 // Triggers a callback. Calls a function in the option hash of the same name. 6475 // Arguments beyond the first `name` are forwarded on. 6476 DragListener.prototype.trigger = function (name) { 6477 var args = []; 6478 for (var _i = 1; _i < arguments.length; _i++) { 6479 args[_i - 1] = arguments[_i]; 6480 } 6481 if (this.options[name]) { 6482 this.options[name].apply(this, args); 6483 } 6484 // makes _methods callable by event name. TODO: kill this 6485 if (this['_' + name]) { 6486 this['_' + name].apply(this, args); 6487 } 6488 }; 6489 // Auto-scroll 6490 // ----------------------------------------------------------------------------------------------------------------- 6491 DragListener.prototype.initAutoScroll = function () { 6492 var scrollEl = this.scrollEl; 6493 this.isAutoScroll = 6494 this.options.scroll && 6495 scrollEl && 6496 !scrollEl.is(window) && 6497 !scrollEl.is(document); 6498 if (this.isAutoScroll) { 6499 // debounce makes sure rapid calls don't happen 6500 this.listenTo(scrollEl, 'scroll', util_1.debounce(this.handleDebouncedScroll, 100)); 6501 } 6502 }; 6503 DragListener.prototype.destroyAutoScroll = function () { 6504 this.endAutoScroll(); // kill any animation loop 6505 // remove the scroll handler if there is a scrollEl 6506 if (this.isAutoScroll) { 6507 this.stopListeningTo(this.scrollEl, 'scroll'); // will probably get removed by unbindHandlers too :( 6508 } 6509 }; 6510 // Computes and stores the bounding rectangle of scrollEl 6511 DragListener.prototype.computeScrollBounds = function () { 6512 if (this.isAutoScroll) { 6513 this.scrollBounds = util_1.getOuterRect(this.scrollEl); 6514 // TODO: use getClientRect in future. but prevents auto scrolling when on top of scrollbars 6515 } 6516 }; 6517 // Called when the dragging is in progress and scrolling should be updated 6518 DragListener.prototype.updateAutoScroll = function (ev) { 6519 var sensitivity = this.scrollSensitivity; 6520 var bounds = this.scrollBounds; 6521 var topCloseness; 6522 var bottomCloseness; 6523 var leftCloseness; 6524 var rightCloseness; 6525 var topVel = 0; 6526 var leftVel = 0; 6527 if (bounds) { // only scroll if scrollEl exists 6528 // compute closeness to edges. valid range is from 0.0 - 1.0 6529 topCloseness = (sensitivity - (util_1.getEvY(ev) - bounds.top)) / sensitivity; 6530 bottomCloseness = (sensitivity - (bounds.bottom - util_1.getEvY(ev))) / sensitivity; 6531 leftCloseness = (sensitivity - (util_1.getEvX(ev) - bounds.left)) / sensitivity; 6532 rightCloseness = (sensitivity - (bounds.right - util_1.getEvX(ev))) / sensitivity; 6533 // translate vertical closeness into velocity. 6534 // mouse must be completely in bounds for velocity to happen. 6535 if (topCloseness >= 0 && topCloseness <= 1) { 6536 topVel = topCloseness * this.scrollSpeed * -1; // negative. for scrolling up 6537 } 6538 else if (bottomCloseness >= 0 && bottomCloseness <= 1) { 6539 topVel = bottomCloseness * this.scrollSpeed; 6540 } 6541 // translate horizontal closeness into velocity 6542 if (leftCloseness >= 0 && leftCloseness <= 1) { 6543 leftVel = leftCloseness * this.scrollSpeed * -1; // negative. for scrolling left 6544 } 6545 else if (rightCloseness >= 0 && rightCloseness <= 1) { 6546 leftVel = rightCloseness * this.scrollSpeed; 6547 } 6548 } 6549 this.setScrollVel(topVel, leftVel); 6550 }; 6551 // Sets the speed-of-scrolling for the scrollEl 6552 DragListener.prototype.setScrollVel = function (topVel, leftVel) { 6553 this.scrollTopVel = topVel; 6554 this.scrollLeftVel = leftVel; 6555 this.constrainScrollVel(); // massages into realistic values 6556 // if there is non-zero velocity, and an animation loop hasn't already started, then START 6557 if ((this.scrollTopVel || this.scrollLeftVel) && !this.scrollIntervalId) { 6558 this.scrollIntervalId = setInterval(util_1.proxy(this, 'scrollIntervalFunc'), // scope to `this` 6559 this.scrollIntervalMs); 6560 } 6561 }; 6562 // Forces scrollTopVel and scrollLeftVel to be zero if scrolling has already gone all the way 6563 DragListener.prototype.constrainScrollVel = function () { 6564 var el = this.scrollEl; 6565 if (this.scrollTopVel < 0) { // scrolling up? 6566 if (el.scrollTop() <= 0) { // already scrolled all the way up? 6567 this.scrollTopVel = 0; 6568 } 6569 } 6570 else if (this.scrollTopVel > 0) { // scrolling down? 6571 if (el.scrollTop() + el[0].clientHeight >= el[0].scrollHeight) { // already scrolled all the way down? 6572 this.scrollTopVel = 0; 6573 } 6574 } 6575 if (this.scrollLeftVel < 0) { // scrolling left? 6576 if (el.scrollLeft() <= 0) { // already scrolled all the left? 6577 this.scrollLeftVel = 0; 6578 } 6579 } 6580 else if (this.scrollLeftVel > 0) { // scrolling right? 6581 if (el.scrollLeft() + el[0].clientWidth >= el[0].scrollWidth) { // already scrolled all the way right? 6582 this.scrollLeftVel = 0; 6583 } 6584 } 6585 }; 6586 // This function gets called during every iteration of the scrolling animation loop 6587 DragListener.prototype.scrollIntervalFunc = function () { 6588 var el = this.scrollEl; 6589 var frac = this.scrollIntervalMs / 1000; // considering animation frequency, what the vel should be mult'd by 6590 // change the value of scrollEl's scroll 6591 if (this.scrollTopVel) { 6592 el.scrollTop(el.scrollTop() + this.scrollTopVel * frac); 6593 } 6594 if (this.scrollLeftVel) { 6595 el.scrollLeft(el.scrollLeft() + this.scrollLeftVel * frac); 6596 } 6597 this.constrainScrollVel(); // since the scroll values changed, recompute the velocities 6598 // if scrolled all the way, which causes the vels to be zero, stop the animation loop 6599 if (!this.scrollTopVel && !this.scrollLeftVel) { 6600 this.endAutoScroll(); 6601 } 6602 }; 6603 // Kills any existing scrolling animation loop 6604 DragListener.prototype.endAutoScroll = function () { 6605 if (this.scrollIntervalId) { 6606 clearInterval(this.scrollIntervalId); 6607 this.scrollIntervalId = null; 6608 this.handleScrollEnd(); 6609 } 6610 }; 6611 // Get called when the scrollEl is scrolled (NOTE: this is delayed via debounce) 6612 DragListener.prototype.handleDebouncedScroll = function () { 6613 // recompute all coordinates, but *only* if this is *not* part of our scrolling animation 6614 if (!this.scrollIntervalId) { 6615 this.handleScrollEnd(); 6616 } 6617 }; 6618 DragListener.prototype.handleScrollEnd = function () { 6619 // Called when scrolling has stopped, whether through auto scroll, or the user scrolling 6620 }; 6621 return DragListener; 6622}()); 6623exports.default = DragListener; 6624ListenerMixin_1.default.mixInto(DragListener); 6625 6626 6627/***/ }), 6628/* 60 */ 6629/***/ (function(module, exports, __webpack_require__) { 6630 6631Object.defineProperty(exports, "__esModule", { value: true }); 6632var tslib_1 = __webpack_require__(2); 6633var util_1 = __webpack_require__(4); 6634var Mixin_1 = __webpack_require__(15); 6635/* 6636A set of rendering and date-related methods for a visual component comprised of one or more rows of day columns. 6637Prerequisite: the object being mixed into needs to be a *Grid* 6638*/ 6639var DayTableMixin = /** @class */ (function (_super) { 6640 tslib_1.__extends(DayTableMixin, _super); 6641 function DayTableMixin() { 6642 return _super !== null && _super.apply(this, arguments) || this; 6643 } 6644 // Populates internal variables used for date calculation and rendering 6645 DayTableMixin.prototype.updateDayTable = function () { 6646 var t = this; 6647 var view = t.view; 6648 var calendar = view.calendar; 6649 var date = calendar.msToUtcMoment(t.dateProfile.renderUnzonedRange.startMs, true); 6650 var end = calendar.msToUtcMoment(t.dateProfile.renderUnzonedRange.endMs, true); 6651 var dayIndex = -1; 6652 var dayIndices = []; 6653 var dayDates = []; 6654 var daysPerRow; 6655 var firstDay; 6656 var rowCnt; 6657 while (date.isBefore(end)) { // loop each day from start to end 6658 if (view.isHiddenDay(date)) { 6659 dayIndices.push(dayIndex + 0.5); // mark that it's between indices 6660 } 6661 else { 6662 dayIndex++; 6663 dayIndices.push(dayIndex); 6664 dayDates.push(date.clone()); 6665 } 6666 date.add(1, 'days'); 6667 } 6668 if (this.breakOnWeeks) { 6669 // count columns until the day-of-week repeats 6670 firstDay = dayDates[0].day(); 6671 for (daysPerRow = 1; daysPerRow < dayDates.length; daysPerRow++) { 6672 if (dayDates[daysPerRow].day() === firstDay) { 6673 break; 6674 } 6675 } 6676 rowCnt = Math.ceil(dayDates.length / daysPerRow); 6677 } 6678 else { 6679 rowCnt = 1; 6680 daysPerRow = dayDates.length; 6681 } 6682 this.dayDates = dayDates; 6683 this.dayIndices = dayIndices; 6684 this.daysPerRow = daysPerRow; 6685 this.rowCnt = rowCnt; 6686 this.updateDayTableCols(); 6687 }; 6688 // Computes and assigned the colCnt property and updates any options that may be computed from it 6689 DayTableMixin.prototype.updateDayTableCols = function () { 6690 this.colCnt = this.computeColCnt(); 6691 this.colHeadFormat = 6692 this.opt('columnHeaderFormat') || 6693 this.opt('columnFormat') || // deprecated 6694 this.computeColHeadFormat(); 6695 }; 6696 // Determines how many columns there should be in the table 6697 DayTableMixin.prototype.computeColCnt = function () { 6698 return this.daysPerRow; 6699 }; 6700 // Computes the ambiguously-timed moment for the given cell 6701 DayTableMixin.prototype.getCellDate = function (row, col) { 6702 return this.dayDates[this.getCellDayIndex(row, col)].clone(); 6703 }; 6704 // Computes the ambiguously-timed date range for the given cell 6705 DayTableMixin.prototype.getCellRange = function (row, col) { 6706 var start = this.getCellDate(row, col); 6707 var end = start.clone().add(1, 'days'); 6708 return { start: start, end: end }; 6709 }; 6710 // Returns the number of day cells, chronologically, from the first of the grid (0-based) 6711 DayTableMixin.prototype.getCellDayIndex = function (row, col) { 6712 return row * this.daysPerRow + this.getColDayIndex(col); 6713 }; 6714 // Returns the numner of day cells, chronologically, from the first cell in *any given row* 6715 DayTableMixin.prototype.getColDayIndex = function (col) { 6716 if (this.isRTL) { 6717 return this.colCnt - 1 - col; 6718 } 6719 else { 6720 return col; 6721 } 6722 }; 6723 // Given a date, returns its chronolocial cell-index from the first cell of the grid. 6724 // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets. 6725 // If before the first offset, returns a negative number. 6726 // If after the last offset, returns an offset past the last cell offset. 6727 // Only works for *start* dates of cells. Will not work for exclusive end dates for cells. 6728 DayTableMixin.prototype.getDateDayIndex = function (date) { 6729 var dayIndices = this.dayIndices; 6730 var dayOffset = date.diff(this.dayDates[0], 'days'); 6731 if (dayOffset < 0) { 6732 return dayIndices[0] - 1; 6733 } 6734 else if (dayOffset >= dayIndices.length) { 6735 return dayIndices[dayIndices.length - 1] + 1; 6736 } 6737 else { 6738 return dayIndices[dayOffset]; 6739 } 6740 }; 6741 /* Options 6742 ------------------------------------------------------------------------------------------------------------------*/ 6743 // Computes a default column header formatting string if `colFormat` is not explicitly defined 6744 DayTableMixin.prototype.computeColHeadFormat = function () { 6745 // if more than one week row, or if there are a lot of columns with not much space, 6746 // put just the day numbers will be in each cell 6747 if (this.rowCnt > 1 || this.colCnt > 10) { 6748 return 'ddd'; // "Sat" 6749 } 6750 else if (this.colCnt > 1) { 6751 return this.opt('dayOfMonthFormat'); // "Sat 12/10" 6752 } 6753 else { 6754 return 'dddd'; // "Saturday" 6755 } 6756 }; 6757 /* Slicing 6758 ------------------------------------------------------------------------------------------------------------------*/ 6759 // Slices up a date range into a segment for every week-row it intersects with 6760 DayTableMixin.prototype.sliceRangeByRow = function (unzonedRange) { 6761 var daysPerRow = this.daysPerRow; 6762 var normalRange = this.view.computeDayRange(unzonedRange); // make whole-day range, considering nextDayThreshold 6763 var rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index 6764 var rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index 6765 var segs = []; 6766 var row; 6767 var rowFirst; 6768 var rowLast; // inclusive day-index range for current row 6769 var segFirst; 6770 var segLast; // inclusive day-index range for segment 6771 for (row = 0; row < this.rowCnt; row++) { 6772 rowFirst = row * daysPerRow; 6773 rowLast = rowFirst + daysPerRow - 1; 6774 // intersect segment's offset range with the row's 6775 segFirst = Math.max(rangeFirst, rowFirst); 6776 segLast = Math.min(rangeLast, rowLast); 6777 // deal with in-between indices 6778 segFirst = Math.ceil(segFirst); // in-between starts round to next cell 6779 segLast = Math.floor(segLast); // in-between ends round to prev cell 6780 if (segFirst <= segLast) { // was there any intersection with the current row? 6781 segs.push({ 6782 row: row, 6783 // normalize to start of row 6784 firstRowDayIndex: segFirst - rowFirst, 6785 lastRowDayIndex: segLast - rowFirst, 6786 // must be matching integers to be the segment's start/end 6787 isStart: segFirst === rangeFirst, 6788 isEnd: segLast === rangeLast 6789 }); 6790 } 6791 } 6792 return segs; 6793 }; 6794 // Slices up a date range into a segment for every day-cell it intersects with. 6795 // TODO: make more DRY with sliceRangeByRow somehow. 6796 DayTableMixin.prototype.sliceRangeByDay = function (unzonedRange) { 6797 var daysPerRow = this.daysPerRow; 6798 var normalRange = this.view.computeDayRange(unzonedRange); // make whole-day range, considering nextDayThreshold 6799 var rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index 6800 var rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index 6801 var segs = []; 6802 var row; 6803 var rowFirst; 6804 var rowLast; // inclusive day-index range for current row 6805 var i; 6806 var segFirst; 6807 var segLast; // inclusive day-index range for segment 6808 for (row = 0; row < this.rowCnt; row++) { 6809 rowFirst = row * daysPerRow; 6810 rowLast = rowFirst + daysPerRow - 1; 6811 for (i = rowFirst; i <= rowLast; i++) { 6812 // intersect segment's offset range with the row's 6813 segFirst = Math.max(rangeFirst, i); 6814 segLast = Math.min(rangeLast, i); 6815 // deal with in-between indices 6816 segFirst = Math.ceil(segFirst); // in-between starts round to next cell 6817 segLast = Math.floor(segLast); // in-between ends round to prev cell 6818 if (segFirst <= segLast) { // was there any intersection with the current row? 6819 segs.push({ 6820 row: row, 6821 // normalize to start of row 6822 firstRowDayIndex: segFirst - rowFirst, 6823 lastRowDayIndex: segLast - rowFirst, 6824 // must be matching integers to be the segment's start/end 6825 isStart: segFirst === rangeFirst, 6826 isEnd: segLast === rangeLast 6827 }); 6828 } 6829 } 6830 } 6831 return segs; 6832 }; 6833 /* Header Rendering 6834 ------------------------------------------------------------------------------------------------------------------*/ 6835 DayTableMixin.prototype.renderHeadHtml = function () { 6836 var theme = this.view.calendar.theme; 6837 return '' + 6838 '<div class="fc-row ' + theme.getClass('headerRow') + '">' + 6839 '<table class="' + theme.getClass('tableGrid') + '">' + 6840 '<thead>' + 6841 this.renderHeadTrHtml() + 6842 '</thead>' + 6843 '</table>' + 6844 '</div>'; 6845 }; 6846 DayTableMixin.prototype.renderHeadIntroHtml = function () { 6847 return this.renderIntroHtml(); // fall back to generic 6848 }; 6849 DayTableMixin.prototype.renderHeadTrHtml = function () { 6850 return '' + 6851 '<tr>' + 6852 (this.isRTL ? '' : this.renderHeadIntroHtml()) + 6853 this.renderHeadDateCellsHtml() + 6854 (this.isRTL ? this.renderHeadIntroHtml() : '') + 6855 '</tr>'; 6856 }; 6857 DayTableMixin.prototype.renderHeadDateCellsHtml = function () { 6858 var htmls = []; 6859 var col; 6860 var date; 6861 for (col = 0; col < this.colCnt; col++) { 6862 date = this.getCellDate(0, col); 6863 htmls.push(this.renderHeadDateCellHtml(date)); 6864 } 6865 return htmls.join(''); 6866 }; 6867 // TODO: when internalApiVersion, accept an object for HTML attributes 6868 // (colspan should be no different) 6869 DayTableMixin.prototype.renderHeadDateCellHtml = function (date, colspan, otherAttrs) { 6870 var t = this; 6871 var view = t.view; 6872 var isDateValid = t.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow. 6873 var classNames = [ 6874 'fc-day-header', 6875 view.calendar.theme.getClass('widgetHeader') 6876 ]; 6877 var innerHtml; 6878 if (typeof t.opt('columnHeaderHtml') === 'function') { 6879 innerHtml = t.opt('columnHeaderHtml')(date); 6880 } 6881 else if (typeof t.opt('columnHeaderText') === 'function') { 6882 innerHtml = util_1.htmlEscape(t.opt('columnHeaderText')(date)); 6883 } 6884 else { 6885 innerHtml = util_1.htmlEscape(date.format(t.colHeadFormat)); 6886 } 6887 // if only one row of days, the classNames on the header can represent the specific days beneath 6888 if (t.rowCnt === 1) { 6889 classNames = classNames.concat( 6890 // includes the day-of-week class 6891 // noThemeHighlight=true (don't highlight the header) 6892 t.getDayClasses(date, true)); 6893 } 6894 else { 6895 classNames.push('fc-' + util_1.dayIDs[date.day()]); // only add the day-of-week class 6896 } 6897 return '' + 6898 '<th class="' + classNames.join(' ') + '"' + 6899 ((isDateValid && t.rowCnt) === 1 ? 6900 ' data-date="' + date.format('YYYY-MM-DD') + '"' : 6901 '') + 6902 (colspan > 1 ? 6903 ' colspan="' + colspan + '"' : 6904 '') + 6905 (otherAttrs ? 6906 ' ' + otherAttrs : 6907 '') + 6908 '>' + 6909 (isDateValid ? 6910 // don't make a link if the heading could represent multiple days, or if there's only one day (forceOff) 6911 view.buildGotoAnchorHtml({ date: date, forceOff: t.rowCnt > 1 || t.colCnt === 1 }, innerHtml) : 6912 // if not valid, display text, but no link 6913 innerHtml) + 6914 '</th>'; 6915 }; 6916 /* Background Rendering 6917 ------------------------------------------------------------------------------------------------------------------*/ 6918 DayTableMixin.prototype.renderBgTrHtml = function (row) { 6919 return '' + 6920 '<tr>' + 6921 (this.isRTL ? '' : this.renderBgIntroHtml(row)) + 6922 this.renderBgCellsHtml(row) + 6923 (this.isRTL ? this.renderBgIntroHtml(row) : '') + 6924 '</tr>'; 6925 }; 6926 DayTableMixin.prototype.renderBgIntroHtml = function (row) { 6927 return this.renderIntroHtml(); // fall back to generic 6928 }; 6929 DayTableMixin.prototype.renderBgCellsHtml = function (row) { 6930 var htmls = []; 6931 var col; 6932 var date; 6933 for (col = 0; col < this.colCnt; col++) { 6934 date = this.getCellDate(row, col); 6935 htmls.push(this.renderBgCellHtml(date)); 6936 } 6937 return htmls.join(''); 6938 }; 6939 DayTableMixin.prototype.renderBgCellHtml = function (date, otherAttrs) { 6940 var t = this; 6941 var view = t.view; 6942 var isDateValid = t.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow. 6943 var classes = t.getDayClasses(date); 6944 classes.unshift('fc-day', view.calendar.theme.getClass('widgetContent')); 6945 return '<td class="' + classes.join(' ') + '"' + 6946 (isDateValid ? 6947 ' data-date="' + date.format('YYYY-MM-DD') + '"' : // if date has a time, won't format it 6948 '') + 6949 (otherAttrs ? 6950 ' ' + otherAttrs : 6951 '') + 6952 '></td>'; 6953 }; 6954 /* Generic 6955 ------------------------------------------------------------------------------------------------------------------*/ 6956 DayTableMixin.prototype.renderIntroHtml = function () { 6957 // Generates the default HTML intro for any row. User classes should override 6958 }; 6959 // TODO: a generic method for dealing with <tr>, RTL, intro 6960 // when increment internalApiVersion 6961 // wrapTr (scheduler) 6962 /* Utils 6963 ------------------------------------------------------------------------------------------------------------------*/ 6964 // Applies the generic "intro" and "outro" HTML to the given cells. 6965 // Intro means the leftmost cell when the calendar is LTR and the rightmost cell when RTL. Vice-versa for outro. 6966 DayTableMixin.prototype.bookendCells = function (trEl) { 6967 var introHtml = this.renderIntroHtml(); 6968 if (introHtml) { 6969 if (this.isRTL) { 6970 trEl.append(introHtml); 6971 } 6972 else { 6973 trEl.prepend(introHtml); 6974 } 6975 } 6976 }; 6977 return DayTableMixin; 6978}(Mixin_1.default)); 6979exports.default = DayTableMixin; 6980 6981 6982/***/ }), 6983/* 61 */ 6984/***/ (function(module, exports) { 6985 6986Object.defineProperty(exports, "__esModule", { value: true }); 6987var BusinessHourRenderer = /** @class */ (function () { 6988 /* 6989 component implements: 6990 - eventRangesToEventFootprints 6991 - eventFootprintsToSegs 6992 */ 6993 function BusinessHourRenderer(component, fillRenderer) { 6994 this.component = component; 6995 this.fillRenderer = fillRenderer; 6996 } 6997 BusinessHourRenderer.prototype.render = function (businessHourGenerator) { 6998 var component = this.component; 6999 var unzonedRange = component._getDateProfile().activeUnzonedRange; 7000 var eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(component.hasAllDayBusinessHours, unzonedRange); 7001 var eventFootprints = eventInstanceGroup ? 7002 component.eventRangesToEventFootprints(eventInstanceGroup.sliceRenderRanges(unzonedRange)) : 7003 []; 7004 this.renderEventFootprints(eventFootprints); 7005 }; 7006 BusinessHourRenderer.prototype.renderEventFootprints = function (eventFootprints) { 7007 var segs = this.component.eventFootprintsToSegs(eventFootprints); 7008 this.renderSegs(segs); 7009 this.segs = segs; 7010 }; 7011 BusinessHourRenderer.prototype.renderSegs = function (segs) { 7012 if (this.fillRenderer) { 7013 this.fillRenderer.renderSegs('businessHours', segs, { 7014 getClasses: function (seg) { 7015 return ['fc-nonbusiness', 'fc-bgevent']; 7016 } 7017 }); 7018 } 7019 }; 7020 BusinessHourRenderer.prototype.unrender = function () { 7021 if (this.fillRenderer) { 7022 this.fillRenderer.unrender('businessHours'); 7023 } 7024 this.segs = null; 7025 }; 7026 BusinessHourRenderer.prototype.getSegs = function () { 7027 return this.segs || []; 7028 }; 7029 return BusinessHourRenderer; 7030}()); 7031exports.default = BusinessHourRenderer; 7032 7033 7034/***/ }), 7035/* 62 */ 7036/***/ (function(module, exports, __webpack_require__) { 7037 7038Object.defineProperty(exports, "__esModule", { value: true }); 7039var $ = __webpack_require__(3); 7040var util_1 = __webpack_require__(4); 7041var FillRenderer = /** @class */ (function () { 7042 function FillRenderer(component) { 7043 this.fillSegTag = 'div'; 7044 this.component = component; 7045 this.elsByFill = {}; 7046 } 7047 FillRenderer.prototype.renderFootprint = function (type, componentFootprint, props) { 7048 this.renderSegs(type, this.component.componentFootprintToSegs(componentFootprint), props); 7049 }; 7050 FillRenderer.prototype.renderSegs = function (type, segs, props) { 7051 var els; 7052 segs = this.buildSegEls(type, segs, props); // assignes `.el` to each seg. returns successfully rendered segs 7053 els = this.attachSegEls(type, segs); 7054 if (els) { 7055 this.reportEls(type, els); 7056 } 7057 return segs; 7058 }; 7059 // Unrenders a specific type of fill that is currently rendered on the grid 7060 FillRenderer.prototype.unrender = function (type) { 7061 var el = this.elsByFill[type]; 7062 if (el) { 7063 el.remove(); 7064 delete this.elsByFill[type]; 7065 } 7066 }; 7067 // Renders and assigns an `el` property for each fill segment. Generic enough to work with different types. 7068 // Only returns segments that successfully rendered. 7069 FillRenderer.prototype.buildSegEls = function (type, segs, props) { 7070 var _this = this; 7071 var html = ''; 7072 var renderedSegs = []; 7073 var i; 7074 if (segs.length) { 7075 // build a large concatenation of segment HTML 7076 for (i = 0; i < segs.length; i++) { 7077 html += this.buildSegHtml(type, segs[i], props); 7078 } 7079 // Grab individual elements from the combined HTML string. Use each as the default rendering. 7080 // Then, compute the 'el' for each segment. 7081 $(html).each(function (i, node) { 7082 var seg = segs[i]; 7083 var el = $(node); 7084 // allow custom filter methods per-type 7085 if (props.filterEl) { 7086 el = props.filterEl(seg, el); 7087 } 7088 if (el) { // custom filters did not cancel the render 7089 el = $(el); // allow custom filter to return raw DOM node 7090 // correct element type? (would be bad if a non-TD were inserted into a table for example) 7091 if (el.is(_this.fillSegTag)) { 7092 seg.el = el; 7093 renderedSegs.push(seg); 7094 } 7095 } 7096 }); 7097 } 7098 return renderedSegs; 7099 }; 7100 // Builds the HTML needed for one fill segment. Generic enough to work with different types. 7101 FillRenderer.prototype.buildSegHtml = function (type, seg, props) { 7102 // custom hooks per-type 7103 var classes = props.getClasses ? props.getClasses(seg) : []; 7104 var css = util_1.cssToStr(props.getCss ? props.getCss(seg) : {}); 7105 return '<' + this.fillSegTag + 7106 (classes.length ? ' class="' + classes.join(' ') + '"' : '') + 7107 (css ? ' style="' + css + '"' : '') + 7108 '></' + this.fillSegTag + '>'; 7109 }; 7110 // Should return wrapping DOM structure 7111 FillRenderer.prototype.attachSegEls = function (type, segs) { 7112 // subclasses must implement 7113 }; 7114 FillRenderer.prototype.reportEls = function (type, nodes) { 7115 if (this.elsByFill[type]) { 7116 this.elsByFill[type] = this.elsByFill[type].add(nodes); 7117 } 7118 else { 7119 this.elsByFill[type] = $(nodes); 7120 } 7121 }; 7122 return FillRenderer; 7123}()); 7124exports.default = FillRenderer; 7125 7126 7127/***/ }), 7128/* 63 */ 7129/***/ (function(module, exports, __webpack_require__) { 7130 7131Object.defineProperty(exports, "__esModule", { value: true }); 7132var SingleEventDef_1 = __webpack_require__(9); 7133var EventFootprint_1 = __webpack_require__(34); 7134var EventSource_1 = __webpack_require__(6); 7135var HelperRenderer = /** @class */ (function () { 7136 function HelperRenderer(component, eventRenderer) { 7137 this.view = component._getView(); 7138 this.component = component; 7139 this.eventRenderer = eventRenderer; 7140 } 7141 HelperRenderer.prototype.renderComponentFootprint = function (componentFootprint) { 7142 this.renderEventFootprints([ 7143 this.fabricateEventFootprint(componentFootprint) 7144 ]); 7145 }; 7146 HelperRenderer.prototype.renderEventDraggingFootprints = function (eventFootprints, sourceSeg, isTouch) { 7147 this.renderEventFootprints(eventFootprints, sourceSeg, 'fc-dragging', isTouch ? null : this.view.opt('dragOpacity')); 7148 }; 7149 HelperRenderer.prototype.renderEventResizingFootprints = function (eventFootprints, sourceSeg, isTouch) { 7150 this.renderEventFootprints(eventFootprints, sourceSeg, 'fc-resizing'); 7151 }; 7152 HelperRenderer.prototype.renderEventFootprints = function (eventFootprints, sourceSeg, extraClassNames, opacity) { 7153 var segs = this.component.eventFootprintsToSegs(eventFootprints); 7154 var classNames = 'fc-helper ' + (extraClassNames || ''); 7155 var i; 7156 // assigns each seg's el and returns a subset of segs that were rendered 7157 segs = this.eventRenderer.renderFgSegEls(segs); 7158 for (i = 0; i < segs.length; i++) { 7159 segs[i].el.addClass(classNames); 7160 } 7161 if (opacity != null) { 7162 for (i = 0; i < segs.length; i++) { 7163 segs[i].el.css('opacity', opacity); 7164 } 7165 } 7166 this.helperEls = this.renderSegs(segs, sourceSeg); 7167 }; 7168 /* 7169 Must return all mock event elements 7170 */ 7171 HelperRenderer.prototype.renderSegs = function (segs, sourceSeg) { 7172 // Subclasses must implement 7173 }; 7174 HelperRenderer.prototype.unrender = function () { 7175 if (this.helperEls) { 7176 this.helperEls.remove(); 7177 this.helperEls = null; 7178 } 7179 }; 7180 HelperRenderer.prototype.fabricateEventFootprint = function (componentFootprint) { 7181 var calendar = this.view.calendar; 7182 var eventDateProfile = calendar.footprintToDateProfile(componentFootprint); 7183 var dummyEvent = new SingleEventDef_1.default(new EventSource_1.default(calendar)); 7184 var dummyInstance; 7185 dummyEvent.dateProfile = eventDateProfile; 7186 dummyInstance = dummyEvent.buildInstance(); 7187 return new EventFootprint_1.default(componentFootprint, dummyEvent, dummyInstance); 7188 }; 7189 return HelperRenderer; 7190}()); 7191exports.default = HelperRenderer; 7192 7193 7194/***/ }), 7195/* 64 */ 7196/***/ (function(module, exports, __webpack_require__) { 7197 7198Object.defineProperty(exports, "__esModule", { value: true }); 7199var tslib_1 = __webpack_require__(2); 7200var GlobalEmitter_1 = __webpack_require__(23); 7201var Interaction_1 = __webpack_require__(14); 7202var EventPointing = /** @class */ (function (_super) { 7203 tslib_1.__extends(EventPointing, _super); 7204 function EventPointing() { 7205 return _super !== null && _super.apply(this, arguments) || this; 7206 } 7207 /* 7208 component must implement: 7209 - publiclyTrigger 7210 */ 7211 EventPointing.prototype.bindToEl = function (el) { 7212 var component = this.component; 7213 component.bindSegHandlerToEl(el, 'click', this.handleClick.bind(this)); 7214 component.bindSegHandlerToEl(el, 'mouseenter', this.handleMouseover.bind(this)); 7215 component.bindSegHandlerToEl(el, 'mouseleave', this.handleMouseout.bind(this)); 7216 }; 7217 EventPointing.prototype.handleClick = function (seg, ev) { 7218 var res = this.component.publiclyTrigger('eventClick', { 7219 context: seg.el[0], 7220 args: [seg.footprint.getEventLegacy(), ev, this.view] 7221 }); 7222 if (res === false) { 7223 ev.preventDefault(); 7224 } 7225 }; 7226 // Updates internal state and triggers handlers for when an event element is moused over 7227 EventPointing.prototype.handleMouseover = function (seg, ev) { 7228 if (!GlobalEmitter_1.default.get().shouldIgnoreMouse() && 7229 !this.mousedOverSeg) { 7230 this.mousedOverSeg = seg; 7231 // TODO: move to EventSelecting's responsibility 7232 if (this.view.isEventDefResizable(seg.footprint.eventDef)) { 7233 seg.el.addClass('fc-allow-mouse-resize'); 7234 } 7235 this.component.publiclyTrigger('eventMouseover', { 7236 context: seg.el[0], 7237 args: [seg.footprint.getEventLegacy(), ev, this.view] 7238 }); 7239 } 7240 }; 7241 // Updates internal state and triggers handlers for when an event element is moused out. 7242 // Can be given no arguments, in which case it will mouseout the segment that was previously moused over. 7243 EventPointing.prototype.handleMouseout = function (seg, ev) { 7244 if (this.mousedOverSeg) { 7245 this.mousedOverSeg = null; 7246 // TODO: move to EventSelecting's responsibility 7247 if (this.view.isEventDefResizable(seg.footprint.eventDef)) { 7248 seg.el.removeClass('fc-allow-mouse-resize'); 7249 } 7250 this.component.publiclyTrigger('eventMouseout', { 7251 context: seg.el[0], 7252 args: [ 7253 seg.footprint.getEventLegacy(), 7254 ev || {}, 7255 this.view 7256 ] 7257 }); 7258 } 7259 }; 7260 EventPointing.prototype.end = function () { 7261 if (this.mousedOverSeg) { 7262 this.handleMouseout(this.mousedOverSeg); 7263 } 7264 }; 7265 return EventPointing; 7266}(Interaction_1.default)); 7267exports.default = EventPointing; 7268 7269 7270/***/ }), 7271/* 65 */ 7272/***/ (function(module, exports, __webpack_require__) { 7273 7274Object.defineProperty(exports, "__esModule", { value: true }); 7275var tslib_1 = __webpack_require__(2); 7276var Mixin_1 = __webpack_require__(15); 7277var DateClicking_1 = __webpack_require__(237); 7278var DateSelecting_1 = __webpack_require__(236); 7279var EventPointing_1 = __webpack_require__(64); 7280var EventDragging_1 = __webpack_require__(235); 7281var EventResizing_1 = __webpack_require__(234); 7282var ExternalDropping_1 = __webpack_require__(233); 7283var StandardInteractionsMixin = /** @class */ (function (_super) { 7284 tslib_1.__extends(StandardInteractionsMixin, _super); 7285 function StandardInteractionsMixin() { 7286 return _super !== null && _super.apply(this, arguments) || this; 7287 } 7288 return StandardInteractionsMixin; 7289}(Mixin_1.default)); 7290exports.default = StandardInteractionsMixin; 7291StandardInteractionsMixin.prototype.dateClickingClass = DateClicking_1.default; 7292StandardInteractionsMixin.prototype.dateSelectingClass = DateSelecting_1.default; 7293StandardInteractionsMixin.prototype.eventPointingClass = EventPointing_1.default; 7294StandardInteractionsMixin.prototype.eventDraggingClass = EventDragging_1.default; 7295StandardInteractionsMixin.prototype.eventResizingClass = EventResizing_1.default; 7296StandardInteractionsMixin.prototype.externalDroppingClass = ExternalDropping_1.default; 7297 7298 7299/***/ }), 7300/* 66 */ 7301/***/ (function(module, exports, __webpack_require__) { 7302 7303Object.defineProperty(exports, "__esModule", { value: true }); 7304var tslib_1 = __webpack_require__(2); 7305var $ = __webpack_require__(3); 7306var util_1 = __webpack_require__(4); 7307var CoordCache_1 = __webpack_require__(58); 7308var Popover_1 = __webpack_require__(227); 7309var UnzonedRange_1 = __webpack_require__(5); 7310var ComponentFootprint_1 = __webpack_require__(12); 7311var EventFootprint_1 = __webpack_require__(34); 7312var BusinessHourRenderer_1 = __webpack_require__(61); 7313var StandardInteractionsMixin_1 = __webpack_require__(65); 7314var InteractiveDateComponent_1 = __webpack_require__(42); 7315var DayTableMixin_1 = __webpack_require__(60); 7316var DayGridEventRenderer_1 = __webpack_require__(243); 7317var DayGridHelperRenderer_1 = __webpack_require__(244); 7318var DayGridFillRenderer_1 = __webpack_require__(245); 7319/* A component that renders a grid of whole-days that runs horizontally. There can be multiple rows, one per week. 7320----------------------------------------------------------------------------------------------------------------------*/ 7321var DayGrid = /** @class */ (function (_super) { 7322 tslib_1.__extends(DayGrid, _super); 7323 function DayGrid(view) { 7324 var _this = _super.call(this, view) || this; 7325 _this.cellWeekNumbersVisible = false; // display week numbers in day cell? 7326 _this.bottomCoordPadding = 0; // hack for extending the hit area for the last row of the coordinate grid 7327 // isRigid determines whether the individual rows should ignore the contents and be a constant height. 7328 // Relies on the view's colCnt and rowCnt. In the future, this component should probably be self-sufficient. 7329 _this.isRigid = false; 7330 _this.hasAllDayBusinessHours = true; 7331 return _this; 7332 } 7333 // Slices up the given span (unzoned start/end with other misc data) into an array of segments 7334 DayGrid.prototype.componentFootprintToSegs = function (componentFootprint) { 7335 var segs = this.sliceRangeByRow(componentFootprint.unzonedRange); 7336 var i; 7337 var seg; 7338 for (i = 0; i < segs.length; i++) { 7339 seg = segs[i]; 7340 if (this.isRTL) { 7341 seg.leftCol = this.daysPerRow - 1 - seg.lastRowDayIndex; 7342 seg.rightCol = this.daysPerRow - 1 - seg.firstRowDayIndex; 7343 } 7344 else { 7345 seg.leftCol = seg.firstRowDayIndex; 7346 seg.rightCol = seg.lastRowDayIndex; 7347 } 7348 } 7349 return segs; 7350 }; 7351 /* Date Rendering 7352 ------------------------------------------------------------------------------------------------------------------*/ 7353 DayGrid.prototype.renderDates = function (dateProfile) { 7354 this.dateProfile = dateProfile; 7355 this.updateDayTable(); 7356 this.renderGrid(); 7357 }; 7358 DayGrid.prototype.unrenderDates = function () { 7359 this.removeSegPopover(); 7360 }; 7361 // Renders the rows and columns into the component's `this.el`, which should already be assigned. 7362 DayGrid.prototype.renderGrid = function () { 7363 var view = this.view; 7364 var rowCnt = this.rowCnt; 7365 var colCnt = this.colCnt; 7366 var html = ''; 7367 var row; 7368 var col; 7369 if (this.headContainerEl) { 7370 this.headContainerEl.html(this.renderHeadHtml()); 7371 } 7372 for (row = 0; row < rowCnt; row++) { 7373 html += this.renderDayRowHtml(row, this.isRigid); 7374 } 7375 this.el.html(html); 7376 this.rowEls = this.el.find('.fc-row'); 7377 this.cellEls = this.el.find('.fc-day, .fc-disabled-day'); 7378 this.rowCoordCache = new CoordCache_1.default({ 7379 els: this.rowEls, 7380 isVertical: true 7381 }); 7382 this.colCoordCache = new CoordCache_1.default({ 7383 els: this.cellEls.slice(0, this.colCnt), 7384 isHorizontal: true 7385 }); 7386 // trigger dayRender with each cell's element 7387 for (row = 0; row < rowCnt; row++) { 7388 for (col = 0; col < colCnt; col++) { 7389 this.publiclyTrigger('dayRender', { 7390 context: view, 7391 args: [ 7392 this.getCellDate(row, col), 7393 this.getCellEl(row, col), 7394 view 7395 ] 7396 }); 7397 } 7398 } 7399 }; 7400 // Generates the HTML for a single row, which is a div that wraps a table. 7401 // `row` is the row number. 7402 DayGrid.prototype.renderDayRowHtml = function (row, isRigid) { 7403 var theme = this.view.calendar.theme; 7404 var classes = ['fc-row', 'fc-week', theme.getClass('dayRow')]; 7405 if (isRigid) { 7406 classes.push('fc-rigid'); 7407 } 7408 return '' + 7409 '<div class="' + classes.join(' ') + '">' + 7410 '<div class="fc-bg">' + 7411 '<table class="' + theme.getClass('tableGrid') + '">' + 7412 this.renderBgTrHtml(row) + 7413 '</table>' + 7414 '</div>' + 7415 '<div class="fc-content-skeleton">' + 7416 '<table>' + 7417 (this.getIsNumbersVisible() ? 7418 '<thead>' + 7419 this.renderNumberTrHtml(row) + 7420 '</thead>' : 7421 '') + 7422 '</table>' + 7423 '</div>' + 7424 '</div>'; 7425 }; 7426 DayGrid.prototype.getIsNumbersVisible = function () { 7427 return this.getIsDayNumbersVisible() || this.cellWeekNumbersVisible; 7428 }; 7429 DayGrid.prototype.getIsDayNumbersVisible = function () { 7430 return this.rowCnt > 1; 7431 }; 7432 /* Grid Number Rendering 7433 ------------------------------------------------------------------------------------------------------------------*/ 7434 DayGrid.prototype.renderNumberTrHtml = function (row) { 7435 return '' + 7436 '<tr>' + 7437 (this.isRTL ? '' : this.renderNumberIntroHtml(row)) + 7438 this.renderNumberCellsHtml(row) + 7439 (this.isRTL ? this.renderNumberIntroHtml(row) : '') + 7440 '</tr>'; 7441 }; 7442 DayGrid.prototype.renderNumberIntroHtml = function (row) { 7443 return this.renderIntroHtml(); 7444 }; 7445 DayGrid.prototype.renderNumberCellsHtml = function (row) { 7446 var htmls = []; 7447 var col; 7448 var date; 7449 for (col = 0; col < this.colCnt; col++) { 7450 date = this.getCellDate(row, col); 7451 htmls.push(this.renderNumberCellHtml(date)); 7452 } 7453 return htmls.join(''); 7454 }; 7455 // Generates the HTML for the <td>s of the "number" row in the DayGrid's content skeleton. 7456 // The number row will only exist if either day numbers or week numbers are turned on. 7457 DayGrid.prototype.renderNumberCellHtml = function (date) { 7458 var view = this.view; 7459 var html = ''; 7460 var isDateValid = this.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow. 7461 var isDayNumberVisible = this.getIsDayNumbersVisible() && isDateValid; 7462 var classes; 7463 var weekCalcFirstDoW; 7464 if (!isDayNumberVisible && !this.cellWeekNumbersVisible) { 7465 // no numbers in day cell (week number must be along the side) 7466 return '<td></td>'; // will create an empty space above events :( 7467 } 7468 classes = this.getDayClasses(date); 7469 classes.unshift('fc-day-top'); 7470 if (this.cellWeekNumbersVisible) { 7471 // To determine the day of week number change under ISO, we cannot 7472 // rely on moment.js methods such as firstDayOfWeek() or weekday(), 7473 // because they rely on the locale's dow (possibly overridden by 7474 // our firstDay option), which may not be Monday. We cannot change 7475 // dow, because that would affect the calendar start day as well. 7476 if (date._locale._fullCalendar_weekCalc === 'ISO') { 7477 weekCalcFirstDoW = 1; // Monday by ISO 8601 definition 7478 } 7479 else { 7480 weekCalcFirstDoW = date._locale.firstDayOfWeek(); 7481 } 7482 } 7483 html += '<td class="' + classes.join(' ') + '"' + 7484 (isDateValid ? 7485 ' data-date="' + date.format() + '"' : 7486 '') + 7487 '>'; 7488 if (this.cellWeekNumbersVisible && (date.day() === weekCalcFirstDoW)) { 7489 html += view.buildGotoAnchorHtml({ date: date, type: 'week' }, { 'class': 'fc-week-number' }, date.format('w') // inner HTML 7490 ); 7491 } 7492 if (isDayNumberVisible) { 7493 html += view.buildGotoAnchorHtml(date, { 'class': 'fc-day-number' }, date.format('D') // inner HTML 7494 ); 7495 } 7496 html += '</td>'; 7497 return html; 7498 }; 7499 /* Hit System 7500 ------------------------------------------------------------------------------------------------------------------*/ 7501 DayGrid.prototype.prepareHits = function () { 7502 this.colCoordCache.build(); 7503 this.rowCoordCache.build(); 7504 this.rowCoordCache.bottoms[this.rowCnt - 1] += this.bottomCoordPadding; // hack 7505 }; 7506 DayGrid.prototype.releaseHits = function () { 7507 this.colCoordCache.clear(); 7508 this.rowCoordCache.clear(); 7509 }; 7510 DayGrid.prototype.queryHit = function (leftOffset, topOffset) { 7511 if (this.colCoordCache.isLeftInBounds(leftOffset) && this.rowCoordCache.isTopInBounds(topOffset)) { 7512 var col = this.colCoordCache.getHorizontalIndex(leftOffset); 7513 var row = this.rowCoordCache.getVerticalIndex(topOffset); 7514 if (row != null && col != null) { 7515 return this.getCellHit(row, col); 7516 } 7517 } 7518 }; 7519 DayGrid.prototype.getHitFootprint = function (hit) { 7520 var range = this.getCellRange(hit.row, hit.col); 7521 return new ComponentFootprint_1.default(new UnzonedRange_1.default(range.start, range.end), true // all-day? 7522 ); 7523 }; 7524 DayGrid.prototype.getHitEl = function (hit) { 7525 return this.getCellEl(hit.row, hit.col); 7526 }; 7527 /* Cell System 7528 ------------------------------------------------------------------------------------------------------------------*/ 7529 // FYI: the first column is the leftmost column, regardless of date 7530 DayGrid.prototype.getCellHit = function (row, col) { 7531 return { 7532 row: row, 7533 col: col, 7534 component: this, 7535 left: this.colCoordCache.getLeftOffset(col), 7536 right: this.colCoordCache.getRightOffset(col), 7537 top: this.rowCoordCache.getTopOffset(row), 7538 bottom: this.rowCoordCache.getBottomOffset(row) 7539 }; 7540 }; 7541 DayGrid.prototype.getCellEl = function (row, col) { 7542 return this.cellEls.eq(row * this.colCnt + col); 7543 }; 7544 /* Event Rendering 7545 ------------------------------------------------------------------------------------------------------------------*/ 7546 // Unrenders all events currently rendered on the grid 7547 DayGrid.prototype.executeEventUnrender = function () { 7548 this.removeSegPopover(); // removes the "more.." events popover 7549 _super.prototype.executeEventUnrender.call(this); 7550 }; 7551 // Retrieves all rendered segment objects currently rendered on the grid 7552 DayGrid.prototype.getOwnEventSegs = function () { 7553 // append the segments from the "more..." popover 7554 return _super.prototype.getOwnEventSegs.call(this).concat(this.popoverSegs || []); 7555 }; 7556 /* Event Drag Visualization 7557 ------------------------------------------------------------------------------------------------------------------*/ 7558 // Renders a visual indication of an event or external element being dragged. 7559 // `eventLocation` has zoned start and end (optional) 7560 DayGrid.prototype.renderDrag = function (eventFootprints, seg, isTouch) { 7561 var i; 7562 for (i = 0; i < eventFootprints.length; i++) { 7563 this.renderHighlight(eventFootprints[i].componentFootprint); 7564 } 7565 // render drags from OTHER components as helpers 7566 if (eventFootprints.length && seg && seg.component !== this) { 7567 this.helperRenderer.renderEventDraggingFootprints(eventFootprints, seg, isTouch); 7568 return true; // signal helpers rendered 7569 } 7570 }; 7571 // Unrenders any visual indication of a hovering event 7572 DayGrid.prototype.unrenderDrag = function () { 7573 this.unrenderHighlight(); 7574 this.helperRenderer.unrender(); 7575 }; 7576 /* Event Resize Visualization 7577 ------------------------------------------------------------------------------------------------------------------*/ 7578 // Renders a visual indication of an event being resized 7579 DayGrid.prototype.renderEventResize = function (eventFootprints, seg, isTouch) { 7580 var i; 7581 for (i = 0; i < eventFootprints.length; i++) { 7582 this.renderHighlight(eventFootprints[i].componentFootprint); 7583 } 7584 this.helperRenderer.renderEventResizingFootprints(eventFootprints, seg, isTouch); 7585 }; 7586 // Unrenders a visual indication of an event being resized 7587 DayGrid.prototype.unrenderEventResize = function () { 7588 this.unrenderHighlight(); 7589 this.helperRenderer.unrender(); 7590 }; 7591 /* More+ Link Popover 7592 ------------------------------------------------------------------------------------------------------------------*/ 7593 DayGrid.prototype.removeSegPopover = function () { 7594 if (this.segPopover) { 7595 this.segPopover.hide(); // in handler, will call segPopover's removeElement 7596 } 7597 }; 7598 // Limits the number of "levels" (vertically stacking layers of events) for each row of the grid. 7599 // `levelLimit` can be false (don't limit), a number, or true (should be computed). 7600 DayGrid.prototype.limitRows = function (levelLimit) { 7601 var rowStructs = this.eventRenderer.rowStructs || []; 7602 var row; // row # 7603 var rowLevelLimit; 7604 for (row = 0; row < rowStructs.length; row++) { 7605 this.unlimitRow(row); 7606 if (!levelLimit) { 7607 rowLevelLimit = false; 7608 } 7609 else if (typeof levelLimit === 'number') { 7610 rowLevelLimit = levelLimit; 7611 } 7612 else { 7613 rowLevelLimit = this.computeRowLevelLimit(row); 7614 } 7615 if (rowLevelLimit !== false) { 7616 this.limitRow(row, rowLevelLimit); 7617 } 7618 } 7619 }; 7620 // Computes the number of levels a row will accomodate without going outside its bounds. 7621 // Assumes the row is "rigid" (maintains a constant height regardless of what is inside). 7622 // `row` is the row number. 7623 DayGrid.prototype.computeRowLevelLimit = function (row) { 7624 var rowEl = this.rowEls.eq(row); // the containing "fake" row div 7625 var rowHeight = rowEl.height(); // TODO: cache somehow? 7626 var trEls = this.eventRenderer.rowStructs[row].tbodyEl.children(); 7627 var i; 7628 var trEl; 7629 var trHeight; 7630 function iterInnerHeights(i, childNode) { 7631 trHeight = Math.max(trHeight, $(childNode).outerHeight()); 7632 } 7633 // Reveal one level <tr> at a time and stop when we find one out of bounds 7634 for (i = 0; i < trEls.length; i++) { 7635 trEl = trEls.eq(i).removeClass('fc-limited'); // reset to original state (reveal) 7636 // with rowspans>1 and IE8, trEl.outerHeight() would return the height of the largest cell, 7637 // so instead, find the tallest inner content element. 7638 trHeight = 0; 7639 trEl.find('> td > :first-child').each(iterInnerHeights); 7640 if (trEl.position().top + trHeight > rowHeight) { 7641 return i; 7642 } 7643 } 7644 return false; // should not limit at all 7645 }; 7646 // Limits the given grid row to the maximum number of levels and injects "more" links if necessary. 7647 // `row` is the row number. 7648 // `levelLimit` is a number for the maximum (inclusive) number of levels allowed. 7649 DayGrid.prototype.limitRow = function (row, levelLimit) { 7650 var _this = this; 7651 var rowStruct = this.eventRenderer.rowStructs[row]; 7652 var moreNodes = []; // array of "more" <a> links and <td> DOM nodes 7653 var col = 0; // col #, left-to-right (not chronologically) 7654 var levelSegs; // array of segment objects in the last allowable level, ordered left-to-right 7655 var cellMatrix; // a matrix (by level, then column) of all <td> jQuery elements in the row 7656 var limitedNodes; // array of temporarily hidden level <tr> and segment <td> DOM nodes 7657 var i; 7658 var seg; 7659 var segsBelow; // array of segment objects below `seg` in the current `col` 7660 var totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies 7661 var colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column) 7662 var td; 7663 var rowspan; 7664 var segMoreNodes; // array of "more" <td> cells that will stand-in for the current seg's cell 7665 var j; 7666 var moreTd; 7667 var moreWrap; 7668 var moreLink; 7669 // Iterates through empty level cells and places "more" links inside if need be 7670 var emptyCellsUntil = function (endCol) { 7671 while (col < endCol) { 7672 segsBelow = _this.getCellSegs(row, col, levelLimit); 7673 if (segsBelow.length) { 7674 td = cellMatrix[levelLimit - 1][col]; 7675 moreLink = _this.renderMoreLink(row, col, segsBelow); 7676 moreWrap = $('<div>').append(moreLink); 7677 td.append(moreWrap); 7678 moreNodes.push(moreWrap[0]); 7679 } 7680 col++; 7681 } 7682 }; 7683 if (levelLimit && levelLimit < rowStruct.segLevels.length) { // is it actually over the limit? 7684 levelSegs = rowStruct.segLevels[levelLimit - 1]; 7685 cellMatrix = rowStruct.cellMatrix; 7686 limitedNodes = rowStruct.tbodyEl.children().slice(levelLimit) // get level <tr> elements past the limit 7687 .addClass('fc-limited').get(); // hide elements and get a simple DOM-nodes array 7688 // iterate though segments in the last allowable level 7689 for (i = 0; i < levelSegs.length; i++) { 7690 seg = levelSegs[i]; 7691 emptyCellsUntil(seg.leftCol); // process empty cells before the segment 7692 // determine *all* segments below `seg` that occupy the same columns 7693 colSegsBelow = []; 7694 totalSegsBelow = 0; 7695 while (col <= seg.rightCol) { 7696 segsBelow = this.getCellSegs(row, col, levelLimit); 7697 colSegsBelow.push(segsBelow); 7698 totalSegsBelow += segsBelow.length; 7699 col++; 7700 } 7701 if (totalSegsBelow) { // do we need to replace this segment with one or many "more" links? 7702 td = cellMatrix[levelLimit - 1][seg.leftCol]; // the segment's parent cell 7703 rowspan = td.attr('rowspan') || 1; 7704 segMoreNodes = []; 7705 // make a replacement <td> for each column the segment occupies. will be one for each colspan 7706 for (j = 0; j < colSegsBelow.length; j++) { 7707 moreTd = $('<td class="fc-more-cell">').attr('rowspan', rowspan); 7708 segsBelow = colSegsBelow[j]; 7709 moreLink = this.renderMoreLink(row, seg.leftCol + j, [seg].concat(segsBelow) // count seg as hidden too 7710 ); 7711 moreWrap = $('<div>').append(moreLink); 7712 moreTd.append(moreWrap); 7713 segMoreNodes.push(moreTd[0]); 7714 moreNodes.push(moreTd[0]); 7715 } 7716 td.addClass('fc-limited').after($(segMoreNodes)); // hide original <td> and inject replacements 7717 limitedNodes.push(td[0]); 7718 } 7719 } 7720 emptyCellsUntil(this.colCnt); // finish off the level 7721 rowStruct.moreEls = $(moreNodes); // for easy undoing later 7722 rowStruct.limitedEls = $(limitedNodes); // for easy undoing later 7723 } 7724 }; 7725 // Reveals all levels and removes all "more"-related elements for a grid's row. 7726 // `row` is a row number. 7727 DayGrid.prototype.unlimitRow = function (row) { 7728 var rowStruct = this.eventRenderer.rowStructs[row]; 7729 if (rowStruct.moreEls) { 7730 rowStruct.moreEls.remove(); 7731 rowStruct.moreEls = null; 7732 } 7733 if (rowStruct.limitedEls) { 7734 rowStruct.limitedEls.removeClass('fc-limited'); 7735 rowStruct.limitedEls = null; 7736 } 7737 }; 7738 // Renders an <a> element that represents hidden event element for a cell. 7739 // Responsible for attaching click handler as well. 7740 DayGrid.prototype.renderMoreLink = function (row, col, hiddenSegs) { 7741 var _this = this; 7742 var view = this.view; 7743 return $('<a class="fc-more">') 7744 .text(this.getMoreLinkText(hiddenSegs.length)) 7745 .on('click', function (ev) { 7746 var clickOption = _this.opt('eventLimitClick'); 7747 var date = _this.getCellDate(row, col); 7748 var moreEl = $(ev.currentTarget); 7749 var dayEl = _this.getCellEl(row, col); 7750 var allSegs = _this.getCellSegs(row, col); 7751 // rescope the segments to be within the cell's date 7752 var reslicedAllSegs = _this.resliceDaySegs(allSegs, date); 7753 var reslicedHiddenSegs = _this.resliceDaySegs(hiddenSegs, date); 7754 if (typeof clickOption === 'function') { 7755 // the returned value can be an atomic option 7756 clickOption = _this.publiclyTrigger('eventLimitClick', { 7757 context: view, 7758 args: [ 7759 { 7760 date: date.clone(), 7761 dayEl: dayEl, 7762 moreEl: moreEl, 7763 segs: reslicedAllSegs, 7764 hiddenSegs: reslicedHiddenSegs 7765 }, 7766 ev, 7767 view 7768 ] 7769 }); 7770 } 7771 if (clickOption === 'popover') { 7772 _this.showSegPopover(row, col, moreEl, reslicedAllSegs); 7773 } 7774 else if (typeof clickOption === 'string') { // a view name 7775 view.calendar.zoomTo(date, clickOption); 7776 } 7777 }); 7778 }; 7779 // Reveals the popover that displays all events within a cell 7780 DayGrid.prototype.showSegPopover = function (row, col, moreLink, segs) { 7781 var _this = this; 7782 var view = this.view; 7783 var moreWrap = moreLink.parent(); // the <div> wrapper around the <a> 7784 var topEl; // the element we want to match the top coordinate of 7785 var options; 7786 if (this.rowCnt === 1) { 7787 topEl = view.el; // will cause the popover to cover any sort of header 7788 } 7789 else { 7790 topEl = this.rowEls.eq(row); // will align with top of row 7791 } 7792 options = { 7793 className: 'fc-more-popover ' + view.calendar.theme.getClass('popover'), 7794 content: this.renderSegPopoverContent(row, col, segs), 7795 parentEl: view.el, 7796 top: topEl.offset().top, 7797 autoHide: true, 7798 viewportConstrain: this.opt('popoverViewportConstrain'), 7799 hide: function () { 7800 // kill everything when the popover is hidden 7801 // notify events to be removed 7802 if (_this.popoverSegs) { 7803 _this.triggerBeforeEventSegsDestroyed(_this.popoverSegs); 7804 } 7805 _this.segPopover.removeElement(); 7806 _this.segPopover = null; 7807 _this.popoverSegs = null; 7808 } 7809 }; 7810 // Determine horizontal coordinate. 7811 // We use the moreWrap instead of the <td> to avoid border confusion. 7812 if (this.isRTL) { 7813 options.right = moreWrap.offset().left + moreWrap.outerWidth() + 1; // +1 to be over cell border 7814 } 7815 else { 7816 options.left = moreWrap.offset().left - 1; // -1 to be over cell border 7817 } 7818 this.segPopover = new Popover_1.default(options); 7819 this.segPopover.show(); 7820 // the popover doesn't live within the grid's container element, and thus won't get the event 7821 // delegated-handlers for free. attach event-related handlers to the popover. 7822 this.bindAllSegHandlersToEl(this.segPopover.el); 7823 this.triggerAfterEventSegsRendered(segs); 7824 }; 7825 // Builds the inner DOM contents of the segment popover 7826 DayGrid.prototype.renderSegPopoverContent = function (row, col, segs) { 7827 var view = this.view; 7828 var theme = view.calendar.theme; 7829 var title = this.getCellDate(row, col).format(this.opt('dayPopoverFormat')); 7830 var content = $('<div class="fc-header ' + theme.getClass('popoverHeader') + '">' + 7831 '<span class="fc-close ' + theme.getIconClass('close') + '"></span>' + 7832 '<span class="fc-title">' + 7833 util_1.htmlEscape(title) + 7834 '</span>' + 7835 '<div class="fc-clear"></div>' + 7836 '</div>' + 7837 '<div class="fc-body ' + theme.getClass('popoverContent') + '">' + 7838 '<div class="fc-event-container"></div>' + 7839 '</div>'); 7840 var segContainer = content.find('.fc-event-container'); 7841 var i; 7842 // render each seg's `el` and only return the visible segs 7843 segs = this.eventRenderer.renderFgSegEls(segs, true); // disableResizing=true 7844 this.popoverSegs = segs; 7845 for (i = 0; i < segs.length; i++) { 7846 // because segments in the popover are not part of a grid coordinate system, provide a hint to any 7847 // grids that want to do drag-n-drop about which cell it came from 7848 this.hitsNeeded(); 7849 segs[i].hit = this.getCellHit(row, col); 7850 this.hitsNotNeeded(); 7851 segContainer.append(segs[i].el); 7852 } 7853 return content; 7854 }; 7855 // Given the events within an array of segment objects, reslice them to be in a single day 7856 DayGrid.prototype.resliceDaySegs = function (segs, dayDate) { 7857 var dayStart = dayDate.clone(); 7858 var dayEnd = dayStart.clone().add(1, 'days'); 7859 var dayRange = new UnzonedRange_1.default(dayStart, dayEnd); 7860 var newSegs = []; 7861 var i; 7862 var seg; 7863 var slicedRange; 7864 for (i = 0; i < segs.length; i++) { 7865 seg = segs[i]; 7866 slicedRange = seg.footprint.componentFootprint.unzonedRange.intersect(dayRange); 7867 if (slicedRange) { 7868 newSegs.push($.extend({}, seg, { 7869 footprint: new EventFootprint_1.default(new ComponentFootprint_1.default(slicedRange, seg.footprint.componentFootprint.isAllDay), seg.footprint.eventDef, seg.footprint.eventInstance), 7870 isStart: seg.isStart && slicedRange.isStart, 7871 isEnd: seg.isEnd && slicedRange.isEnd 7872 })); 7873 } 7874 } 7875 // force an order because eventsToSegs doesn't guarantee one 7876 // TODO: research if still needed 7877 this.eventRenderer.sortEventSegs(newSegs); 7878 return newSegs; 7879 }; 7880 // Generates the text that should be inside a "more" link, given the number of events it represents 7881 DayGrid.prototype.getMoreLinkText = function (num) { 7882 var opt = this.opt('eventLimitText'); 7883 if (typeof opt === 'function') { 7884 return opt(num); 7885 } 7886 else { 7887 return '+' + num + ' ' + opt; 7888 } 7889 }; 7890 // Returns segments within a given cell. 7891 // If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs. 7892 DayGrid.prototype.getCellSegs = function (row, col, startLevel) { 7893 var segMatrix = this.eventRenderer.rowStructs[row].segMatrix; 7894 var level = startLevel || 0; 7895 var segs = []; 7896 var seg; 7897 while (level < segMatrix.length) { 7898 seg = segMatrix[level][col]; 7899 if (seg) { 7900 segs.push(seg); 7901 } 7902 level++; 7903 } 7904 return segs; 7905 }; 7906 return DayGrid; 7907}(InteractiveDateComponent_1.default)); 7908exports.default = DayGrid; 7909DayGrid.prototype.eventRendererClass = DayGridEventRenderer_1.default; 7910DayGrid.prototype.businessHourRendererClass = BusinessHourRenderer_1.default; 7911DayGrid.prototype.helperRendererClass = DayGridHelperRenderer_1.default; 7912DayGrid.prototype.fillRendererClass = DayGridFillRenderer_1.default; 7913StandardInteractionsMixin_1.default.mixInto(DayGrid); 7914DayTableMixin_1.default.mixInto(DayGrid); 7915 7916 7917/***/ }), 7918/* 67 */ 7919/***/ (function(module, exports, __webpack_require__) { 7920 7921Object.defineProperty(exports, "__esModule", { value: true }); 7922var tslib_1 = __webpack_require__(2); 7923var $ = __webpack_require__(3); 7924var util_1 = __webpack_require__(4); 7925var Scroller_1 = __webpack_require__(41); 7926var View_1 = __webpack_require__(43); 7927var BasicViewDateProfileGenerator_1 = __webpack_require__(68); 7928var DayGrid_1 = __webpack_require__(66); 7929/* An abstract class for the "basic" views, as well as month view. Renders one or more rows of day cells. 7930----------------------------------------------------------------------------------------------------------------------*/ 7931// It is a manager for a DayGrid subcomponent, which does most of the heavy lifting. 7932// It is responsible for managing width/height. 7933var BasicView = /** @class */ (function (_super) { 7934 tslib_1.__extends(BasicView, _super); 7935 function BasicView(calendar, viewSpec) { 7936 var _this = _super.call(this, calendar, viewSpec) || this; 7937 _this.dayGrid = _this.instantiateDayGrid(); 7938 _this.dayGrid.isRigid = _this.hasRigidRows(); 7939 if (_this.opt('weekNumbers')) { 7940 if (_this.opt('weekNumbersWithinDays')) { 7941 _this.dayGrid.cellWeekNumbersVisible = true; 7942 _this.dayGrid.colWeekNumbersVisible = false; 7943 } 7944 else { 7945 _this.dayGrid.cellWeekNumbersVisible = false; 7946 _this.dayGrid.colWeekNumbersVisible = true; 7947 } 7948 } 7949 _this.addChild(_this.dayGrid); 7950 _this.scroller = new Scroller_1.default({ 7951 overflowX: 'hidden', 7952 overflowY: 'auto' 7953 }); 7954 return _this; 7955 } 7956 // Generates the DayGrid object this view needs. Draws from this.dayGridClass 7957 BasicView.prototype.instantiateDayGrid = function () { 7958 // generate a subclass on the fly with BasicView-specific behavior 7959 // TODO: cache this subclass 7960 var subclass = makeDayGridSubclass(this.dayGridClass); 7961 return new subclass(this); 7962 }; 7963 BasicView.prototype.executeDateRender = function (dateProfile) { 7964 this.dayGrid.breakOnWeeks = /year|month|week/.test(dateProfile.currentRangeUnit); 7965 _super.prototype.executeDateRender.call(this, dateProfile); 7966 }; 7967 BasicView.prototype.renderSkeleton = function () { 7968 var dayGridContainerEl; 7969 var dayGridEl; 7970 this.el.addClass('fc-basic-view').html(this.renderSkeletonHtml()); 7971 this.scroller.render(); 7972 dayGridContainerEl = this.scroller.el.addClass('fc-day-grid-container'); 7973 dayGridEl = $('<div class="fc-day-grid">').appendTo(dayGridContainerEl); 7974 this.el.find('.fc-body > tr > td').append(dayGridContainerEl); 7975 this.dayGrid.headContainerEl = this.el.find('.fc-head-container'); 7976 this.dayGrid.setElement(dayGridEl); 7977 }; 7978 BasicView.prototype.unrenderSkeleton = function () { 7979 this.dayGrid.removeElement(); 7980 this.scroller.destroy(); 7981 }; 7982 // Builds the HTML skeleton for the view. 7983 // The day-grid component will render inside of a container defined by this HTML. 7984 BasicView.prototype.renderSkeletonHtml = function () { 7985 var theme = this.calendar.theme; 7986 return '' + 7987 '<table class="' + theme.getClass('tableGrid') + '">' + 7988 (this.opt('columnHeader') ? 7989 '<thead class="fc-head">' + 7990 '<tr>' + 7991 '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '"> </td>' + 7992 '</tr>' + 7993 '</thead>' : 7994 '') + 7995 '<tbody class="fc-body">' + 7996 '<tr>' + 7997 '<td class="' + theme.getClass('widgetContent') + '"></td>' + 7998 '</tr>' + 7999 '</tbody>' + 8000 '</table>'; 8001 }; 8002 // Generates an HTML attribute string for setting the width of the week number column, if it is known 8003 BasicView.prototype.weekNumberStyleAttr = function () { 8004 if (this.weekNumberWidth != null) { 8005 return 'style="width:' + this.weekNumberWidth + 'px"'; 8006 } 8007 return ''; 8008 }; 8009 // Determines whether each row should have a constant height 8010 BasicView.prototype.hasRigidRows = function () { 8011 var eventLimit = this.opt('eventLimit'); 8012 return eventLimit && typeof eventLimit !== 'number'; 8013 }; 8014 /* Dimensions 8015 ------------------------------------------------------------------------------------------------------------------*/ 8016 // Refreshes the horizontal dimensions of the view 8017 BasicView.prototype.updateSize = function (totalHeight, isAuto, isResize) { 8018 var eventLimit = this.opt('eventLimit'); 8019 var headRowEl = this.dayGrid.headContainerEl.find('.fc-row'); 8020 var scrollerHeight; 8021 var scrollbarWidths; 8022 // hack to give the view some height prior to dayGrid's columns being rendered 8023 // TODO: separate setting height from scroller VS dayGrid. 8024 if (!this.dayGrid.rowEls) { 8025 if (!isAuto) { 8026 scrollerHeight = this.computeScrollerHeight(totalHeight); 8027 this.scroller.setHeight(scrollerHeight); 8028 } 8029 return; 8030 } 8031 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize); 8032 if (this.dayGrid.colWeekNumbersVisible) { 8033 // Make sure all week number cells running down the side have the same width. 8034 // Record the width for cells created later. 8035 this.weekNumberWidth = util_1.matchCellWidths(this.el.find('.fc-week-number')); 8036 } 8037 // reset all heights to be natural 8038 this.scroller.clear(); 8039 util_1.uncompensateScroll(headRowEl); 8040 this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed 8041 // is the event limit a constant level number? 8042 if (eventLimit && typeof eventLimit === 'number') { 8043 this.dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after 8044 } 8045 // distribute the height to the rows 8046 // (totalHeight is a "recommended" value if isAuto) 8047 scrollerHeight = this.computeScrollerHeight(totalHeight); 8048 this.setGridHeight(scrollerHeight, isAuto); 8049 // is the event limit dynamically calculated? 8050 if (eventLimit && typeof eventLimit !== 'number') { 8051 this.dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set 8052 } 8053 if (!isAuto) { // should we force dimensions of the scroll container? 8054 this.scroller.setHeight(scrollerHeight); 8055 scrollbarWidths = this.scroller.getScrollbarWidths(); 8056 if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars? 8057 util_1.compensateScroll(headRowEl, scrollbarWidths); 8058 // doing the scrollbar compensation might have created text overflow which created more height. redo 8059 scrollerHeight = this.computeScrollerHeight(totalHeight); 8060 this.scroller.setHeight(scrollerHeight); 8061 } 8062 // guarantees the same scrollbar widths 8063 this.scroller.lockOverflow(scrollbarWidths); 8064 } 8065 }; 8066 // given a desired total height of the view, returns what the height of the scroller should be 8067 BasicView.prototype.computeScrollerHeight = function (totalHeight) { 8068 return totalHeight - 8069 util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller 8070 }; 8071 // Sets the height of just the DayGrid component in this view 8072 BasicView.prototype.setGridHeight = function (height, isAuto) { 8073 if (isAuto) { 8074 util_1.undistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding 8075 } 8076 else { 8077 util_1.distributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows 8078 } 8079 }; 8080 /* Scroll 8081 ------------------------------------------------------------------------------------------------------------------*/ 8082 BasicView.prototype.computeInitialDateScroll = function () { 8083 return { top: 0 }; 8084 }; 8085 BasicView.prototype.queryDateScroll = function () { 8086 return { top: this.scroller.getScrollTop() }; 8087 }; 8088 BasicView.prototype.applyDateScroll = function (scroll) { 8089 if (scroll.top !== undefined) { 8090 this.scroller.setScrollTop(scroll.top); 8091 } 8092 }; 8093 return BasicView; 8094}(View_1.default)); 8095exports.default = BasicView; 8096BasicView.prototype.dateProfileGeneratorClass = BasicViewDateProfileGenerator_1.default; 8097BasicView.prototype.dayGridClass = DayGrid_1.default; 8098// customize the rendering behavior of BasicView's dayGrid 8099function makeDayGridSubclass(SuperClass) { 8100 return /** @class */ (function (_super) { 8101 tslib_1.__extends(SubClass, _super); 8102 function SubClass() { 8103 var _this = _super !== null && _super.apply(this, arguments) || this; 8104 _this.colWeekNumbersVisible = false; // display week numbers along the side? 8105 return _this; 8106 } 8107 // Generates the HTML that will go before the day-of week header cells 8108 SubClass.prototype.renderHeadIntroHtml = function () { 8109 var view = this.view; 8110 if (this.colWeekNumbersVisible) { 8111 return '' + 8112 '<th class="fc-week-number ' + view.calendar.theme.getClass('widgetHeader') + '" ' + view.weekNumberStyleAttr() + '>' + 8113 '<span>' + // needed for matchCellWidths 8114 util_1.htmlEscape(this.opt('weekNumberTitle')) + 8115 '</span>' + 8116 '</th>'; 8117 } 8118 return ''; 8119 }; 8120 // Generates the HTML that will go before content-skeleton cells that display the day/week numbers 8121 SubClass.prototype.renderNumberIntroHtml = function (row) { 8122 var view = this.view; 8123 var weekStart = this.getCellDate(row, 0); 8124 if (this.colWeekNumbersVisible) { 8125 return '' + 8126 '<td class="fc-week-number" ' + view.weekNumberStyleAttr() + '>' + 8127 view.buildGotoAnchorHtml(// aside from link, important for matchCellWidths 8128 { date: weekStart, type: 'week', forceOff: this.colCnt === 1 }, weekStart.format('w') // inner HTML 8129 ) + 8130 '</td>'; 8131 } 8132 return ''; 8133 }; 8134 // Generates the HTML that goes before the day bg cells for each day-row 8135 SubClass.prototype.renderBgIntroHtml = function () { 8136 var view = this.view; 8137 if (this.colWeekNumbersVisible) { 8138 return '<td class="fc-week-number ' + view.calendar.theme.getClass('widgetContent') + '" ' + 8139 view.weekNumberStyleAttr() + '></td>'; 8140 } 8141 return ''; 8142 }; 8143 // Generates the HTML that goes before every other type of row generated by DayGrid. 8144 // Affects helper-skeleton and highlight-skeleton rows. 8145 SubClass.prototype.renderIntroHtml = function () { 8146 var view = this.view; 8147 if (this.colWeekNumbersVisible) { 8148 return '<td class="fc-week-number" ' + view.weekNumberStyleAttr() + '></td>'; 8149 } 8150 return ''; 8151 }; 8152 SubClass.prototype.getIsNumbersVisible = function () { 8153 return DayGrid_1.default.prototype.getIsNumbersVisible.apply(this, arguments) || this.colWeekNumbersVisible; 8154 }; 8155 return SubClass; 8156 }(SuperClass)); 8157} 8158 8159 8160/***/ }), 8161/* 68 */ 8162/***/ (function(module, exports, __webpack_require__) { 8163 8164Object.defineProperty(exports, "__esModule", { value: true }); 8165var tslib_1 = __webpack_require__(2); 8166var UnzonedRange_1 = __webpack_require__(5); 8167var DateProfileGenerator_1 = __webpack_require__(55); 8168var BasicViewDateProfileGenerator = /** @class */ (function (_super) { 8169 tslib_1.__extends(BasicViewDateProfileGenerator, _super); 8170 function BasicViewDateProfileGenerator() { 8171 return _super !== null && _super.apply(this, arguments) || this; 8172 } 8173 // Computes the date range that will be rendered. 8174 BasicViewDateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) { 8175 var renderUnzonedRange = _super.prototype.buildRenderRange.call(this, currentUnzonedRange, currentRangeUnit, isRangeAllDay); // an UnzonedRange 8176 var start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay); 8177 var end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay); 8178 // year and month views should be aligned with weeks. this is already done for week 8179 if (/^(year|month)$/.test(currentRangeUnit)) { 8180 start.startOf('week'); 8181 // make end-of-week if not already 8182 if (end.weekday()) { 8183 end.add(1, 'week').startOf('week'); // exclusively move backwards 8184 } 8185 } 8186 return new UnzonedRange_1.default(start, end); 8187 }; 8188 return BasicViewDateProfileGenerator; 8189}(DateProfileGenerator_1.default)); 8190exports.default = BasicViewDateProfileGenerator; 8191 8192 8193/***/ }), 8194/* 69 */, 8195/* 70 */, 8196/* 71 */, 8197/* 72 */, 8198/* 73 */, 8199/* 74 */, 8200/* 75 */, 8201/* 76 */, 8202/* 77 */, 8203/* 78 */, 8204/* 79 */, 8205/* 80 */, 8206/* 81 */, 8207/* 82 */, 8208/* 83 */, 8209/* 84 */, 8210/* 85 */, 8211/* 86 */, 8212/* 87 */, 8213/* 88 */, 8214/* 89 */, 8215/* 90 */, 8216/* 91 */, 8217/* 92 */, 8218/* 93 */, 8219/* 94 */, 8220/* 95 */, 8221/* 96 */, 8222/* 97 */, 8223/* 98 */, 8224/* 99 */, 8225/* 100 */, 8226/* 101 */, 8227/* 102 */, 8228/* 103 */, 8229/* 104 */, 8230/* 105 */, 8231/* 106 */, 8232/* 107 */, 8233/* 108 */, 8234/* 109 */, 8235/* 110 */, 8236/* 111 */, 8237/* 112 */, 8238/* 113 */, 8239/* 114 */, 8240/* 115 */, 8241/* 116 */, 8242/* 117 */, 8243/* 118 */, 8244/* 119 */, 8245/* 120 */, 8246/* 121 */, 8247/* 122 */, 8248/* 123 */, 8249/* 124 */, 8250/* 125 */, 8251/* 126 */, 8252/* 127 */, 8253/* 128 */, 8254/* 129 */, 8255/* 130 */, 8256/* 131 */, 8257/* 132 */, 8258/* 133 */, 8259/* 134 */, 8260/* 135 */, 8261/* 136 */, 8262/* 137 */, 8263/* 138 */, 8264/* 139 */, 8265/* 140 */, 8266/* 141 */, 8267/* 142 */, 8268/* 143 */, 8269/* 144 */, 8270/* 145 */, 8271/* 146 */, 8272/* 147 */, 8273/* 148 */, 8274/* 149 */, 8275/* 150 */, 8276/* 151 */, 8277/* 152 */, 8278/* 153 */, 8279/* 154 */, 8280/* 155 */, 8281/* 156 */, 8282/* 157 */, 8283/* 158 */, 8284/* 159 */, 8285/* 160 */, 8286/* 161 */, 8287/* 162 */, 8288/* 163 */, 8289/* 164 */, 8290/* 165 */, 8291/* 166 */, 8292/* 167 */, 8293/* 168 */, 8294/* 169 */, 8295/* 170 */, 8296/* 171 */, 8297/* 172 */, 8298/* 173 */, 8299/* 174 */, 8300/* 175 */, 8301/* 176 */, 8302/* 177 */, 8303/* 178 */, 8304/* 179 */, 8305/* 180 */, 8306/* 181 */, 8307/* 182 */, 8308/* 183 */, 8309/* 184 */, 8310/* 185 */, 8311/* 186 */, 8312/* 187 */, 8313/* 188 */, 8314/* 189 */, 8315/* 190 */, 8316/* 191 */, 8317/* 192 */, 8318/* 193 */, 8319/* 194 */, 8320/* 195 */, 8321/* 196 */, 8322/* 197 */, 8323/* 198 */, 8324/* 199 */, 8325/* 200 */, 8326/* 201 */, 8327/* 202 */, 8328/* 203 */, 8329/* 204 */, 8330/* 205 */, 8331/* 206 */, 8332/* 207 */, 8333/* 208 */, 8334/* 209 */, 8335/* 210 */, 8336/* 211 */, 8337/* 212 */, 8338/* 213 */, 8339/* 214 */, 8340/* 215 */, 8341/* 216 */, 8342/* 217 */ 8343/***/ (function(module, exports, __webpack_require__) { 8344 8345Object.defineProperty(exports, "__esModule", { value: true }); 8346var UnzonedRange_1 = __webpack_require__(5); 8347var ComponentFootprint_1 = __webpack_require__(12); 8348var EventDefParser_1 = __webpack_require__(36); 8349var EventSource_1 = __webpack_require__(6); 8350var util_1 = __webpack_require__(19); 8351var Constraints = /** @class */ (function () { 8352 function Constraints(eventManager, _calendar) { 8353 this.eventManager = eventManager; 8354 this._calendar = _calendar; 8355 } 8356 Constraints.prototype.opt = function (name) { 8357 return this._calendar.opt(name); 8358 }; 8359 /* 8360 determines if eventInstanceGroup is allowed, 8361 in relation to other EVENTS and business hours. 8362 */ 8363 Constraints.prototype.isEventInstanceGroupAllowed = function (eventInstanceGroup) { 8364 var eventDef = eventInstanceGroup.getEventDef(); 8365 var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges()); 8366 var i; 8367 var peerEventInstances = this.getPeerEventInstances(eventDef); 8368 var peerEventRanges = peerEventInstances.map(util_1.eventInstanceToEventRange); 8369 var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges); 8370 var constraintVal = eventDef.getConstraint(); 8371 var overlapVal = eventDef.getOverlap(); 8372 var eventAllowFunc = this.opt('eventAllow'); 8373 for (i = 0; i < eventFootprints.length; i++) { 8374 if (!this.isFootprintAllowed(eventFootprints[i].componentFootprint, peerEventFootprints, constraintVal, overlapVal, eventFootprints[i].eventInstance)) { 8375 return false; 8376 } 8377 } 8378 if (eventAllowFunc) { 8379 for (i = 0; i < eventFootprints.length; i++) { 8380 if (eventAllowFunc(eventFootprints[i].componentFootprint.toLegacy(this._calendar), eventFootprints[i].getEventLegacy()) === false) { 8381 return false; 8382 } 8383 } 8384 } 8385 return true; 8386 }; 8387 Constraints.prototype.getPeerEventInstances = function (eventDef) { 8388 return this.eventManager.getEventInstancesWithoutId(eventDef.id); 8389 }; 8390 Constraints.prototype.isSelectionFootprintAllowed = function (componentFootprint) { 8391 var peerEventInstances = this.eventManager.getEventInstances(); 8392 var peerEventRanges = peerEventInstances.map(util_1.eventInstanceToEventRange); 8393 var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges); 8394 var selectAllowFunc; 8395 if (this.isFootprintAllowed(componentFootprint, peerEventFootprints, this.opt('selectConstraint'), this.opt('selectOverlap'))) { 8396 selectAllowFunc = this.opt('selectAllow'); 8397 if (selectAllowFunc) { 8398 return selectAllowFunc(componentFootprint.toLegacy(this._calendar)) !== false; 8399 } 8400 else { 8401 return true; 8402 } 8403 } 8404 return false; 8405 }; 8406 Constraints.prototype.isFootprintAllowed = function (componentFootprint, peerEventFootprints, constraintVal, overlapVal, subjectEventInstance // optional 8407 ) { 8408 var constraintFootprints; // ComponentFootprint[] 8409 var overlapEventFootprints; // EventFootprint[] 8410 if (constraintVal != null) { 8411 constraintFootprints = this.constraintValToFootprints(constraintVal, componentFootprint.isAllDay); 8412 if (!this.isFootprintWithinConstraints(componentFootprint, constraintFootprints)) { 8413 return false; 8414 } 8415 } 8416 overlapEventFootprints = this.collectOverlapEventFootprints(peerEventFootprints, componentFootprint); 8417 if (overlapVal === false) { 8418 if (overlapEventFootprints.length) { 8419 return false; 8420 } 8421 } 8422 else if (typeof overlapVal === 'function') { 8423 if (!isOverlapsAllowedByFunc(overlapEventFootprints, overlapVal, subjectEventInstance)) { 8424 return false; 8425 } 8426 } 8427 if (subjectEventInstance) { 8428 if (!isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance)) { 8429 return false; 8430 } 8431 } 8432 return true; 8433 }; 8434 // Constraint 8435 // ------------------------------------------------------------------------------------------------ 8436 Constraints.prototype.isFootprintWithinConstraints = function (componentFootprint, constraintFootprints) { 8437 var i; 8438 for (i = 0; i < constraintFootprints.length; i++) { 8439 if (this.footprintContainsFootprint(constraintFootprints[i], componentFootprint)) { 8440 return true; 8441 } 8442 } 8443 return false; 8444 }; 8445 Constraints.prototype.constraintValToFootprints = function (constraintVal, isAllDay) { 8446 var eventInstances; 8447 if (constraintVal === 'businessHours') { 8448 return this.buildCurrentBusinessFootprints(isAllDay); 8449 } 8450 else if (typeof constraintVal === 'object') { 8451 eventInstances = this.parseEventDefToInstances(constraintVal); // handles recurring events 8452 if (!eventInstances) { // invalid input. fallback to parsing footprint directly 8453 return this.parseFootprints(constraintVal); 8454 } 8455 else { 8456 return this.eventInstancesToFootprints(eventInstances); 8457 } 8458 } 8459 else if (constraintVal != null) { // an ID 8460 eventInstances = this.eventManager.getEventInstancesWithId(constraintVal); 8461 return this.eventInstancesToFootprints(eventInstances); 8462 } 8463 }; 8464 // returns ComponentFootprint[] 8465 // uses current view's range 8466 Constraints.prototype.buildCurrentBusinessFootprints = function (isAllDay) { 8467 var view = this._calendar.view; 8468 var businessHourGenerator = view.get('businessHourGenerator'); 8469 var unzonedRange = view.dateProfile.activeUnzonedRange; 8470 var eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(isAllDay, unzonedRange); 8471 if (eventInstanceGroup) { 8472 return this.eventInstancesToFootprints(eventInstanceGroup.eventInstances); 8473 } 8474 else { 8475 return []; 8476 } 8477 }; 8478 // conversion util 8479 Constraints.prototype.eventInstancesToFootprints = function (eventInstances) { 8480 var eventRanges = eventInstances.map(util_1.eventInstanceToEventRange); 8481 var eventFootprints = this.eventRangesToEventFootprints(eventRanges); 8482 return eventFootprints.map(util_1.eventFootprintToComponentFootprint); 8483 }; 8484 // Overlap 8485 // ------------------------------------------------------------------------------------------------ 8486 Constraints.prototype.collectOverlapEventFootprints = function (peerEventFootprints, targetFootprint) { 8487 var overlapEventFootprints = []; 8488 var i; 8489 for (i = 0; i < peerEventFootprints.length; i++) { 8490 if (this.footprintsIntersect(targetFootprint, peerEventFootprints[i].componentFootprint)) { 8491 overlapEventFootprints.push(peerEventFootprints[i]); 8492 } 8493 } 8494 return overlapEventFootprints; 8495 }; 8496 // Conversion: eventDefs -> eventInstances -> eventRanges -> eventFootprints -> componentFootprints 8497 // ------------------------------------------------------------------------------------------------ 8498 // NOTE: this might seem like repetitive code with the Grid class, however, this code is related to 8499 // constraints whereas the Grid code is related to rendering. Each approach might want to convert 8500 // eventRanges -> eventFootprints in a different way. Regardless, there are opportunities to make 8501 // this more DRY. 8502 /* 8503 Returns false on invalid input. 8504 */ 8505 Constraints.prototype.parseEventDefToInstances = function (eventInput) { 8506 var eventManager = this.eventManager; 8507 var eventDef = EventDefParser_1.default.parse(eventInput, new EventSource_1.default(this._calendar)); 8508 if (!eventDef) { // invalid 8509 return false; 8510 } 8511 return eventDef.buildInstances(eventManager.currentPeriod.unzonedRange); 8512 }; 8513 Constraints.prototype.eventRangesToEventFootprints = function (eventRanges) { 8514 var i; 8515 var eventFootprints = []; 8516 for (i = 0; i < eventRanges.length; i++) { 8517 eventFootprints.push.apply(// footprints 8518 eventFootprints, this.eventRangeToEventFootprints(eventRanges[i])); 8519 } 8520 return eventFootprints; 8521 }; 8522 Constraints.prototype.eventRangeToEventFootprints = function (eventRange) { 8523 return [util_1.eventRangeToEventFootprint(eventRange)]; 8524 }; 8525 /* 8526 Parses footprints directly. 8527 Very similar to EventDateProfile::parse :( 8528 */ 8529 Constraints.prototype.parseFootprints = function (rawInput) { 8530 var start; 8531 var end; 8532 if (rawInput.start) { 8533 start = this._calendar.moment(rawInput.start); 8534 if (!start.isValid()) { 8535 start = null; 8536 } 8537 } 8538 if (rawInput.end) { 8539 end = this._calendar.moment(rawInput.end); 8540 if (!end.isValid()) { 8541 end = null; 8542 } 8543 } 8544 return [ 8545 new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), (start && !start.hasTime()) || (end && !end.hasTime()) // isAllDay 8546 ) 8547 ]; 8548 }; 8549 // Footprint Utils 8550 // ---------------------------------------------------------------------------------------- 8551 Constraints.prototype.footprintContainsFootprint = function (outerFootprint, innerFootprint) { 8552 return outerFootprint.unzonedRange.containsRange(innerFootprint.unzonedRange); 8553 }; 8554 Constraints.prototype.footprintsIntersect = function (footprint0, footprint1) { 8555 return footprint0.unzonedRange.intersectsWith(footprint1.unzonedRange); 8556 }; 8557 return Constraints; 8558}()); 8559exports.default = Constraints; 8560// optional subjectEventInstance 8561function isOverlapsAllowedByFunc(overlapEventFootprints, overlapFunc, subjectEventInstance) { 8562 var i; 8563 for (i = 0; i < overlapEventFootprints.length; i++) { 8564 if (!overlapFunc(overlapEventFootprints[i].eventInstance.toLegacy(), subjectEventInstance ? subjectEventInstance.toLegacy() : null)) { 8565 return false; 8566 } 8567 } 8568 return true; 8569} 8570function isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance) { 8571 var subjectLegacyInstance = subjectEventInstance.toLegacy(); 8572 var i; 8573 var overlapEventInstance; 8574 var overlapEventDef; 8575 var overlapVal; 8576 for (i = 0; i < overlapEventFootprints.length; i++) { 8577 overlapEventInstance = overlapEventFootprints[i].eventInstance; 8578 overlapEventDef = overlapEventInstance.def; 8579 // don't need to pass in calendar, because don't want to consider global eventOverlap property, 8580 // because we already considered that earlier in the process. 8581 overlapVal = overlapEventDef.getOverlap(); 8582 if (overlapVal === false) { 8583 return false; 8584 } 8585 else if (typeof overlapVal === 'function') { 8586 if (!overlapVal(overlapEventInstance.toLegacy(), subjectLegacyInstance)) { 8587 return false; 8588 } 8589 } 8590 } 8591 return true; 8592} 8593 8594 8595/***/ }), 8596/* 218 */ 8597/***/ (function(module, exports, __webpack_require__) { 8598 8599Object.defineProperty(exports, "__esModule", { value: true }); 8600var $ = __webpack_require__(3); 8601var util_1 = __webpack_require__(19); 8602var EventInstanceGroup_1 = __webpack_require__(20); 8603var RecurringEventDef_1 = __webpack_require__(54); 8604var EventSource_1 = __webpack_require__(6); 8605var BUSINESS_HOUR_EVENT_DEFAULTS = { 8606 start: '09:00', 8607 end: '17:00', 8608 dow: [1, 2, 3, 4, 5], 8609 rendering: 'inverse-background' 8610 // classNames are defined in businessHoursSegClasses 8611}; 8612var BusinessHourGenerator = /** @class */ (function () { 8613 function BusinessHourGenerator(rawComplexDef, calendar) { 8614 this.rawComplexDef = rawComplexDef; 8615 this.calendar = calendar; 8616 } 8617 BusinessHourGenerator.prototype.buildEventInstanceGroup = function (isAllDay, unzonedRange) { 8618 var eventDefs = this.buildEventDefs(isAllDay); 8619 var eventInstanceGroup; 8620 if (eventDefs.length) { 8621 eventInstanceGroup = new EventInstanceGroup_1.default(util_1.eventDefsToEventInstances(eventDefs, unzonedRange)); 8622 // so that inverse-background rendering can happen even when no eventRanges in view 8623 eventInstanceGroup.explicitEventDef = eventDefs[0]; 8624 return eventInstanceGroup; 8625 } 8626 }; 8627 BusinessHourGenerator.prototype.buildEventDefs = function (isAllDay) { 8628 var rawComplexDef = this.rawComplexDef; 8629 var rawDefs = []; 8630 var requireDow = false; 8631 var i; 8632 var defs = []; 8633 if (rawComplexDef === true) { 8634 rawDefs = [{}]; // will get BUSINESS_HOUR_EVENT_DEFAULTS verbatim 8635 } 8636 else if ($.isPlainObject(rawComplexDef)) { 8637 rawDefs = [rawComplexDef]; 8638 } 8639 else if ($.isArray(rawComplexDef)) { 8640 rawDefs = rawComplexDef; 8641 requireDow = true; // every sub-definition NEEDS a day-of-week 8642 } 8643 for (i = 0; i < rawDefs.length; i++) { 8644 if (!requireDow || rawDefs[i].dow) { 8645 defs.push(this.buildEventDef(isAllDay, rawDefs[i])); 8646 } 8647 } 8648 return defs; 8649 }; 8650 BusinessHourGenerator.prototype.buildEventDef = function (isAllDay, rawDef) { 8651 var fullRawDef = $.extend({}, BUSINESS_HOUR_EVENT_DEFAULTS, rawDef); 8652 if (isAllDay) { 8653 fullRawDef.start = null; 8654 fullRawDef.end = null; 8655 } 8656 return RecurringEventDef_1.default.parse(fullRawDef, new EventSource_1.default(this.calendar) // dummy source 8657 ); 8658 }; 8659 return BusinessHourGenerator; 8660}()); 8661exports.default = BusinessHourGenerator; 8662 8663 8664/***/ }), 8665/* 219 */ 8666/***/ (function(module, exports, __webpack_require__) { 8667 8668Object.defineProperty(exports, "__esModule", { value: true }); 8669var $ = __webpack_require__(3); 8670var util_1 = __webpack_require__(4); 8671var Promise_1 = __webpack_require__(21); 8672var EmitterMixin_1 = __webpack_require__(13); 8673var UnzonedRange_1 = __webpack_require__(5); 8674var EventInstanceGroup_1 = __webpack_require__(20); 8675var EventPeriod = /** @class */ (function () { 8676 function EventPeriod(start, end, timezone) { 8677 this.pendingCnt = 0; 8678 this.freezeDepth = 0; 8679 this.stuntedReleaseCnt = 0; 8680 this.releaseCnt = 0; 8681 this.start = start; 8682 this.end = end; 8683 this.timezone = timezone; 8684 this.unzonedRange = new UnzonedRange_1.default(start.clone().stripZone(), end.clone().stripZone()); 8685 this.requestsByUid = {}; 8686 this.eventDefsByUid = {}; 8687 this.eventDefsById = {}; 8688 this.eventInstanceGroupsById = {}; 8689 } 8690 EventPeriod.prototype.isWithinRange = function (start, end) { 8691 // TODO: use a range util function? 8692 return !start.isBefore(this.start) && !end.isAfter(this.end); 8693 }; 8694 // Requesting and Purging 8695 // ----------------------------------------------------------------------------------------------------------------- 8696 EventPeriod.prototype.requestSources = function (sources) { 8697 this.freeze(); 8698 for (var i = 0; i < sources.length; i++) { 8699 this.requestSource(sources[i]); 8700 } 8701 this.thaw(); 8702 }; 8703 EventPeriod.prototype.requestSource = function (source) { 8704 var _this = this; 8705 var request = { source: source, status: 'pending', eventDefs: null }; 8706 this.requestsByUid[source.uid] = request; 8707 this.pendingCnt += 1; 8708 source.fetch(this.start, this.end, this.timezone).then(function (eventDefs) { 8709 if (request.status !== 'cancelled') { 8710 request.status = 'completed'; 8711 request.eventDefs = eventDefs; 8712 _this.addEventDefs(eventDefs); 8713 _this.pendingCnt--; 8714 _this.tryRelease(); 8715 } 8716 }, function () { 8717 if (request.status !== 'cancelled') { 8718 request.status = 'failed'; 8719 _this.pendingCnt--; 8720 _this.tryRelease(); 8721 } 8722 }); 8723 }; 8724 EventPeriod.prototype.purgeSource = function (source) { 8725 var request = this.requestsByUid[source.uid]; 8726 if (request) { 8727 delete this.requestsByUid[source.uid]; 8728 if (request.status === 'pending') { 8729 request.status = 'cancelled'; 8730 this.pendingCnt--; 8731 this.tryRelease(); 8732 } 8733 else if (request.status === 'completed') { 8734 request.eventDefs.forEach(this.removeEventDef.bind(this)); 8735 } 8736 } 8737 }; 8738 EventPeriod.prototype.purgeAllSources = function () { 8739 var requestsByUid = this.requestsByUid; 8740 var uid; 8741 var request; 8742 var completedCnt = 0; 8743 for (uid in requestsByUid) { 8744 request = requestsByUid[uid]; 8745 if (request.status === 'pending') { 8746 request.status = 'cancelled'; 8747 } 8748 else if (request.status === 'completed') { 8749 completedCnt++; 8750 } 8751 } 8752 this.requestsByUid = {}; 8753 this.pendingCnt = 0; 8754 if (completedCnt) { 8755 this.removeAllEventDefs(); // might release 8756 } 8757 }; 8758 // Event Definitions 8759 // ----------------------------------------------------------------------------------------------------------------- 8760 EventPeriod.prototype.getEventDefByUid = function (eventDefUid) { 8761 return this.eventDefsByUid[eventDefUid]; 8762 }; 8763 EventPeriod.prototype.getEventDefsById = function (eventDefId) { 8764 var a = this.eventDefsById[eventDefId]; 8765 if (a) { 8766 return a.slice(); // clone 8767 } 8768 return []; 8769 }; 8770 EventPeriod.prototype.addEventDefs = function (eventDefs) { 8771 for (var i = 0; i < eventDefs.length; i++) { 8772 this.addEventDef(eventDefs[i]); 8773 } 8774 }; 8775 EventPeriod.prototype.addEventDef = function (eventDef) { 8776 var eventDefsById = this.eventDefsById; 8777 var eventDefId = eventDef.id; 8778 var eventDefs = eventDefsById[eventDefId] || (eventDefsById[eventDefId] = []); 8779 var eventInstances = eventDef.buildInstances(this.unzonedRange); 8780 var i; 8781 eventDefs.push(eventDef); 8782 this.eventDefsByUid[eventDef.uid] = eventDef; 8783 for (i = 0; i < eventInstances.length; i++) { 8784 this.addEventInstance(eventInstances[i], eventDefId); 8785 } 8786 }; 8787 EventPeriod.prototype.removeEventDefsById = function (eventDefId) { 8788 var _this = this; 8789 this.getEventDefsById(eventDefId).forEach(function (eventDef) { 8790 _this.removeEventDef(eventDef); 8791 }); 8792 }; 8793 EventPeriod.prototype.removeAllEventDefs = function () { 8794 var isEmpty = $.isEmptyObject(this.eventDefsByUid); 8795 this.eventDefsByUid = {}; 8796 this.eventDefsById = {}; 8797 this.eventInstanceGroupsById = {}; 8798 if (!isEmpty) { 8799 this.tryRelease(); 8800 } 8801 }; 8802 EventPeriod.prototype.removeEventDef = function (eventDef) { 8803 var eventDefsById = this.eventDefsById; 8804 var eventDefs = eventDefsById[eventDef.id]; 8805 delete this.eventDefsByUid[eventDef.uid]; 8806 if (eventDefs) { 8807 util_1.removeExact(eventDefs, eventDef); 8808 if (!eventDefs.length) { 8809 delete eventDefsById[eventDef.id]; 8810 } 8811 this.removeEventInstancesForDef(eventDef); 8812 } 8813 }; 8814 // Event Instances 8815 // ----------------------------------------------------------------------------------------------------------------- 8816 EventPeriod.prototype.getEventInstances = function () { 8817 var eventInstanceGroupsById = this.eventInstanceGroupsById; 8818 var eventInstances = []; 8819 var id; 8820 for (id in eventInstanceGroupsById) { 8821 eventInstances.push.apply(eventInstances, // append 8822 eventInstanceGroupsById[id].eventInstances); 8823 } 8824 return eventInstances; 8825 }; 8826 EventPeriod.prototype.getEventInstancesWithId = function (eventDefId) { 8827 var eventInstanceGroup = this.eventInstanceGroupsById[eventDefId]; 8828 if (eventInstanceGroup) { 8829 return eventInstanceGroup.eventInstances.slice(); // clone 8830 } 8831 return []; 8832 }; 8833 EventPeriod.prototype.getEventInstancesWithoutId = function (eventDefId) { 8834 var eventInstanceGroupsById = this.eventInstanceGroupsById; 8835 var matchingInstances = []; 8836 var id; 8837 for (id in eventInstanceGroupsById) { 8838 if (id !== eventDefId) { 8839 matchingInstances.push.apply(matchingInstances, // append 8840 eventInstanceGroupsById[id].eventInstances); 8841 } 8842 } 8843 return matchingInstances; 8844 }; 8845 EventPeriod.prototype.addEventInstance = function (eventInstance, eventDefId) { 8846 var eventInstanceGroupsById = this.eventInstanceGroupsById; 8847 var eventInstanceGroup = eventInstanceGroupsById[eventDefId] || 8848 (eventInstanceGroupsById[eventDefId] = new EventInstanceGroup_1.default()); 8849 eventInstanceGroup.eventInstances.push(eventInstance); 8850 this.tryRelease(); 8851 }; 8852 EventPeriod.prototype.removeEventInstancesForDef = function (eventDef) { 8853 var eventInstanceGroupsById = this.eventInstanceGroupsById; 8854 var eventInstanceGroup = eventInstanceGroupsById[eventDef.id]; 8855 var removeCnt; 8856 if (eventInstanceGroup) { 8857 removeCnt = util_1.removeMatching(eventInstanceGroup.eventInstances, function (currentEventInstance) { 8858 return currentEventInstance.def === eventDef; 8859 }); 8860 if (!eventInstanceGroup.eventInstances.length) { 8861 delete eventInstanceGroupsById[eventDef.id]; 8862 } 8863 if (removeCnt) { 8864 this.tryRelease(); 8865 } 8866 } 8867 }; 8868 // Releasing and Freezing 8869 // ----------------------------------------------------------------------------------------------------------------- 8870 EventPeriod.prototype.tryRelease = function () { 8871 if (!this.pendingCnt) { 8872 if (!this.freezeDepth) { 8873 this.release(); 8874 } 8875 else { 8876 this.stuntedReleaseCnt++; 8877 } 8878 } 8879 }; 8880 EventPeriod.prototype.release = function () { 8881 this.releaseCnt++; 8882 this.trigger('release', this.eventInstanceGroupsById); 8883 }; 8884 EventPeriod.prototype.whenReleased = function () { 8885 var _this = this; 8886 if (this.releaseCnt) { 8887 return Promise_1.default.resolve(this.eventInstanceGroupsById); 8888 } 8889 else { 8890 return Promise_1.default.construct(function (onResolve) { 8891 _this.one('release', onResolve); 8892 }); 8893 } 8894 }; 8895 EventPeriod.prototype.freeze = function () { 8896 if (!(this.freezeDepth++)) { 8897 this.stuntedReleaseCnt = 0; 8898 } 8899 }; 8900 EventPeriod.prototype.thaw = function () { 8901 if (!(--this.freezeDepth) && this.stuntedReleaseCnt && !this.pendingCnt) { 8902 this.release(); 8903 } 8904 }; 8905 return EventPeriod; 8906}()); 8907exports.default = EventPeriod; 8908EmitterMixin_1.default.mixInto(EventPeriod); 8909 8910 8911/***/ }), 8912/* 220 */ 8913/***/ (function(module, exports, __webpack_require__) { 8914 8915Object.defineProperty(exports, "__esModule", { value: true }); 8916var $ = __webpack_require__(3); 8917var util_1 = __webpack_require__(4); 8918var EventPeriod_1 = __webpack_require__(219); 8919var ArrayEventSource_1 = __webpack_require__(56); 8920var EventSource_1 = __webpack_require__(6); 8921var EventSourceParser_1 = __webpack_require__(38); 8922var SingleEventDef_1 = __webpack_require__(9); 8923var EventInstanceGroup_1 = __webpack_require__(20); 8924var EmitterMixin_1 = __webpack_require__(13); 8925var ListenerMixin_1 = __webpack_require__(7); 8926var EventManager = /** @class */ (function () { 8927 function EventManager(calendar) { 8928 this.calendar = calendar; 8929 this.stickySource = new ArrayEventSource_1.default(calendar); 8930 this.otherSources = []; 8931 } 8932 EventManager.prototype.requestEvents = function (start, end, timezone, force) { 8933 if (force || 8934 !this.currentPeriod || 8935 !this.currentPeriod.isWithinRange(start, end) || 8936 timezone !== this.currentPeriod.timezone) { 8937 this.setPeriod(// will change this.currentPeriod 8938 new EventPeriod_1.default(start, end, timezone)); 8939 } 8940 return this.currentPeriod.whenReleased(); 8941 }; 8942 // Source Adding/Removing 8943 // ----------------------------------------------------------------------------------------------------------------- 8944 EventManager.prototype.addSource = function (eventSource) { 8945 this.otherSources.push(eventSource); 8946 if (this.currentPeriod) { 8947 this.currentPeriod.requestSource(eventSource); // might release 8948 } 8949 }; 8950 EventManager.prototype.removeSource = function (doomedSource) { 8951 util_1.removeExact(this.otherSources, doomedSource); 8952 if (this.currentPeriod) { 8953 this.currentPeriod.purgeSource(doomedSource); // might release 8954 } 8955 }; 8956 EventManager.prototype.removeAllSources = function () { 8957 this.otherSources = []; 8958 if (this.currentPeriod) { 8959 this.currentPeriod.purgeAllSources(); // might release 8960 } 8961 }; 8962 // Source Refetching 8963 // ----------------------------------------------------------------------------------------------------------------- 8964 EventManager.prototype.refetchSource = function (eventSource) { 8965 var currentPeriod = this.currentPeriod; 8966 if (currentPeriod) { 8967 currentPeriod.freeze(); 8968 currentPeriod.purgeSource(eventSource); 8969 currentPeriod.requestSource(eventSource); 8970 currentPeriod.thaw(); 8971 } 8972 }; 8973 EventManager.prototype.refetchAllSources = function () { 8974 var currentPeriod = this.currentPeriod; 8975 if (currentPeriod) { 8976 currentPeriod.freeze(); 8977 currentPeriod.purgeAllSources(); 8978 currentPeriod.requestSources(this.getSources()); 8979 currentPeriod.thaw(); 8980 } 8981 }; 8982 // Source Querying 8983 // ----------------------------------------------------------------------------------------------------------------- 8984 EventManager.prototype.getSources = function () { 8985 return [this.stickySource].concat(this.otherSources); 8986 }; 8987 // like querySources, but accepts multple match criteria (like multiple IDs) 8988 EventManager.prototype.multiQuerySources = function (matchInputs) { 8989 // coerce into an array 8990 if (!matchInputs) { 8991 matchInputs = []; 8992 } 8993 else if (!$.isArray(matchInputs)) { 8994 matchInputs = [matchInputs]; 8995 } 8996 var matchingSources = []; 8997 var i; 8998 // resolve raw inputs to real event source objects 8999 for (i = 0; i < matchInputs.length; i++) { 9000 matchingSources.push.apply(// append 9001 matchingSources, this.querySources(matchInputs[i])); 9002 } 9003 return matchingSources; 9004 }; 9005 // matchInput can either by a real event source object, an ID, or the function/URL for the source. 9006 // returns an array of matching source objects. 9007 EventManager.prototype.querySources = function (matchInput) { 9008 var sources = this.otherSources; 9009 var i; 9010 var source; 9011 // given a proper event source object 9012 for (i = 0; i < sources.length; i++) { 9013 source = sources[i]; 9014 if (source === matchInput) { 9015 return [source]; 9016 } 9017 } 9018 // an ID match 9019 source = this.getSourceById(EventSource_1.default.normalizeId(matchInput)); 9020 if (source) { 9021 return [source]; 9022 } 9023 // parse as an event source 9024 matchInput = EventSourceParser_1.default.parse(matchInput, this.calendar); 9025 if (matchInput) { 9026 return $.grep(sources, function (source) { 9027 return isSourcesEquivalent(matchInput, source); 9028 }); 9029 } 9030 }; 9031 /* 9032 ID assumed to already be normalized 9033 */ 9034 EventManager.prototype.getSourceById = function (id) { 9035 return $.grep(this.otherSources, function (source) { 9036 return source.id && source.id === id; 9037 })[0]; 9038 }; 9039 // Event-Period 9040 // ----------------------------------------------------------------------------------------------------------------- 9041 EventManager.prototype.setPeriod = function (eventPeriod) { 9042 if (this.currentPeriod) { 9043 this.unbindPeriod(this.currentPeriod); 9044 this.currentPeriod = null; 9045 } 9046 this.currentPeriod = eventPeriod; 9047 this.bindPeriod(eventPeriod); 9048 eventPeriod.requestSources(this.getSources()); 9049 }; 9050 EventManager.prototype.bindPeriod = function (eventPeriod) { 9051 this.listenTo(eventPeriod, 'release', function (eventsPayload) { 9052 this.trigger('release', eventsPayload); 9053 }); 9054 }; 9055 EventManager.prototype.unbindPeriod = function (eventPeriod) { 9056 this.stopListeningTo(eventPeriod); 9057 }; 9058 // Event Getting/Adding/Removing 9059 // ----------------------------------------------------------------------------------------------------------------- 9060 EventManager.prototype.getEventDefByUid = function (uid) { 9061 if (this.currentPeriod) { 9062 return this.currentPeriod.getEventDefByUid(uid); 9063 } 9064 }; 9065 EventManager.prototype.addEventDef = function (eventDef, isSticky) { 9066 if (isSticky) { 9067 this.stickySource.addEventDef(eventDef); 9068 } 9069 if (this.currentPeriod) { 9070 this.currentPeriod.addEventDef(eventDef); // might release 9071 } 9072 }; 9073 EventManager.prototype.removeEventDefsById = function (eventId) { 9074 this.getSources().forEach(function (eventSource) { 9075 eventSource.removeEventDefsById(eventId); 9076 }); 9077 if (this.currentPeriod) { 9078 this.currentPeriod.removeEventDefsById(eventId); // might release 9079 } 9080 }; 9081 EventManager.prototype.removeAllEventDefs = function () { 9082 this.getSources().forEach(function (eventSource) { 9083 eventSource.removeAllEventDefs(); 9084 }); 9085 if (this.currentPeriod) { 9086 this.currentPeriod.removeAllEventDefs(); 9087 } 9088 }; 9089 // Event Mutating 9090 // ----------------------------------------------------------------------------------------------------------------- 9091 /* 9092 Returns an undo function. 9093 */ 9094 EventManager.prototype.mutateEventsWithId = function (eventDefId, eventDefMutation) { 9095 var currentPeriod = this.currentPeriod; 9096 var eventDefs; 9097 var undoFuncs = []; 9098 if (currentPeriod) { 9099 currentPeriod.freeze(); 9100 eventDefs = currentPeriod.getEventDefsById(eventDefId); 9101 eventDefs.forEach(function (eventDef) { 9102 // add/remove esp because id might change 9103 currentPeriod.removeEventDef(eventDef); 9104 undoFuncs.push(eventDefMutation.mutateSingle(eventDef)); 9105 currentPeriod.addEventDef(eventDef); 9106 }); 9107 currentPeriod.thaw(); 9108 return function () { 9109 currentPeriod.freeze(); 9110 for (var i = 0; i < eventDefs.length; i++) { 9111 currentPeriod.removeEventDef(eventDefs[i]); 9112 undoFuncs[i](); 9113 currentPeriod.addEventDef(eventDefs[i]); 9114 } 9115 currentPeriod.thaw(); 9116 }; 9117 } 9118 return function () { }; 9119 }; 9120 /* 9121 copies and then mutates 9122 */ 9123 EventManager.prototype.buildMutatedEventInstanceGroup = function (eventDefId, eventDefMutation) { 9124 var eventDefs = this.getEventDefsById(eventDefId); 9125 var i; 9126 var defCopy; 9127 var allInstances = []; 9128 for (i = 0; i < eventDefs.length; i++) { 9129 defCopy = eventDefs[i].clone(); 9130 if (defCopy instanceof SingleEventDef_1.default) { 9131 eventDefMutation.mutateSingle(defCopy); 9132 allInstances.push.apply(allInstances, // append 9133 defCopy.buildInstances()); 9134 } 9135 } 9136 return new EventInstanceGroup_1.default(allInstances); 9137 }; 9138 // Freezing 9139 // ----------------------------------------------------------------------------------------------------------------- 9140 EventManager.prototype.freeze = function () { 9141 if (this.currentPeriod) { 9142 this.currentPeriod.freeze(); 9143 } 9144 }; 9145 EventManager.prototype.thaw = function () { 9146 if (this.currentPeriod) { 9147 this.currentPeriod.thaw(); 9148 } 9149 }; 9150 // methods that simply forward to EventPeriod 9151 EventManager.prototype.getEventDefsById = function (eventDefId) { 9152 return this.currentPeriod.getEventDefsById(eventDefId); 9153 }; 9154 EventManager.prototype.getEventInstances = function () { 9155 return this.currentPeriod.getEventInstances(); 9156 }; 9157 EventManager.prototype.getEventInstancesWithId = function (eventDefId) { 9158 return this.currentPeriod.getEventInstancesWithId(eventDefId); 9159 }; 9160 EventManager.prototype.getEventInstancesWithoutId = function (eventDefId) { 9161 return this.currentPeriod.getEventInstancesWithoutId(eventDefId); 9162 }; 9163 return EventManager; 9164}()); 9165exports.default = EventManager; 9166EmitterMixin_1.default.mixInto(EventManager); 9167ListenerMixin_1.default.mixInto(EventManager); 9168function isSourcesEquivalent(source0, source1) { 9169 return source0.getPrimitive() === source1.getPrimitive(); 9170} 9171 9172 9173/***/ }), 9174/* 221 */ 9175/***/ (function(module, exports, __webpack_require__) { 9176 9177Object.defineProperty(exports, "__esModule", { value: true }); 9178var tslib_1 = __webpack_require__(2); 9179var Theme_1 = __webpack_require__(22); 9180var StandardTheme = /** @class */ (function (_super) { 9181 tslib_1.__extends(StandardTheme, _super); 9182 function StandardTheme() { 9183 return _super !== null && _super.apply(this, arguments) || this; 9184 } 9185 return StandardTheme; 9186}(Theme_1.default)); 9187exports.default = StandardTheme; 9188StandardTheme.prototype.classes = { 9189 widget: 'fc-unthemed', 9190 widgetHeader: 'fc-widget-header', 9191 widgetContent: 'fc-widget-content', 9192 buttonGroup: 'fc-button-group', 9193 button: 'fc-button', 9194 cornerLeft: 'fc-corner-left', 9195 cornerRight: 'fc-corner-right', 9196 stateDefault: 'fc-state-default', 9197 stateActive: 'fc-state-active', 9198 stateDisabled: 'fc-state-disabled', 9199 stateHover: 'fc-state-hover', 9200 stateDown: 'fc-state-down', 9201 popoverHeader: 'fc-widget-header', 9202 popoverContent: 'fc-widget-content', 9203 // day grid 9204 headerRow: 'fc-widget-header', 9205 dayRow: 'fc-widget-content', 9206 // list view 9207 listView: 'fc-widget-content' 9208}; 9209StandardTheme.prototype.baseIconClass = 'fc-icon'; 9210StandardTheme.prototype.iconClasses = { 9211 close: 'fc-icon-x', 9212 prev: 'fc-icon-left-single-arrow', 9213 next: 'fc-icon-right-single-arrow', 9214 prevYear: 'fc-icon-left-double-arrow', 9215 nextYear: 'fc-icon-right-double-arrow' 9216}; 9217StandardTheme.prototype.iconOverrideOption = 'buttonIcons'; 9218StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon'; 9219StandardTheme.prototype.iconOverridePrefix = 'fc-icon-'; 9220 9221 9222/***/ }), 9223/* 222 */ 9224/***/ (function(module, exports, __webpack_require__) { 9225 9226Object.defineProperty(exports, "__esModule", { value: true }); 9227var tslib_1 = __webpack_require__(2); 9228var Theme_1 = __webpack_require__(22); 9229var JqueryUiTheme = /** @class */ (function (_super) { 9230 tslib_1.__extends(JqueryUiTheme, _super); 9231 function JqueryUiTheme() { 9232 return _super !== null && _super.apply(this, arguments) || this; 9233 } 9234 return JqueryUiTheme; 9235}(Theme_1.default)); 9236exports.default = JqueryUiTheme; 9237JqueryUiTheme.prototype.classes = { 9238 widget: 'ui-widget', 9239 widgetHeader: 'ui-widget-header', 9240 widgetContent: 'ui-widget-content', 9241 buttonGroup: 'fc-button-group', 9242 button: 'ui-button', 9243 cornerLeft: 'ui-corner-left', 9244 cornerRight: 'ui-corner-right', 9245 stateDefault: 'ui-state-default', 9246 stateActive: 'ui-state-active', 9247 stateDisabled: 'ui-state-disabled', 9248 stateHover: 'ui-state-hover', 9249 stateDown: 'ui-state-down', 9250 today: 'ui-state-highlight', 9251 popoverHeader: 'ui-widget-header', 9252 popoverContent: 'ui-widget-content', 9253 // day grid 9254 headerRow: 'ui-widget-header', 9255 dayRow: 'ui-widget-content', 9256 // list view 9257 listView: 'ui-widget-content' 9258}; 9259JqueryUiTheme.prototype.baseIconClass = 'ui-icon'; 9260JqueryUiTheme.prototype.iconClasses = { 9261 close: 'ui-icon-closethick', 9262 prev: 'ui-icon-circle-triangle-w', 9263 next: 'ui-icon-circle-triangle-e', 9264 prevYear: 'ui-icon-seek-prev', 9265 nextYear: 'ui-icon-seek-next' 9266}; 9267JqueryUiTheme.prototype.iconOverrideOption = 'themeButtonIcons'; 9268JqueryUiTheme.prototype.iconOverrideCustomButtonOption = 'themeIcon'; 9269JqueryUiTheme.prototype.iconOverridePrefix = 'ui-icon-'; 9270 9271 9272/***/ }), 9273/* 223 */ 9274/***/ (function(module, exports, __webpack_require__) { 9275 9276Object.defineProperty(exports, "__esModule", { value: true }); 9277var tslib_1 = __webpack_require__(2); 9278var $ = __webpack_require__(3); 9279var Promise_1 = __webpack_require__(21); 9280var EventSource_1 = __webpack_require__(6); 9281var FuncEventSource = /** @class */ (function (_super) { 9282 tslib_1.__extends(FuncEventSource, _super); 9283 function FuncEventSource() { 9284 return _super !== null && _super.apply(this, arguments) || this; 9285 } 9286 FuncEventSource.parse = function (rawInput, calendar) { 9287 var rawProps; 9288 // normalize raw input 9289 if ($.isFunction(rawInput.events)) { // extended form 9290 rawProps = rawInput; 9291 } 9292 else if ($.isFunction(rawInput)) { // short form 9293 rawProps = { events: rawInput }; 9294 } 9295 if (rawProps) { 9296 return EventSource_1.default.parse.call(this, rawProps, calendar); 9297 } 9298 return false; 9299 }; 9300 FuncEventSource.prototype.fetch = function (start, end, timezone) { 9301 var _this = this; 9302 this.calendar.pushLoading(); 9303 return Promise_1.default.construct(function (onResolve) { 9304 _this.func.call(_this.calendar, start.clone(), end.clone(), timezone, function (rawEventDefs) { 9305 _this.calendar.popLoading(); 9306 onResolve(_this.parseEventDefs(rawEventDefs)); 9307 }); 9308 }); 9309 }; 9310 FuncEventSource.prototype.getPrimitive = function () { 9311 return this.func; 9312 }; 9313 FuncEventSource.prototype.applyManualStandardProps = function (rawProps) { 9314 var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps); 9315 this.func = rawProps.events; 9316 return superSuccess; 9317 }; 9318 return FuncEventSource; 9319}(EventSource_1.default)); 9320exports.default = FuncEventSource; 9321FuncEventSource.defineStandardProps({ 9322 events: false // don't automatically transfer 9323}); 9324 9325 9326/***/ }), 9327/* 224 */ 9328/***/ (function(module, exports, __webpack_require__) { 9329 9330Object.defineProperty(exports, "__esModule", { value: true }); 9331var tslib_1 = __webpack_require__(2); 9332var $ = __webpack_require__(3); 9333var util_1 = __webpack_require__(4); 9334var Promise_1 = __webpack_require__(21); 9335var EventSource_1 = __webpack_require__(6); 9336var JsonFeedEventSource = /** @class */ (function (_super) { 9337 tslib_1.__extends(JsonFeedEventSource, _super); 9338 function JsonFeedEventSource() { 9339 return _super !== null && _super.apply(this, arguments) || this; 9340 } 9341 JsonFeedEventSource.parse = function (rawInput, calendar) { 9342 var rawProps; 9343 // normalize raw input 9344 if (typeof rawInput.url === 'string') { // extended form 9345 rawProps = rawInput; 9346 } 9347 else if (typeof rawInput === 'string') { // short form 9348 rawProps = { url: rawInput }; 9349 } 9350 if (rawProps) { 9351 return EventSource_1.default.parse.call(this, rawProps, calendar); 9352 } 9353 return false; 9354 }; 9355 JsonFeedEventSource.prototype.fetch = function (start, end, timezone) { 9356 var _this = this; 9357 var ajaxSettings = this.ajaxSettings; 9358 var onSuccess = ajaxSettings.success; 9359 var onError = ajaxSettings.error; 9360 var requestParams = this.buildRequestParams(start, end, timezone); 9361 // todo: eventually handle the promise's then, 9362 // don't intercept success/error 9363 // tho will be a breaking API change 9364 this.calendar.pushLoading(); 9365 return Promise_1.default.construct(function (onResolve, onReject) { 9366 $.ajax($.extend({}, // destination 9367 JsonFeedEventSource.AJAX_DEFAULTS, ajaxSettings, { 9368 url: _this.url, 9369 data: requestParams, 9370 success: function (rawEventDefs, status, xhr) { 9371 var callbackRes; 9372 _this.calendar.popLoading(); 9373 if (rawEventDefs) { 9374 callbackRes = util_1.applyAll(onSuccess, _this, [rawEventDefs, status, xhr]); // redirect `this` 9375 if ($.isArray(callbackRes)) { 9376 rawEventDefs = callbackRes; 9377 } 9378 onResolve(_this.parseEventDefs(rawEventDefs)); 9379 } 9380 else { 9381 onReject(); 9382 } 9383 }, 9384 error: function (xhr, statusText, errorThrown) { 9385 _this.calendar.popLoading(); 9386 util_1.applyAll(onError, _this, [xhr, statusText, errorThrown]); // redirect `this` 9387 onReject(); 9388 } 9389 })); 9390 }); 9391 }; 9392 JsonFeedEventSource.prototype.buildRequestParams = function (start, end, timezone) { 9393 var calendar = this.calendar; 9394 var ajaxSettings = this.ajaxSettings; 9395 var startParam; 9396 var endParam; 9397 var timezoneParam; 9398 var customRequestParams; 9399 var params = {}; 9400 startParam = this.startParam; 9401 if (startParam == null) { 9402 startParam = calendar.opt('startParam'); 9403 } 9404 endParam = this.endParam; 9405 if (endParam == null) { 9406 endParam = calendar.opt('endParam'); 9407 } 9408 timezoneParam = this.timezoneParam; 9409 if (timezoneParam == null) { 9410 timezoneParam = calendar.opt('timezoneParam'); 9411 } 9412 // retrieve any outbound GET/POST $.ajax data from the options 9413 if ($.isFunction(ajaxSettings.data)) { 9414 // supplied as a function that returns a key/value object 9415 customRequestParams = ajaxSettings.data(); 9416 } 9417 else { 9418 // probably supplied as a straight key/value object 9419 customRequestParams = ajaxSettings.data || {}; 9420 } 9421 $.extend(params, customRequestParams); 9422 params[startParam] = start.format(); 9423 params[endParam] = end.format(); 9424 if (timezone && timezone !== 'local') { 9425 params[timezoneParam] = timezone; 9426 } 9427 return params; 9428 }; 9429 JsonFeedEventSource.prototype.getPrimitive = function () { 9430 return this.url; 9431 }; 9432 JsonFeedEventSource.prototype.applyMiscProps = function (rawProps) { 9433 this.ajaxSettings = rawProps; 9434 }; 9435 JsonFeedEventSource.AJAX_DEFAULTS = { 9436 dataType: 'json', 9437 cache: false 9438 }; 9439 return JsonFeedEventSource; 9440}(EventSource_1.default)); 9441exports.default = JsonFeedEventSource; 9442JsonFeedEventSource.defineStandardProps({ 9443 // automatically transfer (true)... 9444 url: true, 9445 startParam: true, 9446 endParam: true, 9447 timezoneParam: true 9448}); 9449 9450 9451/***/ }), 9452/* 225 */ 9453/***/ (function(module, exports) { 9454 9455Object.defineProperty(exports, "__esModule", { value: true }); 9456var Iterator = /** @class */ (function () { 9457 function Iterator(items) { 9458 this.items = items || []; 9459 } 9460 /* Calls a method on every item passing the arguments through */ 9461 Iterator.prototype.proxyCall = function (methodName) { 9462 var args = []; 9463 for (var _i = 1; _i < arguments.length; _i++) { 9464 args[_i - 1] = arguments[_i]; 9465 } 9466 var results = []; 9467 this.items.forEach(function (item) { 9468 results.push(item[methodName].apply(item, args)); 9469 }); 9470 return results; 9471 }; 9472 return Iterator; 9473}()); 9474exports.default = Iterator; 9475 9476 9477/***/ }), 9478/* 226 */ 9479/***/ (function(module, exports, __webpack_require__) { 9480 9481Object.defineProperty(exports, "__esModule", { value: true }); 9482var $ = __webpack_require__(3); 9483var util_1 = __webpack_require__(4); 9484var ListenerMixin_1 = __webpack_require__(7); 9485/* Creates a clone of an element and lets it track the mouse as it moves 9486----------------------------------------------------------------------------------------------------------------------*/ 9487var MouseFollower = /** @class */ (function () { 9488 function MouseFollower(sourceEl, options) { 9489 this.isFollowing = false; 9490 this.isHidden = false; 9491 this.isAnimating = false; // doing the revert animation? 9492 this.options = options = options || {}; 9493 this.sourceEl = sourceEl; 9494 this.parentEl = options.parentEl ? $(options.parentEl) : sourceEl.parent(); // default to sourceEl's parent 9495 } 9496 // Causes the element to start following the mouse 9497 MouseFollower.prototype.start = function (ev) { 9498 if (!this.isFollowing) { 9499 this.isFollowing = true; 9500 this.y0 = util_1.getEvY(ev); 9501 this.x0 = util_1.getEvX(ev); 9502 this.topDelta = 0; 9503 this.leftDelta = 0; 9504 if (!this.isHidden) { 9505 this.updatePosition(); 9506 } 9507 if (util_1.getEvIsTouch(ev)) { 9508 this.listenTo($(document), 'touchmove', this.handleMove); 9509 } 9510 else { 9511 this.listenTo($(document), 'mousemove', this.handleMove); 9512 } 9513 } 9514 }; 9515 // Causes the element to stop following the mouse. If shouldRevert is true, will animate back to original position. 9516 // `callback` gets invoked when the animation is complete. If no animation, it is invoked immediately. 9517 MouseFollower.prototype.stop = function (shouldRevert, callback) { 9518 var _this = this; 9519 var revertDuration = this.options.revertDuration; 9520 var complete = function () { 9521 _this.isAnimating = false; 9522 _this.removeElement(); 9523 _this.top0 = _this.left0 = null; // reset state for future updatePosition calls 9524 if (callback) { 9525 callback(); 9526 } 9527 }; 9528 if (this.isFollowing && !this.isAnimating) { // disallow more than one stop animation at a time 9529 this.isFollowing = false; 9530 this.stopListeningTo($(document)); 9531 if (shouldRevert && revertDuration && !this.isHidden) { // do a revert animation? 9532 this.isAnimating = true; 9533 this.el.animate({ 9534 top: this.top0, 9535 left: this.left0 9536 }, { 9537 duration: revertDuration, 9538 complete: complete 9539 }); 9540 } 9541 else { 9542 complete(); 9543 } 9544 } 9545 }; 9546 // Gets the tracking element. Create it if necessary 9547 MouseFollower.prototype.getEl = function () { 9548 var el = this.el; 9549 if (!el) { 9550 el = this.el = this.sourceEl.clone() 9551 .addClass(this.options.additionalClass || '') 9552 .css({ 9553 position: 'absolute', 9554 visibility: '', 9555 display: this.isHidden ? 'none' : '', 9556 margin: 0, 9557 right: 'auto', 9558 bottom: 'auto', 9559 width: this.sourceEl.width(), 9560 height: this.sourceEl.height(), 9561 opacity: this.options.opacity || '', 9562 zIndex: this.options.zIndex 9563 }); 9564 // we don't want long taps or any mouse interaction causing selection/menus. 9565 // would use preventSelection(), but that prevents selectstart, causing problems. 9566 el.addClass('fc-unselectable'); 9567 el.appendTo(this.parentEl); 9568 } 9569 return el; 9570 }; 9571 // Removes the tracking element if it has already been created 9572 MouseFollower.prototype.removeElement = function () { 9573 if (this.el) { 9574 this.el.remove(); 9575 this.el = null; 9576 } 9577 }; 9578 // Update the CSS position of the tracking element 9579 MouseFollower.prototype.updatePosition = function () { 9580 var sourceOffset; 9581 var origin; 9582 this.getEl(); // ensure this.el 9583 // make sure origin info was computed 9584 if (this.top0 == null) { 9585 sourceOffset = this.sourceEl.offset(); 9586 origin = this.el.offsetParent().offset(); 9587 this.top0 = sourceOffset.top - origin.top; 9588 this.left0 = sourceOffset.left - origin.left; 9589 } 9590 this.el.css({ 9591 top: this.top0 + this.topDelta, 9592 left: this.left0 + this.leftDelta 9593 }); 9594 }; 9595 // Gets called when the user moves the mouse 9596 MouseFollower.prototype.handleMove = function (ev) { 9597 this.topDelta = util_1.getEvY(ev) - this.y0; 9598 this.leftDelta = util_1.getEvX(ev) - this.x0; 9599 if (!this.isHidden) { 9600 this.updatePosition(); 9601 } 9602 }; 9603 // Temporarily makes the tracking element invisible. Can be called before following starts 9604 MouseFollower.prototype.hide = function () { 9605 if (!this.isHidden) { 9606 this.isHidden = true; 9607 if (this.el) { 9608 this.el.hide(); 9609 } 9610 } 9611 }; 9612 // Show the tracking element after it has been temporarily hidden 9613 MouseFollower.prototype.show = function () { 9614 if (this.isHidden) { 9615 this.isHidden = false; 9616 this.updatePosition(); 9617 this.getEl().show(); 9618 } 9619 }; 9620 return MouseFollower; 9621}()); 9622exports.default = MouseFollower; 9623ListenerMixin_1.default.mixInto(MouseFollower); 9624 9625 9626/***/ }), 9627/* 227 */ 9628/***/ (function(module, exports, __webpack_require__) { 9629 9630/* A rectangular panel that is absolutely positioned over other content 9631------------------------------------------------------------------------------------------------------------------------ 9632Options: 9633 - className (string) 9634 - content (HTML string or jQuery element set) 9635 - parentEl 9636 - top 9637 - left 9638 - right (the x coord of where the right edge should be. not a "CSS" right) 9639 - autoHide (boolean) 9640 - show (callback) 9641 - hide (callback) 9642*/ 9643Object.defineProperty(exports, "__esModule", { value: true }); 9644var $ = __webpack_require__(3); 9645var util_1 = __webpack_require__(4); 9646var ListenerMixin_1 = __webpack_require__(7); 9647var Popover = /** @class */ (function () { 9648 function Popover(options) { 9649 this.isHidden = true; 9650 this.margin = 10; // the space required between the popover and the edges of the scroll container 9651 this.options = options || {}; 9652 } 9653 // Shows the popover on the specified position. Renders it if not already 9654 Popover.prototype.show = function () { 9655 if (this.isHidden) { 9656 if (!this.el) { 9657 this.render(); 9658 } 9659 this.el.show(); 9660 this.position(); 9661 this.isHidden = false; 9662 this.trigger('show'); 9663 } 9664 }; 9665 // Hides the popover, through CSS, but does not remove it from the DOM 9666 Popover.prototype.hide = function () { 9667 if (!this.isHidden) { 9668 this.el.hide(); 9669 this.isHidden = true; 9670 this.trigger('hide'); 9671 } 9672 }; 9673 // Creates `this.el` and renders content inside of it 9674 Popover.prototype.render = function () { 9675 var _this = this; 9676 var options = this.options; 9677 this.el = $('<div class="fc-popover">') 9678 .addClass(options.className || '') 9679 .css({ 9680 // position initially to the top left to avoid creating scrollbars 9681 top: 0, 9682 left: 0 9683 }) 9684 .append(options.content) 9685 .appendTo(options.parentEl); 9686 // when a click happens on anything inside with a 'fc-close' className, hide the popover 9687 this.el.on('click', '.fc-close', function () { 9688 _this.hide(); 9689 }); 9690 if (options.autoHide) { 9691 this.listenTo($(document), 'mousedown', this.documentMousedown); 9692 } 9693 }; 9694 // Triggered when the user clicks *anywhere* in the document, for the autoHide feature 9695 Popover.prototype.documentMousedown = function (ev) { 9696 // only hide the popover if the click happened outside the popover 9697 if (this.el && !$(ev.target).closest(this.el).length) { 9698 this.hide(); 9699 } 9700 }; 9701 // Hides and unregisters any handlers 9702 Popover.prototype.removeElement = function () { 9703 this.hide(); 9704 if (this.el) { 9705 this.el.remove(); 9706 this.el = null; 9707 } 9708 this.stopListeningTo($(document), 'mousedown'); 9709 }; 9710 // Positions the popover optimally, using the top/left/right options 9711 Popover.prototype.position = function () { 9712 var options = this.options; 9713 var origin = this.el.offsetParent().offset(); 9714 var width = this.el.outerWidth(); 9715 var height = this.el.outerHeight(); 9716 var windowEl = $(window); 9717 var viewportEl = util_1.getScrollParent(this.el); 9718 var viewportTop; 9719 var viewportLeft; 9720 var viewportOffset; 9721 var top; // the "position" (not "offset") values for the popover 9722 var left; // 9723 // compute top and left 9724 top = options.top || 0; 9725 if (options.left !== undefined) { 9726 left = options.left; 9727 } 9728 else if (options.right !== undefined) { 9729 left = options.right - width; // derive the left value from the right value 9730 } 9731 else { 9732 left = 0; 9733 } 9734 if (viewportEl.is(window) || viewportEl.is(document)) { // normalize getScrollParent's result 9735 viewportEl = windowEl; 9736 viewportTop = 0; // the window is always at the top left 9737 viewportLeft = 0; // (and .offset() won't work if called here) 9738 } 9739 else { 9740 viewportOffset = viewportEl.offset(); 9741 viewportTop = viewportOffset.top; 9742 viewportLeft = viewportOffset.left; 9743 } 9744 // if the window is scrolled, it causes the visible area to be further down 9745 viewportTop += windowEl.scrollTop(); 9746 viewportLeft += windowEl.scrollLeft(); 9747 // constrain to the view port. if constrained by two edges, give precedence to top/left 9748 if (options.viewportConstrain !== false) { 9749 top = Math.min(top, viewportTop + viewportEl.outerHeight() - height - this.margin); 9750 top = Math.max(top, viewportTop + this.margin); 9751 left = Math.min(left, viewportLeft + viewportEl.outerWidth() - width - this.margin); 9752 left = Math.max(left, viewportLeft + this.margin); 9753 } 9754 this.el.css({ 9755 top: top - origin.top, 9756 left: left - origin.left 9757 }); 9758 }; 9759 // Triggers a callback. Calls a function in the option hash of the same name. 9760 // Arguments beyond the first `name` are forwarded on. 9761 // TODO: better code reuse for this. Repeat code 9762 Popover.prototype.trigger = function (name) { 9763 if (this.options[name]) { 9764 this.options[name].apply(this, Array.prototype.slice.call(arguments, 1)); 9765 } 9766 }; 9767 return Popover; 9768}()); 9769exports.default = Popover; 9770ListenerMixin_1.default.mixInto(Popover); 9771 9772 9773/***/ }), 9774/* 228 */ 9775/***/ (function(module, exports, __webpack_require__) { 9776 9777Object.defineProperty(exports, "__esModule", { value: true }); 9778var EmitterMixin_1 = __webpack_require__(13); 9779var TaskQueue = /** @class */ (function () { 9780 function TaskQueue() { 9781 this.q = []; 9782 this.isPaused = false; 9783 this.isRunning = false; 9784 } 9785 TaskQueue.prototype.queue = function () { 9786 var args = []; 9787 for (var _i = 0; _i < arguments.length; _i++) { 9788 args[_i] = arguments[_i]; 9789 } 9790 this.q.push.apply(this.q, args); // append 9791 this.tryStart(); 9792 }; 9793 TaskQueue.prototype.pause = function () { 9794 this.isPaused = true; 9795 }; 9796 TaskQueue.prototype.resume = function () { 9797 this.isPaused = false; 9798 this.tryStart(); 9799 }; 9800 TaskQueue.prototype.getIsIdle = function () { 9801 return !this.isRunning && !this.isPaused; 9802 }; 9803 TaskQueue.prototype.tryStart = function () { 9804 if (!this.isRunning && this.canRunNext()) { 9805 this.isRunning = true; 9806 this.trigger('start'); 9807 this.runRemaining(); 9808 } 9809 }; 9810 TaskQueue.prototype.canRunNext = function () { 9811 return !this.isPaused && this.q.length; 9812 }; 9813 TaskQueue.prototype.runRemaining = function () { 9814 var _this = this; 9815 var task; 9816 var res; 9817 do { 9818 task = this.q.shift(); // always freshly reference q. might have been reassigned. 9819 res = this.runTask(task); 9820 if (res && res.then) { 9821 res.then(function () { 9822 if (_this.canRunNext()) { 9823 _this.runRemaining(); 9824 } 9825 }); 9826 return; // prevent marking as stopped 9827 } 9828 } while (this.canRunNext()); 9829 this.trigger('stop'); // not really a 'stop' ... more of a 'drained' 9830 this.isRunning = false; 9831 // if 'stop' handler added more tasks.... TODO: write test for this 9832 this.tryStart(); 9833 }; 9834 TaskQueue.prototype.runTask = function (task) { 9835 return task(); // task *is* the function, but subclasses can change the format of a task 9836 }; 9837 return TaskQueue; 9838}()); 9839exports.default = TaskQueue; 9840EmitterMixin_1.default.mixInto(TaskQueue); 9841 9842 9843/***/ }), 9844/* 229 */ 9845/***/ (function(module, exports, __webpack_require__) { 9846 9847Object.defineProperty(exports, "__esModule", { value: true }); 9848var tslib_1 = __webpack_require__(2); 9849var TaskQueue_1 = __webpack_require__(228); 9850var RenderQueue = /** @class */ (function (_super) { 9851 tslib_1.__extends(RenderQueue, _super); 9852 function RenderQueue(waitsByNamespace) { 9853 var _this = _super.call(this) || this; 9854 _this.waitsByNamespace = waitsByNamespace || {}; 9855 return _this; 9856 } 9857 RenderQueue.prototype.queue = function (taskFunc, namespace, type) { 9858 var task = { 9859 func: taskFunc, 9860 namespace: namespace, 9861 type: type 9862 }; 9863 var waitMs; 9864 if (namespace) { 9865 waitMs = this.waitsByNamespace[namespace]; 9866 } 9867 if (this.waitNamespace) { 9868 if (namespace === this.waitNamespace && waitMs != null) { 9869 this.delayWait(waitMs); 9870 } 9871 else { 9872 this.clearWait(); 9873 this.tryStart(); 9874 } 9875 } 9876 if (this.compoundTask(task)) { // appended to queue? 9877 if (!this.waitNamespace && waitMs != null) { 9878 this.startWait(namespace, waitMs); 9879 } 9880 else { 9881 this.tryStart(); 9882 } 9883 } 9884 }; 9885 RenderQueue.prototype.startWait = function (namespace, waitMs) { 9886 this.waitNamespace = namespace; 9887 this.spawnWait(waitMs); 9888 }; 9889 RenderQueue.prototype.delayWait = function (waitMs) { 9890 clearTimeout(this.waitId); 9891 this.spawnWait(waitMs); 9892 }; 9893 RenderQueue.prototype.spawnWait = function (waitMs) { 9894 var _this = this; 9895 this.waitId = setTimeout(function () { 9896 _this.waitNamespace = null; 9897 _this.tryStart(); 9898 }, waitMs); 9899 }; 9900 RenderQueue.prototype.clearWait = function () { 9901 if (this.waitNamespace) { 9902 clearTimeout(this.waitId); 9903 this.waitId = null; 9904 this.waitNamespace = null; 9905 } 9906 }; 9907 RenderQueue.prototype.canRunNext = function () { 9908 if (!_super.prototype.canRunNext.call(this)) { 9909 return false; 9910 } 9911 // waiting for a certain namespace to stop receiving tasks? 9912 if (this.waitNamespace) { 9913 var q = this.q; 9914 // if there was a different namespace task in the meantime, 9915 // that forces all previously-waiting tasks to suddenly execute. 9916 // TODO: find a way to do this in constant time. 9917 for (var i = 0; i < q.length; i++) { 9918 if (q[i].namespace !== this.waitNamespace) { 9919 return true; // allow execution 9920 } 9921 } 9922 return false; 9923 } 9924 return true; 9925 }; 9926 RenderQueue.prototype.runTask = function (task) { 9927 task.func(); 9928 }; 9929 RenderQueue.prototype.compoundTask = function (newTask) { 9930 var q = this.q; 9931 var shouldAppend = true; 9932 var i; 9933 var task; 9934 if (newTask.namespace && newTask.type === 'destroy') { 9935 // remove all init/add/remove ops with same namespace, regardless of order 9936 for (i = q.length - 1; i >= 0; i--) { 9937 task = q[i]; 9938 if (task.namespace === newTask.namespace) { 9939 switch (task.type) { 9940 case 'init': 9941 shouldAppend = false; 9942 // the latest destroy is cancelled out by not doing the init 9943 /* falls through */ 9944 case 'add': 9945 /* falls through */ 9946 case 'remove': 9947 q.splice(i, 1); // remove task 9948 } 9949 } 9950 } 9951 } 9952 if (shouldAppend) { 9953 q.push(newTask); 9954 } 9955 return shouldAppend; 9956 }; 9957 return RenderQueue; 9958}(TaskQueue_1.default)); 9959exports.default = RenderQueue; 9960 9961 9962/***/ }), 9963/* 230 */ 9964/***/ (function(module, exports, __webpack_require__) { 9965 9966Object.defineProperty(exports, "__esModule", { value: true }); 9967var tslib_1 = __webpack_require__(2); 9968var Model_1 = __webpack_require__(51); 9969var Component = /** @class */ (function (_super) { 9970 tslib_1.__extends(Component, _super); 9971 function Component() { 9972 return _super !== null && _super.apply(this, arguments) || this; 9973 } 9974 Component.prototype.setElement = function (el) { 9975 this.el = el; 9976 this.bindGlobalHandlers(); 9977 this.renderSkeleton(); 9978 this.set('isInDom', true); 9979 }; 9980 Component.prototype.removeElement = function () { 9981 this.unset('isInDom'); 9982 this.unrenderSkeleton(); 9983 this.unbindGlobalHandlers(); 9984 this.el.remove(); 9985 // NOTE: don't null-out this.el in case the View was destroyed within an API callback. 9986 // We don't null-out the View's other jQuery element references upon destroy, 9987 // so we shouldn't kill this.el either. 9988 }; 9989 Component.prototype.bindGlobalHandlers = function () { 9990 // subclasses can override 9991 }; 9992 Component.prototype.unbindGlobalHandlers = function () { 9993 // subclasses can override 9994 }; 9995 /* 9996 NOTE: Can't have a `render` method. Read the deprecation notice in View::executeDateRender 9997 */ 9998 // Renders the basic structure of the view before any content is rendered 9999 Component.prototype.renderSkeleton = function () { 10000 // subclasses should implement 10001 }; 10002 // Unrenders the basic structure of the view 10003 Component.prototype.unrenderSkeleton = function () { 10004 // subclasses should implement 10005 }; 10006 return Component; 10007}(Model_1.default)); 10008exports.default = Component; 10009 10010 10011/***/ }), 10012/* 231 */ 10013/***/ (function(module, exports, __webpack_require__) { 10014 10015Object.defineProperty(exports, "__esModule", { value: true }); 10016var tslib_1 = __webpack_require__(2); 10017var $ = __webpack_require__(3); 10018var moment = __webpack_require__(0); 10019var util_1 = __webpack_require__(4); 10020var moment_ext_1 = __webpack_require__(11); 10021var date_formatting_1 = __webpack_require__(49); 10022var Component_1 = __webpack_require__(230); 10023var util_2 = __webpack_require__(19); 10024var DateComponent = /** @class */ (function (_super) { 10025 tslib_1.__extends(DateComponent, _super); 10026 function DateComponent(_view, _options) { 10027 var _this = _super.call(this) || this; 10028 _this.isRTL = false; // frequently accessed options 10029 _this.hitsNeededDepth = 0; // necessary because multiple callers might need the same hits 10030 _this.hasAllDayBusinessHours = false; // TODO: unify with largeUnit and isTimeScale? 10031 _this.isDatesRendered = false; 10032 // hack to set options prior to the this.opt calls 10033 if (_view) { 10034 _this['view'] = _view; 10035 } 10036 if (_options) { 10037 _this['options'] = _options; 10038 } 10039 _this.uid = String(DateComponent.guid++); 10040 _this.childrenByUid = {}; 10041 _this.nextDayThreshold = moment.duration(_this.opt('nextDayThreshold')); 10042 _this.isRTL = _this.opt('isRTL'); 10043 if (_this.fillRendererClass) { 10044 _this.fillRenderer = new _this.fillRendererClass(_this); 10045 } 10046 if (_this.eventRendererClass) { // fillRenderer is optional -----v 10047 _this.eventRenderer = new _this.eventRendererClass(_this, _this.fillRenderer); 10048 } 10049 if (_this.helperRendererClass && _this.eventRenderer) { 10050 _this.helperRenderer = new _this.helperRendererClass(_this, _this.eventRenderer); 10051 } 10052 if (_this.businessHourRendererClass && _this.fillRenderer) { 10053 _this.businessHourRenderer = new _this.businessHourRendererClass(_this, _this.fillRenderer); 10054 } 10055 return _this; 10056 } 10057 DateComponent.prototype.addChild = function (child) { 10058 if (!this.childrenByUid[child.uid]) { 10059 this.childrenByUid[child.uid] = child; 10060 return true; 10061 } 10062 return false; 10063 }; 10064 DateComponent.prototype.removeChild = function (child) { 10065 if (this.childrenByUid[child.uid]) { 10066 delete this.childrenByUid[child.uid]; 10067 return true; 10068 } 10069 return false; 10070 }; 10071 // TODO: only do if isInDom? 10072 // TODO: make part of Component, along with children/batch-render system? 10073 DateComponent.prototype.updateSize = function (totalHeight, isAuto, isResize) { 10074 this.callChildren('updateSize', arguments); 10075 }; 10076 // Options 10077 // ----------------------------------------------------------------------------------------------------------------- 10078 DateComponent.prototype.opt = function (name) { 10079 return this._getView().opt(name); // default implementation 10080 }; 10081 DateComponent.prototype.publiclyTrigger = function () { 10082 var args = []; 10083 for (var _i = 0; _i < arguments.length; _i++) { 10084 args[_i] = arguments[_i]; 10085 } 10086 var calendar = this._getCalendar(); 10087 return calendar.publiclyTrigger.apply(calendar, args); 10088 }; 10089 DateComponent.prototype.hasPublicHandlers = function () { 10090 var args = []; 10091 for (var _i = 0; _i < arguments.length; _i++) { 10092 args[_i] = arguments[_i]; 10093 } 10094 var calendar = this._getCalendar(); 10095 return calendar.hasPublicHandlers.apply(calendar, args); 10096 }; 10097 // Date 10098 // ----------------------------------------------------------------------------------------------------------------- 10099 DateComponent.prototype.executeDateRender = function (dateProfile) { 10100 this.dateProfile = dateProfile; // for rendering 10101 this.renderDates(dateProfile); 10102 this.isDatesRendered = true; 10103 this.callChildren('executeDateRender', arguments); 10104 }; 10105 DateComponent.prototype.executeDateUnrender = function () { 10106 this.callChildren('executeDateUnrender', arguments); 10107 this.dateProfile = null; 10108 this.unrenderDates(); 10109 this.isDatesRendered = false; 10110 }; 10111 // date-cell content only 10112 DateComponent.prototype.renderDates = function (dateProfile) { 10113 // subclasses should implement 10114 }; 10115 // date-cell content only 10116 DateComponent.prototype.unrenderDates = function () { 10117 // subclasses should override 10118 }; 10119 // Now-Indicator 10120 // ----------------------------------------------------------------------------------------------------------------- 10121 // Returns a string unit, like 'second' or 'minute' that defined how often the current time indicator 10122 // should be refreshed. If something falsy is returned, no time indicator is rendered at all. 10123 DateComponent.prototype.getNowIndicatorUnit = function () { 10124 // subclasses should implement 10125 }; 10126 // Renders a current time indicator at the given datetime 10127 DateComponent.prototype.renderNowIndicator = function (date) { 10128 this.callChildren('renderNowIndicator', arguments); 10129 }; 10130 // Undoes the rendering actions from renderNowIndicator 10131 DateComponent.prototype.unrenderNowIndicator = function () { 10132 this.callChildren('unrenderNowIndicator', arguments); 10133 }; 10134 // Business Hours 10135 // --------------------------------------------------------------------------------------------------------------- 10136 DateComponent.prototype.renderBusinessHours = function (businessHourGenerator) { 10137 if (this.businessHourRenderer) { 10138 this.businessHourRenderer.render(businessHourGenerator); 10139 } 10140 this.callChildren('renderBusinessHours', arguments); 10141 }; 10142 // Unrenders previously-rendered business-hours 10143 DateComponent.prototype.unrenderBusinessHours = function () { 10144 this.callChildren('unrenderBusinessHours', arguments); 10145 if (this.businessHourRenderer) { 10146 this.businessHourRenderer.unrender(); 10147 } 10148 }; 10149 // Event Displaying 10150 // ----------------------------------------------------------------------------------------------------------------- 10151 DateComponent.prototype.executeEventRender = function (eventsPayload) { 10152 if (this.eventRenderer) { 10153 this.eventRenderer.rangeUpdated(); // poorly named now 10154 this.eventRenderer.render(eventsPayload); 10155 } 10156 else if (this['renderEvents']) { // legacy 10157 this['renderEvents'](convertEventsPayloadToLegacyArray(eventsPayload)); 10158 } 10159 this.callChildren('executeEventRender', arguments); 10160 }; 10161 DateComponent.prototype.executeEventUnrender = function () { 10162 this.callChildren('executeEventUnrender', arguments); 10163 if (this.eventRenderer) { 10164 this.eventRenderer.unrender(); 10165 } 10166 else if (this['destroyEvents']) { // legacy 10167 this['destroyEvents'](); 10168 } 10169 }; 10170 DateComponent.prototype.getBusinessHourSegs = function () { 10171 var segs = this.getOwnBusinessHourSegs(); 10172 this.iterChildren(function (child) { 10173 segs.push.apply(segs, child.getBusinessHourSegs()); 10174 }); 10175 return segs; 10176 }; 10177 DateComponent.prototype.getOwnBusinessHourSegs = function () { 10178 if (this.businessHourRenderer) { 10179 return this.businessHourRenderer.getSegs(); 10180 } 10181 return []; 10182 }; 10183 DateComponent.prototype.getEventSegs = function () { 10184 var segs = this.getOwnEventSegs(); 10185 this.iterChildren(function (child) { 10186 segs.push.apply(segs, child.getEventSegs()); 10187 }); 10188 return segs; 10189 }; 10190 DateComponent.prototype.getOwnEventSegs = function () { 10191 if (this.eventRenderer) { 10192 return this.eventRenderer.getSegs(); 10193 } 10194 return []; 10195 }; 10196 // Event Rendering Triggering 10197 // ----------------------------------------------------------------------------------------------------------------- 10198 DateComponent.prototype.triggerAfterEventsRendered = function () { 10199 this.triggerAfterEventSegsRendered(this.getEventSegs()); 10200 this.publiclyTrigger('eventAfterAllRender', { 10201 context: this, 10202 args: [this] 10203 }); 10204 }; 10205 DateComponent.prototype.triggerAfterEventSegsRendered = function (segs) { 10206 var _this = this; 10207 // an optimization, because getEventLegacy is expensive 10208 if (this.hasPublicHandlers('eventAfterRender')) { 10209 segs.forEach(function (seg) { 10210 var legacy; 10211 if (seg.el) { // necessary? 10212 legacy = seg.footprint.getEventLegacy(); 10213 _this.publiclyTrigger('eventAfterRender', { 10214 context: legacy, 10215 args: [legacy, seg.el, _this] 10216 }); 10217 } 10218 }); 10219 } 10220 }; 10221 DateComponent.prototype.triggerBeforeEventsDestroyed = function () { 10222 this.triggerBeforeEventSegsDestroyed(this.getEventSegs()); 10223 }; 10224 DateComponent.prototype.triggerBeforeEventSegsDestroyed = function (segs) { 10225 var _this = this; 10226 if (this.hasPublicHandlers('eventDestroy')) { 10227 segs.forEach(function (seg) { 10228 var legacy; 10229 if (seg.el) { // necessary? 10230 legacy = seg.footprint.getEventLegacy(); 10231 _this.publiclyTrigger('eventDestroy', { 10232 context: legacy, 10233 args: [legacy, seg.el, _this] 10234 }); 10235 } 10236 }); 10237 } 10238 }; 10239 // Event Rendering Utils 10240 // ----------------------------------------------------------------------------------------------------------------- 10241 // Hides all rendered event segments linked to the given event 10242 // RECURSIVE with subcomponents 10243 DateComponent.prototype.showEventsWithId = function (eventDefId) { 10244 this.getEventSegs().forEach(function (seg) { 10245 if (seg.footprint.eventDef.id === eventDefId && 10246 seg.el // necessary? 10247 ) { 10248 seg.el.css('visibility', ''); 10249 } 10250 }); 10251 this.callChildren('showEventsWithId', arguments); 10252 }; 10253 // Shows all rendered event segments linked to the given event 10254 // RECURSIVE with subcomponents 10255 DateComponent.prototype.hideEventsWithId = function (eventDefId) { 10256 this.getEventSegs().forEach(function (seg) { 10257 if (seg.footprint.eventDef.id === eventDefId && 10258 seg.el // necessary? 10259 ) { 10260 seg.el.css('visibility', 'hidden'); 10261 } 10262 }); 10263 this.callChildren('hideEventsWithId', arguments); 10264 }; 10265 // Drag-n-Drop Rendering (for both events and external elements) 10266 // --------------------------------------------------------------------------------------------------------------- 10267 // Renders a visual indication of a event or external-element drag over the given drop zone. 10268 // If an external-element, seg will be `null`. 10269 // Must return elements used for any mock events. 10270 DateComponent.prototype.renderDrag = function (eventFootprints, seg, isTouch) { 10271 var renderedHelper = false; 10272 this.iterChildren(function (child) { 10273 if (child.renderDrag(eventFootprints, seg, isTouch)) { 10274 renderedHelper = true; 10275 } 10276 }); 10277 return renderedHelper; 10278 }; 10279 // Unrenders a visual indication of an event or external-element being dragged. 10280 DateComponent.prototype.unrenderDrag = function () { 10281 this.callChildren('unrenderDrag', arguments); 10282 }; 10283 // Event Resizing 10284 // --------------------------------------------------------------------------------------------------------------- 10285 // Renders a visual indication of an event being resized. 10286 DateComponent.prototype.renderEventResize = function (eventFootprints, seg, isTouch) { 10287 this.callChildren('renderEventResize', arguments); 10288 }; 10289 // Unrenders a visual indication of an event being resized. 10290 DateComponent.prototype.unrenderEventResize = function () { 10291 this.callChildren('unrenderEventResize', arguments); 10292 }; 10293 // Selection 10294 // --------------------------------------------------------------------------------------------------------------- 10295 // Renders a visual indication of the selection 10296 // TODO: rename to `renderSelection` after legacy is gone 10297 DateComponent.prototype.renderSelectionFootprint = function (componentFootprint) { 10298 this.renderHighlight(componentFootprint); 10299 this.callChildren('renderSelectionFootprint', arguments); 10300 }; 10301 // Unrenders a visual indication of selection 10302 DateComponent.prototype.unrenderSelection = function () { 10303 this.unrenderHighlight(); 10304 this.callChildren('unrenderSelection', arguments); 10305 }; 10306 // Highlight 10307 // --------------------------------------------------------------------------------------------------------------- 10308 // Renders an emphasis on the given date range. Given a span (unzoned start/end and other misc data) 10309 DateComponent.prototype.renderHighlight = function (componentFootprint) { 10310 if (this.fillRenderer) { 10311 this.fillRenderer.renderFootprint('highlight', componentFootprint, { 10312 getClasses: function () { 10313 return ['fc-highlight']; 10314 } 10315 }); 10316 } 10317 this.callChildren('renderHighlight', arguments); 10318 }; 10319 // Unrenders the emphasis on a date range 10320 DateComponent.prototype.unrenderHighlight = function () { 10321 if (this.fillRenderer) { 10322 this.fillRenderer.unrender('highlight'); 10323 } 10324 this.callChildren('unrenderHighlight', arguments); 10325 }; 10326 // Hit Areas 10327 // --------------------------------------------------------------------------------------------------------------- 10328 // just because all DateComponents support this interface 10329 // doesn't mean they need to have their own internal coord system. they can defer to sub-components. 10330 DateComponent.prototype.hitsNeeded = function () { 10331 if (!(this.hitsNeededDepth++)) { 10332 this.prepareHits(); 10333 } 10334 this.callChildren('hitsNeeded', arguments); 10335 }; 10336 DateComponent.prototype.hitsNotNeeded = function () { 10337 if (this.hitsNeededDepth && !(--this.hitsNeededDepth)) { 10338 this.releaseHits(); 10339 } 10340 this.callChildren('hitsNotNeeded', arguments); 10341 }; 10342 DateComponent.prototype.prepareHits = function () { 10343 // subclasses can implement 10344 }; 10345 DateComponent.prototype.releaseHits = function () { 10346 // subclasses can implement 10347 }; 10348 // Given coordinates from the topleft of the document, return data about the date-related area underneath. 10349 // Can return an object with arbitrary properties (although top/right/left/bottom are encouraged). 10350 // Must have a `grid` property, a reference to this current grid. TODO: avoid this 10351 // The returned object will be processed by getHitFootprint and getHitEl. 10352 DateComponent.prototype.queryHit = function (leftOffset, topOffset) { 10353 var childrenByUid = this.childrenByUid; 10354 var uid; 10355 var hit; 10356 for (uid in childrenByUid) { 10357 hit = childrenByUid[uid].queryHit(leftOffset, topOffset); 10358 if (hit) { 10359 break; 10360 } 10361 } 10362 return hit; 10363 }; 10364 DateComponent.prototype.getSafeHitFootprint = function (hit) { 10365 var footprint = this.getHitFootprint(hit); 10366 if (!this.dateProfile.activeUnzonedRange.containsRange(footprint.unzonedRange)) { 10367 return null; 10368 } 10369 return footprint; 10370 }; 10371 DateComponent.prototype.getHitFootprint = function (hit) { 10372 // what about being abstract!? 10373 }; 10374 // Given position-level information about a date-related area within the grid, 10375 // should return a jQuery element that best represents it. passed to dayClick callback. 10376 DateComponent.prototype.getHitEl = function (hit) { 10377 // what about being abstract!? 10378 }; 10379 /* Converting eventRange -> eventFootprint 10380 ------------------------------------------------------------------------------------------------------------------*/ 10381 DateComponent.prototype.eventRangesToEventFootprints = function (eventRanges) { 10382 var eventFootprints = []; 10383 var i; 10384 for (i = 0; i < eventRanges.length; i++) { 10385 eventFootprints.push.apply(// append 10386 eventFootprints, this.eventRangeToEventFootprints(eventRanges[i])); 10387 } 10388 return eventFootprints; 10389 }; 10390 DateComponent.prototype.eventRangeToEventFootprints = function (eventRange) { 10391 return [util_2.eventRangeToEventFootprint(eventRange)]; 10392 }; 10393 /* Converting componentFootprint/eventFootprint -> segs 10394 ------------------------------------------------------------------------------------------------------------------*/ 10395 DateComponent.prototype.eventFootprintsToSegs = function (eventFootprints) { 10396 var segs = []; 10397 var i; 10398 for (i = 0; i < eventFootprints.length; i++) { 10399 segs.push.apply(segs, this.eventFootprintToSegs(eventFootprints[i])); 10400 } 10401 return segs; 10402 }; 10403 // Given an event's span (unzoned start/end and other misc data), and the event itself, 10404 // slices into segments and attaches event-derived properties to them. 10405 // eventSpan - { start, end, isStart, isEnd, otherthings... } 10406 DateComponent.prototype.eventFootprintToSegs = function (eventFootprint) { 10407 var unzonedRange = eventFootprint.componentFootprint.unzonedRange; 10408 var segs; 10409 var i; 10410 var seg; 10411 segs = this.componentFootprintToSegs(eventFootprint.componentFootprint); 10412 for (i = 0; i < segs.length; i++) { 10413 seg = segs[i]; 10414 if (!unzonedRange.isStart) { 10415 seg.isStart = false; 10416 } 10417 if (!unzonedRange.isEnd) { 10418 seg.isEnd = false; 10419 } 10420 seg.footprint = eventFootprint; 10421 // TODO: rename to seg.eventFootprint 10422 } 10423 return segs; 10424 }; 10425 DateComponent.prototype.componentFootprintToSegs = function (componentFootprint) { 10426 return []; 10427 }; 10428 // Utils 10429 // --------------------------------------------------------------------------------------------------------------- 10430 DateComponent.prototype.callChildren = function (methodName, args) { 10431 this.iterChildren(function (child) { 10432 child[methodName].apply(child, args); 10433 }); 10434 }; 10435 DateComponent.prototype.iterChildren = function (func) { 10436 var childrenByUid = this.childrenByUid; 10437 var uid; 10438 for (uid in childrenByUid) { 10439 func(childrenByUid[uid]); 10440 } 10441 }; 10442 DateComponent.prototype._getCalendar = function () { 10443 var t = this; 10444 return t.calendar || t.view.calendar; 10445 }; 10446 DateComponent.prototype._getView = function () { 10447 return this.view; 10448 }; 10449 DateComponent.prototype._getDateProfile = function () { 10450 return this._getView().get('dateProfile'); 10451 }; 10452 // Generates HTML for an anchor to another view into the calendar. 10453 // Will either generate an <a> tag or a non-clickable <span> tag, depending on enabled settings. 10454 // `gotoOptions` can either be a moment input, or an object with the form: 10455 // { date, type, forceOff } 10456 // `type` is a view-type like "day" or "week". default value is "day". 10457 // `attrs` and `innerHtml` are use to generate the rest of the HTML tag. 10458 DateComponent.prototype.buildGotoAnchorHtml = function (gotoOptions, attrs, innerHtml) { 10459 var date; 10460 var type; 10461 var forceOff; 10462 var finalOptions; 10463 if ($.isPlainObject(gotoOptions)) { 10464 date = gotoOptions.date; 10465 type = gotoOptions.type; 10466 forceOff = gotoOptions.forceOff; 10467 } 10468 else { 10469 date = gotoOptions; // a single moment input 10470 } 10471 date = moment_ext_1.default(date); // if a string, parse it 10472 finalOptions = { 10473 date: date.format('YYYY-MM-DD'), 10474 type: type || 'day' 10475 }; 10476 if (typeof attrs === 'string') { 10477 innerHtml = attrs; 10478 attrs = null; 10479 } 10480 attrs = attrs ? ' ' + util_1.attrsToStr(attrs) : ''; // will have a leading space 10481 innerHtml = innerHtml || ''; 10482 if (!forceOff && this.opt('navLinks')) { 10483 return '<a' + attrs + 10484 ' data-goto="' + util_1.htmlEscape(JSON.stringify(finalOptions)) + '">' + 10485 innerHtml + 10486 '</a>'; 10487 } 10488 else { 10489 return '<span' + attrs + '>' + 10490 innerHtml + 10491 '</span>'; 10492 } 10493 }; 10494 DateComponent.prototype.getAllDayHtml = function () { 10495 return this.opt('allDayHtml') || util_1.htmlEscape(this.opt('allDayText')); 10496 }; 10497 // Computes HTML classNames for a single-day element 10498 DateComponent.prototype.getDayClasses = function (date, noThemeHighlight) { 10499 var view = this._getView(); 10500 var classes = []; 10501 var today; 10502 if (!this.dateProfile.activeUnzonedRange.containsDate(date)) { 10503 classes.push('fc-disabled-day'); // TODO: jQuery UI theme? 10504 } 10505 else { 10506 classes.push('fc-' + util_1.dayIDs[date.day()]); 10507 if (view.isDateInOtherMonth(date, this.dateProfile)) { // TODO: use DateComponent subclass somehow 10508 classes.push('fc-other-month'); 10509 } 10510 today = view.calendar.getNow(); 10511 if (date.isSame(today, 'day')) { 10512 classes.push('fc-today'); 10513 if (noThemeHighlight !== true) { 10514 classes.push(view.calendar.theme.getClass('today')); 10515 } 10516 } 10517 else if (date < today) { 10518 classes.push('fc-past'); 10519 } 10520 else { 10521 classes.push('fc-future'); 10522 } 10523 } 10524 return classes; 10525 }; 10526 // Utility for formatting a range. Accepts a range object, formatting string, and optional separator. 10527 // Displays all-day ranges naturally, with an inclusive end. Takes the current isRTL into account. 10528 // The timezones of the dates within `range` will be respected. 10529 DateComponent.prototype.formatRange = function (range, isAllDay, formatStr, separator) { 10530 var end = range.end; 10531 if (isAllDay) { 10532 end = end.clone().subtract(1); // convert to inclusive. last ms of previous day 10533 } 10534 return date_formatting_1.formatRange(range.start, end, formatStr, separator, this.isRTL); 10535 }; 10536 // Compute the number of the give units in the "current" range. 10537 // Will return a floating-point number. Won't round. 10538 DateComponent.prototype.currentRangeAs = function (unit) { 10539 return this._getDateProfile().currentUnzonedRange.as(unit); 10540 }; 10541 // Returns the date range of the full days the given range visually appears to occupy. 10542 // Returns a plain object with start/end, NOT an UnzonedRange! 10543 DateComponent.prototype.computeDayRange = function (unzonedRange) { 10544 var calendar = this._getCalendar(); 10545 var startDay = calendar.msToUtcMoment(unzonedRange.startMs, true); // the beginning of the day the range starts 10546 var end = calendar.msToUtcMoment(unzonedRange.endMs); 10547 var endTimeMS = +end.time(); // # of milliseconds into `endDay` 10548 var endDay = end.clone().stripTime(); // the beginning of the day the range exclusively ends 10549 // If the end time is actually inclusively part of the next day and is equal to or 10550 // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`. 10551 // Otherwise, leaving it as inclusive will cause it to exclude `endDay`. 10552 if (endTimeMS && endTimeMS >= this.nextDayThreshold) { 10553 endDay.add(1, 'days'); 10554 } 10555 // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day. 10556 if (endDay <= startDay) { 10557 endDay = startDay.clone().add(1, 'days'); 10558 } 10559 return { start: startDay, end: endDay }; 10560 }; 10561 // Does the given range visually appear to occupy more than one day? 10562 DateComponent.prototype.isMultiDayRange = function (unzonedRange) { 10563 var dayRange = this.computeDayRange(unzonedRange); 10564 return dayRange.end.diff(dayRange.start, 'days') > 1; 10565 }; 10566 DateComponent.guid = 0; // TODO: better system for this? 10567 return DateComponent; 10568}(Component_1.default)); 10569exports.default = DateComponent; 10570// legacy 10571function convertEventsPayloadToLegacyArray(eventsPayload) { 10572 var eventDefId; 10573 var eventInstances; 10574 var legacyEvents = []; 10575 var i; 10576 for (eventDefId in eventsPayload) { 10577 eventInstances = eventsPayload[eventDefId].eventInstances; 10578 for (i = 0; i < eventInstances.length; i++) { 10579 legacyEvents.push(eventInstances[i].toLegacy()); 10580 } 10581 } 10582 return legacyEvents; 10583} 10584 10585 10586/***/ }), 10587/* 232 */ 10588/***/ (function(module, exports, __webpack_require__) { 10589 10590Object.defineProperty(exports, "__esModule", { value: true }); 10591var $ = __webpack_require__(3); 10592var moment = __webpack_require__(0); 10593var util_1 = __webpack_require__(4); 10594var options_1 = __webpack_require__(33); 10595var Iterator_1 = __webpack_require__(225); 10596var GlobalEmitter_1 = __webpack_require__(23); 10597var EmitterMixin_1 = __webpack_require__(13); 10598var ListenerMixin_1 = __webpack_require__(7); 10599var Toolbar_1 = __webpack_require__(257); 10600var OptionsManager_1 = __webpack_require__(258); 10601var ViewSpecManager_1 = __webpack_require__(259); 10602var Constraints_1 = __webpack_require__(217); 10603var locale_1 = __webpack_require__(32); 10604var moment_ext_1 = __webpack_require__(11); 10605var UnzonedRange_1 = __webpack_require__(5); 10606var ComponentFootprint_1 = __webpack_require__(12); 10607var EventDateProfile_1 = __webpack_require__(16); 10608var EventManager_1 = __webpack_require__(220); 10609var BusinessHourGenerator_1 = __webpack_require__(218); 10610var EventSourceParser_1 = __webpack_require__(38); 10611var EventDefParser_1 = __webpack_require__(36); 10612var SingleEventDef_1 = __webpack_require__(9); 10613var EventDefMutation_1 = __webpack_require__(39); 10614var EventSource_1 = __webpack_require__(6); 10615var ThemeRegistry_1 = __webpack_require__(57); 10616var Calendar = /** @class */ (function () { 10617 function Calendar(el, overrides) { 10618 this.loadingLevel = 0; // number of simultaneous loading tasks 10619 this.ignoreUpdateViewSize = 0; 10620 this.freezeContentHeightDepth = 0; 10621 // declare the current calendar instance relies on GlobalEmitter. needed for garbage collection. 10622 // unneeded() is called in destroy. 10623 GlobalEmitter_1.default.needed(); 10624 this.el = el; 10625 this.viewsByType = {}; 10626 this.optionsManager = new OptionsManager_1.default(this, overrides); 10627 this.viewSpecManager = new ViewSpecManager_1.default(this.optionsManager, this); 10628 this.initMomentInternals(); // needs to happen after options hash initialized 10629 this.initCurrentDate(); 10630 this.initEventManager(); 10631 this.constraints = new Constraints_1.default(this.eventManager, this); 10632 this.constructed(); 10633 } 10634 Calendar.prototype.constructed = function () { 10635 // useful for monkeypatching. used? 10636 }; 10637 Calendar.prototype.getView = function () { 10638 return this.view; 10639 }; 10640 Calendar.prototype.publiclyTrigger = function (name, triggerInfo) { 10641 var optHandler = this.opt(name); 10642 var context; 10643 var args; 10644 if ($.isPlainObject(triggerInfo)) { 10645 context = triggerInfo.context; 10646 args = triggerInfo.args; 10647 } 10648 else if ($.isArray(triggerInfo)) { 10649 args = triggerInfo; 10650 } 10651 if (context == null) { 10652 context = this.el[0]; // fallback context 10653 } 10654 if (!args) { 10655 args = []; 10656 } 10657 this.triggerWith(name, context, args); // Emitter's method 10658 if (optHandler) { 10659 return optHandler.apply(context, args); 10660 } 10661 }; 10662 Calendar.prototype.hasPublicHandlers = function (name) { 10663 return this.hasHandlers(name) || 10664 this.opt(name); // handler specified in options 10665 }; 10666 // Options Public API 10667 // ----------------------------------------------------------------------------------------------------------------- 10668 // public getter/setter 10669 Calendar.prototype.option = function (name, value) { 10670 var newOptionHash; 10671 if (typeof name === 'string') { 10672 if (value === undefined) { // getter 10673 return this.optionsManager.get(name); 10674 } 10675 else { // setter for individual option 10676 newOptionHash = {}; 10677 newOptionHash[name] = value; 10678 this.optionsManager.add(newOptionHash); 10679 } 10680 } 10681 else if (typeof name === 'object') { // compound setter with object input 10682 this.optionsManager.add(name); 10683 } 10684 }; 10685 // private getter 10686 Calendar.prototype.opt = function (name) { 10687 return this.optionsManager.get(name); 10688 }; 10689 // View 10690 // ----------------------------------------------------------------------------------------------------------------- 10691 // Given a view name for a custom view or a standard view, creates a ready-to-go View object 10692 Calendar.prototype.instantiateView = function (viewType) { 10693 var spec = this.viewSpecManager.getViewSpec(viewType); 10694 if (!spec) { 10695 throw new Error("View type \"" + viewType + "\" is not valid"); 10696 } 10697 return new spec['class'](this, spec); 10698 }; 10699 // Returns a boolean about whether the view is okay to instantiate at some point 10700 Calendar.prototype.isValidViewType = function (viewType) { 10701 return Boolean(this.viewSpecManager.getViewSpec(viewType)); 10702 }; 10703 Calendar.prototype.changeView = function (viewName, dateOrRange) { 10704 if (dateOrRange) { 10705 if (dateOrRange.start && dateOrRange.end) { // a range 10706 this.optionsManager.recordOverrides({ 10707 visibleRange: dateOrRange 10708 }); 10709 } 10710 else { // a date 10711 this.currentDate = this.moment(dateOrRange).stripZone(); // just like gotoDate 10712 } 10713 } 10714 this.renderView(viewName); 10715 }; 10716 // Forces navigation to a view for the given date. 10717 // `viewType` can be a specific view name or a generic one like "week" or "day". 10718 Calendar.prototype.zoomTo = function (newDate, viewType) { 10719 var spec; 10720 viewType = viewType || 'day'; // day is default zoom 10721 spec = this.viewSpecManager.getViewSpec(viewType) || 10722 this.viewSpecManager.getUnitViewSpec(viewType); 10723 this.currentDate = newDate.clone(); 10724 this.renderView(spec ? spec.type : null); 10725 }; 10726 // Current Date 10727 // ----------------------------------------------------------------------------------------------------------------- 10728 Calendar.prototype.initCurrentDate = function () { 10729 var defaultDateInput = this.opt('defaultDate'); 10730 // compute the initial ambig-timezone date 10731 if (defaultDateInput != null) { 10732 this.currentDate = this.moment(defaultDateInput).stripZone(); 10733 } 10734 else { 10735 this.currentDate = this.getNow(); // getNow already returns unzoned 10736 } 10737 }; 10738 Calendar.prototype.prev = function () { 10739 var view = this.view; 10740 var prevInfo = view.dateProfileGenerator.buildPrev(view.get('dateProfile')); 10741 if (prevInfo.isValid) { 10742 this.currentDate = prevInfo.date; 10743 this.renderView(); 10744 } 10745 }; 10746 Calendar.prototype.next = function () { 10747 var view = this.view; 10748 var nextInfo = view.dateProfileGenerator.buildNext(view.get('dateProfile')); 10749 if (nextInfo.isValid) { 10750 this.currentDate = nextInfo.date; 10751 this.renderView(); 10752 } 10753 }; 10754 Calendar.prototype.prevYear = function () { 10755 this.currentDate.add(-1, 'years'); 10756 this.renderView(); 10757 }; 10758 Calendar.prototype.nextYear = function () { 10759 this.currentDate.add(1, 'years'); 10760 this.renderView(); 10761 }; 10762 Calendar.prototype.today = function () { 10763 this.currentDate = this.getNow(); // should deny like prev/next? 10764 this.renderView(); 10765 }; 10766 Calendar.prototype.gotoDate = function (zonedDateInput) { 10767 this.currentDate = this.moment(zonedDateInput).stripZone(); 10768 this.renderView(); 10769 }; 10770 Calendar.prototype.incrementDate = function (delta) { 10771 this.currentDate.add(moment.duration(delta)); 10772 this.renderView(); 10773 }; 10774 // for external API 10775 Calendar.prototype.getDate = function () { 10776 return this.applyTimezone(this.currentDate); // infuse the calendar's timezone 10777 }; 10778 // Loading Triggering 10779 // ----------------------------------------------------------------------------------------------------------------- 10780 // Should be called when any type of async data fetching begins 10781 Calendar.prototype.pushLoading = function () { 10782 if (!(this.loadingLevel++)) { 10783 this.publiclyTrigger('loading', [true, this.view]); 10784 } 10785 }; 10786 // Should be called when any type of async data fetching completes 10787 Calendar.prototype.popLoading = function () { 10788 if (!(--this.loadingLevel)) { 10789 this.publiclyTrigger('loading', [false, this.view]); 10790 } 10791 }; 10792 // High-level Rendering 10793 // ----------------------------------------------------------------------------------- 10794 Calendar.prototype.render = function () { 10795 if (!this.contentEl) { 10796 this.initialRender(); 10797 } 10798 else if (this.elementVisible()) { 10799 // mainly for the public API 10800 this.calcSize(); 10801 this.updateViewSize(); 10802 } 10803 }; 10804 Calendar.prototype.initialRender = function () { 10805 var _this = this; 10806 var el = this.el; 10807 el.addClass('fc'); 10808 // event delegation for nav links 10809 el.on('click.fc', 'a[data-goto]', function (ev) { 10810 var anchorEl = $(ev.currentTarget); 10811 var gotoOptions = anchorEl.data('goto'); // will automatically parse JSON 10812 var date = _this.moment(gotoOptions.date); 10813 var viewType = gotoOptions.type; 10814 // property like "navLinkDayClick". might be a string or a function 10815 var customAction = _this.view.opt('navLink' + util_1.capitaliseFirstLetter(viewType) + 'Click'); 10816 if (typeof customAction === 'function') { 10817 customAction(date, ev); 10818 } 10819 else { 10820 if (typeof customAction === 'string') { 10821 viewType = customAction; 10822 } 10823 _this.zoomTo(date, viewType); 10824 } 10825 }); 10826 // called immediately, and upon option change 10827 this.optionsManager.watch('settingTheme', ['?theme', '?themeSystem'], function (opts) { 10828 var themeClass = ThemeRegistry_1.getThemeSystemClass(opts.themeSystem || opts.theme); 10829 var theme = new themeClass(_this.optionsManager); 10830 var widgetClass = theme.getClass('widget'); 10831 _this.theme = theme; 10832 if (widgetClass) { 10833 el.addClass(widgetClass); 10834 } 10835 }, function () { 10836 var widgetClass = _this.theme.getClass('widget'); 10837 _this.theme = null; 10838 if (widgetClass) { 10839 el.removeClass(widgetClass); 10840 } 10841 }); 10842 this.optionsManager.watch('settingBusinessHourGenerator', ['?businessHours'], function (deps) { 10843 _this.businessHourGenerator = new BusinessHourGenerator_1.default(deps.businessHours, _this); 10844 if (_this.view) { 10845 _this.view.set('businessHourGenerator', _this.businessHourGenerator); 10846 } 10847 }, function () { 10848 _this.businessHourGenerator = null; 10849 }); 10850 // called immediately, and upon option change. 10851 // HACK: locale often affects isRTL, so we explicitly listen to that too. 10852 this.optionsManager.watch('applyingDirClasses', ['?isRTL', '?locale'], function (opts) { 10853 el.toggleClass('fc-ltr', !opts.isRTL); 10854 el.toggleClass('fc-rtl', opts.isRTL); 10855 }); 10856 this.contentEl = $("<div class='fc-view-container'>").prependTo(el); 10857 this.initToolbars(); 10858 this.renderHeader(); 10859 this.renderFooter(); 10860 this.renderView(this.opt('defaultView')); 10861 if (this.opt('handleWindowResize')) { 10862 $(window).resize(this.windowResizeProxy = util_1.debounce(// prevents rapid calls 10863 this.windowResize.bind(this), this.opt('windowResizeDelay'))); 10864 } 10865 }; 10866 Calendar.prototype.destroy = function () { 10867 if (this.view) { 10868 this.clearView(); 10869 } 10870 this.toolbarsManager.proxyCall('removeElement'); 10871 this.contentEl.remove(); 10872 this.el.removeClass('fc fc-ltr fc-rtl'); 10873 // removes theme-related root className 10874 this.optionsManager.unwatch('settingTheme'); 10875 this.optionsManager.unwatch('settingBusinessHourGenerator'); 10876 this.el.off('.fc'); // unbind nav link handlers 10877 if (this.windowResizeProxy) { 10878 $(window).unbind('resize', this.windowResizeProxy); 10879 this.windowResizeProxy = null; 10880 } 10881 GlobalEmitter_1.default.unneeded(); 10882 }; 10883 Calendar.prototype.elementVisible = function () { 10884 return this.el.is(':visible'); 10885 }; 10886 // Render Queue 10887 // ----------------------------------------------------------------------------------------------------------------- 10888 Calendar.prototype.bindViewHandlers = function (view) { 10889 var _this = this; 10890 view.watch('titleForCalendar', ['title'], function (deps) { 10891 if (view === _this.view) { // hack 10892 _this.setToolbarsTitle(deps.title); 10893 } 10894 }); 10895 view.watch('dateProfileForCalendar', ['dateProfile'], function (deps) { 10896 if (view === _this.view) { // hack 10897 _this.currentDate = deps.dateProfile.date; // might have been constrained by view dates 10898 _this.updateToolbarButtons(deps.dateProfile); 10899 } 10900 }); 10901 }; 10902 Calendar.prototype.unbindViewHandlers = function (view) { 10903 view.unwatch('titleForCalendar'); 10904 view.unwatch('dateProfileForCalendar'); 10905 }; 10906 // View Rendering 10907 // ----------------------------------------------------------------------------------- 10908 // Renders a view because of a date change, view-type change, or for the first time. 10909 // If not given a viewType, keep the current view but render different dates. 10910 // Accepts an optional scroll state to restore to. 10911 Calendar.prototype.renderView = function (viewType) { 10912 var oldView = this.view; 10913 var newView; 10914 this.freezeContentHeight(); 10915 if (oldView && viewType && oldView.type !== viewType) { 10916 this.clearView(); 10917 } 10918 // if viewType changed, or the view was never created, create a fresh view 10919 if (!this.view && viewType) { 10920 newView = this.view = 10921 this.viewsByType[viewType] || 10922 (this.viewsByType[viewType] = this.instantiateView(viewType)); 10923 this.bindViewHandlers(newView); 10924 newView.startBatchRender(); // so that setElement+setDate rendering are joined 10925 newView.setElement($("<div class='fc-view fc-" + viewType + "-view'>").appendTo(this.contentEl)); 10926 this.toolbarsManager.proxyCall('activateButton', viewType); 10927 } 10928 if (this.view) { 10929 // prevent unnecessary change firing 10930 if (this.view.get('businessHourGenerator') !== this.businessHourGenerator) { 10931 this.view.set('businessHourGenerator', this.businessHourGenerator); 10932 } 10933 this.view.setDate(this.currentDate); 10934 if (newView) { 10935 newView.stopBatchRender(); 10936 } 10937 } 10938 this.thawContentHeight(); 10939 }; 10940 // Unrenders the current view and reflects this change in the Header. 10941 // Unregsiters the `view`, but does not remove from viewByType hash. 10942 Calendar.prototype.clearView = function () { 10943 var currentView = this.view; 10944 this.toolbarsManager.proxyCall('deactivateButton', currentView.type); 10945 this.unbindViewHandlers(currentView); 10946 currentView.removeElement(); 10947 currentView.unsetDate(); // so bindViewHandlers doesn't fire with old values next time 10948 this.view = null; 10949 }; 10950 // Destroys the view, including the view object. Then, re-instantiates it and renders it. 10951 // Maintains the same scroll state. 10952 // TODO: maintain any other user-manipulated state. 10953 Calendar.prototype.reinitView = function () { 10954 var oldView = this.view; 10955 var scroll = oldView.queryScroll(); // wouldn't be so complicated if Calendar owned the scroll 10956 this.freezeContentHeight(); 10957 this.clearView(); 10958 this.calcSize(); 10959 this.renderView(oldView.type); // needs the type to freshly render 10960 this.view.applyScroll(scroll); 10961 this.thawContentHeight(); 10962 }; 10963 // Resizing 10964 // ----------------------------------------------------------------------------------- 10965 Calendar.prototype.getSuggestedViewHeight = function () { 10966 if (this.suggestedViewHeight == null) { 10967 this.calcSize(); 10968 } 10969 return this.suggestedViewHeight; 10970 }; 10971 Calendar.prototype.isHeightAuto = function () { 10972 return this.opt('contentHeight') === 'auto' || this.opt('height') === 'auto'; 10973 }; 10974 Calendar.prototype.updateViewSize = function (isResize) { 10975 if (isResize === void 0) { isResize = false; } 10976 var view = this.view; 10977 var scroll; 10978 if (!this.ignoreUpdateViewSize && view) { 10979 if (isResize) { 10980 this.calcSize(); 10981 scroll = view.queryScroll(); 10982 } 10983 this.ignoreUpdateViewSize++; 10984 view.updateSize(this.getSuggestedViewHeight(), this.isHeightAuto(), isResize); 10985 this.ignoreUpdateViewSize--; 10986 if (isResize) { 10987 view.applyScroll(scroll); 10988 } 10989 return true; // signal success 10990 } 10991 }; 10992 Calendar.prototype.calcSize = function () { 10993 if (this.elementVisible()) { 10994 this._calcSize(); 10995 } 10996 }; 10997 Calendar.prototype._calcSize = function () { 10998 var contentHeightInput = this.opt('contentHeight'); 10999 var heightInput = this.opt('height'); 11000 if (typeof contentHeightInput === 'number') { // exists and not 'auto' 11001 this.suggestedViewHeight = contentHeightInput; 11002 } 11003 else if (typeof contentHeightInput === 'function') { // exists and is a function 11004 this.suggestedViewHeight = contentHeightInput(); 11005 } 11006 else if (typeof heightInput === 'number') { // exists and not 'auto' 11007 this.suggestedViewHeight = heightInput - this.queryToolbarsHeight(); 11008 } 11009 else if (typeof heightInput === 'function') { // exists and is a function 11010 this.suggestedViewHeight = heightInput() - this.queryToolbarsHeight(); 11011 } 11012 else if (heightInput === 'parent') { // set to height of parent element 11013 this.suggestedViewHeight = this.el.parent().height() - this.queryToolbarsHeight(); 11014 } 11015 else { 11016 this.suggestedViewHeight = Math.round(this.contentEl.width() / 11017 Math.max(this.opt('aspectRatio'), .5)); 11018 } 11019 }; 11020 Calendar.prototype.windowResize = function (ev) { 11021 if ( 11022 // the purpose: so we don't process jqui "resize" events that have bubbled up 11023 // cast to any because .target, which is Element, can't be compared to window for some reason. 11024 ev.target === window && 11025 this.view && 11026 this.view.isDatesRendered) { 11027 if (this.updateViewSize(true)) { // isResize=true, returns true on success 11028 this.publiclyTrigger('windowResize', [this.view]); 11029 } 11030 } 11031 }; 11032 /* Height "Freezing" 11033 -----------------------------------------------------------------------------*/ 11034 Calendar.prototype.freezeContentHeight = function () { 11035 if (!(this.freezeContentHeightDepth++)) { 11036 this.forceFreezeContentHeight(); 11037 } 11038 }; 11039 Calendar.prototype.forceFreezeContentHeight = function () { 11040 this.contentEl.css({ 11041 width: '100%', 11042 height: this.contentEl.height(), 11043 overflow: 'hidden' 11044 }); 11045 }; 11046 Calendar.prototype.thawContentHeight = function () { 11047 this.freezeContentHeightDepth--; 11048 // always bring back to natural height 11049 this.contentEl.css({ 11050 width: '', 11051 height: '', 11052 overflow: '' 11053 }); 11054 // but if there are future thaws, re-freeze 11055 if (this.freezeContentHeightDepth) { 11056 this.forceFreezeContentHeight(); 11057 } 11058 }; 11059 // Toolbar 11060 // ----------------------------------------------------------------------------------------------------------------- 11061 Calendar.prototype.initToolbars = function () { 11062 this.header = new Toolbar_1.default(this, this.computeHeaderOptions()); 11063 this.footer = new Toolbar_1.default(this, this.computeFooterOptions()); 11064 this.toolbarsManager = new Iterator_1.default([this.header, this.footer]); 11065 }; 11066 Calendar.prototype.computeHeaderOptions = function () { 11067 return { 11068 extraClasses: 'fc-header-toolbar', 11069 layout: this.opt('header') 11070 }; 11071 }; 11072 Calendar.prototype.computeFooterOptions = function () { 11073 return { 11074 extraClasses: 'fc-footer-toolbar', 11075 layout: this.opt('footer') 11076 }; 11077 }; 11078 // can be called repeatedly and Header will rerender 11079 Calendar.prototype.renderHeader = function () { 11080 var header = this.header; 11081 header.setToolbarOptions(this.computeHeaderOptions()); 11082 header.render(); 11083 if (header.el) { 11084 this.el.prepend(header.el); 11085 } 11086 }; 11087 // can be called repeatedly and Footer will rerender 11088 Calendar.prototype.renderFooter = function () { 11089 var footer = this.footer; 11090 footer.setToolbarOptions(this.computeFooterOptions()); 11091 footer.render(); 11092 if (footer.el) { 11093 this.el.append(footer.el); 11094 } 11095 }; 11096 Calendar.prototype.setToolbarsTitle = function (title) { 11097 this.toolbarsManager.proxyCall('updateTitle', title); 11098 }; 11099 Calendar.prototype.updateToolbarButtons = function (dateProfile) { 11100 var now = this.getNow(); 11101 var view = this.view; 11102 var todayInfo = view.dateProfileGenerator.build(now); 11103 var prevInfo = view.dateProfileGenerator.buildPrev(view.get('dateProfile')); 11104 var nextInfo = view.dateProfileGenerator.buildNext(view.get('dateProfile')); 11105 this.toolbarsManager.proxyCall((todayInfo.isValid && !dateProfile.currentUnzonedRange.containsDate(now)) ? 11106 'enableButton' : 11107 'disableButton', 'today'); 11108 this.toolbarsManager.proxyCall(prevInfo.isValid ? 11109 'enableButton' : 11110 'disableButton', 'prev'); 11111 this.toolbarsManager.proxyCall(nextInfo.isValid ? 11112 'enableButton' : 11113 'disableButton', 'next'); 11114 }; 11115 Calendar.prototype.queryToolbarsHeight = function () { 11116 return this.toolbarsManager.items.reduce(function (accumulator, toolbar) { 11117 var toolbarHeight = toolbar.el ? toolbar.el.outerHeight(true) : 0; // includes margin 11118 return accumulator + toolbarHeight; 11119 }, 0); 11120 }; 11121 // Selection 11122 // ----------------------------------------------------------------------------------------------------------------- 11123 // this public method receives start/end dates in any format, with any timezone 11124 Calendar.prototype.select = function (zonedStartInput, zonedEndInput) { 11125 this.view.select(this.buildSelectFootprint.apply(this, arguments)); 11126 }; 11127 Calendar.prototype.unselect = function () { 11128 if (this.view) { 11129 this.view.unselect(); 11130 } 11131 }; 11132 // Given arguments to the select method in the API, returns a span (unzoned start/end and other info) 11133 Calendar.prototype.buildSelectFootprint = function (zonedStartInput, zonedEndInput) { 11134 var start = this.moment(zonedStartInput).stripZone(); 11135 var end; 11136 if (zonedEndInput) { 11137 end = this.moment(zonedEndInput).stripZone(); 11138 } 11139 else if (start.hasTime()) { 11140 end = start.clone().add(this.defaultTimedEventDuration); 11141 } 11142 else { 11143 end = start.clone().add(this.defaultAllDayEventDuration); 11144 } 11145 return new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), !start.hasTime()); 11146 }; 11147 // Date Utils 11148 // ----------------------------------------------------------------------------------------------------------------- 11149 Calendar.prototype.initMomentInternals = function () { 11150 var _this = this; 11151 this.defaultAllDayEventDuration = moment.duration(this.opt('defaultAllDayEventDuration')); 11152 this.defaultTimedEventDuration = moment.duration(this.opt('defaultTimedEventDuration')); 11153 // Called immediately, and when any of the options change. 11154 // Happens before any internal objects rebuild or rerender, because this is very core. 11155 this.optionsManager.watch('buildingMomentLocale', [ 11156 '?locale', '?monthNames', '?monthNamesShort', '?dayNames', '?dayNamesShort', 11157 '?firstDay', '?weekNumberCalculation' 11158 ], function (opts) { 11159 var weekNumberCalculation = opts.weekNumberCalculation; 11160 var firstDay = opts.firstDay; 11161 var _week; 11162 // normalize 11163 if (weekNumberCalculation === 'iso') { 11164 weekNumberCalculation = 'ISO'; // normalize 11165 } 11166 var localeData = Object.create(// make a cheap copy 11167 locale_1.getMomentLocaleData(opts.locale) // will fall back to en 11168 ); 11169 if (opts.monthNames) { 11170 localeData._months = opts.monthNames; 11171 } 11172 if (opts.monthNamesShort) { 11173 localeData._monthsShort = opts.monthNamesShort; 11174 } 11175 if (opts.dayNames) { 11176 localeData._weekdays = opts.dayNames; 11177 } 11178 if (opts.dayNamesShort) { 11179 localeData._weekdaysShort = opts.dayNamesShort; 11180 } 11181 if (firstDay == null && weekNumberCalculation === 'ISO') { 11182 firstDay = 1; 11183 } 11184 if (firstDay != null) { 11185 _week = Object.create(localeData._week); // _week: { dow: # } 11186 _week.dow = firstDay; 11187 localeData._week = _week; 11188 } 11189 if ( // whitelist certain kinds of input 11190 weekNumberCalculation === 'ISO' || 11191 weekNumberCalculation === 'local' || 11192 typeof weekNumberCalculation === 'function') { 11193 localeData._fullCalendar_weekCalc = weekNumberCalculation; // moment-ext will know what to do with it 11194 } 11195 _this.localeData = localeData; 11196 // If the internal current date object already exists, move to new locale. 11197 // We do NOT need to do this technique for event dates, because this happens when converting to "segments". 11198 if (_this.currentDate) { 11199 _this.localizeMoment(_this.currentDate); // sets to localeData 11200 } 11201 }); 11202 }; 11203 // Builds a moment using the settings of the current calendar: timezone and locale. 11204 // Accepts anything the vanilla moment() constructor accepts. 11205 Calendar.prototype.moment = function () { 11206 var args = []; 11207 for (var _i = 0; _i < arguments.length; _i++) { 11208 args[_i] = arguments[_i]; 11209 } 11210 var mom; 11211 if (this.opt('timezone') === 'local') { 11212 mom = moment_ext_1.default.apply(null, args); 11213 // Force the moment to be local, because momentExt doesn't guarantee it. 11214 if (mom.hasTime()) { // don't give ambiguously-timed moments a local zone 11215 mom.local(); 11216 } 11217 } 11218 else if (this.opt('timezone') === 'UTC') { 11219 mom = moment_ext_1.default.utc.apply(null, args); // process as UTC 11220 } 11221 else { 11222 mom = moment_ext_1.default.parseZone.apply(null, args); // let the input decide the zone 11223 } 11224 this.localizeMoment(mom); // TODO 11225 return mom; 11226 }; 11227 Calendar.prototype.msToMoment = function (ms, forceAllDay) { 11228 var mom = moment_ext_1.default.utc(ms); // TODO: optimize by using Date.UTC 11229 if (forceAllDay) { 11230 mom.stripTime(); 11231 } 11232 else { 11233 mom = this.applyTimezone(mom); // may or may not apply locale 11234 } 11235 this.localizeMoment(mom); 11236 return mom; 11237 }; 11238 Calendar.prototype.msToUtcMoment = function (ms, forceAllDay) { 11239 var mom = moment_ext_1.default.utc(ms); // TODO: optimize by using Date.UTC 11240 if (forceAllDay) { 11241 mom.stripTime(); 11242 } 11243 this.localizeMoment(mom); 11244 return mom; 11245 }; 11246 // Updates the given moment's locale settings to the current calendar locale settings. 11247 Calendar.prototype.localizeMoment = function (mom) { 11248 mom._locale = this.localeData; 11249 }; 11250 // Returns a boolean about whether or not the calendar knows how to calculate 11251 // the timezone offset of arbitrary dates in the current timezone. 11252 Calendar.prototype.getIsAmbigTimezone = function () { 11253 return this.opt('timezone') !== 'local' && this.opt('timezone') !== 'UTC'; 11254 }; 11255 // Returns a copy of the given date in the current timezone. Has no effect on dates without times. 11256 Calendar.prototype.applyTimezone = function (date) { 11257 if (!date.hasTime()) { 11258 return date.clone(); 11259 } 11260 var zonedDate = this.moment(date.toArray()); 11261 var timeAdjust = date.time().asMilliseconds() - zonedDate.time().asMilliseconds(); 11262 var adjustedZonedDate; 11263 // Safari sometimes has problems with this coersion when near DST. Adjust if necessary. (bug #2396) 11264 if (timeAdjust) { // is the time result different than expected? 11265 adjustedZonedDate = zonedDate.clone().add(timeAdjust); // add milliseconds 11266 if (date.time().asMilliseconds() - adjustedZonedDate.time().asMilliseconds() === 0) { // does it match perfectly now? 11267 zonedDate = adjustedZonedDate; 11268 } 11269 } 11270 return zonedDate; 11271 }; 11272 /* 11273 Assumes the footprint is non-open-ended. 11274 */ 11275 Calendar.prototype.footprintToDateProfile = function (componentFootprint, ignoreEnd) { 11276 if (ignoreEnd === void 0) { ignoreEnd = false; } 11277 var start = moment_ext_1.default.utc(componentFootprint.unzonedRange.startMs); 11278 var end; 11279 if (!ignoreEnd) { 11280 end = moment_ext_1.default.utc(componentFootprint.unzonedRange.endMs); 11281 } 11282 if (componentFootprint.isAllDay) { 11283 start.stripTime(); 11284 if (end) { 11285 end.stripTime(); 11286 } 11287 } 11288 else { 11289 start = this.applyTimezone(start); 11290 if (end) { 11291 end = this.applyTimezone(end); 11292 } 11293 } 11294 this.localizeMoment(start); 11295 if (end) { 11296 this.localizeMoment(end); 11297 } 11298 return new EventDateProfile_1.default(start, end, this); 11299 }; 11300 // Returns a moment for the current date, as defined by the client's computer or from the `now` option. 11301 // Will return an moment with an ambiguous timezone. 11302 Calendar.prototype.getNow = function () { 11303 var now = this.opt('now'); 11304 if (typeof now === 'function') { 11305 now = now(); 11306 } 11307 return this.moment(now).stripZone(); 11308 }; 11309 // Produces a human-readable string for the given duration. 11310 // Side-effect: changes the locale of the given duration. 11311 Calendar.prototype.humanizeDuration = function (duration) { 11312 return duration.locale(this.opt('locale')).humanize(); 11313 }; 11314 // will return `null` if invalid range 11315 Calendar.prototype.parseUnzonedRange = function (rangeInput) { 11316 var start = null; 11317 var end = null; 11318 if (rangeInput.start) { 11319 start = this.moment(rangeInput.start).stripZone(); 11320 } 11321 if (rangeInput.end) { 11322 end = this.moment(rangeInput.end).stripZone(); 11323 } 11324 if (!start && !end) { 11325 return null; 11326 } 11327 if (start && end && end.isBefore(start)) { 11328 return null; 11329 } 11330 return new UnzonedRange_1.default(start, end); 11331 }; 11332 // Event-Date Utilities 11333 // ----------------------------------------------------------------------------------------------------------------- 11334 Calendar.prototype.initEventManager = function () { 11335 var _this = this; 11336 var eventManager = new EventManager_1.default(this); 11337 var rawSources = this.opt('eventSources') || []; 11338 var singleRawSource = this.opt('events'); 11339 this.eventManager = eventManager; 11340 if (singleRawSource) { 11341 rawSources.unshift(singleRawSource); 11342 } 11343 eventManager.on('release', function (eventsPayload) { 11344 _this.trigger('eventsReset', eventsPayload); 11345 }); 11346 eventManager.freeze(); 11347 rawSources.forEach(function (rawSource) { 11348 var source = EventSourceParser_1.default.parse(rawSource, _this); 11349 if (source) { 11350 eventManager.addSource(source); 11351 } 11352 }); 11353 eventManager.thaw(); 11354 }; 11355 Calendar.prototype.requestEvents = function (start, end) { 11356 return this.eventManager.requestEvents(start, end, this.opt('timezone'), !this.opt('lazyFetching')); 11357 }; 11358 // Get an event's normalized end date. If not present, calculate it from the defaults. 11359 Calendar.prototype.getEventEnd = function (event) { 11360 if (event.end) { 11361 return event.end.clone(); 11362 } 11363 else { 11364 return this.getDefaultEventEnd(event.allDay, event.start); 11365 } 11366 }; 11367 // Given an event's allDay status and start date, return what its fallback end date should be. 11368 // TODO: rename to computeDefaultEventEnd 11369 Calendar.prototype.getDefaultEventEnd = function (allDay, zonedStart) { 11370 var end = zonedStart.clone(); 11371 if (allDay) { 11372 end.stripTime().add(this.defaultAllDayEventDuration); 11373 } 11374 else { 11375 end.add(this.defaultTimedEventDuration); 11376 } 11377 if (this.getIsAmbigTimezone()) { 11378 end.stripZone(); // we don't know what the tzo should be 11379 } 11380 return end; 11381 }; 11382 // Public Events API 11383 // ----------------------------------------------------------------------------------------------------------------- 11384 Calendar.prototype.rerenderEvents = function () { 11385 this.view.flash('displayingEvents'); 11386 }; 11387 Calendar.prototype.refetchEvents = function () { 11388 this.eventManager.refetchAllSources(); 11389 }; 11390 Calendar.prototype.renderEvents = function (eventInputs, isSticky) { 11391 this.eventManager.freeze(); 11392 for (var i = 0; i < eventInputs.length; i++) { 11393 this.renderEvent(eventInputs[i], isSticky); 11394 } 11395 this.eventManager.thaw(); 11396 }; 11397 Calendar.prototype.renderEvent = function (eventInput, isSticky) { 11398 if (isSticky === void 0) { isSticky = false; } 11399 var eventManager = this.eventManager; 11400 var eventDef = EventDefParser_1.default.parse(eventInput, eventInput.source || eventManager.stickySource); 11401 if (eventDef) { 11402 eventManager.addEventDef(eventDef, isSticky); 11403 } 11404 }; 11405 // legacyQuery operates on legacy event instance objects 11406 Calendar.prototype.removeEvents = function (legacyQuery) { 11407 var eventManager = this.eventManager; 11408 var legacyInstances = []; 11409 var idMap = {}; 11410 var eventDef; 11411 var i; 11412 if (legacyQuery == null) { // shortcut for removing all 11413 eventManager.removeAllEventDefs(); // persist=true 11414 } 11415 else { 11416 eventManager.getEventInstances().forEach(function (eventInstance) { 11417 legacyInstances.push(eventInstance.toLegacy()); 11418 }); 11419 legacyInstances = filterLegacyEventInstances(legacyInstances, legacyQuery); 11420 // compute unique IDs 11421 for (i = 0; i < legacyInstances.length; i++) { 11422 eventDef = this.eventManager.getEventDefByUid(legacyInstances[i]._id); 11423 idMap[eventDef.id] = true; 11424 } 11425 eventManager.freeze(); 11426 for (i in idMap) { // reuse `i` as an "id" 11427 eventManager.removeEventDefsById(i); // persist=true 11428 } 11429 eventManager.thaw(); 11430 } 11431 }; 11432 // legacyQuery operates on legacy event instance objects 11433 Calendar.prototype.clientEvents = function (legacyQuery) { 11434 var legacyEventInstances = []; 11435 this.eventManager.getEventInstances().forEach(function (eventInstance) { 11436 legacyEventInstances.push(eventInstance.toLegacy()); 11437 }); 11438 return filterLegacyEventInstances(legacyEventInstances, legacyQuery); 11439 }; 11440 Calendar.prototype.updateEvents = function (eventPropsArray) { 11441 this.eventManager.freeze(); 11442 for (var i = 0; i < eventPropsArray.length; i++) { 11443 this.updateEvent(eventPropsArray[i]); 11444 } 11445 this.eventManager.thaw(); 11446 }; 11447 Calendar.prototype.updateEvent = function (eventProps) { 11448 var eventDef = this.eventManager.getEventDefByUid(eventProps._id); 11449 var eventInstance; 11450 var eventDefMutation; 11451 if (eventDef instanceof SingleEventDef_1.default) { 11452 eventInstance = eventDef.buildInstance(); 11453 eventDefMutation = EventDefMutation_1.default.createFromRawProps(eventInstance, eventProps, // raw props 11454 null // largeUnit -- who uses it? 11455 ); 11456 this.eventManager.mutateEventsWithId(eventDef.id, eventDefMutation); // will release 11457 } 11458 }; 11459 // Public Event Sources API 11460 // ------------------------------------------------------------------------------------ 11461 Calendar.prototype.getEventSources = function () { 11462 return this.eventManager.otherSources.slice(); // clone 11463 }; 11464 Calendar.prototype.getEventSourceById = function (id) { 11465 return this.eventManager.getSourceById(EventSource_1.default.normalizeId(id)); 11466 }; 11467 Calendar.prototype.addEventSource = function (sourceInput) { 11468 var source = EventSourceParser_1.default.parse(sourceInput, this); 11469 if (source) { 11470 this.eventManager.addSource(source); 11471 } 11472 }; 11473 Calendar.prototype.removeEventSources = function (sourceMultiQuery) { 11474 var eventManager = this.eventManager; 11475 var sources; 11476 var i; 11477 if (sourceMultiQuery == null) { 11478 this.eventManager.removeAllSources(); 11479 } 11480 else { 11481 sources = eventManager.multiQuerySources(sourceMultiQuery); 11482 eventManager.freeze(); 11483 for (i = 0; i < sources.length; i++) { 11484 eventManager.removeSource(sources[i]); 11485 } 11486 eventManager.thaw(); 11487 } 11488 }; 11489 Calendar.prototype.removeEventSource = function (sourceQuery) { 11490 var eventManager = this.eventManager; 11491 var sources = eventManager.querySources(sourceQuery); 11492 var i; 11493 eventManager.freeze(); 11494 for (i = 0; i < sources.length; i++) { 11495 eventManager.removeSource(sources[i]); 11496 } 11497 eventManager.thaw(); 11498 }; 11499 Calendar.prototype.refetchEventSources = function (sourceMultiQuery) { 11500 var eventManager = this.eventManager; 11501 var sources = eventManager.multiQuerySources(sourceMultiQuery); 11502 var i; 11503 eventManager.freeze(); 11504 for (i = 0; i < sources.length; i++) { 11505 eventManager.refetchSource(sources[i]); 11506 } 11507 eventManager.thaw(); 11508 }; 11509 // not for internal use. use options module directly instead. 11510 Calendar.defaults = options_1.globalDefaults; 11511 Calendar.englishDefaults = options_1.englishDefaults; 11512 Calendar.rtlDefaults = options_1.rtlDefaults; 11513 return Calendar; 11514}()); 11515exports.default = Calendar; 11516EmitterMixin_1.default.mixInto(Calendar); 11517ListenerMixin_1.default.mixInto(Calendar); 11518function filterLegacyEventInstances(legacyEventInstances, legacyQuery) { 11519 if (legacyQuery == null) { 11520 return legacyEventInstances; 11521 } 11522 else if ($.isFunction(legacyQuery)) { 11523 return legacyEventInstances.filter(legacyQuery); 11524 } 11525 else { // an event ID 11526 legacyQuery += ''; // normalize to string 11527 return legacyEventInstances.filter(function (legacyEventInstance) { 11528 // soft comparison because id not be normalized to string 11529 // tslint:disable-next-line 11530 return legacyEventInstance.id == legacyQuery || 11531 legacyEventInstance._id === legacyQuery; // can specify internal id, but must exactly match 11532 }); 11533 } 11534} 11535 11536 11537/***/ }), 11538/* 233 */ 11539/***/ (function(module, exports, __webpack_require__) { 11540 11541Object.defineProperty(exports, "__esModule", { value: true }); 11542var tslib_1 = __webpack_require__(2); 11543var $ = __webpack_require__(3); 11544var moment = __webpack_require__(0); 11545var exportHooks = __webpack_require__(18); 11546var util_1 = __webpack_require__(4); 11547var moment_ext_1 = __webpack_require__(11); 11548var ListenerMixin_1 = __webpack_require__(7); 11549var HitDragListener_1 = __webpack_require__(17); 11550var SingleEventDef_1 = __webpack_require__(9); 11551var EventInstanceGroup_1 = __webpack_require__(20); 11552var EventSource_1 = __webpack_require__(6); 11553var Interaction_1 = __webpack_require__(14); 11554var ExternalDropping = /** @class */ (function (_super) { 11555 tslib_1.__extends(ExternalDropping, _super); 11556 function ExternalDropping() { 11557 var _this = _super !== null && _super.apply(this, arguments) || this; 11558 _this.isDragging = false; // jqui-dragging an external element? boolean 11559 return _this; 11560 } 11561 /* 11562 component impements: 11563 - eventRangesToEventFootprints 11564 - isEventInstanceGroupAllowed 11565 - isExternalInstanceGroupAllowed 11566 - renderDrag 11567 - unrenderDrag 11568 */ 11569 ExternalDropping.prototype.end = function () { 11570 if (this.dragListener) { 11571 this.dragListener.endInteraction(); 11572 } 11573 }; 11574 ExternalDropping.prototype.bindToDocument = function () { 11575 this.listenTo($(document), { 11576 dragstart: this.handleDragStart, 11577 sortstart: this.handleDragStart // jqui 11578 }); 11579 }; 11580 ExternalDropping.prototype.unbindFromDocument = function () { 11581 this.stopListeningTo($(document)); 11582 }; 11583 // Called when a jQuery UI drag is initiated anywhere in the DOM 11584 ExternalDropping.prototype.handleDragStart = function (ev, ui) { 11585 var el; 11586 var accept; 11587 if (this.opt('droppable')) { // only listen if this setting is on 11588 el = $((ui ? ui.item : null) || ev.target); 11589 // Test that the dragged element passes the dropAccept selector or filter function. 11590 // FYI, the default is "*" (matches all) 11591 accept = this.opt('dropAccept'); 11592 if ($.isFunction(accept) ? accept.call(el[0], el) : el.is(accept)) { 11593 if (!this.isDragging) { // prevent double-listening if fired twice 11594 this.listenToExternalDrag(el, ev, ui); 11595 } 11596 } 11597 } 11598 }; 11599 // Called when a jQuery UI drag starts and it needs to be monitored for dropping 11600 ExternalDropping.prototype.listenToExternalDrag = function (el, ev, ui) { 11601 var _this = this; 11602 var component = this.component; 11603 var view = this.view; 11604 var meta = getDraggedElMeta(el); // extra data about event drop, including possible event to create 11605 var singleEventDef; // a null value signals an unsuccessful drag 11606 // listener that tracks mouse movement over date-associated pixel regions 11607 var dragListener = this.dragListener = new HitDragListener_1.default(component, { 11608 interactionStart: function () { 11609 _this.isDragging = true; 11610 }, 11611 hitOver: function (hit) { 11612 var isAllowed = true; 11613 var hitFootprint = hit.component.getSafeHitFootprint(hit); // hit might not belong to this grid 11614 var mutatedEventInstanceGroup; 11615 if (hitFootprint) { 11616 singleEventDef = _this.computeExternalDrop(hitFootprint, meta); 11617 if (singleEventDef) { 11618 mutatedEventInstanceGroup = new EventInstanceGroup_1.default(singleEventDef.buildInstances()); 11619 isAllowed = meta.eventProps ? // isEvent? 11620 component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup) : 11621 component.isExternalInstanceGroupAllowed(mutatedEventInstanceGroup); 11622 } 11623 else { 11624 isAllowed = false; 11625 } 11626 } 11627 else { 11628 isAllowed = false; 11629 } 11630 if (!isAllowed) { 11631 singleEventDef = null; 11632 util_1.disableCursor(); 11633 } 11634 if (singleEventDef) { 11635 component.renderDrag(// called without a seg parameter 11636 component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, view.calendar))); 11637 } 11638 }, 11639 hitOut: function () { 11640 singleEventDef = null; // signal unsuccessful 11641 }, 11642 hitDone: function () { 11643 util_1.enableCursor(); 11644 component.unrenderDrag(); 11645 }, 11646 interactionEnd: function (ev) { 11647 if (singleEventDef) { // element was dropped on a valid hit 11648 view.reportExternalDrop(singleEventDef, Boolean(meta.eventProps), // isEvent 11649 Boolean(meta.stick), // isSticky 11650 el, ev, ui); 11651 } 11652 _this.isDragging = false; 11653 _this.dragListener = null; 11654 } 11655 }); 11656 dragListener.startDrag(ev); // start listening immediately 11657 }; 11658 // Given a hit to be dropped upon, and misc data associated with the jqui drag (guaranteed to be a plain object), 11659 // returns the zoned start/end dates for the event that would result from the hypothetical drop. end might be null. 11660 // Returning a null value signals an invalid drop hit. 11661 // DOES NOT consider overlap/constraint. 11662 // Assumes both footprints are non-open-ended. 11663 ExternalDropping.prototype.computeExternalDrop = function (componentFootprint, meta) { 11664 var calendar = this.view.calendar; 11665 var start = moment_ext_1.default.utc(componentFootprint.unzonedRange.startMs).stripZone(); 11666 var end; 11667 var eventDef; 11668 if (componentFootprint.isAllDay) { 11669 // if dropped on an all-day span, and element's metadata specified a time, set it 11670 if (meta.startTime) { 11671 start.time(meta.startTime); 11672 } 11673 else { 11674 start.stripTime(); 11675 } 11676 } 11677 if (meta.duration) { 11678 end = start.clone().add(meta.duration); 11679 } 11680 start = calendar.applyTimezone(start); 11681 if (end) { 11682 end = calendar.applyTimezone(end); 11683 } 11684 eventDef = SingleEventDef_1.default.parse($.extend({}, meta.eventProps, { 11685 start: start, 11686 end: end 11687 }), new EventSource_1.default(calendar)); 11688 return eventDef; 11689 }; 11690 return ExternalDropping; 11691}(Interaction_1.default)); 11692exports.default = ExternalDropping; 11693ListenerMixin_1.default.mixInto(ExternalDropping); 11694/* External-Dragging-Element Data 11695----------------------------------------------------------------------------------------------------------------------*/ 11696// Require all HTML5 data-* attributes used by FullCalendar to have this prefix. 11697// A value of '' will query attributes like data-event. A value of 'fc' will query attributes like data-fc-event. 11698exportHooks.dataAttrPrefix = ''; 11699// Given a jQuery element that might represent a dragged FullCalendar event, returns an intermediate data structure 11700// to be used for Event Object creation. 11701// A defined `.eventProps`, even when empty, indicates that an event should be created. 11702function getDraggedElMeta(el) { 11703 var prefix = exportHooks.dataAttrPrefix; 11704 var eventProps; // properties for creating the event, not related to date/time 11705 var startTime; // a Duration 11706 var duration; 11707 var stick; 11708 if (prefix) { 11709 prefix += '-'; 11710 } 11711 eventProps = el.data(prefix + 'event') || null; 11712 if (eventProps) { 11713 if (typeof eventProps === 'object') { 11714 eventProps = $.extend({}, eventProps); // make a copy 11715 } 11716 else { // something like 1 or true. still signal event creation 11717 eventProps = {}; 11718 } 11719 // pluck special-cased date/time properties 11720 startTime = eventProps.start; 11721 if (startTime == null) { 11722 startTime = eventProps.time; 11723 } // accept 'time' as well 11724 duration = eventProps.duration; 11725 stick = eventProps.stick; 11726 delete eventProps.start; 11727 delete eventProps.time; 11728 delete eventProps.duration; 11729 delete eventProps.stick; 11730 } 11731 // fallback to standalone attribute values for each of the date/time properties 11732 if (startTime == null) { 11733 startTime = el.data(prefix + 'start'); 11734 } 11735 if (startTime == null) { 11736 startTime = el.data(prefix + 'time'); 11737 } // accept 'time' as well 11738 if (duration == null) { 11739 duration = el.data(prefix + 'duration'); 11740 } 11741 if (stick == null) { 11742 stick = el.data(prefix + 'stick'); 11743 } 11744 // massage into correct data types 11745 startTime = startTime != null ? moment.duration(startTime) : null; 11746 duration = duration != null ? moment.duration(duration) : null; 11747 stick = Boolean(stick); 11748 return { eventProps: eventProps, startTime: startTime, duration: duration, stick: stick }; 11749} 11750 11751 11752/***/ }), 11753/* 234 */ 11754/***/ (function(module, exports, __webpack_require__) { 11755 11756Object.defineProperty(exports, "__esModule", { value: true }); 11757var tslib_1 = __webpack_require__(2); 11758var $ = __webpack_require__(3); 11759var util_1 = __webpack_require__(4); 11760var EventDefMutation_1 = __webpack_require__(39); 11761var EventDefDateMutation_1 = __webpack_require__(40); 11762var HitDragListener_1 = __webpack_require__(17); 11763var Interaction_1 = __webpack_require__(14); 11764var EventResizing = /** @class */ (function (_super) { 11765 tslib_1.__extends(EventResizing, _super); 11766 /* 11767 component impements: 11768 - bindSegHandlerToEl 11769 - publiclyTrigger 11770 - diffDates 11771 - eventRangesToEventFootprints 11772 - isEventInstanceGroupAllowed 11773 - getSafeHitFootprint 11774 */ 11775 function EventResizing(component, eventPointing) { 11776 var _this = _super.call(this, component) || this; 11777 _this.isResizing = false; 11778 _this.eventPointing = eventPointing; 11779 return _this; 11780 } 11781 EventResizing.prototype.end = function () { 11782 if (this.dragListener) { 11783 this.dragListener.endInteraction(); 11784 } 11785 }; 11786 EventResizing.prototype.bindToEl = function (el) { 11787 var component = this.component; 11788 component.bindSegHandlerToEl(el, 'mousedown', this.handleMouseDown.bind(this)); 11789 component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this)); 11790 }; 11791 EventResizing.prototype.handleMouseDown = function (seg, ev) { 11792 if (this.component.canStartResize(seg, ev)) { 11793 this.buildDragListener(seg, $(ev.target).is('.fc-start-resizer')) 11794 .startInteraction(ev, { distance: 5 }); 11795 } 11796 }; 11797 EventResizing.prototype.handleTouchStart = function (seg, ev) { 11798 if (this.component.canStartResize(seg, ev)) { 11799 this.buildDragListener(seg, $(ev.target).is('.fc-start-resizer')) 11800 .startInteraction(ev); 11801 } 11802 }; 11803 // Creates a listener that tracks the user as they resize an event segment. 11804 // Generic enough to work with any type of Grid. 11805 EventResizing.prototype.buildDragListener = function (seg, isStart) { 11806 var _this = this; 11807 var component = this.component; 11808 var view = this.view; 11809 var calendar = view.calendar; 11810 var eventManager = calendar.eventManager; 11811 var el = seg.el; 11812 var eventDef = seg.footprint.eventDef; 11813 var eventInstance = seg.footprint.eventInstance; 11814 var isDragging; 11815 var resizeMutation; // zoned event date properties. falsy if invalid resize 11816 // Tracks mouse movement over the *grid's* coordinate map 11817 var dragListener = this.dragListener = new HitDragListener_1.default(component, { 11818 scroll: this.opt('dragScroll'), 11819 subjectEl: el, 11820 interactionStart: function () { 11821 isDragging = false; 11822 }, 11823 dragStart: function (ev) { 11824 isDragging = true; 11825 // ensure a mouseout on the manipulated event has been reported 11826 _this.eventPointing.handleMouseout(seg, ev); 11827 _this.segResizeStart(seg, ev); 11828 }, 11829 hitOver: function (hit, isOrig, origHit) { 11830 var isAllowed = true; 11831 var origHitFootprint = component.getSafeHitFootprint(origHit); 11832 var hitFootprint = component.getSafeHitFootprint(hit); 11833 var mutatedEventInstanceGroup; 11834 if (origHitFootprint && hitFootprint) { 11835 resizeMutation = isStart ? 11836 _this.computeEventStartResizeMutation(origHitFootprint, hitFootprint, seg.footprint) : 11837 _this.computeEventEndResizeMutation(origHitFootprint, hitFootprint, seg.footprint); 11838 if (resizeMutation) { 11839 mutatedEventInstanceGroup = eventManager.buildMutatedEventInstanceGroup(eventDef.id, resizeMutation); 11840 isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup); 11841 } 11842 else { 11843 isAllowed = false; 11844 } 11845 } 11846 else { 11847 isAllowed = false; 11848 } 11849 if (!isAllowed) { 11850 resizeMutation = null; 11851 util_1.disableCursor(); 11852 } 11853 else if (resizeMutation.isEmpty()) { 11854 // no change. (FYI, event dates might have zones) 11855 resizeMutation = null; 11856 } 11857 if (resizeMutation) { 11858 view.hideEventsWithId(seg.footprint.eventDef.id); 11859 view.renderEventResize(component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, calendar)), seg); 11860 } 11861 }, 11862 hitOut: function () { 11863 resizeMutation = null; 11864 }, 11865 hitDone: function () { 11866 view.unrenderEventResize(seg); 11867 view.showEventsWithId(seg.footprint.eventDef.id); 11868 util_1.enableCursor(); 11869 }, 11870 interactionEnd: function (ev) { 11871 if (isDragging) { 11872 _this.segResizeStop(seg, ev); 11873 } 11874 if (resizeMutation) { // valid date to resize to? 11875 // no need to re-show original, will rerender all anyways. esp important if eventRenderWait 11876 view.reportEventResize(eventInstance, resizeMutation, el, ev); 11877 } 11878 _this.dragListener = null; 11879 } 11880 }); 11881 return dragListener; 11882 }; 11883 // Called before event segment resizing starts 11884 EventResizing.prototype.segResizeStart = function (seg, ev) { 11885 this.isResizing = true; 11886 this.component.publiclyTrigger('eventResizeStart', { 11887 context: seg.el[0], 11888 args: [ 11889 seg.footprint.getEventLegacy(), 11890 ev, 11891 {}, 11892 this.view 11893 ] 11894 }); 11895 }; 11896 // Called after event segment resizing stops 11897 EventResizing.prototype.segResizeStop = function (seg, ev) { 11898 this.isResizing = false; 11899 this.component.publiclyTrigger('eventResizeStop', { 11900 context: seg.el[0], 11901 args: [ 11902 seg.footprint.getEventLegacy(), 11903 ev, 11904 {}, 11905 this.view 11906 ] 11907 }); 11908 }; 11909 // Returns new date-information for an event segment being resized from its start 11910 EventResizing.prototype.computeEventStartResizeMutation = function (startFootprint, endFootprint, origEventFootprint) { 11911 var origRange = origEventFootprint.componentFootprint.unzonedRange; 11912 var startDelta = this.component.diffDates(endFootprint.unzonedRange.getStart(), startFootprint.unzonedRange.getStart()); 11913 var dateMutation; 11914 var eventDefMutation; 11915 if (origRange.getStart().add(startDelta) < origRange.getEnd()) { 11916 dateMutation = new EventDefDateMutation_1.default(); 11917 dateMutation.setStartDelta(startDelta); 11918 eventDefMutation = new EventDefMutation_1.default(); 11919 eventDefMutation.setDateMutation(dateMutation); 11920 return eventDefMutation; 11921 } 11922 return false; 11923 }; 11924 // Returns new date-information for an event segment being resized from its end 11925 EventResizing.prototype.computeEventEndResizeMutation = function (startFootprint, endFootprint, origEventFootprint) { 11926 var origRange = origEventFootprint.componentFootprint.unzonedRange; 11927 var endDelta = this.component.diffDates(endFootprint.unzonedRange.getEnd(), startFootprint.unzonedRange.getEnd()); 11928 var dateMutation; 11929 var eventDefMutation; 11930 if (origRange.getEnd().add(endDelta) > origRange.getStart()) { 11931 dateMutation = new EventDefDateMutation_1.default(); 11932 dateMutation.setEndDelta(endDelta); 11933 eventDefMutation = new EventDefMutation_1.default(); 11934 eventDefMutation.setDateMutation(dateMutation); 11935 return eventDefMutation; 11936 } 11937 return false; 11938 }; 11939 return EventResizing; 11940}(Interaction_1.default)); 11941exports.default = EventResizing; 11942 11943 11944/***/ }), 11945/* 235 */ 11946/***/ (function(module, exports, __webpack_require__) { 11947 11948Object.defineProperty(exports, "__esModule", { value: true }); 11949var tslib_1 = __webpack_require__(2); 11950var util_1 = __webpack_require__(4); 11951var EventDefMutation_1 = __webpack_require__(39); 11952var EventDefDateMutation_1 = __webpack_require__(40); 11953var DragListener_1 = __webpack_require__(59); 11954var HitDragListener_1 = __webpack_require__(17); 11955var MouseFollower_1 = __webpack_require__(226); 11956var Interaction_1 = __webpack_require__(14); 11957var EventDragging = /** @class */ (function (_super) { 11958 tslib_1.__extends(EventDragging, _super); 11959 /* 11960 component implements: 11961 - bindSegHandlerToEl 11962 - publiclyTrigger 11963 - diffDates 11964 - eventRangesToEventFootprints 11965 - isEventInstanceGroupAllowed 11966 */ 11967 function EventDragging(component, eventPointing) { 11968 var _this = _super.call(this, component) || this; 11969 _this.isDragging = false; 11970 _this.eventPointing = eventPointing; 11971 return _this; 11972 } 11973 EventDragging.prototype.end = function () { 11974 if (this.dragListener) { 11975 this.dragListener.endInteraction(); 11976 } 11977 }; 11978 EventDragging.prototype.getSelectionDelay = function () { 11979 var delay = this.opt('eventLongPressDelay'); 11980 if (delay == null) { 11981 delay = this.opt('longPressDelay'); // fallback 11982 } 11983 return delay; 11984 }; 11985 EventDragging.prototype.bindToEl = function (el) { 11986 var component = this.component; 11987 component.bindSegHandlerToEl(el, 'mousedown', this.handleMousedown.bind(this)); 11988 component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this)); 11989 }; 11990 EventDragging.prototype.handleMousedown = function (seg, ev) { 11991 if (!this.component.shouldIgnoreMouse() && 11992 this.component.canStartDrag(seg, ev)) { 11993 this.buildDragListener(seg).startInteraction(ev, { distance: 5 }); 11994 } 11995 }; 11996 EventDragging.prototype.handleTouchStart = function (seg, ev) { 11997 var component = this.component; 11998 var settings = { 11999 delay: this.view.isEventDefSelected(seg.footprint.eventDef) ? // already selected? 12000 0 : this.getSelectionDelay() 12001 }; 12002 if (component.canStartDrag(seg, ev)) { 12003 this.buildDragListener(seg).startInteraction(ev, settings); 12004 } 12005 else if (component.canStartSelection(seg, ev)) { 12006 this.buildSelectListener(seg).startInteraction(ev, settings); 12007 } 12008 }; 12009 // seg isn't draggable, but let's use a generic DragListener 12010 // simply for the delay, so it can be selected. 12011 // Has side effect of setting/unsetting `dragListener` 12012 EventDragging.prototype.buildSelectListener = function (seg) { 12013 var _this = this; 12014 var view = this.view; 12015 var eventDef = seg.footprint.eventDef; 12016 var eventInstance = seg.footprint.eventInstance; // null for inverse-background events 12017 if (this.dragListener) { 12018 return this.dragListener; 12019 } 12020 var dragListener = this.dragListener = new DragListener_1.default({ 12021 dragStart: function (ev) { 12022 if (dragListener.isTouch && 12023 !view.isEventDefSelected(eventDef) && 12024 eventInstance) { 12025 // if not previously selected, will fire after a delay. then, select the event 12026 view.selectEventInstance(eventInstance); 12027 } 12028 }, 12029 interactionEnd: function (ev) { 12030 _this.dragListener = null; 12031 } 12032 }); 12033 return dragListener; 12034 }; 12035 // Builds a listener that will track user-dragging on an event segment. 12036 // Generic enough to work with any type of Grid. 12037 // Has side effect of setting/unsetting `dragListener` 12038 EventDragging.prototype.buildDragListener = function (seg) { 12039 var _this = this; 12040 var component = this.component; 12041 var view = this.view; 12042 var calendar = view.calendar; 12043 var eventManager = calendar.eventManager; 12044 var el = seg.el; 12045 var eventDef = seg.footprint.eventDef; 12046 var eventInstance = seg.footprint.eventInstance; // null for inverse-background events 12047 var isDragging; 12048 var mouseFollower; // A clone of the original element that will move with the mouse 12049 var eventDefMutation; 12050 if (this.dragListener) { 12051 return this.dragListener; 12052 } 12053 // Tracks mouse movement over the *view's* coordinate map. Allows dragging and dropping between subcomponents 12054 // of the view. 12055 var dragListener = this.dragListener = new HitDragListener_1.default(view, { 12056 scroll: this.opt('dragScroll'), 12057 subjectEl: el, 12058 subjectCenter: true, 12059 interactionStart: function (ev) { 12060 seg.component = component; // for renderDrag 12061 isDragging = false; 12062 mouseFollower = new MouseFollower_1.default(seg.el, { 12063 additionalClass: 'fc-dragging', 12064 parentEl: view.el, 12065 opacity: dragListener.isTouch ? null : _this.opt('dragOpacity'), 12066 revertDuration: _this.opt('dragRevertDuration'), 12067 zIndex: 2 // one above the .fc-view 12068 }); 12069 mouseFollower.hide(); // don't show until we know this is a real drag 12070 mouseFollower.start(ev); 12071 }, 12072 dragStart: function (ev) { 12073 if (dragListener.isTouch && 12074 !view.isEventDefSelected(eventDef) && 12075 eventInstance) { 12076 // if not previously selected, will fire after a delay. then, select the event 12077 view.selectEventInstance(eventInstance); 12078 } 12079 isDragging = true; 12080 // ensure a mouseout on the manipulated event has been reported 12081 _this.eventPointing.handleMouseout(seg, ev); 12082 _this.segDragStart(seg, ev); 12083 view.hideEventsWithId(seg.footprint.eventDef.id); 12084 }, 12085 hitOver: function (hit, isOrig, origHit) { 12086 var isAllowed = true; 12087 var origFootprint; 12088 var footprint; 12089 var mutatedEventInstanceGroup; 12090 // starting hit could be forced (DayGrid.limit) 12091 if (seg.hit) { 12092 origHit = seg.hit; 12093 } 12094 // hit might not belong to this grid, so query origin grid 12095 origFootprint = origHit.component.getSafeHitFootprint(origHit); 12096 footprint = hit.component.getSafeHitFootprint(hit); 12097 if (origFootprint && footprint) { 12098 eventDefMutation = _this.computeEventDropMutation(origFootprint, footprint, eventDef); 12099 if (eventDefMutation) { 12100 mutatedEventInstanceGroup = eventManager.buildMutatedEventInstanceGroup(eventDef.id, eventDefMutation); 12101 isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup); 12102 } 12103 else { 12104 isAllowed = false; 12105 } 12106 } 12107 else { 12108 isAllowed = false; 12109 } 12110 if (!isAllowed) { 12111 eventDefMutation = null; 12112 util_1.disableCursor(); 12113 } 12114 // if a valid drop location, have the subclass render a visual indication 12115 if (eventDefMutation && 12116 view.renderDrag(// truthy if rendered something 12117 component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, calendar)), seg, dragListener.isTouch)) { 12118 mouseFollower.hide(); // if the subclass is already using a mock event "helper", hide our own 12119 } 12120 else { 12121 mouseFollower.show(); // otherwise, have the helper follow the mouse (no snapping) 12122 } 12123 if (isOrig) { 12124 // needs to have moved hits to be a valid drop 12125 eventDefMutation = null; 12126 } 12127 }, 12128 hitOut: function () { 12129 view.unrenderDrag(seg); // unrender whatever was done in renderDrag 12130 mouseFollower.show(); // show in case we are moving out of all hits 12131 eventDefMutation = null; 12132 }, 12133 hitDone: function () { 12134 util_1.enableCursor(); 12135 }, 12136 interactionEnd: function (ev) { 12137 delete seg.component; // prevent side effects 12138 // do revert animation if hasn't changed. calls a callback when finished (whether animation or not) 12139 mouseFollower.stop(!eventDefMutation, function () { 12140 if (isDragging) { 12141 view.unrenderDrag(seg); 12142 _this.segDragStop(seg, ev); 12143 } 12144 view.showEventsWithId(seg.footprint.eventDef.id); 12145 if (eventDefMutation) { 12146 // no need to re-show original, will rerender all anyways. esp important if eventRenderWait 12147 view.reportEventDrop(eventInstance, eventDefMutation, el, ev); 12148 } 12149 }); 12150 _this.dragListener = null; 12151 } 12152 }); 12153 return dragListener; 12154 }; 12155 // Called before event segment dragging starts 12156 EventDragging.prototype.segDragStart = function (seg, ev) { 12157 this.isDragging = true; 12158 this.component.publiclyTrigger('eventDragStart', { 12159 context: seg.el[0], 12160 args: [ 12161 seg.footprint.getEventLegacy(), 12162 ev, 12163 {}, 12164 this.view 12165 ] 12166 }); 12167 }; 12168 // Called after event segment dragging stops 12169 EventDragging.prototype.segDragStop = function (seg, ev) { 12170 this.isDragging = false; 12171 this.component.publiclyTrigger('eventDragStop', { 12172 context: seg.el[0], 12173 args: [ 12174 seg.footprint.getEventLegacy(), 12175 ev, 12176 {}, 12177 this.view 12178 ] 12179 }); 12180 }; 12181 // DOES NOT consider overlap/constraint 12182 EventDragging.prototype.computeEventDropMutation = function (startFootprint, endFootprint, eventDef) { 12183 var eventDefMutation = new EventDefMutation_1.default(); 12184 eventDefMutation.setDateMutation(this.computeEventDateMutation(startFootprint, endFootprint)); 12185 return eventDefMutation; 12186 }; 12187 EventDragging.prototype.computeEventDateMutation = function (startFootprint, endFootprint) { 12188 var date0 = startFootprint.unzonedRange.getStart(); 12189 var date1 = endFootprint.unzonedRange.getStart(); 12190 var clearEnd = false; 12191 var forceTimed = false; 12192 var forceAllDay = false; 12193 var dateDelta; 12194 var dateMutation; 12195 if (startFootprint.isAllDay !== endFootprint.isAllDay) { 12196 clearEnd = true; 12197 if (endFootprint.isAllDay) { 12198 forceAllDay = true; 12199 date0.stripTime(); 12200 } 12201 else { 12202 forceTimed = true; 12203 } 12204 } 12205 dateDelta = this.component.diffDates(date1, date0); 12206 dateMutation = new EventDefDateMutation_1.default(); 12207 dateMutation.clearEnd = clearEnd; 12208 dateMutation.forceTimed = forceTimed; 12209 dateMutation.forceAllDay = forceAllDay; 12210 dateMutation.setDateDelta(dateDelta); 12211 return dateMutation; 12212 }; 12213 return EventDragging; 12214}(Interaction_1.default)); 12215exports.default = EventDragging; 12216 12217 12218/***/ }), 12219/* 236 */ 12220/***/ (function(module, exports, __webpack_require__) { 12221 12222Object.defineProperty(exports, "__esModule", { value: true }); 12223var tslib_1 = __webpack_require__(2); 12224var util_1 = __webpack_require__(4); 12225var HitDragListener_1 = __webpack_require__(17); 12226var ComponentFootprint_1 = __webpack_require__(12); 12227var UnzonedRange_1 = __webpack_require__(5); 12228var Interaction_1 = __webpack_require__(14); 12229var DateSelecting = /** @class */ (function (_super) { 12230 tslib_1.__extends(DateSelecting, _super); 12231 /* 12232 component must implement: 12233 - bindDateHandlerToEl 12234 - getSafeHitFootprint 12235 - renderHighlight 12236 - unrenderHighlight 12237 */ 12238 function DateSelecting(component) { 12239 var _this = _super.call(this, component) || this; 12240 _this.dragListener = _this.buildDragListener(); 12241 return _this; 12242 } 12243 DateSelecting.prototype.end = function () { 12244 this.dragListener.endInteraction(); 12245 }; 12246 DateSelecting.prototype.getDelay = function () { 12247 var delay = this.opt('selectLongPressDelay'); 12248 if (delay == null) { 12249 delay = this.opt('longPressDelay'); // fallback 12250 } 12251 return delay; 12252 }; 12253 DateSelecting.prototype.bindToEl = function (el) { 12254 var _this = this; 12255 var component = this.component; 12256 var dragListener = this.dragListener; 12257 component.bindDateHandlerToEl(el, 'mousedown', function (ev) { 12258 if (_this.opt('selectable') && !component.shouldIgnoreMouse()) { 12259 dragListener.startInteraction(ev, { 12260 distance: _this.opt('selectMinDistance') 12261 }); 12262 } 12263 }); 12264 component.bindDateHandlerToEl(el, 'touchstart', function (ev) { 12265 if (_this.opt('selectable') && !component.shouldIgnoreTouch()) { 12266 dragListener.startInteraction(ev, { 12267 delay: _this.getDelay() 12268 }); 12269 } 12270 }); 12271 util_1.preventSelection(el); 12272 }; 12273 // Creates a listener that tracks the user's drag across day elements, for day selecting. 12274 DateSelecting.prototype.buildDragListener = function () { 12275 var _this = this; 12276 var component = this.component; 12277 var selectionFootprint; // null if invalid selection 12278 var dragListener = new HitDragListener_1.default(component, { 12279 scroll: this.opt('dragScroll'), 12280 interactionStart: function () { 12281 selectionFootprint = null; 12282 }, 12283 dragStart: function (ev) { 12284 _this.view.unselect(ev); // since we could be rendering a new selection, we want to clear any old one 12285 }, 12286 hitOver: function (hit, isOrig, origHit) { 12287 var origHitFootprint; 12288 var hitFootprint; 12289 if (origHit) { // click needs to have started on a hit 12290 origHitFootprint = component.getSafeHitFootprint(origHit); 12291 hitFootprint = component.getSafeHitFootprint(hit); 12292 if (origHitFootprint && hitFootprint) { 12293 selectionFootprint = _this.computeSelection(origHitFootprint, hitFootprint); 12294 } 12295 else { 12296 selectionFootprint = null; 12297 } 12298 if (selectionFootprint) { 12299 component.renderSelectionFootprint(selectionFootprint); 12300 } 12301 else if (selectionFootprint === false) { 12302 util_1.disableCursor(); 12303 } 12304 } 12305 }, 12306 hitOut: function () { 12307 selectionFootprint = null; 12308 component.unrenderSelection(); 12309 }, 12310 hitDone: function () { 12311 util_1.enableCursor(); 12312 }, 12313 interactionEnd: function (ev, isCancelled) { 12314 if (!isCancelled && selectionFootprint) { 12315 // the selection will already have been rendered. just report it 12316 _this.view.reportSelection(selectionFootprint, ev); 12317 } 12318 } 12319 }); 12320 return dragListener; 12321 }; 12322 // Given the first and last date-spans of a selection, returns another date-span object. 12323 // Subclasses can override and provide additional data in the span object. Will be passed to renderSelectionFootprint(). 12324 // Will return false if the selection is invalid and this should be indicated to the user. 12325 // Will return null/undefined if a selection invalid but no error should be reported. 12326 DateSelecting.prototype.computeSelection = function (footprint0, footprint1) { 12327 var wholeFootprint = this.computeSelectionFootprint(footprint0, footprint1); 12328 if (wholeFootprint && !this.isSelectionFootprintAllowed(wholeFootprint)) { 12329 return false; 12330 } 12331 return wholeFootprint; 12332 }; 12333 // Given two spans, must return the combination of the two. 12334 // TODO: do this separation of concerns (combining VS validation) for event dnd/resize too. 12335 // Assumes both footprints are non-open-ended. 12336 DateSelecting.prototype.computeSelectionFootprint = function (footprint0, footprint1) { 12337 var ms = [ 12338 footprint0.unzonedRange.startMs, 12339 footprint0.unzonedRange.endMs, 12340 footprint1.unzonedRange.startMs, 12341 footprint1.unzonedRange.endMs 12342 ]; 12343 ms.sort(util_1.compareNumbers); 12344 return new ComponentFootprint_1.default(new UnzonedRange_1.default(ms[0], ms[3]), footprint0.isAllDay); 12345 }; 12346 DateSelecting.prototype.isSelectionFootprintAllowed = function (componentFootprint) { 12347 return this.component.dateProfile.validUnzonedRange.containsRange(componentFootprint.unzonedRange) && 12348 this.view.calendar.constraints.isSelectionFootprintAllowed(componentFootprint); 12349 }; 12350 return DateSelecting; 12351}(Interaction_1.default)); 12352exports.default = DateSelecting; 12353 12354 12355/***/ }), 12356/* 237 */ 12357/***/ (function(module, exports, __webpack_require__) { 12358 12359Object.defineProperty(exports, "__esModule", { value: true }); 12360var tslib_1 = __webpack_require__(2); 12361var HitDragListener_1 = __webpack_require__(17); 12362var Interaction_1 = __webpack_require__(14); 12363var DateClicking = /** @class */ (function (_super) { 12364 tslib_1.__extends(DateClicking, _super); 12365 /* 12366 component must implement: 12367 - bindDateHandlerToEl 12368 - getSafeHitFootprint 12369 - getHitEl 12370 */ 12371 function DateClicking(component) { 12372 var _this = _super.call(this, component) || this; 12373 _this.dragListener = _this.buildDragListener(); 12374 return _this; 12375 } 12376 DateClicking.prototype.end = function () { 12377 this.dragListener.endInteraction(); 12378 }; 12379 DateClicking.prototype.bindToEl = function (el) { 12380 var component = this.component; 12381 var dragListener = this.dragListener; 12382 component.bindDateHandlerToEl(el, 'mousedown', function (ev) { 12383 if (!component.shouldIgnoreMouse()) { 12384 dragListener.startInteraction(ev); 12385 } 12386 }); 12387 component.bindDateHandlerToEl(el, 'touchstart', function (ev) { 12388 if (!component.shouldIgnoreTouch()) { 12389 dragListener.startInteraction(ev); 12390 } 12391 }); 12392 }; 12393 // Creates a listener that tracks the user's drag across day elements, for day clicking. 12394 DateClicking.prototype.buildDragListener = function () { 12395 var _this = this; 12396 var component = this.component; 12397 var dayClickHit; // null if invalid dayClick 12398 var dragListener = new HitDragListener_1.default(component, { 12399 scroll: this.opt('dragScroll'), 12400 interactionStart: function () { 12401 dayClickHit = dragListener.origHit; 12402 }, 12403 hitOver: function (hit, isOrig, origHit) { 12404 // if user dragged to another cell at any point, it can no longer be a dayClick 12405 if (!isOrig) { 12406 dayClickHit = null; 12407 } 12408 }, 12409 hitOut: function () { 12410 dayClickHit = null; 12411 }, 12412 interactionEnd: function (ev, isCancelled) { 12413 var componentFootprint; 12414 if (!isCancelled && dayClickHit) { 12415 componentFootprint = component.getSafeHitFootprint(dayClickHit); 12416 if (componentFootprint) { 12417 _this.view.triggerDayClick(componentFootprint, component.getHitEl(dayClickHit), ev); 12418 } 12419 } 12420 } 12421 }); 12422 // because dragListener won't be called with any time delay, "dragging" will begin immediately, 12423 // which will kill any touchmoving/scrolling. Prevent this. 12424 dragListener.shouldCancelTouchScroll = false; 12425 dragListener.scrollAlwaysKills = true; 12426 return dragListener; 12427 }; 12428 return DateClicking; 12429}(Interaction_1.default)); 12430exports.default = DateClicking; 12431 12432 12433/***/ }), 12434/* 238 */ 12435/***/ (function(module, exports, __webpack_require__) { 12436 12437Object.defineProperty(exports, "__esModule", { value: true }); 12438var tslib_1 = __webpack_require__(2); 12439var moment = __webpack_require__(0); 12440var $ = __webpack_require__(3); 12441var util_1 = __webpack_require__(4); 12442var Scroller_1 = __webpack_require__(41); 12443var View_1 = __webpack_require__(43); 12444var TimeGrid_1 = __webpack_require__(239); 12445var DayGrid_1 = __webpack_require__(66); 12446var AGENDA_ALL_DAY_EVENT_LIMIT = 5; 12447var agendaTimeGridMethods; 12448var agendaDayGridMethods; 12449/* An abstract class for all agenda-related views. Displays one more columns with time slots running vertically. 12450----------------------------------------------------------------------------------------------------------------------*/ 12451// Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on). 12452// Responsible for managing width/height. 12453var AgendaView = /** @class */ (function (_super) { 12454 tslib_1.__extends(AgendaView, _super); 12455 function AgendaView(calendar, viewSpec) { 12456 var _this = _super.call(this, calendar, viewSpec) || this; 12457 _this.usesMinMaxTime = true; // indicates that minTime/maxTime affects rendering 12458 _this.timeGrid = _this.instantiateTimeGrid(); 12459 _this.addChild(_this.timeGrid); 12460 if (_this.opt('allDaySlot')) { // should we display the "all-day" area? 12461 _this.dayGrid = _this.instantiateDayGrid(); // the all-day subcomponent of this view 12462 _this.addChild(_this.dayGrid); 12463 } 12464 _this.scroller = new Scroller_1.default({ 12465 overflowX: 'hidden', 12466 overflowY: 'auto' 12467 }); 12468 return _this; 12469 } 12470 // Instantiates the TimeGrid object this view needs. Draws from this.timeGridClass 12471 AgendaView.prototype.instantiateTimeGrid = function () { 12472 var timeGrid = new this.timeGridClass(this); 12473 util_1.copyOwnProps(agendaTimeGridMethods, timeGrid); 12474 return timeGrid; 12475 }; 12476 // Instantiates the DayGrid object this view might need. Draws from this.dayGridClass 12477 AgendaView.prototype.instantiateDayGrid = function () { 12478 var dayGrid = new this.dayGridClass(this); 12479 util_1.copyOwnProps(agendaDayGridMethods, dayGrid); 12480 return dayGrid; 12481 }; 12482 /* Rendering 12483 ------------------------------------------------------------------------------------------------------------------*/ 12484 AgendaView.prototype.renderSkeleton = function () { 12485 var timeGridWrapEl; 12486 var timeGridEl; 12487 this.el.addClass('fc-agenda-view').html(this.renderSkeletonHtml()); 12488 this.scroller.render(); 12489 timeGridWrapEl = this.scroller.el.addClass('fc-time-grid-container'); 12490 timeGridEl = $('<div class="fc-time-grid">').appendTo(timeGridWrapEl); 12491 this.el.find('.fc-body > tr > td').append(timeGridWrapEl); 12492 this.timeGrid.headContainerEl = this.el.find('.fc-head-container'); 12493 this.timeGrid.setElement(timeGridEl); 12494 if (this.dayGrid) { 12495 this.dayGrid.setElement(this.el.find('.fc-day-grid')); 12496 // have the day-grid extend it's coordinate area over the <hr> dividing the two grids 12497 this.dayGrid.bottomCoordPadding = this.dayGrid.el.next('hr').outerHeight(); 12498 } 12499 }; 12500 AgendaView.prototype.unrenderSkeleton = function () { 12501 this.timeGrid.removeElement(); 12502 if (this.dayGrid) { 12503 this.dayGrid.removeElement(); 12504 } 12505 this.scroller.destroy(); 12506 }; 12507 // Builds the HTML skeleton for the view. 12508 // The day-grid and time-grid components will render inside containers defined by this HTML. 12509 AgendaView.prototype.renderSkeletonHtml = function () { 12510 var theme = this.calendar.theme; 12511 return '' + 12512 '<table class="' + theme.getClass('tableGrid') + '">' + 12513 (this.opt('columnHeader') ? 12514 '<thead class="fc-head">' + 12515 '<tr>' + 12516 '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '"> </td>' + 12517 '</tr>' + 12518 '</thead>' : 12519 '') + 12520 '<tbody class="fc-body">' + 12521 '<tr>' + 12522 '<td class="' + theme.getClass('widgetContent') + '">' + 12523 (this.dayGrid ? 12524 '<div class="fc-day-grid"></div>' + 12525 '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '"></hr>' : 12526 '') + 12527 '</td>' + 12528 '</tr>' + 12529 '</tbody>' + 12530 '</table>'; 12531 }; 12532 // Generates an HTML attribute string for setting the width of the axis, if it is known 12533 AgendaView.prototype.axisStyleAttr = function () { 12534 if (this.axisWidth != null) { 12535 return 'style="width:' + this.axisWidth + 'px"'; 12536 } 12537 return ''; 12538 }; 12539 /* Now Indicator 12540 ------------------------------------------------------------------------------------------------------------------*/ 12541 AgendaView.prototype.getNowIndicatorUnit = function () { 12542 return this.timeGrid.getNowIndicatorUnit(); 12543 }; 12544 /* Dimensions 12545 ------------------------------------------------------------------------------------------------------------------*/ 12546 // Adjusts the vertical dimensions of the view to the specified values 12547 AgendaView.prototype.updateSize = function (totalHeight, isAuto, isResize) { 12548 var eventLimit; 12549 var scrollerHeight; 12550 var scrollbarWidths; 12551 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize); 12552 // make all axis cells line up, and record the width so newly created axis cells will have it 12553 this.axisWidth = util_1.matchCellWidths(this.el.find('.fc-axis')); 12554 // hack to give the view some height prior to timeGrid's columns being rendered 12555 // TODO: separate setting height from scroller VS timeGrid. 12556 if (!this.timeGrid.colEls) { 12557 if (!isAuto) { 12558 scrollerHeight = this.computeScrollerHeight(totalHeight); 12559 this.scroller.setHeight(scrollerHeight); 12560 } 12561 return; 12562 } 12563 // set of fake row elements that must compensate when scroller has scrollbars 12564 var noScrollRowEls = this.el.find('.fc-row:not(.fc-scroller *)'); 12565 // reset all dimensions back to the original state 12566 this.timeGrid.bottomRuleEl.hide(); // .show() will be called later if this <hr> is necessary 12567 this.scroller.clear(); // sets height to 'auto' and clears overflow 12568 util_1.uncompensateScroll(noScrollRowEls); 12569 // limit number of events in the all-day area 12570 if (this.dayGrid) { 12571 this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed 12572 eventLimit = this.opt('eventLimit'); 12573 if (eventLimit && typeof eventLimit !== 'number') { 12574 eventLimit = AGENDA_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number 12575 } 12576 if (eventLimit) { 12577 this.dayGrid.limitRows(eventLimit); 12578 } 12579 } 12580 if (!isAuto) { // should we force dimensions of the scroll container? 12581 scrollerHeight = this.computeScrollerHeight(totalHeight); 12582 this.scroller.setHeight(scrollerHeight); 12583 scrollbarWidths = this.scroller.getScrollbarWidths(); 12584 if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars? 12585 // make the all-day and header rows lines up 12586 util_1.compensateScroll(noScrollRowEls, scrollbarWidths); 12587 // the scrollbar compensation might have changed text flow, which might affect height, so recalculate 12588 // and reapply the desired height to the scroller. 12589 scrollerHeight = this.computeScrollerHeight(totalHeight); 12590 this.scroller.setHeight(scrollerHeight); 12591 } 12592 // guarantees the same scrollbar widths 12593 this.scroller.lockOverflow(scrollbarWidths); 12594 // if there's any space below the slats, show the horizontal rule. 12595 // this won't cause any new overflow, because lockOverflow already called. 12596 if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) { 12597 this.timeGrid.bottomRuleEl.show(); 12598 } 12599 } 12600 }; 12601 // given a desired total height of the view, returns what the height of the scroller should be 12602 AgendaView.prototype.computeScrollerHeight = function (totalHeight) { 12603 return totalHeight - 12604 util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller 12605 }; 12606 /* Scroll 12607 ------------------------------------------------------------------------------------------------------------------*/ 12608 // Computes the initial pre-configured scroll state prior to allowing the user to change it 12609 AgendaView.prototype.computeInitialDateScroll = function () { 12610 var scrollTime = moment.duration(this.opt('scrollTime')); 12611 var top = this.timeGrid.computeTimeTop(scrollTime); 12612 // zoom can give weird floating-point values. rather scroll a little bit further 12613 top = Math.ceil(top); 12614 if (top) { 12615 top++; // to overcome top border that slots beyond the first have. looks better 12616 } 12617 return { top: top }; 12618 }; 12619 AgendaView.prototype.queryDateScroll = function () { 12620 return { top: this.scroller.getScrollTop() }; 12621 }; 12622 AgendaView.prototype.applyDateScroll = function (scroll) { 12623 if (scroll.top !== undefined) { 12624 this.scroller.setScrollTop(scroll.top); 12625 } 12626 }; 12627 /* Hit Areas 12628 ------------------------------------------------------------------------------------------------------------------*/ 12629 // forward all hit-related method calls to the grids (dayGrid might not be defined) 12630 AgendaView.prototype.getHitFootprint = function (hit) { 12631 // TODO: hit.component is set as a hack to identify where the hit came from 12632 return hit.component.getHitFootprint(hit); 12633 }; 12634 AgendaView.prototype.getHitEl = function (hit) { 12635 // TODO: hit.component is set as a hack to identify where the hit came from 12636 return hit.component.getHitEl(hit); 12637 }; 12638 /* Event Rendering 12639 ------------------------------------------------------------------------------------------------------------------*/ 12640 AgendaView.prototype.executeEventRender = function (eventsPayload) { 12641 var dayEventsPayload = {}; 12642 var timedEventsPayload = {}; 12643 var id; 12644 var eventInstanceGroup; 12645 // separate the events into all-day and timed 12646 for (id in eventsPayload) { 12647 eventInstanceGroup = eventsPayload[id]; 12648 if (eventInstanceGroup.getEventDef().isAllDay()) { 12649 dayEventsPayload[id] = eventInstanceGroup; 12650 } 12651 else { 12652 timedEventsPayload[id] = eventInstanceGroup; 12653 } 12654 } 12655 this.timeGrid.executeEventRender(timedEventsPayload); 12656 if (this.dayGrid) { 12657 this.dayGrid.executeEventRender(dayEventsPayload); 12658 } 12659 }; 12660 /* Dragging/Resizing Routing 12661 ------------------------------------------------------------------------------------------------------------------*/ 12662 // A returned value of `true` signals that a mock "helper" event has been rendered. 12663 AgendaView.prototype.renderDrag = function (eventFootprints, seg, isTouch) { 12664 var groups = groupEventFootprintsByAllDay(eventFootprints); 12665 var renderedHelper = false; 12666 renderedHelper = this.timeGrid.renderDrag(groups.timed, seg, isTouch); 12667 if (this.dayGrid) { 12668 renderedHelper = this.dayGrid.renderDrag(groups.allDay, seg, isTouch) || renderedHelper; 12669 } 12670 return renderedHelper; 12671 }; 12672 AgendaView.prototype.renderEventResize = function (eventFootprints, seg, isTouch) { 12673 var groups = groupEventFootprintsByAllDay(eventFootprints); 12674 this.timeGrid.renderEventResize(groups.timed, seg, isTouch); 12675 if (this.dayGrid) { 12676 this.dayGrid.renderEventResize(groups.allDay, seg, isTouch); 12677 } 12678 }; 12679 /* Selection 12680 ------------------------------------------------------------------------------------------------------------------*/ 12681 // Renders a visual indication of a selection 12682 AgendaView.prototype.renderSelectionFootprint = function (componentFootprint) { 12683 if (!componentFootprint.isAllDay) { 12684 this.timeGrid.renderSelectionFootprint(componentFootprint); 12685 } 12686 else if (this.dayGrid) { 12687 this.dayGrid.renderSelectionFootprint(componentFootprint); 12688 } 12689 }; 12690 return AgendaView; 12691}(View_1.default)); 12692exports.default = AgendaView; 12693AgendaView.prototype.timeGridClass = TimeGrid_1.default; 12694AgendaView.prototype.dayGridClass = DayGrid_1.default; 12695// Will customize the rendering behavior of the AgendaView's timeGrid 12696agendaTimeGridMethods = { 12697 // Generates the HTML that will go before the day-of week header cells 12698 renderHeadIntroHtml: function () { 12699 var view = this.view; 12700 var calendar = view.calendar; 12701 var weekStart = calendar.msToUtcMoment(this.dateProfile.renderUnzonedRange.startMs, true); 12702 var weekText; 12703 if (this.opt('weekNumbers')) { 12704 weekText = weekStart.format(this.opt('smallWeekFormat')); 12705 return '' + 12706 '<th class="fc-axis fc-week-number ' + calendar.theme.getClass('widgetHeader') + '" ' + view.axisStyleAttr() + '>' + 12707 view.buildGotoAnchorHtml(// aside from link, important for matchCellWidths 12708 { date: weekStart, type: 'week', forceOff: this.colCnt > 1 }, util_1.htmlEscape(weekText) // inner HTML 12709 ) + 12710 '</th>'; 12711 } 12712 else { 12713 return '<th class="fc-axis ' + calendar.theme.getClass('widgetHeader') + '" ' + view.axisStyleAttr() + '></th>'; 12714 } 12715 }, 12716 // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column. 12717 renderBgIntroHtml: function () { 12718 var view = this.view; 12719 return '<td class="fc-axis ' + view.calendar.theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '></td>'; 12720 }, 12721 // Generates the HTML that goes before all other types of cells. 12722 // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid. 12723 renderIntroHtml: function () { 12724 var view = this.view; 12725 return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>'; 12726 } 12727}; 12728// Will customize the rendering behavior of the AgendaView's dayGrid 12729agendaDayGridMethods = { 12730 // Generates the HTML that goes before the all-day cells 12731 renderBgIntroHtml: function () { 12732 var view = this.view; 12733 return '' + 12734 '<td class="fc-axis ' + view.calendar.theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '>' + 12735 '<span>' + // needed for matchCellWidths 12736 view.getAllDayHtml() + 12737 '</span>' + 12738 '</td>'; 12739 }, 12740 // Generates the HTML that goes before all other types of cells. 12741 // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid. 12742 renderIntroHtml: function () { 12743 var view = this.view; 12744 return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>'; 12745 } 12746}; 12747function groupEventFootprintsByAllDay(eventFootprints) { 12748 var allDay = []; 12749 var timed = []; 12750 var i; 12751 for (i = 0; i < eventFootprints.length; i++) { 12752 if (eventFootprints[i].componentFootprint.isAllDay) { 12753 allDay.push(eventFootprints[i]); 12754 } 12755 else { 12756 timed.push(eventFootprints[i]); 12757 } 12758 } 12759 return { allDay: allDay, timed: timed }; 12760} 12761 12762 12763/***/ }), 12764/* 239 */ 12765/***/ (function(module, exports, __webpack_require__) { 12766 12767Object.defineProperty(exports, "__esModule", { value: true }); 12768var tslib_1 = __webpack_require__(2); 12769var $ = __webpack_require__(3); 12770var moment = __webpack_require__(0); 12771var util_1 = __webpack_require__(4); 12772var InteractiveDateComponent_1 = __webpack_require__(42); 12773var BusinessHourRenderer_1 = __webpack_require__(61); 12774var StandardInteractionsMixin_1 = __webpack_require__(65); 12775var DayTableMixin_1 = __webpack_require__(60); 12776var CoordCache_1 = __webpack_require__(58); 12777var UnzonedRange_1 = __webpack_require__(5); 12778var ComponentFootprint_1 = __webpack_require__(12); 12779var TimeGridEventRenderer_1 = __webpack_require__(240); 12780var TimeGridHelperRenderer_1 = __webpack_require__(241); 12781var TimeGridFillRenderer_1 = __webpack_require__(242); 12782/* A component that renders one or more columns of vertical time slots 12783----------------------------------------------------------------------------------------------------------------------*/ 12784// We mixin DayTable, even though there is only a single row of days 12785// potential nice values for the slot-duration and interval-duration 12786// from largest to smallest 12787var AGENDA_STOCK_SUB_DURATIONS = [ 12788 { hours: 1 }, 12789 { minutes: 30 }, 12790 { minutes: 15 }, 12791 { seconds: 30 }, 12792 { seconds: 15 } 12793]; 12794var TimeGrid = /** @class */ (function (_super) { 12795 tslib_1.__extends(TimeGrid, _super); 12796 function TimeGrid(view) { 12797 var _this = _super.call(this, view) || this; 12798 _this.processOptions(); 12799 return _this; 12800 } 12801 // Slices up the given span (unzoned start/end with other misc data) into an array of segments 12802 TimeGrid.prototype.componentFootprintToSegs = function (componentFootprint) { 12803 var segs = this.sliceRangeByTimes(componentFootprint.unzonedRange); 12804 var i; 12805 for (i = 0; i < segs.length; i++) { 12806 if (this.isRTL) { 12807 segs[i].col = this.daysPerRow - 1 - segs[i].dayIndex; 12808 } 12809 else { 12810 segs[i].col = segs[i].dayIndex; 12811 } 12812 } 12813 return segs; 12814 }; 12815 /* Date Handling 12816 ------------------------------------------------------------------------------------------------------------------*/ 12817 TimeGrid.prototype.sliceRangeByTimes = function (unzonedRange) { 12818 var segs = []; 12819 var segRange; 12820 var dayIndex; 12821 for (dayIndex = 0; dayIndex < this.daysPerRow; dayIndex++) { 12822 segRange = unzonedRange.intersect(this.dayRanges[dayIndex]); 12823 if (segRange) { 12824 segs.push({ 12825 startMs: segRange.startMs, 12826 endMs: segRange.endMs, 12827 isStart: segRange.isStart, 12828 isEnd: segRange.isEnd, 12829 dayIndex: dayIndex 12830 }); 12831 } 12832 } 12833 return segs; 12834 }; 12835 /* Options 12836 ------------------------------------------------------------------------------------------------------------------*/ 12837 // Parses various options into properties of this object 12838 TimeGrid.prototype.processOptions = function () { 12839 var slotDuration = this.opt('slotDuration'); 12840 var snapDuration = this.opt('snapDuration'); 12841 var input; 12842 slotDuration = moment.duration(slotDuration); 12843 snapDuration = snapDuration ? moment.duration(snapDuration) : slotDuration; 12844 this.slotDuration = slotDuration; 12845 this.snapDuration = snapDuration; 12846 this.snapsPerSlot = slotDuration / snapDuration; // TODO: ensure an integer multiple? 12847 // might be an array value (for TimelineView). 12848 // if so, getting the most granular entry (the last one probably). 12849 input = this.opt('slotLabelFormat'); 12850 if ($.isArray(input)) { 12851 input = input[input.length - 1]; 12852 } 12853 this.labelFormat = input || 12854 this.opt('smallTimeFormat'); // the computed default 12855 input = this.opt('slotLabelInterval'); 12856 this.labelInterval = input ? 12857 moment.duration(input) : 12858 this.computeLabelInterval(slotDuration); 12859 }; 12860 // Computes an automatic value for slotLabelInterval 12861 TimeGrid.prototype.computeLabelInterval = function (slotDuration) { 12862 var i; 12863 var labelInterval; 12864 var slotsPerLabel; 12865 // find the smallest stock label interval that results in more than one slots-per-label 12866 for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) { 12867 labelInterval = moment.duration(AGENDA_STOCK_SUB_DURATIONS[i]); 12868 slotsPerLabel = util_1.divideDurationByDuration(labelInterval, slotDuration); 12869 if (util_1.isInt(slotsPerLabel) && slotsPerLabel > 1) { 12870 return labelInterval; 12871 } 12872 } 12873 return moment.duration(slotDuration); // fall back. clone 12874 }; 12875 /* Date Rendering 12876 ------------------------------------------------------------------------------------------------------------------*/ 12877 TimeGrid.prototype.renderDates = function (dateProfile) { 12878 this.dateProfile = dateProfile; 12879 this.updateDayTable(); 12880 this.renderSlats(); 12881 this.renderColumns(); 12882 }; 12883 TimeGrid.prototype.unrenderDates = function () { 12884 // this.unrenderSlats(); // don't need this because repeated .html() calls clear 12885 this.unrenderColumns(); 12886 }; 12887 TimeGrid.prototype.renderSkeleton = function () { 12888 var theme = this.view.calendar.theme; 12889 this.el.html('<div class="fc-bg"></div>' + 12890 '<div class="fc-slats"></div>' + 12891 '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '" style="display:none"></hr>'); 12892 this.bottomRuleEl = this.el.find('hr'); 12893 }; 12894 TimeGrid.prototype.renderSlats = function () { 12895 var theme = this.view.calendar.theme; 12896 this.slatContainerEl = this.el.find('> .fc-slats') 12897 .html(// avoids needing ::unrenderSlats() 12898 '<table class="' + theme.getClass('tableGrid') + '">' + 12899 this.renderSlatRowHtml() + 12900 '</table>'); 12901 this.slatEls = this.slatContainerEl.find('tr'); 12902 this.slatCoordCache = new CoordCache_1.default({ 12903 els: this.slatEls, 12904 isVertical: true 12905 }); 12906 }; 12907 // Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL. 12908 TimeGrid.prototype.renderSlatRowHtml = function () { 12909 var view = this.view; 12910 var calendar = view.calendar; 12911 var theme = calendar.theme; 12912 var isRTL = this.isRTL; 12913 var dateProfile = this.dateProfile; 12914 var html = ''; 12915 var slotTime = moment.duration(+dateProfile.minTime); // wish there was .clone() for durations 12916 var slotIterator = moment.duration(0); 12917 var slotDate; // will be on the view's first day, but we only care about its time 12918 var isLabeled; 12919 var axisHtml; 12920 // Calculate the time for each slot 12921 while (slotTime < dateProfile.maxTime) { 12922 slotDate = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.startMs).time(slotTime); 12923 isLabeled = util_1.isInt(util_1.divideDurationByDuration(slotIterator, this.labelInterval)); 12924 axisHtml = 12925 '<td class="fc-axis fc-time ' + theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '>' + 12926 (isLabeled ? 12927 '<span>' + // for matchCellWidths 12928 util_1.htmlEscape(slotDate.format(this.labelFormat)) + 12929 '</span>' : 12930 '') + 12931 '</td>'; 12932 html += 12933 '<tr data-time="' + slotDate.format('HH:mm:ss') + '"' + 12934 (isLabeled ? '' : ' class="fc-minor"') + 12935 '>' + 12936 (!isRTL ? axisHtml : '') + 12937 '<td class="' + theme.getClass('widgetContent') + '"></td>' + 12938 (isRTL ? axisHtml : '') + 12939 '</tr>'; 12940 slotTime.add(this.slotDuration); 12941 slotIterator.add(this.slotDuration); 12942 } 12943 return html; 12944 }; 12945 TimeGrid.prototype.renderColumns = function () { 12946 var dateProfile = this.dateProfile; 12947 var theme = this.view.calendar.theme; 12948 this.dayRanges = this.dayDates.map(function (dayDate) { 12949 return new UnzonedRange_1.default(dayDate.clone().add(dateProfile.minTime), dayDate.clone().add(dateProfile.maxTime)); 12950 }); 12951 if (this.headContainerEl) { 12952 this.headContainerEl.html(this.renderHeadHtml()); 12953 } 12954 this.el.find('> .fc-bg').html('<table class="' + theme.getClass('tableGrid') + '">' + 12955 this.renderBgTrHtml(0) + // row=0 12956 '</table>'); 12957 this.colEls = this.el.find('.fc-day, .fc-disabled-day'); 12958 this.colCoordCache = new CoordCache_1.default({ 12959 els: this.colEls, 12960 isHorizontal: true 12961 }); 12962 this.renderContentSkeleton(); 12963 }; 12964 TimeGrid.prototype.unrenderColumns = function () { 12965 this.unrenderContentSkeleton(); 12966 }; 12967 /* Content Skeleton 12968 ------------------------------------------------------------------------------------------------------------------*/ 12969 // Renders the DOM that the view's content will live in 12970 TimeGrid.prototype.renderContentSkeleton = function () { 12971 var cellHtml = ''; 12972 var i; 12973 var skeletonEl; 12974 for (i = 0; i < this.colCnt; i++) { 12975 cellHtml += 12976 '<td>' + 12977 '<div class="fc-content-col">' + 12978 '<div class="fc-event-container fc-helper-container"></div>' + 12979 '<div class="fc-event-container"></div>' + 12980 '<div class="fc-highlight-container"></div>' + 12981 '<div class="fc-bgevent-container"></div>' + 12982 '<div class="fc-business-container"></div>' + 12983 '</div>' + 12984 '</td>'; 12985 } 12986 skeletonEl = this.contentSkeletonEl = $('<div class="fc-content-skeleton">' + 12987 '<table>' + 12988 '<tr>' + cellHtml + '</tr>' + 12989 '</table>' + 12990 '</div>'); 12991 this.colContainerEls = skeletonEl.find('.fc-content-col'); 12992 this.helperContainerEls = skeletonEl.find('.fc-helper-container'); 12993 this.fgContainerEls = skeletonEl.find('.fc-event-container:not(.fc-helper-container)'); 12994 this.bgContainerEls = skeletonEl.find('.fc-bgevent-container'); 12995 this.highlightContainerEls = skeletonEl.find('.fc-highlight-container'); 12996 this.businessContainerEls = skeletonEl.find('.fc-business-container'); 12997 this.bookendCells(skeletonEl.find('tr')); // TODO: do this on string level 12998 this.el.append(skeletonEl); 12999 }; 13000 TimeGrid.prototype.unrenderContentSkeleton = function () { 13001 if (this.contentSkeletonEl) { // defensive :( 13002 this.contentSkeletonEl.remove(); 13003 this.contentSkeletonEl = null; 13004 this.colContainerEls = null; 13005 this.helperContainerEls = null; 13006 this.fgContainerEls = null; 13007 this.bgContainerEls = null; 13008 this.highlightContainerEls = null; 13009 this.businessContainerEls = null; 13010 } 13011 }; 13012 // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col 13013 TimeGrid.prototype.groupSegsByCol = function (segs) { 13014 var segsByCol = []; 13015 var i; 13016 for (i = 0; i < this.colCnt; i++) { 13017 segsByCol.push([]); 13018 } 13019 for (i = 0; i < segs.length; i++) { 13020 segsByCol[segs[i].col].push(segs[i]); 13021 } 13022 return segsByCol; 13023 }; 13024 // Given segments grouped by column, insert the segments' elements into a parallel array of container 13025 // elements, each living within a column. 13026 TimeGrid.prototype.attachSegsByCol = function (segsByCol, containerEls) { 13027 var col; 13028 var segs; 13029 var i; 13030 for (col = 0; col < this.colCnt; col++) { // iterate each column grouping 13031 segs = segsByCol[col]; 13032 for (i = 0; i < segs.length; i++) { 13033 containerEls.eq(col).append(segs[i].el); 13034 } 13035 } 13036 }; 13037 /* Now Indicator 13038 ------------------------------------------------------------------------------------------------------------------*/ 13039 TimeGrid.prototype.getNowIndicatorUnit = function () { 13040 return 'minute'; // will refresh on the minute 13041 }; 13042 TimeGrid.prototype.renderNowIndicator = function (date) { 13043 // HACK: if date columns not ready for some reason (scheduler) 13044 if (!this.colContainerEls) { 13045 return; 13046 } 13047 // seg system might be overkill, but it handles scenario where line needs to be rendered 13048 // more than once because of columns with the same date (resources columns for example) 13049 var segs = this.componentFootprintToSegs(new ComponentFootprint_1.default(new UnzonedRange_1.default(date, date.valueOf() + 1), // protect against null range 13050 false // all-day 13051 )); 13052 var top = this.computeDateTop(date, date); 13053 var nodes = []; 13054 var i; 13055 // render lines within the columns 13056 for (i = 0; i < segs.length; i++) { 13057 nodes.push($('<div class="fc-now-indicator fc-now-indicator-line"></div>') 13058 .css('top', top) 13059 .appendTo(this.colContainerEls.eq(segs[i].col))[0]); 13060 } 13061 // render an arrow over the axis 13062 if (segs.length > 0) { // is the current time in view? 13063 nodes.push($('<div class="fc-now-indicator fc-now-indicator-arrow"></div>') 13064 .css('top', top) 13065 .appendTo(this.el.find('.fc-content-skeleton'))[0]); 13066 } 13067 this.nowIndicatorEls = $(nodes); 13068 }; 13069 TimeGrid.prototype.unrenderNowIndicator = function () { 13070 if (this.nowIndicatorEls) { 13071 this.nowIndicatorEls.remove(); 13072 this.nowIndicatorEls = null; 13073 } 13074 }; 13075 /* Coordinates 13076 ------------------------------------------------------------------------------------------------------------------*/ 13077 TimeGrid.prototype.updateSize = function (totalHeight, isAuto, isResize) { 13078 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize); 13079 this.slatCoordCache.build(); 13080 if (isResize) { 13081 this.updateSegVerticals([].concat(this.eventRenderer.getSegs(), this.businessSegs || [])); 13082 } 13083 }; 13084 TimeGrid.prototype.getTotalSlatHeight = function () { 13085 return this.slatContainerEl.outerHeight(); 13086 }; 13087 // Computes the top coordinate, relative to the bounds of the grid, of the given date. 13088 // `ms` can be a millisecond UTC time OR a UTC moment. 13089 // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight. 13090 TimeGrid.prototype.computeDateTop = function (ms, startOfDayDate) { 13091 return this.computeTimeTop(moment.duration(ms - startOfDayDate.clone().stripTime())); 13092 }; 13093 // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration). 13094 TimeGrid.prototype.computeTimeTop = function (time) { 13095 var len = this.slatEls.length; 13096 var dateProfile = this.dateProfile; 13097 var slatCoverage = (time - dateProfile.minTime) / this.slotDuration; // floating-point value of # of slots covered 13098 var slatIndex; 13099 var slatRemainder; 13100 // compute a floating-point number for how many slats should be progressed through. 13101 // from 0 to number of slats (inclusive) 13102 // constrained because minTime/maxTime might be customized. 13103 slatCoverage = Math.max(0, slatCoverage); 13104 slatCoverage = Math.min(len, slatCoverage); 13105 // an integer index of the furthest whole slat 13106 // from 0 to number slats (*exclusive*, so len-1) 13107 slatIndex = Math.floor(slatCoverage); 13108 slatIndex = Math.min(slatIndex, len - 1); 13109 // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition. 13110 // could be 1.0 if slatCoverage is covering *all* the slots 13111 slatRemainder = slatCoverage - slatIndex; 13112 return this.slatCoordCache.getTopPosition(slatIndex) + 13113 this.slatCoordCache.getHeight(slatIndex) * slatRemainder; 13114 }; 13115 // Refreshes the CSS top/bottom coordinates for each segment element. 13116 // Works when called after initial render, after a window resize/zoom for example. 13117 TimeGrid.prototype.updateSegVerticals = function (segs) { 13118 this.computeSegVerticals(segs); 13119 this.assignSegVerticals(segs); 13120 }; 13121 // For each segment in an array, computes and assigns its top and bottom properties 13122 TimeGrid.prototype.computeSegVerticals = function (segs) { 13123 var eventMinHeight = this.opt('agendaEventMinHeight'); 13124 var i; 13125 var seg; 13126 var dayDate; 13127 for (i = 0; i < segs.length; i++) { 13128 seg = segs[i]; 13129 dayDate = this.dayDates[seg.dayIndex]; 13130 seg.top = this.computeDateTop(seg.startMs, dayDate); 13131 seg.bottom = Math.max(seg.top + eventMinHeight, this.computeDateTop(seg.endMs, dayDate)); 13132 } 13133 }; 13134 // Given segments that already have their top/bottom properties computed, applies those values to 13135 // the segments' elements. 13136 TimeGrid.prototype.assignSegVerticals = function (segs) { 13137 var i; 13138 var seg; 13139 for (i = 0; i < segs.length; i++) { 13140 seg = segs[i]; 13141 seg.el.css(this.generateSegVerticalCss(seg)); 13142 } 13143 }; 13144 // Generates an object with CSS properties for the top/bottom coordinates of a segment element 13145 TimeGrid.prototype.generateSegVerticalCss = function (seg) { 13146 return { 13147 top: seg.top, 13148 bottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container 13149 }; 13150 }; 13151 /* Hit System 13152 ------------------------------------------------------------------------------------------------------------------*/ 13153 TimeGrid.prototype.prepareHits = function () { 13154 this.colCoordCache.build(); 13155 this.slatCoordCache.build(); 13156 }; 13157 TimeGrid.prototype.releaseHits = function () { 13158 this.colCoordCache.clear(); 13159 // NOTE: don't clear slatCoordCache because we rely on it for computeTimeTop 13160 }; 13161 TimeGrid.prototype.queryHit = function (leftOffset, topOffset) { 13162 var snapsPerSlot = this.snapsPerSlot; 13163 var colCoordCache = this.colCoordCache; 13164 var slatCoordCache = this.slatCoordCache; 13165 if (colCoordCache.isLeftInBounds(leftOffset) && slatCoordCache.isTopInBounds(topOffset)) { 13166 var colIndex = colCoordCache.getHorizontalIndex(leftOffset); 13167 var slatIndex = slatCoordCache.getVerticalIndex(topOffset); 13168 if (colIndex != null && slatIndex != null) { 13169 var slatTop = slatCoordCache.getTopOffset(slatIndex); 13170 var slatHeight = slatCoordCache.getHeight(slatIndex); 13171 var partial = (topOffset - slatTop) / slatHeight; // floating point number between 0 and 1 13172 var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat 13173 var snapIndex = slatIndex * snapsPerSlot + localSnapIndex; 13174 var snapTop = slatTop + (localSnapIndex / snapsPerSlot) * slatHeight; 13175 var snapBottom = slatTop + ((localSnapIndex + 1) / snapsPerSlot) * slatHeight; 13176 return { 13177 col: colIndex, 13178 snap: snapIndex, 13179 component: this, 13180 left: colCoordCache.getLeftOffset(colIndex), 13181 right: colCoordCache.getRightOffset(colIndex), 13182 top: snapTop, 13183 bottom: snapBottom 13184 }; 13185 } 13186 } 13187 }; 13188 TimeGrid.prototype.getHitFootprint = function (hit) { 13189 var start = this.getCellDate(0, hit.col); // row=0 13190 var time = this.computeSnapTime(hit.snap); // pass in the snap-index 13191 var end; 13192 start.time(time); 13193 end = start.clone().add(this.snapDuration); 13194 return new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), false // all-day? 13195 ); 13196 }; 13197 // Given a row number of the grid, representing a "snap", returns a time (Duration) from its start-of-day 13198 TimeGrid.prototype.computeSnapTime = function (snapIndex) { 13199 return moment.duration(this.dateProfile.minTime + this.snapDuration * snapIndex); 13200 }; 13201 TimeGrid.prototype.getHitEl = function (hit) { 13202 return this.colEls.eq(hit.col); 13203 }; 13204 /* Event Drag Visualization 13205 ------------------------------------------------------------------------------------------------------------------*/ 13206 // Renders a visual indication of an event being dragged over the specified date(s). 13207 // A returned value of `true` signals that a mock "helper" event has been rendered. 13208 TimeGrid.prototype.renderDrag = function (eventFootprints, seg, isTouch) { 13209 var i; 13210 if (seg) { // if there is event information for this drag, render a helper event 13211 if (eventFootprints.length) { 13212 this.helperRenderer.renderEventDraggingFootprints(eventFootprints, seg, isTouch); 13213 // signal that a helper has been rendered 13214 return true; 13215 } 13216 } 13217 else { // otherwise, just render a highlight 13218 for (i = 0; i < eventFootprints.length; i++) { 13219 this.renderHighlight(eventFootprints[i].componentFootprint); 13220 } 13221 } 13222 }; 13223 // Unrenders any visual indication of an event being dragged 13224 TimeGrid.prototype.unrenderDrag = function () { 13225 this.unrenderHighlight(); 13226 this.helperRenderer.unrender(); 13227 }; 13228 /* Event Resize Visualization 13229 ------------------------------------------------------------------------------------------------------------------*/ 13230 // Renders a visual indication of an event being resized 13231 TimeGrid.prototype.renderEventResize = function (eventFootprints, seg, isTouch) { 13232 this.helperRenderer.renderEventResizingFootprints(eventFootprints, seg, isTouch); 13233 }; 13234 // Unrenders any visual indication of an event being resized 13235 TimeGrid.prototype.unrenderEventResize = function () { 13236 this.helperRenderer.unrender(); 13237 }; 13238 /* Selection 13239 ------------------------------------------------------------------------------------------------------------------*/ 13240 // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight. 13241 TimeGrid.prototype.renderSelectionFootprint = function (componentFootprint) { 13242 if (this.opt('selectHelper')) { // this setting signals that a mock helper event should be rendered 13243 this.helperRenderer.renderComponentFootprint(componentFootprint); 13244 } 13245 else { 13246 this.renderHighlight(componentFootprint); 13247 } 13248 }; 13249 // Unrenders any visual indication of a selection 13250 TimeGrid.prototype.unrenderSelection = function () { 13251 this.helperRenderer.unrender(); 13252 this.unrenderHighlight(); 13253 }; 13254 return TimeGrid; 13255}(InteractiveDateComponent_1.default)); 13256exports.default = TimeGrid; 13257TimeGrid.prototype.eventRendererClass = TimeGridEventRenderer_1.default; 13258TimeGrid.prototype.businessHourRendererClass = BusinessHourRenderer_1.default; 13259TimeGrid.prototype.helperRendererClass = TimeGridHelperRenderer_1.default; 13260TimeGrid.prototype.fillRendererClass = TimeGridFillRenderer_1.default; 13261StandardInteractionsMixin_1.default.mixInto(TimeGrid); 13262DayTableMixin_1.default.mixInto(TimeGrid); 13263 13264 13265/***/ }), 13266/* 240 */ 13267/***/ (function(module, exports, __webpack_require__) { 13268 13269Object.defineProperty(exports, "__esModule", { value: true }); 13270var tslib_1 = __webpack_require__(2); 13271var util_1 = __webpack_require__(4); 13272var EventRenderer_1 = __webpack_require__(44); 13273/* 13274Only handles foreground segs. 13275Does not own rendering. Use for low-level util methods by TimeGrid. 13276*/ 13277var TimeGridEventRenderer = /** @class */ (function (_super) { 13278 tslib_1.__extends(TimeGridEventRenderer, _super); 13279 function TimeGridEventRenderer(timeGrid, fillRenderer) { 13280 var _this = _super.call(this, timeGrid, fillRenderer) || this; 13281 _this.timeGrid = timeGrid; 13282 return _this; 13283 } 13284 TimeGridEventRenderer.prototype.renderFgSegs = function (segs) { 13285 this.renderFgSegsIntoContainers(segs, this.timeGrid.fgContainerEls); 13286 }; 13287 // Given an array of foreground segments, render a DOM element for each, computes position, 13288 // and attaches to the column inner-container elements. 13289 TimeGridEventRenderer.prototype.renderFgSegsIntoContainers = function (segs, containerEls) { 13290 var segsByCol; 13291 var col; 13292 segsByCol = this.timeGrid.groupSegsByCol(segs); 13293 for (col = 0; col < this.timeGrid.colCnt; col++) { 13294 this.updateFgSegCoords(segsByCol[col]); 13295 } 13296 this.timeGrid.attachSegsByCol(segsByCol, containerEls); 13297 }; 13298 TimeGridEventRenderer.prototype.unrenderFgSegs = function () { 13299 if (this.fgSegs) { // hack 13300 this.fgSegs.forEach(function (seg) { 13301 seg.el.remove(); 13302 }); 13303 } 13304 }; 13305 // Computes a default event time formatting string if `timeFormat` is not explicitly defined 13306 TimeGridEventRenderer.prototype.computeEventTimeFormat = function () { 13307 return this.opt('noMeridiemTimeFormat'); // like "6:30" (no AM/PM) 13308 }; 13309 // Computes a default `displayEventEnd` value if one is not expliclty defined 13310 TimeGridEventRenderer.prototype.computeDisplayEventEnd = function () { 13311 return true; 13312 }; 13313 // Renders the HTML for a single event segment's default rendering 13314 TimeGridEventRenderer.prototype.fgSegHtml = function (seg, disableResizing) { 13315 var view = this.view; 13316 var calendar = view.calendar; 13317 var componentFootprint = seg.footprint.componentFootprint; 13318 var isAllDay = componentFootprint.isAllDay; 13319 var eventDef = seg.footprint.eventDef; 13320 var isDraggable = view.isEventDefDraggable(eventDef); 13321 var isResizableFromStart = !disableResizing && seg.isStart && view.isEventDefResizableFromStart(eventDef); 13322 var isResizableFromEnd = !disableResizing && seg.isEnd && view.isEventDefResizableFromEnd(eventDef); 13323 var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd); 13324 var skinCss = util_1.cssToStr(this.getSkinCss(eventDef)); 13325 var timeText; 13326 var fullTimeText; // more verbose time text. for the print stylesheet 13327 var startTimeText; // just the start time text 13328 classes.unshift('fc-time-grid-event', 'fc-v-event'); 13329 // if the event appears to span more than one day... 13330 if (view.isMultiDayRange(componentFootprint.unzonedRange)) { 13331 // Don't display time text on segments that run entirely through a day. 13332 // That would appear as midnight-midnight and would look dumb. 13333 // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am) 13334 if (seg.isStart || seg.isEnd) { 13335 var zonedStart = calendar.msToMoment(seg.startMs); 13336 var zonedEnd = calendar.msToMoment(seg.endMs); 13337 timeText = this._getTimeText(zonedStart, zonedEnd, isAllDay); 13338 fullTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, 'LT'); 13339 startTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, null, false); // displayEnd=false 13340 } 13341 } 13342 else { 13343 // Display the normal time text for the *event's* times 13344 timeText = this.getTimeText(seg.footprint); 13345 fullTimeText = this.getTimeText(seg.footprint, 'LT'); 13346 startTimeText = this.getTimeText(seg.footprint, null, false); // displayEnd=false 13347 } 13348 return '<a class="' + classes.join(' ') + '"' + 13349 (eventDef.url ? 13350 ' href="' + util_1.htmlEscape(eventDef.url) + '"' : 13351 '') + 13352 (skinCss ? 13353 ' style="' + skinCss + '"' : 13354 '') + 13355 '>' + 13356 '<div class="fc-content">' + 13357 (timeText ? 13358 '<div class="fc-time"' + 13359 ' data-start="' + util_1.htmlEscape(startTimeText) + '"' + 13360 ' data-full="' + util_1.htmlEscape(fullTimeText) + '"' + 13361 '>' + 13362 '<span>' + util_1.htmlEscape(timeText) + '</span>' + 13363 '</div>' : 13364 '') + 13365 (eventDef.title ? 13366 '<div class="fc-title">' + 13367 util_1.htmlEscape(eventDef.title) + 13368 '</div>' : 13369 '') + 13370 '</div>' + 13371 '<div class="fc-bg"></div>' + 13372 /* TODO: write CSS for this 13373 (isResizableFromStart ? 13374 '<div class="fc-resizer fc-start-resizer"></div>' : 13375 '' 13376 ) + 13377 */ 13378 (isResizableFromEnd ? 13379 '<div class="fc-resizer fc-end-resizer"></div>' : 13380 '') + 13381 '</a>'; 13382 }; 13383 // Given segments that are assumed to all live in the *same column*, 13384 // compute their verical/horizontal coordinates and assign to their elements. 13385 TimeGridEventRenderer.prototype.updateFgSegCoords = function (segs) { 13386 this.timeGrid.computeSegVerticals(segs); // horizontals relies on this 13387 this.computeFgSegHorizontals(segs); // compute horizontal coordinates, z-index's, and reorder the array 13388 this.timeGrid.assignSegVerticals(segs); 13389 this.assignFgSegHorizontals(segs); 13390 }; 13391 // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each. 13392 // NOTE: Also reorders the given array by date! 13393 TimeGridEventRenderer.prototype.computeFgSegHorizontals = function (segs) { 13394 var levels; 13395 var level0; 13396 var i; 13397 this.sortEventSegs(segs); // order by certain criteria 13398 levels = buildSlotSegLevels(segs); 13399 computeForwardSlotSegs(levels); 13400 if ((level0 = levels[0])) { 13401 for (i = 0; i < level0.length; i++) { 13402 computeSlotSegPressures(level0[i]); 13403 } 13404 for (i = 0; i < level0.length; i++) { 13405 this.computeFgSegForwardBack(level0[i], 0, 0); 13406 } 13407 } 13408 }; 13409 // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range 13410 // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and 13411 // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left. 13412 // 13413 // The segment might be part of a "series", which means consecutive segments with the same pressure 13414 // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of 13415 // segments behind this one in the current series, and `seriesBackwardCoord` is the starting 13416 // coordinate of the first segment in the series. 13417 TimeGridEventRenderer.prototype.computeFgSegForwardBack = function (seg, seriesBackwardPressure, seriesBackwardCoord) { 13418 var forwardSegs = seg.forwardSegs; 13419 var i; 13420 if (seg.forwardCoord === undefined) { // not already computed 13421 if (!forwardSegs.length) { 13422 // if there are no forward segments, this segment should butt up against the edge 13423 seg.forwardCoord = 1; 13424 } 13425 else { 13426 // sort highest pressure first 13427 this.sortForwardSegs(forwardSegs); 13428 // this segment's forwardCoord will be calculated from the backwardCoord of the 13429 // highest-pressure forward segment. 13430 this.computeFgSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord); 13431 seg.forwardCoord = forwardSegs[0].backwardCoord; 13432 } 13433 // calculate the backwardCoord from the forwardCoord. consider the series 13434 seg.backwardCoord = seg.forwardCoord - 13435 (seg.forwardCoord - seriesBackwardCoord) / // available width for series 13436 (seriesBackwardPressure + 1); // # of segments in the series 13437 // use this segment's coordinates to computed the coordinates of the less-pressurized 13438 // forward segments 13439 for (i = 0; i < forwardSegs.length; i++) { 13440 this.computeFgSegForwardBack(forwardSegs[i], 0, seg.forwardCoord); 13441 } 13442 } 13443 }; 13444 TimeGridEventRenderer.prototype.sortForwardSegs = function (forwardSegs) { 13445 forwardSegs.sort(util_1.proxy(this, 'compareForwardSegs')); 13446 }; 13447 // A cmp function for determining which forward segment to rely on more when computing coordinates. 13448 TimeGridEventRenderer.prototype.compareForwardSegs = function (seg1, seg2) { 13449 // put higher-pressure first 13450 return seg2.forwardPressure - seg1.forwardPressure || 13451 // put segments that are closer to initial edge first (and favor ones with no coords yet) 13452 (seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) || 13453 // do normal sorting... 13454 this.compareEventSegs(seg1, seg2); 13455 }; 13456 // Given foreground event segments that have already had their position coordinates computed, 13457 // assigns position-related CSS values to their elements. 13458 TimeGridEventRenderer.prototype.assignFgSegHorizontals = function (segs) { 13459 var i; 13460 var seg; 13461 for (i = 0; i < segs.length; i++) { 13462 seg = segs[i]; 13463 seg.el.css(this.generateFgSegHorizontalCss(seg)); 13464 // if the event is short that the title will be cut off, 13465 // attach a className that condenses the title into the time area. 13466 if (seg.footprint.eventDef.title && seg.bottom - seg.top < 30) { 13467 seg.el.addClass('fc-short'); // TODO: "condensed" is a better name 13468 } 13469 } 13470 }; 13471 // Generates an object with CSS properties/values that should be applied to an event segment element. 13472 // Contains important positioning-related properties that should be applied to any event element, customized or not. 13473 TimeGridEventRenderer.prototype.generateFgSegHorizontalCss = function (seg) { 13474 var shouldOverlap = this.opt('slotEventOverlap'); 13475 var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point 13476 var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point 13477 var props = this.timeGrid.generateSegVerticalCss(seg); // get top/bottom first 13478 var isRTL = this.timeGrid.isRTL; 13479 var left; // amount of space from left edge, a fraction of the total width 13480 var right; // amount of space from right edge, a fraction of the total width 13481 if (shouldOverlap) { 13482 // double the width, but don't go beyond the maximum forward coordinate (1.0) 13483 forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2); 13484 } 13485 if (isRTL) { 13486 left = 1 - forwardCoord; 13487 right = backwardCoord; 13488 } 13489 else { 13490 left = backwardCoord; 13491 right = 1 - forwardCoord; 13492 } 13493 props.zIndex = seg.level + 1; // convert from 0-base to 1-based 13494 props.left = left * 100 + '%'; 13495 props.right = right * 100 + '%'; 13496 if (shouldOverlap && seg.forwardPressure) { 13497 // add padding to the edge so that forward stacked events don't cover the resizer's icon 13498 props[isRTL ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width 13499 } 13500 return props; 13501 }; 13502 return TimeGridEventRenderer; 13503}(EventRenderer_1.default)); 13504exports.default = TimeGridEventRenderer; 13505// Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is 13506// left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date. 13507function buildSlotSegLevels(segs) { 13508 var levels = []; 13509 var i; 13510 var seg; 13511 var j; 13512 for (i = 0; i < segs.length; i++) { 13513 seg = segs[i]; 13514 // go through all the levels and stop on the first level where there are no collisions 13515 for (j = 0; j < levels.length; j++) { 13516 if (!computeSlotSegCollisions(seg, levels[j]).length) { 13517 break; 13518 } 13519 } 13520 seg.level = j; 13521 (levels[j] || (levels[j] = [])).push(seg); 13522 } 13523 return levels; 13524} 13525// For every segment, figure out the other segments that are in subsequent 13526// levels that also occupy the same vertical space. Accumulate in seg.forwardSegs 13527function computeForwardSlotSegs(levels) { 13528 var i; 13529 var level; 13530 var j; 13531 var seg; 13532 var k; 13533 for (i = 0; i < levels.length; i++) { 13534 level = levels[i]; 13535 for (j = 0; j < level.length; j++) { 13536 seg = level[j]; 13537 seg.forwardSegs = []; 13538 for (k = i + 1; k < levels.length; k++) { 13539 computeSlotSegCollisions(seg, levels[k], seg.forwardSegs); 13540 } 13541 } 13542 } 13543} 13544// Figure out which path forward (via seg.forwardSegs) results in the longest path until 13545// the furthest edge is reached. The number of segments in this path will be seg.forwardPressure 13546function computeSlotSegPressures(seg) { 13547 var forwardSegs = seg.forwardSegs; 13548 var forwardPressure = 0; 13549 var i; 13550 var forwardSeg; 13551 if (seg.forwardPressure === undefined) { // not already computed 13552 for (i = 0; i < forwardSegs.length; i++) { 13553 forwardSeg = forwardSegs[i]; 13554 // figure out the child's maximum forward path 13555 computeSlotSegPressures(forwardSeg); 13556 // either use the existing maximum, or use the child's forward pressure 13557 // plus one (for the forwardSeg itself) 13558 forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure); 13559 } 13560 seg.forwardPressure = forwardPressure; 13561 } 13562} 13563// Find all the segments in `otherSegs` that vertically collide with `seg`. 13564// Append into an optionally-supplied `results` array and return. 13565function computeSlotSegCollisions(seg, otherSegs, results) { 13566 if (results === void 0) { results = []; } 13567 for (var i = 0; i < otherSegs.length; i++) { 13568 if (isSlotSegCollision(seg, otherSegs[i])) { 13569 results.push(otherSegs[i]); 13570 } 13571 } 13572 return results; 13573} 13574// Do these segments occupy the same vertical space? 13575function isSlotSegCollision(seg1, seg2) { 13576 return seg1.bottom > seg2.top && seg1.top < seg2.bottom; 13577} 13578 13579 13580/***/ }), 13581/* 241 */ 13582/***/ (function(module, exports, __webpack_require__) { 13583 13584Object.defineProperty(exports, "__esModule", { value: true }); 13585var tslib_1 = __webpack_require__(2); 13586var $ = __webpack_require__(3); 13587var HelperRenderer_1 = __webpack_require__(63); 13588var TimeGridHelperRenderer = /** @class */ (function (_super) { 13589 tslib_1.__extends(TimeGridHelperRenderer, _super); 13590 function TimeGridHelperRenderer() { 13591 return _super !== null && _super.apply(this, arguments) || this; 13592 } 13593 TimeGridHelperRenderer.prototype.renderSegs = function (segs, sourceSeg) { 13594 var helperNodes = []; 13595 var i; 13596 var seg; 13597 var sourceEl; 13598 // TODO: not good to call eventRenderer this way 13599 this.eventRenderer.renderFgSegsIntoContainers(segs, this.component.helperContainerEls); 13600 // Try to make the segment that is in the same row as sourceSeg look the same 13601 for (i = 0; i < segs.length; i++) { 13602 seg = segs[i]; 13603 if (sourceSeg && sourceSeg.col === seg.col) { 13604 sourceEl = sourceSeg.el; 13605 seg.el.css({ 13606 left: sourceEl.css('left'), 13607 right: sourceEl.css('right'), 13608 'margin-left': sourceEl.css('margin-left'), 13609 'margin-right': sourceEl.css('margin-right') 13610 }); 13611 } 13612 helperNodes.push(seg.el[0]); 13613 } 13614 return $(helperNodes); // must return the elements rendered 13615 }; 13616 return TimeGridHelperRenderer; 13617}(HelperRenderer_1.default)); 13618exports.default = TimeGridHelperRenderer; 13619 13620 13621/***/ }), 13622/* 242 */ 13623/***/ (function(module, exports, __webpack_require__) { 13624 13625Object.defineProperty(exports, "__esModule", { value: true }); 13626var tslib_1 = __webpack_require__(2); 13627var FillRenderer_1 = __webpack_require__(62); 13628var TimeGridFillRenderer = /** @class */ (function (_super) { 13629 tslib_1.__extends(TimeGridFillRenderer, _super); 13630 function TimeGridFillRenderer() { 13631 return _super !== null && _super.apply(this, arguments) || this; 13632 } 13633 TimeGridFillRenderer.prototype.attachSegEls = function (type, segs) { 13634 var timeGrid = this.component; 13635 var containerEls; 13636 // TODO: more efficient lookup 13637 if (type === 'bgEvent') { 13638 containerEls = timeGrid.bgContainerEls; 13639 } 13640 else if (type === 'businessHours') { 13641 containerEls = timeGrid.businessContainerEls; 13642 } 13643 else if (type === 'highlight') { 13644 containerEls = timeGrid.highlightContainerEls; 13645 } 13646 timeGrid.updateSegVerticals(segs); 13647 timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls); 13648 return segs.map(function (seg) { 13649 return seg.el[0]; 13650 }); 13651 }; 13652 return TimeGridFillRenderer; 13653}(FillRenderer_1.default)); 13654exports.default = TimeGridFillRenderer; 13655 13656 13657/***/ }), 13658/* 243 */ 13659/***/ (function(module, exports, __webpack_require__) { 13660 13661Object.defineProperty(exports, "__esModule", { value: true }); 13662var tslib_1 = __webpack_require__(2); 13663var $ = __webpack_require__(3); 13664var util_1 = __webpack_require__(4); 13665var EventRenderer_1 = __webpack_require__(44); 13666/* Event-rendering methods for the DayGrid class 13667----------------------------------------------------------------------------------------------------------------------*/ 13668var DayGridEventRenderer = /** @class */ (function (_super) { 13669 tslib_1.__extends(DayGridEventRenderer, _super); 13670 function DayGridEventRenderer(dayGrid, fillRenderer) { 13671 var _this = _super.call(this, dayGrid, fillRenderer) || this; 13672 _this.dayGrid = dayGrid; 13673 return _this; 13674 } 13675 DayGridEventRenderer.prototype.renderBgRanges = function (eventRanges) { 13676 // don't render timed background events 13677 eventRanges = $.grep(eventRanges, function (eventRange) { 13678 return eventRange.eventDef.isAllDay(); 13679 }); 13680 _super.prototype.renderBgRanges.call(this, eventRanges); 13681 }; 13682 // Renders the given foreground event segments onto the grid 13683 DayGridEventRenderer.prototype.renderFgSegs = function (segs) { 13684 var rowStructs = this.rowStructs = this.renderSegRows(segs); 13685 // append to each row's content skeleton 13686 this.dayGrid.rowEls.each(function (i, rowNode) { 13687 $(rowNode).find('.fc-content-skeleton > table').append(rowStructs[i].tbodyEl); 13688 }); 13689 }; 13690 // Unrenders all currently rendered foreground event segments 13691 DayGridEventRenderer.prototype.unrenderFgSegs = function () { 13692 var rowStructs = this.rowStructs || []; 13693 var rowStruct; 13694 while ((rowStruct = rowStructs.pop())) { 13695 rowStruct.tbodyEl.remove(); 13696 } 13697 this.rowStructs = null; 13698 }; 13699 // Uses the given events array to generate <tbody> elements that should be appended to each row's content skeleton. 13700 // Returns an array of rowStruct objects (see the bottom of `renderSegRow`). 13701 // PRECONDITION: each segment shoud already have a rendered and assigned `.el` 13702 DayGridEventRenderer.prototype.renderSegRows = function (segs) { 13703 var rowStructs = []; 13704 var segRows; 13705 var row; 13706 segRows = this.groupSegRows(segs); // group into nested arrays 13707 // iterate each row of segment groupings 13708 for (row = 0; row < segRows.length; row++) { 13709 rowStructs.push(this.renderSegRow(row, segRows[row])); 13710 } 13711 return rowStructs; 13712 }; 13713 // Given a row # and an array of segments all in the same row, render a <tbody> element, a skeleton that contains 13714 // the segments. Returns object with a bunch of internal data about how the render was calculated. 13715 // NOTE: modifies rowSegs 13716 DayGridEventRenderer.prototype.renderSegRow = function (row, rowSegs) { 13717 var colCnt = this.dayGrid.colCnt; 13718 var segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels 13719 var levelCnt = Math.max(1, segLevels.length); // ensure at least one level 13720 var tbody = $('<tbody>'); 13721 var segMatrix = []; // lookup for which segments are rendered into which level+col cells 13722 var cellMatrix = []; // lookup for all <td> elements of the level+col matrix 13723 var loneCellMatrix = []; // lookup for <td> elements that only take up a single column 13724 var i; 13725 var levelSegs; 13726 var col; 13727 var tr; 13728 var j; 13729 var seg; 13730 var td; 13731 // populates empty cells from the current column (`col`) to `endCol` 13732 function emptyCellsUntil(endCol) { 13733 while (col < endCol) { 13734 // try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell 13735 td = (loneCellMatrix[i - 1] || [])[col]; 13736 if (td) { 13737 td.attr('rowspan', parseInt(td.attr('rowspan') || 1, 10) + 1); 13738 } 13739 else { 13740 td = $('<td>'); 13741 tr.append(td); 13742 } 13743 cellMatrix[i][col] = td; 13744 loneCellMatrix[i][col] = td; 13745 col++; 13746 } 13747 } 13748 for (i = 0; i < levelCnt; i++) { // iterate through all levels 13749 levelSegs = segLevels[i]; 13750 col = 0; 13751 tr = $('<tr>'); 13752 segMatrix.push([]); 13753 cellMatrix.push([]); 13754 loneCellMatrix.push([]); 13755 // levelCnt might be 1 even though there are no actual levels. protect against this. 13756 // this single empty row is useful for styling. 13757 if (levelSegs) { 13758 for (j = 0; j < levelSegs.length; j++) { // iterate through segments in level 13759 seg = levelSegs[j]; 13760 emptyCellsUntil(seg.leftCol); 13761 // create a container that occupies or more columns. append the event element. 13762 td = $('<td class="fc-event-container">').append(seg.el); 13763 if (seg.leftCol !== seg.rightCol) { 13764 td.attr('colspan', seg.rightCol - seg.leftCol + 1); 13765 } 13766 else { // a single-column segment 13767 loneCellMatrix[i][col] = td; 13768 } 13769 while (col <= seg.rightCol) { 13770 cellMatrix[i][col] = td; 13771 segMatrix[i][col] = seg; 13772 col++; 13773 } 13774 tr.append(td); 13775 } 13776 } 13777 emptyCellsUntil(colCnt); // finish off the row 13778 this.dayGrid.bookendCells(tr); 13779 tbody.append(tr); 13780 } 13781 return { 13782 row: row, 13783 tbodyEl: tbody, 13784 cellMatrix: cellMatrix, 13785 segMatrix: segMatrix, 13786 segLevels: segLevels, 13787 segs: rowSegs 13788 }; 13789 }; 13790 // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels. 13791 // NOTE: modifies segs 13792 DayGridEventRenderer.prototype.buildSegLevels = function (segs) { 13793 var levels = []; 13794 var i; 13795 var seg; 13796 var j; 13797 // Give preference to elements with certain criteria, so they have 13798 // a chance to be closer to the top. 13799 this.sortEventSegs(segs); 13800 for (i = 0; i < segs.length; i++) { 13801 seg = segs[i]; 13802 // loop through levels, starting with the topmost, until the segment doesn't collide with other segments 13803 for (j = 0; j < levels.length; j++) { 13804 if (!isDaySegCollision(seg, levels[j])) { 13805 break; 13806 } 13807 } 13808 // `j` now holds the desired subrow index 13809 seg.level = j; 13810 // create new level array if needed and append segment 13811 (levels[j] || (levels[j] = [])).push(seg); 13812 } 13813 // order segments left-to-right. very important if calendar is RTL 13814 for (j = 0; j < levels.length; j++) { 13815 levels[j].sort(compareDaySegCols); 13816 } 13817 return levels; 13818 }; 13819 // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row 13820 DayGridEventRenderer.prototype.groupSegRows = function (segs) { 13821 var segRows = []; 13822 var i; 13823 for (i = 0; i < this.dayGrid.rowCnt; i++) { 13824 segRows.push([]); 13825 } 13826 for (i = 0; i < segs.length; i++) { 13827 segRows[segs[i].row].push(segs[i]); 13828 } 13829 return segRows; 13830 }; 13831 // Computes a default event time formatting string if `timeFormat` is not explicitly defined 13832 DayGridEventRenderer.prototype.computeEventTimeFormat = function () { 13833 return this.opt('extraSmallTimeFormat'); // like "6p" or "6:30p" 13834 }; 13835 // Computes a default `displayEventEnd` value if one is not expliclty defined 13836 DayGridEventRenderer.prototype.computeDisplayEventEnd = function () { 13837 return this.dayGrid.colCnt === 1; // we'll likely have space if there's only one day 13838 }; 13839 // Builds the HTML to be used for the default element for an individual segment 13840 DayGridEventRenderer.prototype.fgSegHtml = function (seg, disableResizing) { 13841 var view = this.view; 13842 var eventDef = seg.footprint.eventDef; 13843 var isAllDay = seg.footprint.componentFootprint.isAllDay; 13844 var isDraggable = view.isEventDefDraggable(eventDef); 13845 var isResizableFromStart = !disableResizing && isAllDay && 13846 seg.isStart && view.isEventDefResizableFromStart(eventDef); 13847 var isResizableFromEnd = !disableResizing && isAllDay && 13848 seg.isEnd && view.isEventDefResizableFromEnd(eventDef); 13849 var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd); 13850 var skinCss = util_1.cssToStr(this.getSkinCss(eventDef)); 13851 var timeHtml = ''; 13852 var timeText; 13853 var titleHtml; 13854 classes.unshift('fc-day-grid-event', 'fc-h-event'); 13855 // Only display a timed events time if it is the starting segment 13856 if (seg.isStart) { 13857 timeText = this.getTimeText(seg.footprint); 13858 if (timeText) { 13859 timeHtml = '<span class="fc-time">' + util_1.htmlEscape(timeText) + '</span>'; 13860 } 13861 } 13862 titleHtml = 13863 '<span class="fc-title">' + 13864 (util_1.htmlEscape(eventDef.title || '') || ' ') + // we always want one line of height 13865 '</span>'; 13866 return '<a class="' + classes.join(' ') + '"' + 13867 (eventDef.url ? 13868 ' href="' + util_1.htmlEscape(eventDef.url) + '"' : 13869 '') + 13870 (skinCss ? 13871 ' style="' + skinCss + '"' : 13872 '') + 13873 '>' + 13874 '<div class="fc-content">' + 13875 (this.dayGrid.isRTL ? 13876 titleHtml + ' ' + timeHtml : // put a natural space in between 13877 timeHtml + ' ' + titleHtml // 13878 ) + 13879 '</div>' + 13880 (isResizableFromStart ? 13881 '<div class="fc-resizer fc-start-resizer"></div>' : 13882 '') + 13883 (isResizableFromEnd ? 13884 '<div class="fc-resizer fc-end-resizer"></div>' : 13885 '') + 13886 '</a>'; 13887 }; 13888 return DayGridEventRenderer; 13889}(EventRenderer_1.default)); 13890exports.default = DayGridEventRenderer; 13891// Computes whether two segments' columns collide. They are assumed to be in the same row. 13892function isDaySegCollision(seg, otherSegs) { 13893 var i; 13894 var otherSeg; 13895 for (i = 0; i < otherSegs.length; i++) { 13896 otherSeg = otherSegs[i]; 13897 if (otherSeg.leftCol <= seg.rightCol && 13898 otherSeg.rightCol >= seg.leftCol) { 13899 return true; 13900 } 13901 } 13902 return false; 13903} 13904// A cmp function for determining the leftmost event 13905function compareDaySegCols(a, b) { 13906 return a.leftCol - b.leftCol; 13907} 13908 13909 13910/***/ }), 13911/* 244 */ 13912/***/ (function(module, exports, __webpack_require__) { 13913 13914Object.defineProperty(exports, "__esModule", { value: true }); 13915var tslib_1 = __webpack_require__(2); 13916var $ = __webpack_require__(3); 13917var HelperRenderer_1 = __webpack_require__(63); 13918var DayGridHelperRenderer = /** @class */ (function (_super) { 13919 tslib_1.__extends(DayGridHelperRenderer, _super); 13920 function DayGridHelperRenderer() { 13921 return _super !== null && _super.apply(this, arguments) || this; 13922 } 13923 // Renders a mock "helper" event. `sourceSeg` is the associated internal segment object. It can be null. 13924 DayGridHelperRenderer.prototype.renderSegs = function (segs, sourceSeg) { 13925 var helperNodes = []; 13926 var rowStructs; 13927 // TODO: not good to call eventRenderer this way 13928 rowStructs = this.eventRenderer.renderSegRows(segs); 13929 // inject each new event skeleton into each associated row 13930 this.component.rowEls.each(function (row, rowNode) { 13931 var rowEl = $(rowNode); // the .fc-row 13932 var skeletonEl = $('<div class="fc-helper-skeleton"><table></table></div>'); // will be absolutely positioned 13933 var skeletonTopEl; 13934 var skeletonTop; 13935 // If there is an original segment, match the top position. Otherwise, put it at the row's top level 13936 if (sourceSeg && sourceSeg.row === row) { 13937 skeletonTop = sourceSeg.el.position().top; 13938 } 13939 else { 13940 skeletonTopEl = rowEl.find('.fc-content-skeleton tbody'); 13941 if (!skeletonTopEl.length) { // when no events 13942 skeletonTopEl = rowEl.find('.fc-content-skeleton table'); 13943 } 13944 skeletonTop = skeletonTopEl.position().top; 13945 } 13946 skeletonEl.css('top', skeletonTop) 13947 .find('table') 13948 .append(rowStructs[row].tbodyEl); 13949 rowEl.append(skeletonEl); 13950 helperNodes.push(skeletonEl[0]); 13951 }); 13952 return $(helperNodes); // must return the elements rendered 13953 }; 13954 return DayGridHelperRenderer; 13955}(HelperRenderer_1.default)); 13956exports.default = DayGridHelperRenderer; 13957 13958 13959/***/ }), 13960/* 245 */ 13961/***/ (function(module, exports, __webpack_require__) { 13962 13963Object.defineProperty(exports, "__esModule", { value: true }); 13964var tslib_1 = __webpack_require__(2); 13965var $ = __webpack_require__(3); 13966var FillRenderer_1 = __webpack_require__(62); 13967var DayGridFillRenderer = /** @class */ (function (_super) { 13968 tslib_1.__extends(DayGridFillRenderer, _super); 13969 function DayGridFillRenderer() { 13970 var _this = _super !== null && _super.apply(this, arguments) || this; 13971 _this.fillSegTag = 'td'; // override the default tag name 13972 return _this; 13973 } 13974 DayGridFillRenderer.prototype.attachSegEls = function (type, segs) { 13975 var nodes = []; 13976 var i; 13977 var seg; 13978 var skeletonEl; 13979 for (i = 0; i < segs.length; i++) { 13980 seg = segs[i]; 13981 skeletonEl = this.renderFillRow(type, seg); 13982 this.component.rowEls.eq(seg.row).append(skeletonEl); 13983 nodes.push(skeletonEl[0]); 13984 } 13985 return nodes; 13986 }; 13987 // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered. 13988 DayGridFillRenderer.prototype.renderFillRow = function (type, seg) { 13989 var colCnt = this.component.colCnt; 13990 var startCol = seg.leftCol; 13991 var endCol = seg.rightCol + 1; 13992 var className; 13993 var skeletonEl; 13994 var trEl; 13995 if (type === 'businessHours') { 13996 className = 'bgevent'; 13997 } 13998 else { 13999 className = type.toLowerCase(); 14000 } 14001 skeletonEl = $('<div class="fc-' + className + '-skeleton">' + 14002 '<table><tr></tr></table>' + 14003 '</div>'); 14004 trEl = skeletonEl.find('tr'); 14005 if (startCol > 0) { 14006 trEl.append( 14007 // will create (startCol + 1) td's 14008 new Array(startCol + 1).join('<td></td>')); 14009 } 14010 trEl.append(seg.el.attr('colspan', endCol - startCol)); 14011 if (endCol < colCnt) { 14012 trEl.append( 14013 // will create (colCnt - endCol) td's 14014 new Array(colCnt - endCol + 1).join('<td></td>')); 14015 } 14016 this.component.bookendCells(trEl); 14017 return skeletonEl; 14018 }; 14019 return DayGridFillRenderer; 14020}(FillRenderer_1.default)); 14021exports.default = DayGridFillRenderer; 14022 14023 14024/***/ }), 14025/* 246 */ 14026/***/ (function(module, exports, __webpack_require__) { 14027 14028Object.defineProperty(exports, "__esModule", { value: true }); 14029var tslib_1 = __webpack_require__(2); 14030var moment = __webpack_require__(0); 14031var util_1 = __webpack_require__(4); 14032var BasicView_1 = __webpack_require__(67); 14033var MonthViewDateProfileGenerator_1 = __webpack_require__(247); 14034/* A month view with day cells running in rows (one-per-week) and columns 14035----------------------------------------------------------------------------------------------------------------------*/ 14036var MonthView = /** @class */ (function (_super) { 14037 tslib_1.__extends(MonthView, _super); 14038 function MonthView() { 14039 return _super !== null && _super.apply(this, arguments) || this; 14040 } 14041 // Overrides the default BasicView behavior to have special multi-week auto-height logic 14042 MonthView.prototype.setGridHeight = function (height, isAuto) { 14043 // if auto, make the height of each row the height that it would be if there were 6 weeks 14044 if (isAuto) { 14045 height *= this.dayGrid.rowCnt / 6; 14046 } 14047 util_1.distributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows 14048 }; 14049 MonthView.prototype.isDateInOtherMonth = function (date, dateProfile) { 14050 return date.month() !== moment.utc(dateProfile.currentUnzonedRange.startMs).month(); // TODO: optimize 14051 }; 14052 return MonthView; 14053}(BasicView_1.default)); 14054exports.default = MonthView; 14055MonthView.prototype.dateProfileGeneratorClass = MonthViewDateProfileGenerator_1.default; 14056 14057 14058/***/ }), 14059/* 247 */ 14060/***/ (function(module, exports, __webpack_require__) { 14061 14062Object.defineProperty(exports, "__esModule", { value: true }); 14063var tslib_1 = __webpack_require__(2); 14064var BasicViewDateProfileGenerator_1 = __webpack_require__(68); 14065var UnzonedRange_1 = __webpack_require__(5); 14066var MonthViewDateProfileGenerator = /** @class */ (function (_super) { 14067 tslib_1.__extends(MonthViewDateProfileGenerator, _super); 14068 function MonthViewDateProfileGenerator() { 14069 return _super !== null && _super.apply(this, arguments) || this; 14070 } 14071 // Computes the date range that will be rendered. 14072 MonthViewDateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) { 14073 var renderUnzonedRange = _super.prototype.buildRenderRange.call(this, currentUnzonedRange, currentRangeUnit, isRangeAllDay); 14074 var start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay); 14075 var end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay); 14076 var rowCnt; 14077 // ensure 6 weeks 14078 if (this.opt('fixedWeekCount')) { 14079 rowCnt = Math.ceil(// could be partial weeks due to hiddenDays 14080 end.diff(start, 'weeks', true) // dontRound=true 14081 ); 14082 end.add(6 - rowCnt, 'weeks'); 14083 } 14084 return new UnzonedRange_1.default(start, end); 14085 }; 14086 return MonthViewDateProfileGenerator; 14087}(BasicViewDateProfileGenerator_1.default)); 14088exports.default = MonthViewDateProfileGenerator; 14089 14090 14091/***/ }), 14092/* 248 */ 14093/***/ (function(module, exports, __webpack_require__) { 14094 14095Object.defineProperty(exports, "__esModule", { value: true }); 14096var tslib_1 = __webpack_require__(2); 14097var $ = __webpack_require__(3); 14098var util_1 = __webpack_require__(4); 14099var UnzonedRange_1 = __webpack_require__(5); 14100var View_1 = __webpack_require__(43); 14101var Scroller_1 = __webpack_require__(41); 14102var ListEventRenderer_1 = __webpack_require__(249); 14103var ListEventPointing_1 = __webpack_require__(250); 14104/* 14105Responsible for the scroller, and forwarding event-related actions into the "grid". 14106*/ 14107var ListView = /** @class */ (function (_super) { 14108 tslib_1.__extends(ListView, _super); 14109 function ListView(calendar, viewSpec) { 14110 var _this = _super.call(this, calendar, viewSpec) || this; 14111 _this.segSelector = '.fc-list-item'; // which elements accept event actions 14112 _this.scroller = new Scroller_1.default({ 14113 overflowX: 'hidden', 14114 overflowY: 'auto' 14115 }); 14116 return _this; 14117 } 14118 ListView.prototype.renderSkeleton = function () { 14119 this.el.addClass('fc-list-view ' + 14120 this.calendar.theme.getClass('listView')); 14121 this.scroller.render(); 14122 this.scroller.el.appendTo(this.el); 14123 this.contentEl = this.scroller.scrollEl; // shortcut 14124 }; 14125 ListView.prototype.unrenderSkeleton = function () { 14126 this.scroller.destroy(); // will remove the Grid too 14127 }; 14128 ListView.prototype.updateSize = function (totalHeight, isAuto, isResize) { 14129 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize); 14130 this.scroller.clear(); // sets height to 'auto' and clears overflow 14131 if (!isAuto) { 14132 this.scroller.setHeight(this.computeScrollerHeight(totalHeight)); 14133 } 14134 }; 14135 ListView.prototype.computeScrollerHeight = function (totalHeight) { 14136 return totalHeight - 14137 util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller 14138 }; 14139 ListView.prototype.renderDates = function (dateProfile) { 14140 var calendar = this.calendar; 14141 var dayStart = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.startMs, true); 14142 var viewEnd = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.endMs, true); 14143 var dayDates = []; 14144 var dayRanges = []; 14145 while (dayStart < viewEnd) { 14146 dayDates.push(dayStart.clone()); 14147 dayRanges.push(new UnzonedRange_1.default(dayStart, dayStart.clone().add(1, 'day'))); 14148 dayStart.add(1, 'day'); 14149 } 14150 this.dayDates = dayDates; 14151 this.dayRanges = dayRanges; 14152 // all real rendering happens in EventRenderer 14153 }; 14154 // slices by day 14155 ListView.prototype.componentFootprintToSegs = function (footprint) { 14156 var dayRanges = this.dayRanges; 14157 var dayIndex; 14158 var segRange; 14159 var seg; 14160 var segs = []; 14161 for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex++) { 14162 segRange = footprint.unzonedRange.intersect(dayRanges[dayIndex]); 14163 if (segRange) { 14164 seg = { 14165 startMs: segRange.startMs, 14166 endMs: segRange.endMs, 14167 isStart: segRange.isStart, 14168 isEnd: segRange.isEnd, 14169 dayIndex: dayIndex 14170 }; 14171 segs.push(seg); 14172 // detect when footprint won't go fully into the next day, 14173 // and mutate the latest seg to the be the end. 14174 if (!seg.isEnd && !footprint.isAllDay && 14175 dayIndex + 1 < dayRanges.length && 14176 footprint.unzonedRange.endMs < dayRanges[dayIndex + 1].startMs + this.nextDayThreshold) { 14177 seg.endMs = footprint.unzonedRange.endMs; 14178 seg.isEnd = true; 14179 break; 14180 } 14181 } 14182 } 14183 return segs; 14184 }; 14185 ListView.prototype.renderEmptyMessage = function () { 14186 this.contentEl.html('<div class="fc-list-empty-wrap2">' + // TODO: try less wraps 14187 '<div class="fc-list-empty-wrap1">' + 14188 '<div class="fc-list-empty">' + 14189 util_1.htmlEscape(this.opt('noEventsMessage')) + 14190 '</div>' + 14191 '</div>' + 14192 '</div>'); 14193 }; 14194 // render the event segments in the view 14195 ListView.prototype.renderSegList = function (allSegs) { 14196 var segsByDay = this.groupSegsByDay(allSegs); // sparse array 14197 var dayIndex; 14198 var daySegs; 14199 var i; 14200 var tableEl = $('<table class="fc-list-table ' + this.calendar.theme.getClass('tableList') + '"><tbody></tbody></table>'); 14201 var tbodyEl = tableEl.find('tbody'); 14202 for (dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) { 14203 daySegs = segsByDay[dayIndex]; 14204 if (daySegs) { // sparse array, so might be undefined 14205 // append a day header 14206 tbodyEl.append(this.dayHeaderHtml(this.dayDates[dayIndex])); 14207 this.eventRenderer.sortEventSegs(daySegs); 14208 for (i = 0; i < daySegs.length; i++) { 14209 tbodyEl.append(daySegs[i].el); // append event row 14210 } 14211 } 14212 } 14213 this.contentEl.empty().append(tableEl); 14214 }; 14215 // Returns a sparse array of arrays, segs grouped by their dayIndex 14216 ListView.prototype.groupSegsByDay = function (segs) { 14217 var segsByDay = []; // sparse array 14218 var i; 14219 var seg; 14220 for (i = 0; i < segs.length; i++) { 14221 seg = segs[i]; 14222 (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = [])) 14223 .push(seg); 14224 } 14225 return segsByDay; 14226 }; 14227 // generates the HTML for the day headers that live amongst the event rows 14228 ListView.prototype.dayHeaderHtml = function (dayDate) { 14229 var mainFormat = this.opt('listDayFormat'); 14230 var altFormat = this.opt('listDayAltFormat'); 14231 return '<tr class="fc-list-heading" data-date="' + dayDate.format('YYYY-MM-DD') + '">' + 14232 '<td class="' + (this.calendar.theme.getClass('tableListHeading') || 14233 this.calendar.theme.getClass('widgetHeader')) + '" colspan="3">' + 14234 (mainFormat ? 14235 this.buildGotoAnchorHtml(dayDate, { 'class': 'fc-list-heading-main' }, util_1.htmlEscape(dayDate.format(mainFormat)) // inner HTML 14236 ) : 14237 '') + 14238 (altFormat ? 14239 this.buildGotoAnchorHtml(dayDate, { 'class': 'fc-list-heading-alt' }, util_1.htmlEscape(dayDate.format(altFormat)) // inner HTML 14240 ) : 14241 '') + 14242 '</td>' + 14243 '</tr>'; 14244 }; 14245 return ListView; 14246}(View_1.default)); 14247exports.default = ListView; 14248ListView.prototype.eventRendererClass = ListEventRenderer_1.default; 14249ListView.prototype.eventPointingClass = ListEventPointing_1.default; 14250 14251 14252/***/ }), 14253/* 249 */ 14254/***/ (function(module, exports, __webpack_require__) { 14255 14256Object.defineProperty(exports, "__esModule", { value: true }); 14257var tslib_1 = __webpack_require__(2); 14258var util_1 = __webpack_require__(4); 14259var EventRenderer_1 = __webpack_require__(44); 14260var ListEventRenderer = /** @class */ (function (_super) { 14261 tslib_1.__extends(ListEventRenderer, _super); 14262 function ListEventRenderer() { 14263 return _super !== null && _super.apply(this, arguments) || this; 14264 } 14265 ListEventRenderer.prototype.renderFgSegs = function (segs) { 14266 if (!segs.length) { 14267 this.component.renderEmptyMessage(); 14268 } 14269 else { 14270 this.component.renderSegList(segs); 14271 } 14272 }; 14273 // generates the HTML for a single event row 14274 ListEventRenderer.prototype.fgSegHtml = function (seg) { 14275 var view = this.view; 14276 var calendar = view.calendar; 14277 var theme = calendar.theme; 14278 var eventFootprint = seg.footprint; 14279 var eventDef = eventFootprint.eventDef; 14280 var componentFootprint = eventFootprint.componentFootprint; 14281 var url = eventDef.url; 14282 var classes = ['fc-list-item'].concat(this.getClasses(eventDef)); 14283 var bgColor = this.getBgColor(eventDef); 14284 var timeHtml; 14285 if (componentFootprint.isAllDay) { 14286 timeHtml = view.getAllDayHtml(); 14287 } 14288 else if (view.isMultiDayRange(componentFootprint.unzonedRange)) { 14289 if (seg.isStart || seg.isEnd) { // outer segment that probably lasts part of the day 14290 timeHtml = util_1.htmlEscape(this._getTimeText(calendar.msToMoment(seg.startMs), calendar.msToMoment(seg.endMs), componentFootprint.isAllDay)); 14291 } 14292 else { // inner segment that lasts the whole day 14293 timeHtml = view.getAllDayHtml(); 14294 } 14295 } 14296 else { 14297 // Display the normal time text for the *event's* times 14298 timeHtml = util_1.htmlEscape(this.getTimeText(eventFootprint)); 14299 } 14300 if (url) { 14301 classes.push('fc-has-url'); 14302 } 14303 return '<tr class="' + classes.join(' ') + '">' + 14304 (this.displayEventTime ? 14305 '<td class="fc-list-item-time ' + theme.getClass('widgetContent') + '">' + 14306 (timeHtml || '') + 14307 '</td>' : 14308 '') + 14309 '<td class="fc-list-item-marker ' + theme.getClass('widgetContent') + '">' + 14310 '<span class="fc-event-dot"' + 14311 (bgColor ? 14312 ' style="background-color:' + bgColor + '"' : 14313 '') + 14314 '></span>' + 14315 '</td>' + 14316 '<td class="fc-list-item-title ' + theme.getClass('widgetContent') + '">' + 14317 '<a' + (url ? ' href="' + util_1.htmlEscape(url) + '"' : '') + '>' + 14318 util_1.htmlEscape(eventDef.title || '') + 14319 '</a>' + 14320 '</td>' + 14321 '</tr>'; 14322 }; 14323 // like "4:00am" 14324 ListEventRenderer.prototype.computeEventTimeFormat = function () { 14325 return this.opt('mediumTimeFormat'); 14326 }; 14327 return ListEventRenderer; 14328}(EventRenderer_1.default)); 14329exports.default = ListEventRenderer; 14330 14331 14332/***/ }), 14333/* 250 */ 14334/***/ (function(module, exports, __webpack_require__) { 14335 14336Object.defineProperty(exports, "__esModule", { value: true }); 14337var tslib_1 = __webpack_require__(2); 14338var $ = __webpack_require__(3); 14339var EventPointing_1 = __webpack_require__(64); 14340var ListEventPointing = /** @class */ (function (_super) { 14341 tslib_1.__extends(ListEventPointing, _super); 14342 function ListEventPointing() { 14343 return _super !== null && _super.apply(this, arguments) || this; 14344 } 14345 // for events with a url, the whole <tr> should be clickable, 14346 // but it's impossible to wrap with an <a> tag. simulate this. 14347 ListEventPointing.prototype.handleClick = function (seg, ev) { 14348 var url; 14349 _super.prototype.handleClick.call(this, seg, ev); // might prevent the default action 14350 // not clicking on or within an <a> with an href 14351 if (!$(ev.target).closest('a[href]').length) { 14352 url = seg.footprint.eventDef.url; 14353 if (url && !ev.isDefaultPrevented()) { // jsEvent not cancelled in handler 14354 window.location.href = url; // simulate link click 14355 } 14356 } 14357 }; 14358 return ListEventPointing; 14359}(EventPointing_1.default)); 14360exports.default = ListEventPointing; 14361 14362 14363/***/ }), 14364/* 251 */, 14365/* 252 */, 14366/* 253 */, 14367/* 254 */, 14368/* 255 */, 14369/* 256 */ 14370/***/ (function(module, exports, __webpack_require__) { 14371 14372var $ = __webpack_require__(3); 14373var exportHooks = __webpack_require__(18); 14374var util_1 = __webpack_require__(4); 14375var Calendar_1 = __webpack_require__(232); 14376// for intentional side-effects 14377__webpack_require__(11); 14378__webpack_require__(49); 14379__webpack_require__(260); 14380__webpack_require__(261); 14381__webpack_require__(264); 14382__webpack_require__(265); 14383__webpack_require__(266); 14384__webpack_require__(267); 14385$.fullCalendar = exportHooks; 14386$.fn.fullCalendar = function (options) { 14387 var args = Array.prototype.slice.call(arguments, 1); // for a possible method call 14388 var res = this; // what this function will return (this jQuery object by default) 14389 this.each(function (i, _element) { 14390 var element = $(_element); 14391 var calendar = element.data('fullCalendar'); // get the existing calendar object (if any) 14392 var singleRes; // the returned value of this single method call 14393 // a method call 14394 if (typeof options === 'string') { 14395 if (options === 'getCalendar') { 14396 if (!i) { // first element only 14397 res = calendar; 14398 } 14399 } 14400 else if (options === 'destroy') { // don't warn if no calendar object 14401 if (calendar) { 14402 calendar.destroy(); 14403 element.removeData('fullCalendar'); 14404 } 14405 } 14406 else if (!calendar) { 14407 util_1.warn('Attempting to call a FullCalendar method on an element with no calendar.'); 14408 } 14409 else if ($.isFunction(calendar[options])) { 14410 singleRes = calendar[options].apply(calendar, args); 14411 if (!i) { 14412 res = singleRes; // record the first method call result 14413 } 14414 if (options === 'destroy') { // for the destroy method, must remove Calendar object data 14415 element.removeData('fullCalendar'); 14416 } 14417 } 14418 else { 14419 util_1.warn("'" + options + "' is an unknown FullCalendar method."); 14420 } 14421 } 14422 else if (!calendar) { // don't initialize twice 14423 calendar = new Calendar_1.default(element, options); 14424 element.data('fullCalendar', calendar); 14425 calendar.render(); 14426 } 14427 }); 14428 return res; 14429}; 14430module.exports = exportHooks; 14431 14432 14433/***/ }), 14434/* 257 */ 14435/***/ (function(module, exports, __webpack_require__) { 14436 14437Object.defineProperty(exports, "__esModule", { value: true }); 14438var $ = __webpack_require__(3); 14439var util_1 = __webpack_require__(4); 14440/* Toolbar with buttons and title 14441----------------------------------------------------------------------------------------------------------------------*/ 14442var Toolbar = /** @class */ (function () { 14443 function Toolbar(calendar, toolbarOptions) { 14444 this.el = null; // mirrors local `el` 14445 this.viewsWithButtons = []; 14446 this.calendar = calendar; 14447 this.toolbarOptions = toolbarOptions; 14448 } 14449 // method to update toolbar-specific options, not calendar-wide options 14450 Toolbar.prototype.setToolbarOptions = function (newToolbarOptions) { 14451 this.toolbarOptions = newToolbarOptions; 14452 }; 14453 // can be called repeatedly and will rerender 14454 Toolbar.prototype.render = function () { 14455 var sections = this.toolbarOptions.layout; 14456 var el = this.el; 14457 if (sections) { 14458 if (!el) { 14459 el = this.el = $("<div class='fc-toolbar " + this.toolbarOptions.extraClasses + "'>"); 14460 } 14461 else { 14462 el.empty(); 14463 } 14464 el.append(this.renderSection('left')) 14465 .append(this.renderSection('right')) 14466 .append(this.renderSection('center')) 14467 .append('<div class="fc-clear"></div>'); 14468 } 14469 else { 14470 this.removeElement(); 14471 } 14472 }; 14473 Toolbar.prototype.removeElement = function () { 14474 if (this.el) { 14475 this.el.remove(); 14476 this.el = null; 14477 } 14478 }; 14479 Toolbar.prototype.renderSection = function (position) { 14480 var _this = this; 14481 var calendar = this.calendar; 14482 var theme = calendar.theme; 14483 var optionsManager = calendar.optionsManager; 14484 var viewSpecManager = calendar.viewSpecManager; 14485 var sectionEl = $('<div class="fc-' + position + '">'); 14486 var buttonStr = this.toolbarOptions.layout[position]; 14487 var calendarCustomButtons = optionsManager.get('customButtons') || {}; 14488 var calendarButtonTextOverrides = optionsManager.overrides.buttonText || {}; 14489 var calendarButtonText = optionsManager.get('buttonText') || {}; 14490 if (buttonStr) { 14491 $.each(buttonStr.split(' '), function (i, buttonGroupStr) { 14492 var groupChildren = $(); 14493 var isOnlyButtons = true; 14494 var groupEl; 14495 $.each(buttonGroupStr.split(','), function (j, buttonName) { 14496 var customButtonProps; 14497 var viewSpec; 14498 var buttonClick; 14499 var buttonIcon; // only one of these will be set 14500 var buttonText; // " 14501 var buttonInnerHtml; 14502 var buttonClasses; 14503 var buttonEl; 14504 var buttonAriaAttr; 14505 if (buttonName === 'title') { 14506 groupChildren = groupChildren.add($('<h2> </h2>')); // we always want it to take up height 14507 isOnlyButtons = false; 14508 } 14509 else { 14510 if ((customButtonProps = calendarCustomButtons[buttonName])) { 14511 buttonClick = function (ev) { 14512 if (customButtonProps.click) { 14513 customButtonProps.click.call(buttonEl[0], ev); 14514 } 14515 }; 14516 (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) || 14517 (buttonIcon = theme.getIconClass(buttonName)) || 14518 (buttonText = customButtonProps.text); 14519 } 14520 else if ((viewSpec = viewSpecManager.getViewSpec(buttonName))) { 14521 _this.viewsWithButtons.push(buttonName); 14522 buttonClick = function () { 14523 calendar.changeView(buttonName); 14524 }; 14525 (buttonText = viewSpec.buttonTextOverride) || 14526 (buttonIcon = theme.getIconClass(buttonName)) || 14527 (buttonText = viewSpec.buttonTextDefault); 14528 } 14529 else if (calendar[buttonName]) { // a calendar method 14530 buttonClick = function () { 14531 calendar[buttonName](); 14532 }; 14533 (buttonText = calendarButtonTextOverrides[buttonName]) || 14534 (buttonIcon = theme.getIconClass(buttonName)) || 14535 (buttonText = calendarButtonText[buttonName]); 14536 // ^ everything else is considered default 14537 } 14538 if (buttonClick) { 14539 buttonClasses = [ 14540 'fc-' + buttonName + '-button', 14541 theme.getClass('button'), 14542 theme.getClass('stateDefault') 14543 ]; 14544 if (buttonText) { 14545 buttonInnerHtml = util_1.htmlEscape(buttonText); 14546 buttonAriaAttr = ''; 14547 } 14548 else if (buttonIcon) { 14549 buttonInnerHtml = "<span class='" + buttonIcon + "'></span>"; 14550 buttonAriaAttr = ' aria-label="' + buttonName + '"'; 14551 } 14552 buttonEl = $(// type="button" so that it doesn't submit a form 14553 '<button type="button" class="' + buttonClasses.join(' ') + '"' + 14554 buttonAriaAttr + 14555 '>' + buttonInnerHtml + '</button>') 14556 .click(function (ev) { 14557 // don't process clicks for disabled buttons 14558 if (!buttonEl.hasClass(theme.getClass('stateDisabled'))) { 14559 buttonClick(ev); 14560 // after the click action, if the button becomes the "active" tab, or disabled, 14561 // it should never have a hover class, so remove it now. 14562 if (buttonEl.hasClass(theme.getClass('stateActive')) || 14563 buttonEl.hasClass(theme.getClass('stateDisabled'))) { 14564 buttonEl.removeClass(theme.getClass('stateHover')); 14565 } 14566 } 14567 }) 14568 .mousedown(function () { 14569 // the *down* effect (mouse pressed in). 14570 // only on buttons that are not the "active" tab, or disabled 14571 buttonEl 14572 .not('.' + theme.getClass('stateActive')) 14573 .not('.' + theme.getClass('stateDisabled')) 14574 .addClass(theme.getClass('stateDown')); 14575 }) 14576 .mouseup(function () { 14577 // undo the *down* effect 14578 buttonEl.removeClass(theme.getClass('stateDown')); 14579 }) 14580 .hover(function () { 14581 // the *hover* effect. 14582 // only on buttons that are not the "active" tab, or disabled 14583 buttonEl 14584 .not('.' + theme.getClass('stateActive')) 14585 .not('.' + theme.getClass('stateDisabled')) 14586 .addClass(theme.getClass('stateHover')); 14587 }, function () { 14588 // undo the *hover* effect 14589 buttonEl 14590 .removeClass(theme.getClass('stateHover')) 14591 .removeClass(theme.getClass('stateDown')); // if mouseleave happens before mouseup 14592 }); 14593 groupChildren = groupChildren.add(buttonEl); 14594 } 14595 } 14596 }); 14597 if (isOnlyButtons) { 14598 groupChildren 14599 .first().addClass(theme.getClass('cornerLeft')).end() 14600 .last().addClass(theme.getClass('cornerRight')).end(); 14601 } 14602 if (groupChildren.length > 1) { 14603 groupEl = $('<div>'); 14604 if (isOnlyButtons) { 14605 groupEl.addClass(theme.getClass('buttonGroup')); 14606 } 14607 groupEl.append(groupChildren); 14608 sectionEl.append(groupEl); 14609 } 14610 else { 14611 sectionEl.append(groupChildren); // 1 or 0 children 14612 } 14613 }); 14614 } 14615 return sectionEl; 14616 }; 14617 Toolbar.prototype.updateTitle = function (text) { 14618 if (this.el) { 14619 this.el.find('h2').text(text); 14620 } 14621 }; 14622 Toolbar.prototype.activateButton = function (buttonName) { 14623 if (this.el) { 14624 this.el.find('.fc-' + buttonName + '-button') 14625 .addClass(this.calendar.theme.getClass('stateActive')); 14626 } 14627 }; 14628 Toolbar.prototype.deactivateButton = function (buttonName) { 14629 if (this.el) { 14630 this.el.find('.fc-' + buttonName + '-button') 14631 .removeClass(this.calendar.theme.getClass('stateActive')); 14632 } 14633 }; 14634 Toolbar.prototype.disableButton = function (buttonName) { 14635 if (this.el) { 14636 this.el.find('.fc-' + buttonName + '-button') 14637 .prop('disabled', true) 14638 .addClass(this.calendar.theme.getClass('stateDisabled')); 14639 } 14640 }; 14641 Toolbar.prototype.enableButton = function (buttonName) { 14642 if (this.el) { 14643 this.el.find('.fc-' + buttonName + '-button') 14644 .prop('disabled', false) 14645 .removeClass(this.calendar.theme.getClass('stateDisabled')); 14646 } 14647 }; 14648 Toolbar.prototype.getViewsWithButtons = function () { 14649 return this.viewsWithButtons; 14650 }; 14651 return Toolbar; 14652}()); 14653exports.default = Toolbar; 14654 14655 14656/***/ }), 14657/* 258 */ 14658/***/ (function(module, exports, __webpack_require__) { 14659 14660Object.defineProperty(exports, "__esModule", { value: true }); 14661var tslib_1 = __webpack_require__(2); 14662var $ = __webpack_require__(3); 14663var util_1 = __webpack_require__(4); 14664var options_1 = __webpack_require__(33); 14665var locale_1 = __webpack_require__(32); 14666var Model_1 = __webpack_require__(51); 14667var OptionsManager = /** @class */ (function (_super) { 14668 tslib_1.__extends(OptionsManager, _super); 14669 function OptionsManager(_calendar, overrides) { 14670 var _this = _super.call(this) || this; 14671 _this._calendar = _calendar; 14672 _this.overrides = $.extend({}, overrides); // make a copy 14673 _this.dynamicOverrides = {}; 14674 _this.compute(); 14675 return _this; 14676 } 14677 OptionsManager.prototype.add = function (newOptionHash) { 14678 var optionCnt = 0; 14679 var optionName; 14680 this.recordOverrides(newOptionHash); // will trigger this model's watchers 14681 for (optionName in newOptionHash) { 14682 optionCnt++; 14683 } 14684 // special-case handling of single option change. 14685 // if only one option change, `optionName` will be its name. 14686 if (optionCnt === 1) { 14687 if (optionName === 'height' || optionName === 'contentHeight' || optionName === 'aspectRatio') { 14688 this._calendar.updateViewSize(true); // isResize=true 14689 return; 14690 } 14691 else if (optionName === 'defaultDate') { 14692 return; // can't change date this way. use gotoDate instead 14693 } 14694 else if (optionName === 'businessHours') { 14695 return; // this model already reacts to this 14696 } 14697 else if (/^(event|select)(Overlap|Constraint|Allow)$/.test(optionName)) { 14698 return; // doesn't affect rendering. only interactions. 14699 } 14700 else if (optionName === 'timezone') { 14701 this._calendar.view.flash('initialEvents'); 14702 return; 14703 } 14704 } 14705 // catch-all. rerender the header and footer and rebuild/rerender the current view 14706 this._calendar.renderHeader(); 14707 this._calendar.renderFooter(); 14708 // even non-current views will be affected by this option change. do before rerender 14709 // TODO: detangle 14710 this._calendar.viewsByType = {}; 14711 this._calendar.reinitView(); 14712 }; 14713 // Computes the flattened options hash for the calendar and assigns to `this.options`. 14714 // Assumes this.overrides and this.dynamicOverrides have already been initialized. 14715 OptionsManager.prototype.compute = function () { 14716 var locale; 14717 var localeDefaults; 14718 var isRTL; 14719 var dirDefaults; 14720 var rawOptions; 14721 locale = util_1.firstDefined(// explicit locale option given? 14722 this.dynamicOverrides.locale, this.overrides.locale); 14723 localeDefaults = locale_1.localeOptionHash[locale]; 14724 if (!localeDefaults) { // explicit locale option not given or invalid? 14725 locale = options_1.globalDefaults.locale; 14726 localeDefaults = locale_1.localeOptionHash[locale] || {}; 14727 } 14728 isRTL = util_1.firstDefined(// based on options computed so far, is direction RTL? 14729 this.dynamicOverrides.isRTL, this.overrides.isRTL, localeDefaults.isRTL, options_1.globalDefaults.isRTL); 14730 dirDefaults = isRTL ? options_1.rtlDefaults : {}; 14731 this.dirDefaults = dirDefaults; 14732 this.localeDefaults = localeDefaults; 14733 rawOptions = options_1.mergeOptions([ 14734 options_1.globalDefaults, 14735 dirDefaults, 14736 localeDefaults, 14737 this.overrides, 14738 this.dynamicOverrides 14739 ]); 14740 locale_1.populateInstanceComputableOptions(rawOptions); // fill in gaps with computed options 14741 this.reset(rawOptions); 14742 }; 14743 // stores the new options internally, but does not rerender anything. 14744 OptionsManager.prototype.recordOverrides = function (newOptionHash) { 14745 var optionName; 14746 for (optionName in newOptionHash) { 14747 this.dynamicOverrides[optionName] = newOptionHash[optionName]; 14748 } 14749 this._calendar.viewSpecManager.clearCache(); // the dynamic override invalidates the options in this cache, so just clear it 14750 this.compute(); // this.options needs to be recomputed after the dynamic override 14751 }; 14752 return OptionsManager; 14753}(Model_1.default)); 14754exports.default = OptionsManager; 14755 14756 14757/***/ }), 14758/* 259 */ 14759/***/ (function(module, exports, __webpack_require__) { 14760 14761Object.defineProperty(exports, "__esModule", { value: true }); 14762var moment = __webpack_require__(0); 14763var $ = __webpack_require__(3); 14764var ViewRegistry_1 = __webpack_require__(24); 14765var util_1 = __webpack_require__(4); 14766var options_1 = __webpack_require__(33); 14767var locale_1 = __webpack_require__(32); 14768var ViewSpecManager = /** @class */ (function () { 14769 function ViewSpecManager(optionsManager, _calendar) { 14770 this.optionsManager = optionsManager; 14771 this._calendar = _calendar; 14772 this.clearCache(); 14773 } 14774 ViewSpecManager.prototype.clearCache = function () { 14775 this.viewSpecCache = {}; 14776 }; 14777 // Gets information about how to create a view. Will use a cache. 14778 ViewSpecManager.prototype.getViewSpec = function (viewType) { 14779 var cache = this.viewSpecCache; 14780 return cache[viewType] || (cache[viewType] = this.buildViewSpec(viewType)); 14781 }; 14782 // Given a duration singular unit, like "week" or "day", finds a matching view spec. 14783 // Preference is given to views that have corresponding buttons. 14784 ViewSpecManager.prototype.getUnitViewSpec = function (unit) { 14785 var viewTypes; 14786 var i; 14787 var spec; 14788 if ($.inArray(unit, util_1.unitsDesc) !== -1) { 14789 // put views that have buttons first. there will be duplicates, but oh well 14790 viewTypes = this._calendar.header.getViewsWithButtons(); // TODO: include footer as well? 14791 $.each(ViewRegistry_1.viewHash, function (viewType) { 14792 viewTypes.push(viewType); 14793 }); 14794 for (i = 0; i < viewTypes.length; i++) { 14795 spec = this.getViewSpec(viewTypes[i]); 14796 if (spec) { 14797 if (spec.singleUnit === unit) { 14798 return spec; 14799 } 14800 } 14801 } 14802 } 14803 }; 14804 // Builds an object with information on how to create a given view 14805 ViewSpecManager.prototype.buildViewSpec = function (requestedViewType) { 14806 var viewOverrides = this.optionsManager.overrides.views || {}; 14807 var specChain = []; // for the view. lowest to highest priority 14808 var defaultsChain = []; // for the view. lowest to highest priority 14809 var overridesChain = []; // for the view. lowest to highest priority 14810 var viewType = requestedViewType; 14811 var spec; // for the view 14812 var overrides; // for the view 14813 var durationInput; 14814 var duration; 14815 var unit; 14816 // iterate from the specific view definition to a more general one until we hit an actual View class 14817 while (viewType) { 14818 spec = ViewRegistry_1.viewHash[viewType]; 14819 overrides = viewOverrides[viewType]; 14820 viewType = null; // clear. might repopulate for another iteration 14821 if (typeof spec === 'function') { // TODO: deprecate 14822 spec = { 'class': spec }; 14823 } 14824 if (spec) { 14825 specChain.unshift(spec); 14826 defaultsChain.unshift(spec.defaults || {}); 14827 durationInput = durationInput || spec.duration; 14828 viewType = viewType || spec.type; 14829 } 14830 if (overrides) { 14831 overridesChain.unshift(overrides); // view-specific option hashes have options at zero-level 14832 durationInput = durationInput || overrides.duration; 14833 viewType = viewType || overrides.type; 14834 } 14835 } 14836 spec = util_1.mergeProps(specChain); 14837 spec.type = requestedViewType; 14838 if (!spec['class']) { 14839 return false; 14840 } 14841 // fall back to top-level `duration` option 14842 durationInput = durationInput || 14843 this.optionsManager.dynamicOverrides.duration || 14844 this.optionsManager.overrides.duration; 14845 if (durationInput) { 14846 duration = moment.duration(durationInput); 14847 if (duration.valueOf()) { // valid? 14848 unit = util_1.computeDurationGreatestUnit(duration, durationInput); 14849 spec.duration = duration; 14850 spec.durationUnit = unit; 14851 // view is a single-unit duration, like "week" or "day" 14852 // incorporate options for this. lowest priority 14853 if (duration.as(unit) === 1) { 14854 spec.singleUnit = unit; 14855 overridesChain.unshift(viewOverrides[unit] || {}); 14856 } 14857 } 14858 } 14859 spec.defaults = options_1.mergeOptions(defaultsChain); 14860 spec.overrides = options_1.mergeOptions(overridesChain); 14861 this.buildViewSpecOptions(spec); 14862 this.buildViewSpecButtonText(spec, requestedViewType); 14863 return spec; 14864 }; 14865 // Builds and assigns a view spec's options object from its already-assigned defaults and overrides 14866 ViewSpecManager.prototype.buildViewSpecOptions = function (spec) { 14867 var optionsManager = this.optionsManager; 14868 spec.options = options_1.mergeOptions([ 14869 options_1.globalDefaults, 14870 spec.defaults, 14871 optionsManager.dirDefaults, 14872 optionsManager.localeDefaults, 14873 optionsManager.overrides, 14874 spec.overrides, 14875 optionsManager.dynamicOverrides // dynamically set via setter. highest precedence 14876 ]); 14877 locale_1.populateInstanceComputableOptions(spec.options); 14878 }; 14879 // Computes and assigns a view spec's buttonText-related options 14880 ViewSpecManager.prototype.buildViewSpecButtonText = function (spec, requestedViewType) { 14881 var optionsManager = this.optionsManager; 14882 // given an options object with a possible `buttonText` hash, lookup the buttonText for the 14883 // requested view, falling back to a generic unit entry like "week" or "day" 14884 function queryButtonText(options) { 14885 var buttonText = options.buttonText || {}; 14886 return buttonText[requestedViewType] || 14887 // view can decide to look up a certain key 14888 (spec.buttonTextKey ? buttonText[spec.buttonTextKey] : null) || 14889 // a key like "month" 14890 (spec.singleUnit ? buttonText[spec.singleUnit] : null); 14891 } 14892 // highest to lowest priority 14893 spec.buttonTextOverride = 14894 queryButtonText(optionsManager.dynamicOverrides) || 14895 queryButtonText(optionsManager.overrides) || // constructor-specified buttonText lookup hash takes precedence 14896 spec.overrides.buttonText; // `buttonText` for view-specific options is a string 14897 // highest to lowest priority. mirrors buildViewSpecOptions 14898 spec.buttonTextDefault = 14899 queryButtonText(optionsManager.localeDefaults) || 14900 queryButtonText(optionsManager.dirDefaults) || 14901 spec.defaults.buttonText || // a single string. from ViewSubclass.defaults 14902 queryButtonText(options_1.globalDefaults) || 14903 (spec.duration ? this._calendar.humanizeDuration(spec.duration) : null) || // like "3 days" 14904 requestedViewType; // fall back to given view name 14905 }; 14906 return ViewSpecManager; 14907}()); 14908exports.default = ViewSpecManager; 14909 14910 14911/***/ }), 14912/* 260 */ 14913/***/ (function(module, exports, __webpack_require__) { 14914 14915Object.defineProperty(exports, "__esModule", { value: true }); 14916var EventSourceParser_1 = __webpack_require__(38); 14917var ArrayEventSource_1 = __webpack_require__(56); 14918var FuncEventSource_1 = __webpack_require__(223); 14919var JsonFeedEventSource_1 = __webpack_require__(224); 14920EventSourceParser_1.default.registerClass(ArrayEventSource_1.default); 14921EventSourceParser_1.default.registerClass(FuncEventSource_1.default); 14922EventSourceParser_1.default.registerClass(JsonFeedEventSource_1.default); 14923 14924 14925/***/ }), 14926/* 261 */ 14927/***/ (function(module, exports, __webpack_require__) { 14928 14929Object.defineProperty(exports, "__esModule", { value: true }); 14930var ThemeRegistry_1 = __webpack_require__(57); 14931var StandardTheme_1 = __webpack_require__(221); 14932var JqueryUiTheme_1 = __webpack_require__(222); 14933var Bootstrap3Theme_1 = __webpack_require__(262); 14934var Bootstrap4Theme_1 = __webpack_require__(263); 14935ThemeRegistry_1.defineThemeSystem('standard', StandardTheme_1.default); 14936ThemeRegistry_1.defineThemeSystem('jquery-ui', JqueryUiTheme_1.default); 14937ThemeRegistry_1.defineThemeSystem('bootstrap3', Bootstrap3Theme_1.default); 14938ThemeRegistry_1.defineThemeSystem('bootstrap4', Bootstrap4Theme_1.default); 14939 14940 14941/***/ }), 14942/* 262 */ 14943/***/ (function(module, exports, __webpack_require__) { 14944 14945Object.defineProperty(exports, "__esModule", { value: true }); 14946var tslib_1 = __webpack_require__(2); 14947var Theme_1 = __webpack_require__(22); 14948var Bootstrap3Theme = /** @class */ (function (_super) { 14949 tslib_1.__extends(Bootstrap3Theme, _super); 14950 function Bootstrap3Theme() { 14951 return _super !== null && _super.apply(this, arguments) || this; 14952 } 14953 return Bootstrap3Theme; 14954}(Theme_1.default)); 14955exports.default = Bootstrap3Theme; 14956Bootstrap3Theme.prototype.classes = { 14957 widget: 'fc-bootstrap3', 14958 tableGrid: 'table-bordered', 14959 tableList: 'table', 14960 tableListHeading: 'active', 14961 buttonGroup: 'btn-group', 14962 button: 'btn btn-default', 14963 stateActive: 'active', 14964 stateDisabled: 'disabled', 14965 today: 'alert alert-info', 14966 popover: 'panel panel-default', 14967 popoverHeader: 'panel-heading', 14968 popoverContent: 'panel-body', 14969 // day grid 14970 // for left/right border color when border is inset from edges (all-day in agenda view) 14971 // avoid `panel` class b/c don't want margins/radius. only border color. 14972 headerRow: 'panel-default', 14973 dayRow: 'panel-default', 14974 // list view 14975 listView: 'panel panel-default' 14976}; 14977Bootstrap3Theme.prototype.baseIconClass = 'glyphicon'; 14978Bootstrap3Theme.prototype.iconClasses = { 14979 close: 'glyphicon-remove', 14980 prev: 'glyphicon-chevron-left', 14981 next: 'glyphicon-chevron-right', 14982 prevYear: 'glyphicon-backward', 14983 nextYear: 'glyphicon-forward' 14984}; 14985Bootstrap3Theme.prototype.iconOverrideOption = 'bootstrapGlyphicons'; 14986Bootstrap3Theme.prototype.iconOverrideCustomButtonOption = 'bootstrapGlyphicon'; 14987Bootstrap3Theme.prototype.iconOverridePrefix = 'glyphicon-'; 14988 14989 14990/***/ }), 14991/* 263 */ 14992/***/ (function(module, exports, __webpack_require__) { 14993 14994Object.defineProperty(exports, "__esModule", { value: true }); 14995var tslib_1 = __webpack_require__(2); 14996var Theme_1 = __webpack_require__(22); 14997var Bootstrap4Theme = /** @class */ (function (_super) { 14998 tslib_1.__extends(Bootstrap4Theme, _super); 14999 function Bootstrap4Theme() { 15000 return _super !== null && _super.apply(this, arguments) || this; 15001 } 15002 return Bootstrap4Theme; 15003}(Theme_1.default)); 15004exports.default = Bootstrap4Theme; 15005Bootstrap4Theme.prototype.classes = { 15006 widget: 'fc-bootstrap4', 15007 tableGrid: 'table-bordered', 15008 tableList: 'table', 15009 tableListHeading: 'table-active', 15010 buttonGroup: 'btn-group', 15011 button: 'btn btn-primary', 15012 stateActive: 'active', 15013 stateDisabled: 'disabled', 15014 today: 'alert alert-info', 15015 popover: 'card card-primary', 15016 popoverHeader: 'card-header', 15017 popoverContent: 'card-body', 15018 // day grid 15019 // for left/right border color when border is inset from edges (all-day in agenda view) 15020 // avoid `table` class b/c don't want margins/padding/structure. only border color. 15021 headerRow: 'table-bordered', 15022 dayRow: 'table-bordered', 15023 // list view 15024 listView: 'card card-primary' 15025}; 15026Bootstrap4Theme.prototype.baseIconClass = 'fa'; 15027Bootstrap4Theme.prototype.iconClasses = { 15028 close: 'fa-times', 15029 prev: 'fa-chevron-left', 15030 next: 'fa-chevron-right', 15031 prevYear: 'fa-angle-double-left', 15032 nextYear: 'fa-angle-double-right' 15033}; 15034Bootstrap4Theme.prototype.iconOverrideOption = 'bootstrapFontAwesome'; 15035Bootstrap4Theme.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome'; 15036Bootstrap4Theme.prototype.iconOverridePrefix = 'fa-'; 15037 15038 15039/***/ }), 15040/* 264 */ 15041/***/ (function(module, exports, __webpack_require__) { 15042 15043Object.defineProperty(exports, "__esModule", { value: true }); 15044var ViewRegistry_1 = __webpack_require__(24); 15045var BasicView_1 = __webpack_require__(67); 15046var MonthView_1 = __webpack_require__(246); 15047ViewRegistry_1.defineView('basic', { 15048 'class': BasicView_1.default 15049}); 15050ViewRegistry_1.defineView('basicDay', { 15051 type: 'basic', 15052 duration: { days: 1 } 15053}); 15054ViewRegistry_1.defineView('basicWeek', { 15055 type: 'basic', 15056 duration: { weeks: 1 } 15057}); 15058ViewRegistry_1.defineView('month', { 15059 'class': MonthView_1.default, 15060 duration: { months: 1 }, 15061 defaults: { 15062 fixedWeekCount: true 15063 } 15064}); 15065 15066 15067/***/ }), 15068/* 265 */ 15069/***/ (function(module, exports, __webpack_require__) { 15070 15071Object.defineProperty(exports, "__esModule", { value: true }); 15072var ViewRegistry_1 = __webpack_require__(24); 15073var AgendaView_1 = __webpack_require__(238); 15074ViewRegistry_1.defineView('agenda', { 15075 'class': AgendaView_1.default, 15076 defaults: { 15077 allDaySlot: true, 15078 slotDuration: '00:30:00', 15079 slotEventOverlap: true // a bad name. confused with overlap/constraint system 15080 } 15081}); 15082ViewRegistry_1.defineView('agendaDay', { 15083 type: 'agenda', 15084 duration: { days: 1 } 15085}); 15086ViewRegistry_1.defineView('agendaWeek', { 15087 type: 'agenda', 15088 duration: { weeks: 1 } 15089}); 15090 15091 15092/***/ }), 15093/* 266 */ 15094/***/ (function(module, exports, __webpack_require__) { 15095 15096Object.defineProperty(exports, "__esModule", { value: true }); 15097var ViewRegistry_1 = __webpack_require__(24); 15098var ListView_1 = __webpack_require__(248); 15099ViewRegistry_1.defineView('list', { 15100 'class': ListView_1.default, 15101 buttonTextKey: 'list', 15102 defaults: { 15103 buttonText: 'list', 15104 listDayFormat: 'LL', 15105 noEventsMessage: 'No events to display' 15106 } 15107}); 15108ViewRegistry_1.defineView('listDay', { 15109 type: 'list', 15110 duration: { days: 1 }, 15111 defaults: { 15112 listDayFormat: 'dddd' // day-of-week is all we need. full date is probably in header 15113 } 15114}); 15115ViewRegistry_1.defineView('listWeek', { 15116 type: 'list', 15117 duration: { weeks: 1 }, 15118 defaults: { 15119 listDayFormat: 'dddd', 15120 listDayAltFormat: 'LL' 15121 } 15122}); 15123ViewRegistry_1.defineView('listMonth', { 15124 type: 'list', 15125 duration: { month: 1 }, 15126 defaults: { 15127 listDayAltFormat: 'dddd' // day-of-week is nice-to-have 15128 } 15129}); 15130ViewRegistry_1.defineView('listYear', { 15131 type: 'list', 15132 duration: { year: 1 }, 15133 defaults: { 15134 listDayAltFormat: 'dddd' // day-of-week is nice-to-have 15135 } 15136}); 15137 15138 15139/***/ }), 15140/* 267 */ 15141/***/ (function(module, exports) { 15142 15143Object.defineProperty(exports, "__esModule", { value: true }); 15144 15145 15146/***/ }) 15147/******/ ]); 15148});